From 076ef26929413189ae5987b7cf41b2c3275f45fe Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Oct 2020 19:30:21 +1100 Subject: [PATCH 01/17] Include lib for AWS --- .gitignore | 2 +- lib/AccountLockout.js | 172 ++ lib/Adapters/AdapterLoader.js | 63 + lib/Adapters/Analytics/AnalyticsAdapter.js | 41 + lib/Adapters/Auth/AuthAdapter.js | 34 + lib/Adapters/Auth/OAuth1Client.js | 227 ++ lib/Adapters/Auth/apple.js | 105 + lib/Adapters/Auth/facebook.js | 62 + lib/Adapters/Auth/gcenter.js | 126 + lib/Adapters/Auth/github.js | 40 + lib/Adapters/Auth/google.js | 167 ++ lib/Adapters/Auth/gpgames.js | 35 + lib/Adapters/Auth/httpsRequest.js | 47 + lib/Adapters/Auth/index.js | 173 ++ lib/Adapters/Auth/instagram.js | 31 + lib/Adapters/Auth/janraincapture.js | 46 + lib/Adapters/Auth/janrainengage.js | 52 + lib/Adapters/Auth/keycloak.js | 125 + lib/Adapters/Auth/ldap.js | 83 + lib/Adapters/Auth/line.js | 41 + lib/Adapters/Auth/linkedin.js | 46 + lib/Adapters/Auth/meetup.js | 39 + lib/Adapters/Auth/microsoft.js | 39 + lib/Adapters/Auth/oauth2.js | 142 + lib/Adapters/Auth/phantauth.js | 47 + lib/Adapters/Auth/qq.js | 48 + lib/Adapters/Auth/spotify.js | 51 + lib/Adapters/Auth/twitter.js | 60 + lib/Adapters/Auth/vkontakte.js | 54 + lib/Adapters/Auth/wechat.js | 33 + lib/Adapters/Auth/weibo.js | 47 + lib/Adapters/Cache/CacheAdapter.js | 50 + lib/Adapters/Cache/InMemoryCache.js | 76 + lib/Adapters/Cache/InMemoryCacheAdapter.js | 45 + lib/Adapters/Cache/LRUCache.js | 46 + lib/Adapters/Cache/NullCacheAdapter.js | 34 + .../RedisCacheAdapter/KeyPromiseQueue.js | 59 + lib/Adapters/Cache/RedisCacheAdapter/index.js | 130 + lib/Adapters/Email/MailAdapter.js | 40 + lib/Adapters/Files/FilesAdapter.js | 136 + lib/Adapters/Files/GridFSBucketAdapter.js | 273 ++ lib/Adapters/Files/GridStoreAdapter.js | 182 ++ lib/Adapters/Logger/LoggerAdapter.js | 39 + lib/Adapters/Logger/WinstonLogger.js | 137 + lib/Adapters/Logger/WinstonLoggerAdapter.js | 75 + lib/Adapters/MessageQueue/EventEmitterMQ.js | 73 + lib/Adapters/PubSub/EventEmitterPubSub.js | 65 + lib/Adapters/PubSub/PubSubAdapter.js | 39 + lib/Adapters/PubSub/RedisPubSub.js | 33 + lib/Adapters/Push/PushAdapter.js | 50 + lib/Adapters/Storage/Mongo/MongoCollection.js | 229 ++ .../Storage/Mongo/MongoSchemaCollection.js | 365 +++ .../Storage/Mongo/MongoStorageAdapter.js | 957 +++++++ lib/Adapters/Storage/Mongo/MongoTransform.js | 1795 ++++++++++++ .../Storage/Postgres/PostgresClient.js | 40 + .../Storage/Postgres/PostgresConfigParser.js | 95 + .../Postgres/PostgresStorageAdapter.js | 2496 +++++++++++++++++ .../Storage/Postgres/sql/array/add-unique.sql | 11 + .../Storage/Postgres/sql/array/add.sql | 11 + .../Postgres/sql/array/contains-all-regex.sql | 14 + .../Postgres/sql/array/contains-all.sql | 14 + .../Storage/Postgres/sql/array/contains.sql | 11 + .../Storage/Postgres/sql/array/remove.sql | 11 + lib/Adapters/Storage/Postgres/sql/index.js | 35 + .../sql/misc/json-object-set-keys.sql | 19 + lib/Adapters/Storage/StorageAdapter.js | 2 + lib/Adapters/WebSocketServer/WSAdapter.js | 45 + lib/Adapters/WebSocketServer/WSSAdapter.js | 74 + lib/Auth.js | 373 +++ lib/ClientSDK.js | 47 + lib/Config.js | 348 +++ lib/Controllers/AdaptableController.js | 88 + lib/Controllers/AnalyticsController.js | 52 + lib/Controllers/CacheController.js | 92 + lib/Controllers/DatabaseController.js | 1485 ++++++++++ lib/Controllers/FilesController.js | 136 + lib/Controllers/HooksController.js | 301 ++ lib/Controllers/LiveQueryController.js | 71 + lib/Controllers/LoggerController.js | 265 ++ lib/Controllers/ParseGraphQLController.js | 358 +++ lib/Controllers/PushController.js | 257 ++ lib/Controllers/SchemaCache.js | 75 + lib/Controllers/SchemaController.js | 1662 +++++++++++ lib/Controllers/UserController.js | 318 +++ lib/Controllers/index.js | 312 +++ lib/Controllers/types.js | 2 + lib/GraphQL/ParseGraphQLSchema.js | 446 +++ lib/GraphQL/ParseGraphQLServer.js | 140 + lib/GraphQL/helpers/objectsMutations.js | 40 + lib/GraphQL/helpers/objectsQueries.js | 307 ++ .../loaders/defaultGraphQLMutations.js | 28 + lib/GraphQL/loaders/defaultGraphQLQueries.js | 29 + lib/GraphQL/loaders/defaultGraphQLTypes.js | 1271 +++++++++ lib/GraphQL/loaders/defaultRelaySchema.js | 71 + lib/GraphQL/loaders/filesMutations.js | 103 + lib/GraphQL/loaders/functionsMutations.js | 90 + lib/GraphQL/loaders/parseClassMutations.js | 288 ++ lib/GraphQL/loaders/parseClassQueries.js | 150 + lib/GraphQL/loaders/parseClassTypes.js | 531 ++++ lib/GraphQL/loaders/schemaDirectives.js | 72 + lib/GraphQL/loaders/schemaMutations.js | 179 ++ lib/GraphQL/loaders/schemaQueries.js | 93 + lib/GraphQL/loaders/schemaTypes.js | 376 +++ lib/GraphQL/loaders/usersMutations.js | 333 +++ lib/GraphQL/loaders/usersQueries.js | 111 + lib/GraphQL/parseGraphQLUtils.js | 69 + lib/GraphQL/transformers/className.js | 17 + lib/GraphQL/transformers/constraintType.js | 73 + lib/GraphQL/transformers/inputType.js | 71 + lib/GraphQL/transformers/mutation.js | 275 ++ lib/GraphQL/transformers/outputType.js | 71 + lib/GraphQL/transformers/query.js | 273 ++ lib/GraphQL/transformers/schemaFields.js | 128 + lib/LiveQuery/Client.js | 114 + lib/LiveQuery/Id.js | 26 + lib/LiveQuery/ParseCloudCodePublisher.js | 50 + lib/LiveQuery/ParseLiveQueryServer.js | 847 ++++++ lib/LiveQuery/ParsePubSub.js | 49 + lib/LiveQuery/ParseWebSocketServer.js | 80 + lib/LiveQuery/QueryTools.js | 407 +++ lib/LiveQuery/RequestSchema.js | 146 + lib/LiveQuery/SessionTokenCache.js | 67 + lib/LiveQuery/Subscription.js | 61 + lib/LiveQuery/equalObjects.js | 62 + lib/Options/Definitions.js | 531 ++++ lib/Options/docs.js | 122 + lib/Options/index.js | 18 + lib/Options/parsers.js | 90 + lib/ParseMessageQueue.js | 34 + lib/ParseServer.js | 495 ++++ lib/ParseServerRESTController.js | 184 ++ lib/PromiseRouter.js | 255 ++ lib/Push/PushQueue.js | 79 + lib/Push/PushWorker.js | 130 + lib/Push/utils.js | 159 ++ lib/RestQuery.js | 978 +++++++ lib/RestWrite.js | 1480 ++++++++++ lib/Routers/AggregateRouter.js | 153 + lib/Routers/AnalyticsRouter.js | 32 + lib/Routers/AudiencesRouter.js | 70 + lib/Routers/ClassesRouter.js | 231 ++ lib/Routers/CloudCodeRouter.js | 105 + lib/Routers/FeaturesRouter.js | 79 + lib/Routers/FilesRouter.js | 260 ++ lib/Routers/FunctionsRouter.js | 181 ++ lib/Routers/GlobalConfigRouter.js | 95 + lib/Routers/GraphQLRouter.js | 55 + lib/Routers/HooksRouter.js | 144 + lib/Routers/IAPValidationRouter.js | 136 + lib/Routers/InstallationsRouter.js | 57 + lib/Routers/LogsRouter.js | 71 + lib/Routers/PublicAPIRouter.js | 322 +++ lib/Routers/PurgeRouter.js | 60 + lib/Routers/PushRouter.js | 92 + lib/Routers/RolesRouter.js | 40 + lib/Routers/SchemasRouter.js | 120 + lib/Routers/SessionsRouter.js | 107 + lib/Routers/UsersRouter.js | 436 +++ lib/StatusHandler.js | 386 +++ lib/TestUtils.js | 31 + lib/batch.js | 132 + lib/cache.js | 16 + .../definitions/parse-live-query-server.js | 12 + lib/cli/definitions/parse-server.js | 12 + lib/cli/parse-live-query-server.js | 19 + lib/cli/parse-server.js | 111 + lib/cli/utils/commander.js | 163 ++ lib/cli/utils/runner.js | 65 + lib/cloud-code/HTTPResponse.js | 73 + lib/cloud-code/Parse.Cloud.js | 685 +++++ lib/cloud-code/httpRequest.js | 192 ++ lib/cryptoUtils.js | 62 + lib/defaults.js | 60 + lib/deprecated.js | 13 + lib/index.js | 107 + lib/logger.js | 47 + lib/middlewares.js | 492 ++++ lib/password.js | 38 + lib/request.js | 4 + lib/requiredParameter.js | 13 + lib/rest.js | 208 ++ lib/triggers.js | 1040 +++++++ lib/vendor/README.md | 8 + lib/vendor/mongodbUrl.js | 1064 +++++++ 184 files changed, 36323 insertions(+), 1 deletion(-) create mode 100644 lib/AccountLockout.js create mode 100644 lib/Adapters/AdapterLoader.js create mode 100644 lib/Adapters/Analytics/AnalyticsAdapter.js create mode 100644 lib/Adapters/Auth/AuthAdapter.js create mode 100644 lib/Adapters/Auth/OAuth1Client.js create mode 100644 lib/Adapters/Auth/apple.js create mode 100644 lib/Adapters/Auth/facebook.js create mode 100644 lib/Adapters/Auth/gcenter.js create mode 100644 lib/Adapters/Auth/github.js create mode 100644 lib/Adapters/Auth/google.js create mode 100644 lib/Adapters/Auth/gpgames.js create mode 100644 lib/Adapters/Auth/httpsRequest.js create mode 100755 lib/Adapters/Auth/index.js create mode 100644 lib/Adapters/Auth/instagram.js create mode 100644 lib/Adapters/Auth/janraincapture.js create mode 100644 lib/Adapters/Auth/janrainengage.js create mode 100644 lib/Adapters/Auth/keycloak.js create mode 100644 lib/Adapters/Auth/ldap.js create mode 100644 lib/Adapters/Auth/line.js create mode 100644 lib/Adapters/Auth/linkedin.js create mode 100644 lib/Adapters/Auth/meetup.js create mode 100644 lib/Adapters/Auth/microsoft.js create mode 100644 lib/Adapters/Auth/oauth2.js create mode 100644 lib/Adapters/Auth/phantauth.js create mode 100644 lib/Adapters/Auth/qq.js create mode 100644 lib/Adapters/Auth/spotify.js create mode 100644 lib/Adapters/Auth/twitter.js create mode 100644 lib/Adapters/Auth/vkontakte.js create mode 100644 lib/Adapters/Auth/wechat.js create mode 100644 lib/Adapters/Auth/weibo.js create mode 100644 lib/Adapters/Cache/CacheAdapter.js create mode 100644 lib/Adapters/Cache/InMemoryCache.js create mode 100644 lib/Adapters/Cache/InMemoryCacheAdapter.js create mode 100644 lib/Adapters/Cache/LRUCache.js create mode 100644 lib/Adapters/Cache/NullCacheAdapter.js create mode 100644 lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js create mode 100644 lib/Adapters/Cache/RedisCacheAdapter/index.js create mode 100644 lib/Adapters/Email/MailAdapter.js create mode 100644 lib/Adapters/Files/FilesAdapter.js create mode 100644 lib/Adapters/Files/GridFSBucketAdapter.js create mode 100644 lib/Adapters/Files/GridStoreAdapter.js create mode 100644 lib/Adapters/Logger/LoggerAdapter.js create mode 100644 lib/Adapters/Logger/WinstonLogger.js create mode 100644 lib/Adapters/Logger/WinstonLoggerAdapter.js create mode 100644 lib/Adapters/MessageQueue/EventEmitterMQ.js create mode 100644 lib/Adapters/PubSub/EventEmitterPubSub.js create mode 100644 lib/Adapters/PubSub/PubSubAdapter.js create mode 100644 lib/Adapters/PubSub/RedisPubSub.js create mode 100644 lib/Adapters/Push/PushAdapter.js create mode 100644 lib/Adapters/Storage/Mongo/MongoCollection.js create mode 100644 lib/Adapters/Storage/Mongo/MongoSchemaCollection.js create mode 100644 lib/Adapters/Storage/Mongo/MongoStorageAdapter.js create mode 100644 lib/Adapters/Storage/Mongo/MongoTransform.js create mode 100644 lib/Adapters/Storage/Postgres/PostgresClient.js create mode 100644 lib/Adapters/Storage/Postgres/PostgresConfigParser.js create mode 100644 lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js create mode 100644 lib/Adapters/Storage/Postgres/sql/array/add-unique.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/add.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/remove.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/index.js create mode 100644 lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql create mode 100644 lib/Adapters/Storage/StorageAdapter.js create mode 100644 lib/Adapters/WebSocketServer/WSAdapter.js create mode 100644 lib/Adapters/WebSocketServer/WSSAdapter.js create mode 100644 lib/Auth.js create mode 100644 lib/ClientSDK.js create mode 100644 lib/Config.js create mode 100644 lib/Controllers/AdaptableController.js create mode 100644 lib/Controllers/AnalyticsController.js create mode 100644 lib/Controllers/CacheController.js create mode 100644 lib/Controllers/DatabaseController.js create mode 100644 lib/Controllers/FilesController.js create mode 100644 lib/Controllers/HooksController.js create mode 100644 lib/Controllers/LiveQueryController.js create mode 100644 lib/Controllers/LoggerController.js create mode 100644 lib/Controllers/ParseGraphQLController.js create mode 100644 lib/Controllers/PushController.js create mode 100644 lib/Controllers/SchemaCache.js create mode 100644 lib/Controllers/SchemaController.js create mode 100644 lib/Controllers/UserController.js create mode 100644 lib/Controllers/index.js create mode 100644 lib/Controllers/types.js create mode 100644 lib/GraphQL/ParseGraphQLSchema.js create mode 100644 lib/GraphQL/ParseGraphQLServer.js create mode 100644 lib/GraphQL/helpers/objectsMutations.js create mode 100644 lib/GraphQL/helpers/objectsQueries.js create mode 100644 lib/GraphQL/loaders/defaultGraphQLMutations.js create mode 100644 lib/GraphQL/loaders/defaultGraphQLQueries.js create mode 100644 lib/GraphQL/loaders/defaultGraphQLTypes.js create mode 100644 lib/GraphQL/loaders/defaultRelaySchema.js create mode 100644 lib/GraphQL/loaders/filesMutations.js create mode 100644 lib/GraphQL/loaders/functionsMutations.js create mode 100644 lib/GraphQL/loaders/parseClassMutations.js create mode 100644 lib/GraphQL/loaders/parseClassQueries.js create mode 100644 lib/GraphQL/loaders/parseClassTypes.js create mode 100644 lib/GraphQL/loaders/schemaDirectives.js create mode 100644 lib/GraphQL/loaders/schemaMutations.js create mode 100644 lib/GraphQL/loaders/schemaQueries.js create mode 100644 lib/GraphQL/loaders/schemaTypes.js create mode 100644 lib/GraphQL/loaders/usersMutations.js create mode 100644 lib/GraphQL/loaders/usersQueries.js create mode 100644 lib/GraphQL/parseGraphQLUtils.js create mode 100644 lib/GraphQL/transformers/className.js create mode 100644 lib/GraphQL/transformers/constraintType.js create mode 100644 lib/GraphQL/transformers/inputType.js create mode 100644 lib/GraphQL/transformers/mutation.js create mode 100644 lib/GraphQL/transformers/outputType.js create mode 100644 lib/GraphQL/transformers/query.js create mode 100644 lib/GraphQL/transformers/schemaFields.js create mode 100644 lib/LiveQuery/Client.js create mode 100644 lib/LiveQuery/Id.js create mode 100644 lib/LiveQuery/ParseCloudCodePublisher.js create mode 100644 lib/LiveQuery/ParseLiveQueryServer.js create mode 100644 lib/LiveQuery/ParsePubSub.js create mode 100644 lib/LiveQuery/ParseWebSocketServer.js create mode 100644 lib/LiveQuery/QueryTools.js create mode 100644 lib/LiveQuery/RequestSchema.js create mode 100644 lib/LiveQuery/SessionTokenCache.js create mode 100644 lib/LiveQuery/Subscription.js create mode 100644 lib/LiveQuery/equalObjects.js create mode 100644 lib/Options/Definitions.js create mode 100644 lib/Options/docs.js create mode 100644 lib/Options/index.js create mode 100644 lib/Options/parsers.js create mode 100644 lib/ParseMessageQueue.js create mode 100644 lib/ParseServer.js create mode 100644 lib/ParseServerRESTController.js create mode 100644 lib/PromiseRouter.js create mode 100644 lib/Push/PushQueue.js create mode 100644 lib/Push/PushWorker.js create mode 100644 lib/Push/utils.js create mode 100644 lib/RestQuery.js create mode 100644 lib/RestWrite.js create mode 100644 lib/Routers/AggregateRouter.js create mode 100644 lib/Routers/AnalyticsRouter.js create mode 100644 lib/Routers/AudiencesRouter.js create mode 100644 lib/Routers/ClassesRouter.js create mode 100644 lib/Routers/CloudCodeRouter.js create mode 100644 lib/Routers/FeaturesRouter.js create mode 100644 lib/Routers/FilesRouter.js create mode 100644 lib/Routers/FunctionsRouter.js create mode 100644 lib/Routers/GlobalConfigRouter.js create mode 100644 lib/Routers/GraphQLRouter.js create mode 100644 lib/Routers/HooksRouter.js create mode 100644 lib/Routers/IAPValidationRouter.js create mode 100644 lib/Routers/InstallationsRouter.js create mode 100644 lib/Routers/LogsRouter.js create mode 100644 lib/Routers/PublicAPIRouter.js create mode 100644 lib/Routers/PurgeRouter.js create mode 100644 lib/Routers/PushRouter.js create mode 100644 lib/Routers/RolesRouter.js create mode 100644 lib/Routers/SchemasRouter.js create mode 100644 lib/Routers/SessionsRouter.js create mode 100644 lib/Routers/UsersRouter.js create mode 100644 lib/StatusHandler.js create mode 100644 lib/TestUtils.js create mode 100644 lib/batch.js create mode 100644 lib/cache.js create mode 100644 lib/cli/definitions/parse-live-query-server.js create mode 100644 lib/cli/definitions/parse-server.js create mode 100644 lib/cli/parse-live-query-server.js create mode 100755 lib/cli/parse-server.js create mode 100644 lib/cli/utils/commander.js create mode 100644 lib/cli/utils/runner.js create mode 100644 lib/cloud-code/HTTPResponse.js create mode 100644 lib/cloud-code/Parse.Cloud.js create mode 100644 lib/cloud-code/httpRequest.js create mode 100644 lib/cryptoUtils.js create mode 100644 lib/defaults.js create mode 100644 lib/deprecated.js create mode 100644 lib/index.js create mode 100644 lib/logger.js create mode 100644 lib/middlewares.js create mode 100644 lib/password.js create mode 100644 lib/request.js create mode 100644 lib/requiredParameter.js create mode 100644 lib/rest.js create mode 100644 lib/triggers.js create mode 100644 lib/vendor/README.md create mode 100644 lib/vendor/mongodbUrl.js diff --git a/.gitignore b/.gitignore index e4e19156c2..751741e08a 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,7 @@ node_modules .vscode # Babel.js -lib/ + # cache folder .cache diff --git a/lib/AccountLockout.js b/lib/AccountLockout.js new file mode 100644 index 0000000000..45fe53ef56 --- /dev/null +++ b/lib/AccountLockout.js @@ -0,0 +1,172 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AccountLockout = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// This class handles the Account Lockout Policy settings. +class AccountLockout { + constructor(user, config) { + this._user = user; + this._config = config; + } + /** + * set _failed_login_count to value + */ + + + _setFailedLoginCount(value) { + const query = { + username: this._user.username + }; + const updateFields = { + _failed_login_count: value + }; + return this._config.database.update('_User', query, updateFields); + } + /** + * check if the _failed_login_count field has been set + */ + + + _isFailedLoginCountSet() { + const query = { + username: this._user.username, + _failed_login_count: { + $exists: true + } + }; + return this._config.database.find('_User', query).then(users => { + if (Array.isArray(users) && users.length > 0) { + return true; + } else { + return false; + } + }); + } + /** + * if _failed_login_count is NOT set then set it to 0 + * else do nothing + */ + + + _initFailedLoginCount() { + return this._isFailedLoginCountSet().then(failedLoginCountIsSet => { + if (!failedLoginCountIsSet) { + return this._setFailedLoginCount(0); + } + }); + } + /** + * increment _failed_login_count by 1 + */ + + + _incrementFailedLoginCount() { + const query = { + username: this._user.username + }; + const updateFields = { + _failed_login_count: { + __op: 'Increment', + amount: 1 + } + }; + return this._config.database.update('_User', query, updateFields); + } + /** + * if the failed login count is greater than the threshold + * then sets lockout expiration to 'currenttime + accountPolicy.duration', i.e., account is locked out for the next 'accountPolicy.duration' minutes + * else do nothing + */ + + + _setLockoutExpiration() { + const query = { + username: this._user.username, + _failed_login_count: { + $gte: this._config.accountLockout.threshold + } + }; + const now = new Date(); + const updateFields = { + _account_lockout_expires_at: _node.default._encode(new Date(now.getTime() + this._config.accountLockout.duration * 60 * 1000)) + }; + return this._config.database.update('_User', query, updateFields).catch(err => { + if (err && err.code && err.message && err.code === 101 && err.message === 'Object not found.') { + return; // nothing to update so we are good + } else { + throw err; // unknown error + } + }); + } + /** + * if _account_lockout_expires_at > current_time and _failed_login_count > threshold + * reject with account locked error + * else + * resolve + */ + + + _notLocked() { + const query = { + username: this._user.username, + _account_lockout_expires_at: { + $gt: _node.default._encode(new Date()) + }, + _failed_login_count: { + $gte: this._config.accountLockout.threshold + } + }; + return this._config.database.find('_User', query).then(users => { + if (Array.isArray(users) && users.length > 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your account is locked due to multiple failed login attempts. Please try again after ' + this._config.accountLockout.duration + ' minute(s)'); + } + }); + } + /** + * set and/or increment _failed_login_count + * if _failed_login_count > threshold + * set the _account_lockout_expires_at to current_time + accountPolicy.duration + * else + * do nothing + */ + + + _handleFailedLoginAttempt() { + return this._initFailedLoginCount().then(() => { + return this._incrementFailedLoginCount(); + }).then(() => { + return this._setLockoutExpiration(); + }); + } + /** + * handle login attempt if the Account Lockout Policy is enabled + */ + + + handleLoginAttempt(loginSuccessful) { + if (!this._config.accountLockout) { + return Promise.resolve(); + } + + return this._notLocked().then(() => { + if (loginSuccessful) { + return this._setFailedLoginCount(0); + } else { + return this._handleFailedLoginAttempt(); + } + }); + } + +} + +exports.AccountLockout = AccountLockout; +var _default = AccountLockout; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BY2NvdW50TG9ja291dC5qcyJdLCJuYW1lcyI6WyJBY2NvdW50TG9ja291dCIsImNvbnN0cnVjdG9yIiwidXNlciIsImNvbmZpZyIsIl91c2VyIiwiX2NvbmZpZyIsIl9zZXRGYWlsZWRMb2dpbkNvdW50IiwidmFsdWUiLCJxdWVyeSIsInVzZXJuYW1lIiwidXBkYXRlRmllbGRzIiwiX2ZhaWxlZF9sb2dpbl9jb3VudCIsImRhdGFiYXNlIiwidXBkYXRlIiwiX2lzRmFpbGVkTG9naW5Db3VudFNldCIsIiRleGlzdHMiLCJmaW5kIiwidGhlbiIsInVzZXJzIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiX2luaXRGYWlsZWRMb2dpbkNvdW50IiwiZmFpbGVkTG9naW5Db3VudElzU2V0IiwiX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQiLCJfX29wIiwiYW1vdW50IiwiX3NldExvY2tvdXRFeHBpcmF0aW9uIiwiJGd0ZSIsImFjY291bnRMb2Nrb3V0IiwidGhyZXNob2xkIiwibm93IiwiRGF0ZSIsIl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCIsIlBhcnNlIiwiX2VuY29kZSIsImdldFRpbWUiLCJkdXJhdGlvbiIsImNhdGNoIiwiZXJyIiwiY29kZSIsIm1lc3NhZ2UiLCJfbm90TG9ja2VkIiwiJGd0IiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiX2hhbmRsZUZhaWxlZExvZ2luQXR0ZW1wdCIsImhhbmRsZUxvZ2luQXR0ZW1wdCIsImxvZ2luU3VjY2Vzc2Z1bCIsIlByb21pc2UiLCJyZXNvbHZlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFEQTtBQUdPLE1BQU1BLGNBQU4sQ0FBcUI7QUFDMUJDLEVBQUFBLFdBQVcsQ0FBQ0MsSUFBRCxFQUFPQyxNQUFQLEVBQWU7QUFDeEIsU0FBS0MsS0FBTCxHQUFhRixJQUFiO0FBQ0EsU0FBS0csT0FBTCxHQUFlRixNQUFmO0FBQ0Q7QUFFRDs7Ozs7QUFHQUcsRUFBQUEsb0JBQW9CLENBQUNDLEtBQUQsRUFBUTtBQUMxQixVQUFNQyxLQUFLLEdBQUc7QUFDWkMsTUFBQUEsUUFBUSxFQUFFLEtBQUtMLEtBQUwsQ0FBV0s7QUFEVCxLQUFkO0FBSUEsVUFBTUMsWUFBWSxHQUFHO0FBQ25CQyxNQUFBQSxtQkFBbUIsRUFBRUo7QUFERixLQUFyQjtBQUlBLFdBQU8sS0FBS0YsT0FBTCxDQUFhTyxRQUFiLENBQXNCQyxNQUF0QixDQUE2QixPQUE3QixFQUFzQ0wsS0FBdEMsRUFBNkNFLFlBQTdDLENBQVA7QUFDRDtBQUVEOzs7OztBQUdBSSxFQUFBQSxzQkFBc0IsR0FBRztBQUN2QixVQUFNTixLQUFLLEdBQUc7QUFDWkMsTUFBQUEsUUFBUSxFQUFFLEtBQUtMLEtBQUwsQ0FBV0ssUUFEVDtBQUVaRSxNQUFBQSxtQkFBbUIsRUFBRTtBQUFFSSxRQUFBQSxPQUFPLEVBQUU7QUFBWDtBQUZULEtBQWQ7QUFLQSxXQUFPLEtBQUtWLE9BQUwsQ0FBYU8sUUFBYixDQUFzQkksSUFBdEIsQ0FBMkIsT0FBM0IsRUFBb0NSLEtBQXBDLEVBQTJDUyxJQUEzQyxDQUFnREMsS0FBSyxJQUFJO0FBQzlELFVBQUlDLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixLQUFkLEtBQXdCQSxLQUFLLENBQUNHLE1BQU4sR0FBZSxDQUEzQyxFQUE4QztBQUM1QyxlQUFPLElBQVA7QUFDRCxPQUZELE1BRU87QUFDTCxlQUFPLEtBQVA7QUFDRDtBQUNGLEtBTk0sQ0FBUDtBQU9EO0FBRUQ7Ozs7OztBQUlBQyxFQUFBQSxxQkFBcUIsR0FBRztBQUN0QixXQUFPLEtBQUtSLHNCQUFMLEdBQThCRyxJQUE5QixDQUFtQ00scUJBQXFCLElBQUk7QUFDakUsVUFBSSxDQUFDQSxxQkFBTCxFQUE0QjtBQUMxQixlQUFPLEtBQUtqQixvQkFBTCxDQUEwQixDQUExQixDQUFQO0FBQ0Q7QUFDRixLQUpNLENBQVA7QUFLRDtBQUVEOzs7OztBQUdBa0IsRUFBQUEsMEJBQTBCLEdBQUc7QUFDM0IsVUFBTWhCLEtBQUssR0FBRztBQUNaQyxNQUFBQSxRQUFRLEVBQUUsS0FBS0wsS0FBTCxDQUFXSztBQURULEtBQWQ7QUFJQSxVQUFNQyxZQUFZLEdBQUc7QUFDbkJDLE1BQUFBLG1CQUFtQixFQUFFO0FBQUVjLFFBQUFBLElBQUksRUFBRSxXQUFSO0FBQXFCQyxRQUFBQSxNQUFNLEVBQUU7QUFBN0I7QUFERixLQUFyQjtBQUlBLFdBQU8sS0FBS3JCLE9BQUwsQ0FBYU8sUUFBYixDQUFzQkMsTUFBdEIsQ0FBNkIsT0FBN0IsRUFBc0NMLEtBQXRDLEVBQTZDRSxZQUE3QyxDQUFQO0FBQ0Q7QUFFRDs7Ozs7OztBQUtBaUIsRUFBQUEscUJBQXFCLEdBQUc7QUFDdEIsVUFBTW5CLEtBQUssR0FBRztBQUNaQyxNQUFBQSxRQUFRLEVBQUUsS0FBS0wsS0FBTCxDQUFXSyxRQURUO0FBRVpFLE1BQUFBLG1CQUFtQixFQUFFO0FBQUVpQixRQUFBQSxJQUFJLEVBQUUsS0FBS3ZCLE9BQUwsQ0FBYXdCLGNBQWIsQ0FBNEJDO0FBQXBDO0FBRlQsS0FBZDtBQUtBLFVBQU1DLEdBQUcsR0FBRyxJQUFJQyxJQUFKLEVBQVo7QUFFQSxVQUFNdEIsWUFBWSxHQUFHO0FBQ25CdUIsTUFBQUEsMkJBQTJCLEVBQUVDLGNBQU1DLE9BQU4sQ0FDM0IsSUFBSUgsSUFBSixDQUFTRCxHQUFHLENBQUNLLE9BQUosS0FBZ0IsS0FBSy9CLE9BQUwsQ0FBYXdCLGNBQWIsQ0FBNEJRLFFBQTVCLEdBQXVDLEVBQXZDLEdBQTRDLElBQXJFLENBRDJCO0FBRFYsS0FBckI7QUFNQSxXQUFPLEtBQUtoQyxPQUFMLENBQWFPLFFBQWIsQ0FBc0JDLE1BQXRCLENBQTZCLE9BQTdCLEVBQXNDTCxLQUF0QyxFQUE2Q0UsWUFBN0MsRUFBMkQ0QixLQUEzRCxDQUFpRUMsR0FBRyxJQUFJO0FBQzdFLFVBQ0VBLEdBQUcsSUFDSEEsR0FBRyxDQUFDQyxJQURKLElBRUFELEdBQUcsQ0FBQ0UsT0FGSixJQUdBRixHQUFHLENBQUNDLElBQUosS0FBYSxHQUhiLElBSUFELEdBQUcsQ0FBQ0UsT0FBSixLQUFnQixtQkFMbEIsRUFNRTtBQUNBLGVBREEsQ0FDUTtBQUNULE9BUkQsTUFRTztBQUNMLGNBQU1GLEdBQU4sQ0FESyxDQUNNO0FBQ1o7QUFDRixLQVpNLENBQVA7QUFhRDtBQUVEOzs7Ozs7OztBQU1BRyxFQUFBQSxVQUFVLEdBQUc7QUFDWCxVQUFNbEMsS0FBSyxHQUFHO0FBQ1pDLE1BQUFBLFFBQVEsRUFBRSxLQUFLTCxLQUFMLENBQVdLLFFBRFQ7QUFFWndCLE1BQUFBLDJCQUEyQixFQUFFO0FBQUVVLFFBQUFBLEdBQUcsRUFBRVQsY0FBTUMsT0FBTixDQUFjLElBQUlILElBQUosRUFBZDtBQUFQLE9BRmpCO0FBR1pyQixNQUFBQSxtQkFBbUIsRUFBRTtBQUFFaUIsUUFBQUEsSUFBSSxFQUFFLEtBQUt2QixPQUFMLENBQWF3QixjQUFiLENBQTRCQztBQUFwQztBQUhULEtBQWQ7QUFNQSxXQUFPLEtBQUt6QixPQUFMLENBQWFPLFFBQWIsQ0FBc0JJLElBQXRCLENBQTJCLE9BQTNCLEVBQW9DUixLQUFwQyxFQUEyQ1MsSUFBM0MsQ0FBZ0RDLEtBQUssSUFBSTtBQUM5RCxVQUFJQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0YsS0FBZCxLQUF3QkEsS0FBSyxDQUFDRyxNQUFOLEdBQWUsQ0FBM0MsRUFBOEM7QUFDNUMsY0FBTSxJQUFJYSxjQUFNVSxLQUFWLENBQ0pWLGNBQU1VLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSiwwRkFDRSxLQUFLeEMsT0FBTCxDQUFhd0IsY0FBYixDQUE0QlEsUUFEOUIsR0FFRSxZQUpFLENBQU47QUFNRDtBQUNGLEtBVE0sQ0FBUDtBQVVEO0FBRUQ7Ozs7Ozs7OztBQU9BUyxFQUFBQSx5QkFBeUIsR0FBRztBQUMxQixXQUFPLEtBQUt4QixxQkFBTCxHQUNKTCxJQURJLENBQ0MsTUFBTTtBQUNWLGFBQU8sS0FBS08sMEJBQUwsRUFBUDtBQUNELEtBSEksRUFJSlAsSUFKSSxDQUlDLE1BQU07QUFDVixhQUFPLEtBQUtVLHFCQUFMLEVBQVA7QUFDRCxLQU5JLENBQVA7QUFPRDtBQUVEOzs7OztBQUdBb0IsRUFBQUEsa0JBQWtCLENBQUNDLGVBQUQsRUFBa0I7QUFDbEMsUUFBSSxDQUFDLEtBQUszQyxPQUFMLENBQWF3QixjQUFsQixFQUFrQztBQUNoQyxhQUFPb0IsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtSLFVBQUwsR0FBa0J6QixJQUFsQixDQUF1QixNQUFNO0FBQ2xDLFVBQUkrQixlQUFKLEVBQXFCO0FBQ25CLGVBQU8sS0FBSzFDLG9CQUFMLENBQTBCLENBQTFCLENBQVA7QUFDRCxPQUZELE1BRU87QUFDTCxlQUFPLEtBQUt3Qyx5QkFBTCxFQUFQO0FBQ0Q7QUFDRixLQU5NLENBQVA7QUFPRDs7QUE1SnlCOzs7ZUErSmI5QyxjIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBjbGFzcyBoYW5kbGVzIHRoZSBBY2NvdW50IExvY2tvdXQgUG9saWN5IHNldHRpbmdzLlxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5leHBvcnQgY2xhc3MgQWNjb3VudExvY2tvdXQge1xuICBjb25zdHJ1Y3Rvcih1c2VyLCBjb25maWcpIHtcbiAgICB0aGlzLl91c2VyID0gdXNlcjtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cblxuICAvKipcbiAgICogc2V0IF9mYWlsZWRfbG9naW5fY291bnQgdG8gdmFsdWVcbiAgICovXG4gIF9zZXRGYWlsZWRMb2dpbkNvdW50KHZhbHVlKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogdmFsdWUsXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNoZWNrIGlmIHRoZSBfZmFpbGVkX2xvZ2luX2NvdW50IGZpZWxkIGhhcyBiZWVuIHNldFxuICAgKi9cbiAgX2lzRmFpbGVkTG9naW5Db3VudFNldCgpIHtcbiAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgIHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lLFxuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyAkZXhpc3RzOiB0cnVlIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCBxdWVyeSkudGhlbih1c2VycyA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh1c2VycykgJiYgdXNlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpZiBfZmFpbGVkX2xvZ2luX2NvdW50IGlzIE5PVCBzZXQgdGhlbiBzZXQgaXQgdG8gMFxuICAgKiBlbHNlIGRvIG5vdGhpbmdcbiAgICovXG4gIF9pbml0RmFpbGVkTG9naW5Db3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNGYWlsZWRMb2dpbkNvdW50U2V0KCkudGhlbihmYWlsZWRMb2dpbkNvdW50SXNTZXQgPT4ge1xuICAgICAgaWYgKCFmYWlsZWRMb2dpbkNvdW50SXNTZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldEZhaWxlZExvZ2luQ291bnQoMCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaW5jcmVtZW50IF9mYWlsZWRfbG9naW5fY291bnQgYnkgMVxuICAgKi9cbiAgX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyBfX29wOiAnSW5jcmVtZW50JywgYW1vdW50OiAxIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIGlmIHRoZSBmYWlsZWQgbG9naW4gY291bnQgaXMgZ3JlYXRlciB0aGFuIHRoZSB0aHJlc2hvbGRcbiAgICogdGhlbiBzZXRzIGxvY2tvdXQgZXhwaXJhdGlvbiB0byAnY3VycmVudHRpbWUgKyBhY2NvdW50UG9saWN5LmR1cmF0aW9uJywgaS5lLiwgYWNjb3VudCBpcyBsb2NrZWQgb3V0IGZvciB0aGUgbmV4dCAnYWNjb3VudFBvbGljeS5kdXJhdGlvbicgbWludXRlc1xuICAgKiBlbHNlIGRvIG5vdGhpbmdcbiAgICovXG4gIF9zZXRMb2Nrb3V0RXhwaXJhdGlvbigpIHtcbiAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgIHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lLFxuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyAkZ3RlOiB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQudGhyZXNob2xkIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cbiAgICBjb25zdCB1cGRhdGVGaWVsZHMgPSB7XG4gICAgICBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ6IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQuZHVyYXRpb24gKiA2MCAqIDEwMDApXG4gICAgICApLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKS5jYXRjaChlcnIgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBlcnIgJiZcbiAgICAgICAgZXJyLmNvZGUgJiZcbiAgICAgICAgZXJyLm1lc3NhZ2UgJiZcbiAgICAgICAgZXJyLmNvZGUgPT09IDEwMSAmJlxuICAgICAgICBlcnIubWVzc2FnZSA9PT0gJ09iamVjdCBub3QgZm91bmQuJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybjsgLy8gbm90aGluZyB0byB1cGRhdGUgc28gd2UgYXJlIGdvb2RcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjsgLy8gdW5rbm93biBlcnJvclxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGlmIF9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCA+IGN1cnJlbnRfdGltZSBhbmQgX2ZhaWxlZF9sb2dpbl9jb3VudCA+IHRocmVzaG9sZFxuICAgKiAgIHJlamVjdCB3aXRoIGFjY291bnQgbG9ja2VkIGVycm9yXG4gICAqIGVsc2VcbiAgICogICByZXNvbHZlXG4gICAqL1xuICBfbm90TG9ja2VkKCkge1xuICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgdXNlcm5hbWU6IHRoaXMuX3VzZXIudXNlcm5hbWUsXG4gICAgICBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ6IHsgJGd0OiBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpIH0sXG4gICAgICBfZmFpbGVkX2xvZ2luX2NvdW50OiB7ICRndGU6IHRoaXMuX2NvbmZpZy5hY2NvdW50TG9ja291dC50aHJlc2hvbGQgfSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5kYXRhYmFzZS5maW5kKCdfVXNlcicsIHF1ZXJ5KS50aGVuKHVzZXJzID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHVzZXJzKSAmJiB1c2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdZb3VyIGFjY291bnQgaXMgbG9ja2VkIGR1ZSB0byBtdWx0aXBsZSBmYWlsZWQgbG9naW4gYXR0ZW1wdHMuIFBsZWFzZSB0cnkgYWdhaW4gYWZ0ZXIgJyArXG4gICAgICAgICAgICB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQuZHVyYXRpb24gK1xuICAgICAgICAgICAgJyBtaW51dGUocyknXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogc2V0IGFuZC9vciBpbmNyZW1lbnQgX2ZhaWxlZF9sb2dpbl9jb3VudFxuICAgKiBpZiBfZmFpbGVkX2xvZ2luX2NvdW50ID4gdGhyZXNob2xkXG4gICAqICAgc2V0IHRoZSBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQgdG8gY3VycmVudF90aW1lICsgYWNjb3VudFBvbGljeS5kdXJhdGlvblxuICAgKiBlbHNlXG4gICAqICAgZG8gbm90aGluZ1xuICAgKi9cbiAgX2hhbmRsZUZhaWxlZExvZ2luQXR0ZW1wdCgpIHtcbiAgICByZXR1cm4gdGhpcy5faW5pdEZhaWxlZExvZ2luQ291bnQoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faW5jcmVtZW50RmFpbGVkTG9naW5Db3VudCgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldExvY2tvdXRFeHBpcmF0aW9uKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBoYW5kbGUgbG9naW4gYXR0ZW1wdCBpZiB0aGUgQWNjb3VudCBMb2Nrb3V0IFBvbGljeSBpcyBlbmFibGVkXG4gICAqL1xuICBoYW5kbGVMb2dpbkF0dGVtcHQobG9naW5TdWNjZXNzZnVsKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX25vdExvY2tlZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKGxvZ2luU3VjY2Vzc2Z1bCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2V0RmFpbGVkTG9naW5Db3VudCgwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVGYWlsZWRMb2dpbkF0dGVtcHQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBY2NvdW50TG9ja291dDtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/AdapterLoader.js b/lib/Adapters/AdapterLoader.js new file mode 100644 index 0000000000..51cbe9e2a1 --- /dev/null +++ b/lib/Adapters/AdapterLoader.js @@ -0,0 +1,63 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadAdapter = loadAdapter; +exports.default = void 0; + +/** + * @module AdapterLoader + */ + +/** + * @static + * Attempt to load an adapter or fallback to the default. + * @param {Adapter} adapter an adapter + * @param {Adapter} defaultAdapter the default adapter to load + * @param {any} options options to pass to the contstructor + * @returns {Object} the loaded adapter + */ +function loadAdapter(adapter, defaultAdapter, options) { + if (!adapter) { + if (!defaultAdapter) { + return options; + } // Load from the default adapter when no adapter is set + + + return loadAdapter(defaultAdapter, undefined, options); + } else if (typeof adapter === 'function') { + try { + return adapter(options); + } catch (e) { + if (e.name === 'TypeError') { + var Adapter = adapter; + return new Adapter(options); + } else { + throw e; + } + } + } else if (typeof adapter === 'string') { + /* eslint-disable */ + adapter = require(adapter); // If it's define as a module, get the default + + if (adapter.default) { + adapter = adapter.default; + } + + return loadAdapter(adapter, undefined, options); + } else if (adapter.module) { + return loadAdapter(adapter.module, undefined, adapter.options); + } else if (adapter.class) { + return loadAdapter(adapter.class, undefined, adapter.options); + } else if (adapter.adapter) { + return loadAdapter(adapter.adapter, undefined, adapter.options); + } // return the adapter as provided + + + return adapter; +} + +var _default = loadAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9BZGFwdGVycy9BZGFwdGVyTG9hZGVyLmpzIl0sIm5hbWVzIjpbImxvYWRBZGFwdGVyIiwiYWRhcHRlciIsImRlZmF1bHRBZGFwdGVyIiwib3B0aW9ucyIsInVuZGVmaW5lZCIsImUiLCJuYW1lIiwiQWRhcHRlciIsInJlcXVpcmUiLCJkZWZhdWx0IiwibW9kdWxlIiwiY2xhc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7QUFHQTs7Ozs7Ozs7QUFRTyxTQUFTQSxXQUFULENBQXdCQyxPQUF4QixFQUFpQ0MsY0FBakMsRUFBaURDLE9BQWpELEVBQTZEO0FBQ2xFLE1BQUksQ0FBQ0YsT0FBTCxFQUFjO0FBQ1osUUFBSSxDQUFDQyxjQUFMLEVBQXFCO0FBQ25CLGFBQU9DLE9BQVA7QUFDRCxLQUhXLENBSVo7OztBQUNBLFdBQU9ILFdBQVcsQ0FBQ0UsY0FBRCxFQUFpQkUsU0FBakIsRUFBNEJELE9BQTVCLENBQWxCO0FBQ0QsR0FORCxNQU1PLElBQUksT0FBT0YsT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUN4QyxRQUFJO0FBQ0YsYUFBT0EsT0FBTyxDQUFDRSxPQUFELENBQWQ7QUFDRCxLQUZELENBRUUsT0FBT0UsQ0FBUCxFQUFVO0FBQ1YsVUFBSUEsQ0FBQyxDQUFDQyxJQUFGLEtBQVcsV0FBZixFQUE0QjtBQUMxQixZQUFJQyxPQUFPLEdBQUdOLE9BQWQ7QUFDQSxlQUFPLElBQUlNLE9BQUosQ0FBWUosT0FBWixDQUFQO0FBQ0QsT0FIRCxNQUdPO0FBQ0wsY0FBTUUsQ0FBTjtBQUNEO0FBQ0Y7QUFDRixHQVhNLE1BV0EsSUFBSSxPQUFPSixPQUFQLEtBQW1CLFFBQXZCLEVBQWlDO0FBQ3RDO0FBQ0FBLElBQUFBLE9BQU8sR0FBR08sT0FBTyxDQUFDUCxPQUFELENBQWpCLENBRnNDLENBR3RDOztBQUNBLFFBQUlBLE9BQU8sQ0FBQ1EsT0FBWixFQUFxQjtBQUNuQlIsTUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNRLE9BQWxCO0FBQ0Q7O0FBQ0QsV0FBT1QsV0FBVyxDQUFDQyxPQUFELEVBQVVHLFNBQVYsRUFBcUJELE9BQXJCLENBQWxCO0FBQ0QsR0FSTSxNQVFBLElBQUlGLE9BQU8sQ0FBQ1MsTUFBWixFQUFvQjtBQUN6QixXQUFPVixXQUFXLENBQUNDLE9BQU8sQ0FBQ1MsTUFBVCxFQUFpQk4sU0FBakIsRUFBNEJILE9BQU8sQ0FBQ0UsT0FBcEMsQ0FBbEI7QUFDRCxHQUZNLE1BRUEsSUFBSUYsT0FBTyxDQUFDVSxLQUFaLEVBQW1CO0FBQ3hCLFdBQU9YLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDVSxLQUFULEVBQWdCUCxTQUFoQixFQUEyQkgsT0FBTyxDQUFDRSxPQUFuQyxDQUFsQjtBQUNELEdBRk0sTUFFQSxJQUFJRixPQUFPLENBQUNBLE9BQVosRUFBcUI7QUFDMUIsV0FBT0QsV0FBVyxDQUFDQyxPQUFPLENBQUNBLE9BQVQsRUFBa0JHLFNBQWxCLEVBQTZCSCxPQUFPLENBQUNFLE9BQXJDLENBQWxCO0FBQ0QsR0FoQ2lFLENBaUNsRTs7O0FBQ0EsU0FBT0YsT0FBUDtBQUNEOztlQUVjRCxXIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJMb2FkZXJcbiAqL1xuLyoqXG4gKiBAc3RhdGljXG4gKiBBdHRlbXB0IHRvIGxvYWQgYW4gYWRhcHRlciBvciBmYWxsYmFjayB0byB0aGUgZGVmYXVsdC5cbiAqIEBwYXJhbSB7QWRhcHRlcn0gYWRhcHRlciBhbiBhZGFwdGVyXG4gKiBAcGFyYW0ge0FkYXB0ZXJ9IGRlZmF1bHRBZGFwdGVyIHRoZSBkZWZhdWx0IGFkYXB0ZXIgdG8gbG9hZFxuICogQHBhcmFtIHthbnl9IG9wdGlvbnMgb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb250c3RydWN0b3JcbiAqIEByZXR1cm5zIHtPYmplY3R9IHRoZSBsb2FkZWQgYWRhcHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFkYXB0ZXI8VD4oYWRhcHRlciwgZGVmYXVsdEFkYXB0ZXIsIG9wdGlvbnMpOiBUIHtcbiAgaWYgKCFhZGFwdGVyKSB7XG4gICAgaWYgKCFkZWZhdWx0QWRhcHRlcikge1xuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8vIExvYWQgZnJvbSB0aGUgZGVmYXVsdCBhZGFwdGVyIHdoZW4gbm8gYWRhcHRlciBpcyBzZXRcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoZGVmYXVsdEFkYXB0ZXIsIHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFkYXB0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGFkYXB0ZXIob3B0aW9ucyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUubmFtZSA9PT0gJ1R5cGVFcnJvcicpIHtcbiAgICAgICAgdmFyIEFkYXB0ZXIgPSBhZGFwdGVyO1xuICAgICAgICByZXR1cm4gbmV3IEFkYXB0ZXIob3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgYWRhcHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAgIGFkYXB0ZXIgPSByZXF1aXJlKGFkYXB0ZXIpO1xuICAgIC8vIElmIGl0J3MgZGVmaW5lIGFzIGEgbW9kdWxlLCBnZXQgdGhlIGRlZmF1bHRcbiAgICBpZiAoYWRhcHRlci5kZWZhdWx0KSB7XG4gICAgICBhZGFwdGVyID0gYWRhcHRlci5kZWZhdWx0O1xuICAgIH1cbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlciwgdW5kZWZpbmVkLCBvcHRpb25zKTtcbiAgfSBlbHNlIGlmIChhZGFwdGVyLm1vZHVsZSkge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLm1vZHVsZSwgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuY2xhc3MpIHtcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlci5jbGFzcywgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuYWRhcHRlcikge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLmFkYXB0ZXIsIHVuZGVmaW5lZCwgYWRhcHRlci5vcHRpb25zKTtcbiAgfVxuICAvLyByZXR1cm4gdGhlIGFkYXB0ZXIgYXMgcHJvdmlkZWRcbiAgcmV0dXJuIGFkYXB0ZXI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGxvYWRBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Analytics/AnalyticsAdapter.js b/lib/Adapters/Analytics/AnalyticsAdapter.js new file mode 100644 index 0000000000..109ac4b3f6 --- /dev/null +++ b/lib/Adapters/Analytics/AnalyticsAdapter.js @@ -0,0 +1,41 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AnalyticsAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface AnalyticsAdapter + */ +class AnalyticsAdapter { + /** + @param {any} parameters: the analytics request body, analytics info will be in the dimensions property + @param {Request} req: the original http request + */ + appOpened(parameters, req) { + return Promise.resolve({}); + } + /** + @param {String} eventName: the name of the custom eventName + @param {any} parameters: the analytics request body, analytics info will be in the dimensions property + @param {Request} req: the original http request + */ + + + trackEvent(eventName, parameters, req) { + return Promise.resolve({}); + } + +} + +exports.AnalyticsAdapter = AnalyticsAdapter; +var _default = AnalyticsAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJBbmFseXRpY3NBZGFwdGVyIiwiYXBwT3BlbmVkIiwicGFyYW1ldGVycyIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwidHJhY2tFdmVudCIsImV2ZW50TmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7OztBQUdPLE1BQU1BLGdCQUFOLENBQXVCO0FBQzVCOzs7O0FBSUFDLEVBQUFBLFNBQVMsQ0FBQ0MsVUFBRCxFQUFhQyxHQUFiLEVBQWtCO0FBQ3pCLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0Q7QUFFRDs7Ozs7OztBQUtBQyxFQUFBQSxVQUFVLENBQUNDLFNBQUQsRUFBWUwsVUFBWixFQUF3QkMsR0FBeEIsRUFBNkI7QUFDckMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEVBQWhCLENBQVA7QUFDRDs7QUFoQjJCOzs7ZUFtQmZMLGdCIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJzXG4gKi9cbi8qKlxuICogQGludGVyZmFjZSBBbmFseXRpY3NBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NBZGFwdGVyIHtcbiAgLyoqXG4gIEBwYXJhbSB7YW55fSBwYXJhbWV0ZXJzOiB0aGUgYW5hbHl0aWNzIHJlcXVlc3QgYm9keSwgYW5hbHl0aWNzIGluZm8gd2lsbCBiZSBpbiB0aGUgZGltZW5zaW9ucyBwcm9wZXJ0eVxuICBAcGFyYW0ge1JlcXVlc3R9IHJlcTogdGhlIG9yaWdpbmFsIGh0dHAgcmVxdWVzdFxuICAgKi9cbiAgYXBwT3BlbmVkKHBhcmFtZXRlcnMsIHJlcSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG5cbiAgLyoqXG4gIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWU6IHRoZSBuYW1lIG9mIHRoZSBjdXN0b20gZXZlbnROYW1lXG4gIEBwYXJhbSB7YW55fSBwYXJhbWV0ZXJzOiB0aGUgYW5hbHl0aWNzIHJlcXVlc3QgYm9keSwgYW5hbHl0aWNzIGluZm8gd2lsbCBiZSBpbiB0aGUgZGltZW5zaW9ucyBwcm9wZXJ0eVxuICBAcGFyYW0ge1JlcXVlc3R9IHJlcTogdGhlIG9yaWdpbmFsIGh0dHAgcmVxdWVzdFxuICAgKi9cbiAgdHJhY2tFdmVudChldmVudE5hbWUsIHBhcmFtZXRlcnMsIHJlcSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuYWx5dGljc0FkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/AuthAdapter.js b/lib/Adapters/Auth/AuthAdapter.js new file mode 100644 index 0000000000..2b1f9ba12b --- /dev/null +++ b/lib/Adapters/Auth/AuthAdapter.js @@ -0,0 +1,34 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AuthAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ +class AuthAdapter { + /* + @param appIds: the specified app ids in the configuration + @param authData: the client provided authData + @param options: additional options + @returns a promise that resolves if the applicationId is valid + */ + validateAppId(appIds, authData, options) { + return Promise.resolve({}); + } + /* + @param authData: the client provided authData + @param options: additional options + */ + + + validateAuthData(authData, options) { + return Promise.resolve({}); + } + +} + +exports.AuthAdapter = AuthAdapter; +var _default = AuthAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL0F1dGhBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkF1dGhBZGFwdGVyIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImF1dGhEYXRhIiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwidmFsaWRhdGVBdXRoRGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2Qjs7Ozs7O0FBTUFDLEVBQUFBLGFBQWEsQ0FBQ0MsTUFBRCxFQUFTQyxRQUFULEVBQW1CQyxPQUFuQixFQUE0QjtBQUN2QyxXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEO0FBRUQ7Ozs7OztBQUlBQyxFQUFBQSxnQkFBZ0IsQ0FBQ0osUUFBRCxFQUFXQyxPQUFYLEVBQW9CO0FBQ2xDLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0Q7O0FBakJzQjs7O2VBb0JWTixXIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuZXhwb3J0IGNsYXNzIEF1dGhBZGFwdGVyIHtcbiAgLypcbiAgQHBhcmFtIGFwcElkczogdGhlIHNwZWNpZmllZCBhcHAgaWRzIGluIHRoZSBjb25maWd1cmF0aW9uXG4gIEBwYXJhbSBhdXRoRGF0YTogdGhlIGNsaWVudCBwcm92aWRlZCBhdXRoRGF0YVxuICBAcGFyYW0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gIEByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGlmIHRoZSBhcHBsaWNhdGlvbklkIGlzIHZhbGlkXG4gICAqL1xuICB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuXG4gIC8qXG4gIEBwYXJhbSBhdXRoRGF0YTogdGhlIGNsaWVudCBwcm92aWRlZCBhdXRoRGF0YVxuICBAcGFyYW0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gICAqL1xuICB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXV0aEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/OAuth1Client.js b/lib/Adapters/Auth/OAuth1Client.js new file mode 100644 index 0000000000..f9689a6e32 --- /dev/null +++ b/lib/Adapters/Auth/OAuth1Client.js @@ -0,0 +1,227 @@ +"use strict"; + +var https = require('https'), + crypto = require('crypto'); + +var Parse = require('parse/node').Parse; + +var OAuth = function (options) { + if (!options) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth'); + } + + this.consumer_key = options.consumer_key; + this.consumer_secret = options.consumer_secret; + this.auth_token = options.auth_token; + this.auth_token_secret = options.auth_token_secret; + this.host = options.host; + this.oauth_params = options.oauth_params || {}; +}; + +OAuth.prototype.send = function (method, path, params, body) { + var request = this.buildRequest(method, path, params, body); // Encode the body properly, the current Parse Implementation don't do it properly + + return new Promise(function (resolve, reject) { + var httpRequest = https.request(request, function (res) { + var data = ''; + res.on('data', function (chunk) { + data += chunk; + }); + res.on('end', function () { + data = JSON.parse(data); + resolve(data); + }); + }).on('error', function () { + reject('Failed to make an OAuth request'); + }); + + if (request.body) { + httpRequest.write(request.body); + } + + httpRequest.end(); + }); +}; + +OAuth.prototype.buildRequest = function (method, path, params, body) { + if (path.indexOf('/') != 0) { + path = '/' + path; + } + + if (params && Object.keys(params).length > 0) { + path += '?' + OAuth.buildParameterString(params); + } + + var request = { + host: this.host, + path: path, + method: method.toUpperCase() + }; + var oauth_params = this.oauth_params || {}; + oauth_params.oauth_consumer_key = this.consumer_key; + + if (this.auth_token) { + oauth_params['oauth_token'] = this.auth_token; + } + + request = OAuth.signRequest(request, oauth_params, this.consumer_secret, this.auth_token_secret); + + if (body && Object.keys(body).length > 0) { + request.body = OAuth.buildParameterString(body); + } + + return request; +}; + +OAuth.prototype.get = function (path, params) { + return this.send('GET', path, params); +}; + +OAuth.prototype.post = function (path, params, body) { + return this.send('POST', path, params, body); +}; +/* + Proper string %escape encoding +*/ + + +OAuth.encode = function (str) { + // discuss at: http://phpjs.org/functions/rawurlencode/ + // original by: Brett Zamir (http://brett-zamir.me) + // input by: travc + // input by: Brett Zamir (http://brett-zamir.me) + // input by: Michael Grier + // input by: Ratheous + // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // bugfixed by: Brett Zamir (http://brett-zamir.me) + // bugfixed by: Joris + // reimplemented by: Brett Zamir (http://brett-zamir.me) + // reimplemented by: Brett Zamir (http://brett-zamir.me) + // note: This reflects PHP 5.3/6.0+ behavior + // note: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on + // note: pages served as UTF-8 + // example 1: rawurlencode('Kevin van Zonneveld!'); + // returns 1: 'Kevin%20van%20Zonneveld%21' + // example 2: rawurlencode('http://kevin.vanzonneveld.net/'); + // returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F' + // example 3: rawurlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'); + // returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a' + str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current + // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. + + return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); +}; + +OAuth.signatureMethod = 'HMAC-SHA1'; +OAuth.version = '1.0'; +/* + Generate a nonce +*/ + +OAuth.nonce = function () { + var text = ''; + var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + for (var i = 0; i < 30; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); + + return text; +}; + +OAuth.buildParameterString = function (obj) { + // Sort keys and encode values + if (obj) { + var keys = Object.keys(obj).sort(); // Map key=value, join them by & + + return keys.map(function (key) { + return key + '=' + OAuth.encode(obj[key]); + }).join('&'); + } + + return ''; +}; +/* + Build the signature string from the object +*/ + + +OAuth.buildSignatureString = function (method, url, parameters) { + return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join('&'); +}; +/* + Retuns encoded HMAC-SHA1 from key and text +*/ + + +OAuth.signature = function (text, key) { + crypto = require('crypto'); + return OAuth.encode(crypto.createHmac('sha1', key).update(text).digest('base64')); +}; + +OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_token_secret) { + oauth_parameters = oauth_parameters || {}; // Set default values + + if (!oauth_parameters.oauth_nonce) { + oauth_parameters.oauth_nonce = OAuth.nonce(); + } + + if (!oauth_parameters.oauth_timestamp) { + oauth_parameters.oauth_timestamp = Math.floor(new Date().getTime() / 1000); + } + + if (!oauth_parameters.oauth_signature_method) { + oauth_parameters.oauth_signature_method = OAuth.signatureMethod; + } + + if (!oauth_parameters.oauth_version) { + oauth_parameters.oauth_version = OAuth.version; + } + + if (!auth_token_secret) { + auth_token_secret = ''; + } // Force GET method if unset + + + if (!request.method) { + request.method = 'GET'; + } // Collect all the parameters in one signatureParameters object + + + var signatureParams = {}; + var parametersToMerge = [request.params, request.body, oauth_parameters]; + + for (var i in parametersToMerge) { + var parameters = parametersToMerge[i]; + + for (var k in parameters) { + signatureParams[k] = parameters[k]; + } + } // Create a string based on the parameters + + + var parameterString = OAuth.buildParameterString(signatureParams); // Build the signature string + + var url = 'https://' + request.host + '' + request.path; + var signatureString = OAuth.buildSignatureString(request.method, url, parameterString); // Hash the signature string + + var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join('&'); + var signature = OAuth.signature(signatureString, signatureKey); // Set the signature in the params + + oauth_parameters.oauth_signature = signature; + + if (!request.headers) { + request.headers = {}; + } // Set the authorization header + + + var authHeader = Object.keys(oauth_parameters).sort().map(function (key) { + var value = oauth_parameters[key]; + return key + '="' + value + '"'; + }).join(', '); + request.headers.Authorization = 'OAuth ' + authHeader; // Set the content type header + + request.headers['Content-Type'] = 'application/x-www-form-urlencoded'; + return request; +}; + +module.exports = OAuth; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL09BdXRoMUNsaWVudC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBbkI7QUFBQSxJQUNFQyxNQUFNLEdBQUdELE9BQU8sQ0FBQyxRQUFELENBRGxCOztBQUVBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkUsS0FBbEM7O0FBRUEsSUFBSUMsS0FBSyxHQUFHLFVBQVNDLE9BQVQsRUFBa0I7QUFDNUIsTUFBSSxDQUFDQSxPQUFMLEVBQWM7QUFDWixVQUFNLElBQUlGLEtBQUssQ0FBQ0csS0FBVixDQUNKSCxLQUFLLENBQUNHLEtBQU4sQ0FBWUMscUJBRFIsRUFFSiw0QkFGSSxDQUFOO0FBSUQ7O0FBQ0QsT0FBS0MsWUFBTCxHQUFvQkgsT0FBTyxDQUFDRyxZQUE1QjtBQUNBLE9BQUtDLGVBQUwsR0FBdUJKLE9BQU8sQ0FBQ0ksZUFBL0I7QUFDQSxPQUFLQyxVQUFMLEdBQWtCTCxPQUFPLENBQUNLLFVBQTFCO0FBQ0EsT0FBS0MsaUJBQUwsR0FBeUJOLE9BQU8sQ0FBQ00saUJBQWpDO0FBQ0EsT0FBS0MsSUFBTCxHQUFZUCxPQUFPLENBQUNPLElBQXBCO0FBQ0EsT0FBS0MsWUFBTCxHQUFvQlIsT0FBTyxDQUFDUSxZQUFSLElBQXdCLEVBQTVDO0FBQ0QsQ0FiRDs7QUFlQVQsS0FBSyxDQUFDVSxTQUFOLENBQWdCQyxJQUFoQixHQUF1QixVQUFTQyxNQUFULEVBQWlCQyxJQUFqQixFQUF1QkMsTUFBdkIsRUFBK0JDLElBQS9CLEVBQXFDO0FBQzFELE1BQUlDLE9BQU8sR0FBRyxLQUFLQyxZQUFMLENBQWtCTCxNQUFsQixFQUEwQkMsSUFBMUIsRUFBZ0NDLE1BQWhDLEVBQXdDQyxJQUF4QyxDQUFkLENBRDBELENBRTFEOztBQUNBLFNBQU8sSUFBSUcsT0FBSixDQUFZLFVBQVNDLE9BQVQsRUFBa0JDLE1BQWxCLEVBQTBCO0FBQzNDLFFBQUlDLFdBQVcsR0FBR3pCLEtBQUssQ0FDcEJvQixPQURlLENBQ1BBLE9BRE8sRUFDRSxVQUFTTSxHQUFULEVBQWM7QUFDOUIsVUFBSUMsSUFBSSxHQUFHLEVBQVg7QUFDQUQsTUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sTUFBUCxFQUFlLFVBQVNDLEtBQVQsRUFBZ0I7QUFDN0JGLFFBQUFBLElBQUksSUFBSUUsS0FBUjtBQUNELE9BRkQ7QUFHQUgsTUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sS0FBUCxFQUFjLFlBQVc7QUFDdkJELFFBQUFBLElBQUksR0FBR0csSUFBSSxDQUFDQyxLQUFMLENBQVdKLElBQVgsQ0FBUDtBQUNBSixRQUFBQSxPQUFPLENBQUNJLElBQUQsQ0FBUDtBQUNELE9BSEQ7QUFJRCxLQVZlLEVBV2ZDLEVBWGUsQ0FXWixPQVhZLEVBV0gsWUFBVztBQUN0QkosTUFBQUEsTUFBTSxDQUFDLGlDQUFELENBQU47QUFDRCxLQWJlLENBQWxCOztBQWNBLFFBQUlKLE9BQU8sQ0FBQ0QsSUFBWixFQUFrQjtBQUNoQk0sTUFBQUEsV0FBVyxDQUFDTyxLQUFaLENBQWtCWixPQUFPLENBQUNELElBQTFCO0FBQ0Q7O0FBQ0RNLElBQUFBLFdBQVcsQ0FBQ1EsR0FBWjtBQUNELEdBbkJNLENBQVA7QUFvQkQsQ0F2QkQ7O0FBeUJBN0IsS0FBSyxDQUFDVSxTQUFOLENBQWdCTyxZQUFoQixHQUErQixVQUFTTCxNQUFULEVBQWlCQyxJQUFqQixFQUF1QkMsTUFBdkIsRUFBK0JDLElBQS9CLEVBQXFDO0FBQ2xFLE1BQUlGLElBQUksQ0FBQ2lCLE9BQUwsQ0FBYSxHQUFiLEtBQXFCLENBQXpCLEVBQTRCO0FBQzFCakIsSUFBQUEsSUFBSSxHQUFHLE1BQU1BLElBQWI7QUFDRDs7QUFDRCxNQUFJQyxNQUFNLElBQUlpQixNQUFNLENBQUNDLElBQVAsQ0FBWWxCLE1BQVosRUFBb0JtQixNQUFwQixHQUE2QixDQUEzQyxFQUE4QztBQUM1Q3BCLElBQUFBLElBQUksSUFBSSxNQUFNYixLQUFLLENBQUNrQyxvQkFBTixDQUEyQnBCLE1BQTNCLENBQWQ7QUFDRDs7QUFFRCxNQUFJRSxPQUFPLEdBQUc7QUFDWlIsSUFBQUEsSUFBSSxFQUFFLEtBQUtBLElBREM7QUFFWkssSUFBQUEsSUFBSSxFQUFFQSxJQUZNO0FBR1pELElBQUFBLE1BQU0sRUFBRUEsTUFBTSxDQUFDdUIsV0FBUDtBQUhJLEdBQWQ7QUFNQSxNQUFJMUIsWUFBWSxHQUFHLEtBQUtBLFlBQUwsSUFBcUIsRUFBeEM7QUFDQUEsRUFBQUEsWUFBWSxDQUFDMkIsa0JBQWIsR0FBa0MsS0FBS2hDLFlBQXZDOztBQUNBLE1BQUksS0FBS0UsVUFBVCxFQUFxQjtBQUNuQkcsSUFBQUEsWUFBWSxDQUFDLGFBQUQsQ0FBWixHQUE4QixLQUFLSCxVQUFuQztBQUNEOztBQUVEVSxFQUFBQSxPQUFPLEdBQUdoQixLQUFLLENBQUNxQyxXQUFOLENBQ1JyQixPQURRLEVBRVJQLFlBRlEsRUFHUixLQUFLSixlQUhHLEVBSVIsS0FBS0UsaUJBSkcsQ0FBVjs7QUFPQSxNQUFJUSxJQUFJLElBQUlnQixNQUFNLENBQUNDLElBQVAsQ0FBWWpCLElBQVosRUFBa0JrQixNQUFsQixHQUEyQixDQUF2QyxFQUEwQztBQUN4Q2pCLElBQUFBLE9BQU8sQ0FBQ0QsSUFBUixHQUFlZixLQUFLLENBQUNrQyxvQkFBTixDQUEyQm5CLElBQTNCLENBQWY7QUFDRDs7QUFDRCxTQUFPQyxPQUFQO0FBQ0QsQ0EvQkQ7O0FBaUNBaEIsS0FBSyxDQUFDVSxTQUFOLENBQWdCNEIsR0FBaEIsR0FBc0IsVUFBU3pCLElBQVQsRUFBZUMsTUFBZixFQUF1QjtBQUMzQyxTQUFPLEtBQUtILElBQUwsQ0FBVSxLQUFWLEVBQWlCRSxJQUFqQixFQUF1QkMsTUFBdkIsQ0FBUDtBQUNELENBRkQ7O0FBSUFkLEtBQUssQ0FBQ1UsU0FBTixDQUFnQjZCLElBQWhCLEdBQXVCLFVBQVMxQixJQUFULEVBQWVDLE1BQWYsRUFBdUJDLElBQXZCLEVBQTZCO0FBQ2xELFNBQU8sS0FBS0osSUFBTCxDQUFVLE1BQVYsRUFBa0JFLElBQWxCLEVBQXdCQyxNQUF4QixFQUFnQ0MsSUFBaEMsQ0FBUDtBQUNELENBRkQ7QUFJQTs7Ozs7QUFHQWYsS0FBSyxDQUFDd0MsTUFBTixHQUFlLFVBQVNDLEdBQVQsRUFBYztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUFBLEVBQUFBLEdBQUcsR0FBRyxDQUFDQSxHQUFHLEdBQUcsRUFBUCxFQUFXQyxRQUFYLEVBQU4sQ0F0QjJCLENBd0IzQjtBQUNBOztBQUNBLFNBQU9DLGtCQUFrQixDQUFDRixHQUFELENBQWxCLENBQ0pHLE9BREksQ0FDSSxJQURKLEVBQ1UsS0FEVixFQUVKQSxPQUZJLENBRUksSUFGSixFQUVVLEtBRlYsRUFHSkEsT0FISSxDQUdJLEtBSEosRUFHVyxLQUhYLEVBSUpBLE9BSkksQ0FJSSxLQUpKLEVBSVcsS0FKWCxFQUtKQSxPQUxJLENBS0ksS0FMSixFQUtXLEtBTFgsQ0FBUDtBQU1ELENBaENEOztBQWtDQTVDLEtBQUssQ0FBQzZDLGVBQU4sR0FBd0IsV0FBeEI7QUFDQTdDLEtBQUssQ0FBQzhDLE9BQU4sR0FBZ0IsS0FBaEI7QUFFQTs7OztBQUdBOUMsS0FBSyxDQUFDK0MsS0FBTixHQUFjLFlBQVc7QUFDdkIsTUFBSUMsSUFBSSxHQUFHLEVBQVg7QUFDQSxNQUFJQyxRQUFRLEdBQ1YsZ0VBREY7O0FBR0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHLEVBQXBCLEVBQXdCQSxDQUFDLEVBQXpCLEVBQ0VGLElBQUksSUFBSUMsUUFBUSxDQUFDRSxNQUFULENBQWdCQyxJQUFJLENBQUNDLEtBQUwsQ0FBV0QsSUFBSSxDQUFDRSxNQUFMLEtBQWdCTCxRQUFRLENBQUNoQixNQUFwQyxDQUFoQixDQUFSOztBQUVGLFNBQU9lLElBQVA7QUFDRCxDQVREOztBQVdBaEQsS0FBSyxDQUFDa0Msb0JBQU4sR0FBNkIsVUFBU3FCLEdBQVQsRUFBYztBQUN6QztBQUNBLE1BQUlBLEdBQUosRUFBUztBQUNQLFFBQUl2QixJQUFJLEdBQUdELE1BQU0sQ0FBQ0MsSUFBUCxDQUFZdUIsR0FBWixFQUFpQkMsSUFBakIsRUFBWCxDQURPLENBR1A7O0FBQ0EsV0FBT3hCLElBQUksQ0FDUnlCLEdBREksQ0FDQSxVQUFTQyxHQUFULEVBQWM7QUFDakIsYUFBT0EsR0FBRyxHQUFHLEdBQU4sR0FBWTFELEtBQUssQ0FBQ3dDLE1BQU4sQ0FBYWUsR0FBRyxDQUFDRyxHQUFELENBQWhCLENBQW5CO0FBQ0QsS0FISSxFQUlKQyxJQUpJLENBSUMsR0FKRCxDQUFQO0FBS0Q7O0FBRUQsU0FBTyxFQUFQO0FBQ0QsQ0FkRDtBQWdCQTs7Ozs7QUFJQTNELEtBQUssQ0FBQzRELG9CQUFOLEdBQTZCLFVBQVNoRCxNQUFULEVBQWlCaUQsR0FBakIsRUFBc0JDLFVBQXRCLEVBQWtDO0FBQzdELFNBQU8sQ0FDTGxELE1BQU0sQ0FBQ3VCLFdBQVAsRUFESyxFQUVMbkMsS0FBSyxDQUFDd0MsTUFBTixDQUFhcUIsR0FBYixDQUZLLEVBR0w3RCxLQUFLLENBQUN3QyxNQUFOLENBQWFzQixVQUFiLENBSEssRUFJTEgsSUFKSyxDQUlBLEdBSkEsQ0FBUDtBQUtELENBTkQ7QUFRQTs7Ozs7QUFHQTNELEtBQUssQ0FBQytELFNBQU4sR0FBa0IsVUFBU2YsSUFBVCxFQUFlVSxHQUFmLEVBQW9CO0FBQ3BDNUQsRUFBQUEsTUFBTSxHQUFHRCxPQUFPLENBQUMsUUFBRCxDQUFoQjtBQUNBLFNBQU9HLEtBQUssQ0FBQ3dDLE1BQU4sQ0FDTDFDLE1BQU0sQ0FDSGtFLFVBREgsQ0FDYyxNQURkLEVBQ3NCTixHQUR0QixFQUVHTyxNQUZILENBRVVqQixJQUZWLEVBR0drQixNQUhILENBR1UsUUFIVixDQURLLENBQVA7QUFNRCxDQVJEOztBQVVBbEUsS0FBSyxDQUFDcUMsV0FBTixHQUFvQixVQUNsQnJCLE9BRGtCLEVBRWxCbUQsZ0JBRmtCLEVBR2xCOUQsZUFIa0IsRUFJbEJFLGlCQUprQixFQUtsQjtBQUNBNEQsRUFBQUEsZ0JBQWdCLEdBQUdBLGdCQUFnQixJQUFJLEVBQXZDLENBREEsQ0FHQTs7QUFDQSxNQUFJLENBQUNBLGdCQUFnQixDQUFDQyxXQUF0QixFQUFtQztBQUNqQ0QsSUFBQUEsZ0JBQWdCLENBQUNDLFdBQWpCLEdBQStCcEUsS0FBSyxDQUFDK0MsS0FBTixFQUEvQjtBQUNEOztBQUNELE1BQUksQ0FBQ29CLGdCQUFnQixDQUFDRSxlQUF0QixFQUF1QztBQUNyQ0YsSUFBQUEsZ0JBQWdCLENBQUNFLGVBQWpCLEdBQW1DakIsSUFBSSxDQUFDQyxLQUFMLENBQVcsSUFBSWlCLElBQUosR0FBV0MsT0FBWCxLQUF1QixJQUFsQyxDQUFuQztBQUNEOztBQUNELE1BQUksQ0FBQ0osZ0JBQWdCLENBQUNLLHNCQUF0QixFQUE4QztBQUM1Q0wsSUFBQUEsZ0JBQWdCLENBQUNLLHNCQUFqQixHQUEwQ3hFLEtBQUssQ0FBQzZDLGVBQWhEO0FBQ0Q7O0FBQ0QsTUFBSSxDQUFDc0IsZ0JBQWdCLENBQUNNLGFBQXRCLEVBQXFDO0FBQ25DTixJQUFBQSxnQkFBZ0IsQ0FBQ00sYUFBakIsR0FBaUN6RSxLQUFLLENBQUM4QyxPQUF2QztBQUNEOztBQUVELE1BQUksQ0FBQ3ZDLGlCQUFMLEVBQXdCO0FBQ3RCQSxJQUFBQSxpQkFBaUIsR0FBRyxFQUFwQjtBQUNELEdBbkJELENBb0JBOzs7QUFDQSxNQUFJLENBQUNTLE9BQU8sQ0FBQ0osTUFBYixFQUFxQjtBQUNuQkksSUFBQUEsT0FBTyxDQUFDSixNQUFSLEdBQWlCLEtBQWpCO0FBQ0QsR0F2QkQsQ0F5QkE7OztBQUNBLE1BQUk4RCxlQUFlLEdBQUcsRUFBdEI7QUFDQSxNQUFJQyxpQkFBaUIsR0FBRyxDQUFDM0QsT0FBTyxDQUFDRixNQUFULEVBQWlCRSxPQUFPLENBQUNELElBQXpCLEVBQStCb0QsZ0JBQS9CLENBQXhCOztBQUNBLE9BQUssSUFBSWpCLENBQVQsSUFBY3lCLGlCQUFkLEVBQWlDO0FBQy9CLFFBQUliLFVBQVUsR0FBR2EsaUJBQWlCLENBQUN6QixDQUFELENBQWxDOztBQUNBLFNBQUssSUFBSTBCLENBQVQsSUFBY2QsVUFBZCxFQUEwQjtBQUN4QlksTUFBQUEsZUFBZSxDQUFDRSxDQUFELENBQWYsR0FBcUJkLFVBQVUsQ0FBQ2MsQ0FBRCxDQUEvQjtBQUNEO0FBQ0YsR0FqQ0QsQ0FtQ0E7OztBQUNBLE1BQUlDLGVBQWUsR0FBRzdFLEtBQUssQ0FBQ2tDLG9CQUFOLENBQTJCd0MsZUFBM0IsQ0FBdEIsQ0FwQ0EsQ0FzQ0E7O0FBQ0EsTUFBSWIsR0FBRyxHQUFHLGFBQWE3QyxPQUFPLENBQUNSLElBQXJCLEdBQTRCLEVBQTVCLEdBQWlDUSxPQUFPLENBQUNILElBQW5EO0FBRUEsTUFBSWlFLGVBQWUsR0FBRzlFLEtBQUssQ0FBQzRELG9CQUFOLENBQ3BCNUMsT0FBTyxDQUFDSixNQURZLEVBRXBCaUQsR0FGb0IsRUFHcEJnQixlQUhvQixDQUF0QixDQXpDQSxDQThDQTs7QUFDQSxNQUFJRSxZQUFZLEdBQUcsQ0FDakIvRSxLQUFLLENBQUN3QyxNQUFOLENBQWFuQyxlQUFiLENBRGlCLEVBRWpCTCxLQUFLLENBQUN3QyxNQUFOLENBQWFqQyxpQkFBYixDQUZpQixFQUdqQm9ELElBSGlCLENBR1osR0FIWSxDQUFuQjtBQUtBLE1BQUlJLFNBQVMsR0FBRy9ELEtBQUssQ0FBQytELFNBQU4sQ0FBZ0JlLGVBQWhCLEVBQWlDQyxZQUFqQyxDQUFoQixDQXBEQSxDQXNEQTs7QUFDQVosRUFBQUEsZ0JBQWdCLENBQUNhLGVBQWpCLEdBQW1DakIsU0FBbkM7O0FBQ0EsTUFBSSxDQUFDL0MsT0FBTyxDQUFDaUUsT0FBYixFQUFzQjtBQUNwQmpFLElBQUFBLE9BQU8sQ0FBQ2lFLE9BQVIsR0FBa0IsRUFBbEI7QUFDRCxHQTFERCxDQTREQTs7O0FBQ0EsTUFBSUMsVUFBVSxHQUFHbkQsTUFBTSxDQUFDQyxJQUFQLENBQVltQyxnQkFBWixFQUNkWCxJQURjLEdBRWRDLEdBRmMsQ0FFVixVQUFTQyxHQUFULEVBQWM7QUFDakIsUUFBSXlCLEtBQUssR0FBR2hCLGdCQUFnQixDQUFDVCxHQUFELENBQTVCO0FBQ0EsV0FBT0EsR0FBRyxHQUFHLElBQU4sR0FBYXlCLEtBQWIsR0FBcUIsR0FBNUI7QUFDRCxHQUxjLEVBTWR4QixJQU5jLENBTVQsSUFOUyxDQUFqQjtBQVFBM0MsRUFBQUEsT0FBTyxDQUFDaUUsT0FBUixDQUFnQkcsYUFBaEIsR0FBZ0MsV0FBV0YsVUFBM0MsQ0FyRUEsQ0F1RUE7O0FBQ0FsRSxFQUFBQSxPQUFPLENBQUNpRSxPQUFSLENBQWdCLGNBQWhCLElBQWtDLG1DQUFsQztBQUNBLFNBQU9qRSxPQUFQO0FBQ0QsQ0EvRUQ7O0FBaUZBcUUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCdEYsS0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxudmFyIE9BdXRoID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAnTm8gb3B0aW9ucyBwYXNzZWQgdG8gT0F1dGgnXG4gICAgKTtcbiAgfVxuICB0aGlzLmNvbnN1bWVyX2tleSA9IG9wdGlvbnMuY29uc3VtZXJfa2V5O1xuICB0aGlzLmNvbnN1bWVyX3NlY3JldCA9IG9wdGlvbnMuY29uc3VtZXJfc2VjcmV0O1xuICB0aGlzLmF1dGhfdG9rZW4gPSBvcHRpb25zLmF1dGhfdG9rZW47XG4gIHRoaXMuYXV0aF90b2tlbl9zZWNyZXQgPSBvcHRpb25zLmF1dGhfdG9rZW5fc2VjcmV0O1xuICB0aGlzLmhvc3QgPSBvcHRpb25zLmhvc3Q7XG4gIHRoaXMub2F1dGhfcGFyYW1zID0gb3B0aW9ucy5vYXV0aF9wYXJhbXMgfHwge307XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uKG1ldGhvZCwgcGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHZhciByZXF1ZXN0ID0gdGhpcy5idWlsZFJlcXVlc3QobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xuICAvLyBFbmNvZGUgdGhlIGJvZHkgcHJvcGVybHksIHRoZSBjdXJyZW50IFBhcnNlIEltcGxlbWVudGF0aW9uIGRvbid0IGRvIGl0IHByb3Blcmx5XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgaHR0cFJlcXVlc3QgPSBodHRwc1xuICAgICAgLnJlcXVlc3QocmVxdWVzdCwgZnVuY3Rpb24ocmVzKSB7XG4gICAgICAgIHZhciBkYXRhID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QoJ0ZhaWxlZCB0byBtYWtlIGFuIE9BdXRoIHJlcXVlc3QnKTtcbiAgICAgIH0pO1xuICAgIGlmIChyZXF1ZXN0LmJvZHkpIHtcbiAgICAgIGh0dHBSZXF1ZXN0LndyaXRlKHJlcXVlc3QuYm9keSk7XG4gICAgfVxuICAgIGh0dHBSZXF1ZXN0LmVuZCgpO1xuICB9KTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5idWlsZFJlcXVlc3QgPSBmdW5jdGlvbihtZXRob2QsIHBhdGgsIHBhcmFtcywgYm9keSkge1xuICBpZiAocGF0aC5pbmRleE9mKCcvJykgIT0gMCkge1xuICAgIHBhdGggPSAnLycgKyBwYXRoO1xuICB9XG4gIGlmIChwYXJhbXMgJiYgT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPiAwKSB7XG4gICAgcGF0aCArPSAnPycgKyBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhwYXJhbXMpO1xuICB9XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgaG9zdDogdGhpcy5ob3N0LFxuICAgIHBhdGg6IHBhdGgsXG4gICAgbWV0aG9kOiBtZXRob2QudG9VcHBlckNhc2UoKSxcbiAgfTtcblxuICB2YXIgb2F1dGhfcGFyYW1zID0gdGhpcy5vYXV0aF9wYXJhbXMgfHwge307XG4gIG9hdXRoX3BhcmFtcy5vYXV0aF9jb25zdW1lcl9rZXkgPSB0aGlzLmNvbnN1bWVyX2tleTtcbiAgaWYgKHRoaXMuYXV0aF90b2tlbikge1xuICAgIG9hdXRoX3BhcmFtc1snb2F1dGhfdG9rZW4nXSA9IHRoaXMuYXV0aF90b2tlbjtcbiAgfVxuXG4gIHJlcXVlc3QgPSBPQXV0aC5zaWduUmVxdWVzdChcbiAgICByZXF1ZXN0LFxuICAgIG9hdXRoX3BhcmFtcyxcbiAgICB0aGlzLmNvbnN1bWVyX3NlY3JldCxcbiAgICB0aGlzLmF1dGhfdG9rZW5fc2VjcmV0XG4gICk7XG5cbiAgaWYgKGJvZHkgJiYgT2JqZWN0LmtleXMoYm9keSkubGVuZ3RoID4gMCkge1xuICAgIHJlcXVlc3QuYm9keSA9IE9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nKGJvZHkpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuT0F1dGgucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHBhdGgsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5zZW5kKCdHRVQnLCBwYXRoLCBwYXJhbXMpO1xufTtcblxuT0F1dGgucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbihwYXRoLCBwYXJhbXMsIGJvZHkpIHtcbiAgcmV0dXJuIHRoaXMuc2VuZCgnUE9TVCcsIHBhdGgsIHBhcmFtcywgYm9keSk7XG59O1xuXG4vKlxuXHRQcm9wZXIgc3RyaW5nICVlc2NhcGUgZW5jb2RpbmdcbiovXG5PQXV0aC5lbmNvZGUgPSBmdW5jdGlvbihzdHIpIHtcbiAgLy8gICAgICAgZGlzY3VzcyBhdDogaHR0cDovL3BocGpzLm9yZy9mdW5jdGlvbnMvcmF3dXJsZW5jb2RlL1xuICAvLyAgICAgIG9yaWdpbmFsIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiB0cmF2Y1xuICAvLyAgICAgICAgIGlucHV0IGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiBNaWNoYWVsIEdyaWVyXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IFJhdGhlb3VzXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEtldmluIHZhbiBab25uZXZlbGQgKGh0dHA6Ly9rZXZpbi52YW56b25uZXZlbGQubmV0KVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBKb3Jpc1xuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgICAgICBub3RlOiBUaGlzIHJlZmxlY3RzIFBIUCA1LjMvNi4wKyBiZWhhdmlvclxuICAvLyAgICAgICAgICAgICBub3RlOiBQbGVhc2UgYmUgYXdhcmUgdGhhdCB0aGlzIGZ1bmN0aW9uIGV4cGVjdHMgdG8gZW5jb2RlIGludG8gVVRGLTggZW5jb2RlZCBzdHJpbmdzLCBhcyBmb3VuZCBvblxuICAvLyAgICAgICAgICAgICBub3RlOiBwYWdlcyBzZXJ2ZWQgYXMgVVRGLThcbiAgLy8gICAgICAgIGV4YW1wbGUgMTogcmF3dXJsZW5jb2RlKCdLZXZpbiB2YW4gWm9ubmV2ZWxkIScpO1xuICAvLyAgICAgICAgcmV0dXJucyAxOiAnS2V2aW4lMjB2YW4lMjBab25uZXZlbGQlMjEnXG4gIC8vICAgICAgICBleGFtcGxlIDI6IHJhd3VybGVuY29kZSgnaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQvJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDI6ICdodHRwJTNBJTJGJTJGa2V2aW4udmFuem9ubmV2ZWxkLm5ldCUyRidcbiAgLy8gICAgICAgIGV4YW1wbGUgMzogcmF3dXJsZW5jb2RlKCdodHRwOi8vd3d3Lmdvb2dsZS5ubC9zZWFyY2g/cT1waHAuanMmaWU9dXRmLTgmb2U9dXRmLTgmYXE9dCZybHM9Y29tLnVidW50dTplbi1VUzp1bm9mZmljaWFsJmNsaWVudD1maXJlZm94LWEnKTtcbiAgLy8gICAgICAgIHJldHVybnMgMzogJ2h0dHAlM0ElMkYlMkZ3d3cuZ29vZ2xlLm5sJTJGc2VhcmNoJTNGcSUzRHBocC5qcyUyNmllJTNEdXRmLTglMjZvZSUzRHV0Zi04JTI2YXElM0R0JTI2cmxzJTNEY29tLnVidW50dSUzQWVuLVVTJTNBdW5vZmZpY2lhbCUyNmNsaWVudCUzRGZpcmVmb3gtYSdcblxuICBzdHIgPSAoc3RyICsgJycpLnRvU3RyaW5nKCk7XG5cbiAgLy8gVGlsZGUgc2hvdWxkIGJlIGFsbG93ZWQgdW5lc2NhcGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiBQSFAgKGFzIHJlZmxlY3RlZCBiZWxvdyksIGJ1dCBpZiB5b3Ugd2FudCB0byByZWZsZWN0IGN1cnJlbnRcbiAgLy8gUEhQIGJlaGF2aW9yLCB5b3Ugd291bGQgbmVlZCB0byBhZGQgXCIucmVwbGFjZSgvfi9nLCAnJTdFJyk7XCIgdG8gdGhlIGZvbGxvd2luZy5cbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpXG4gICAgLnJlcGxhY2UoLyEvZywgJyUyMScpXG4gICAgLnJlcGxhY2UoLycvZywgJyUyNycpXG4gICAgLnJlcGxhY2UoL1xcKC9nLCAnJTI4JylcbiAgICAucmVwbGFjZSgvXFwpL2csICclMjknKVxuICAgIC5yZXBsYWNlKC9cXCovZywgJyUyQScpO1xufTtcblxuT0F1dGguc2lnbmF0dXJlTWV0aG9kID0gJ0hNQUMtU0hBMSc7XG5PQXV0aC52ZXJzaW9uID0gJzEuMCc7XG5cbi8qXG5cdEdlbmVyYXRlIGEgbm9uY2VcbiovXG5PQXV0aC5ub25jZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdGV4dCA9ICcnO1xuICB2YXIgcG9zc2libGUgPVxuICAgICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAzMDsgaSsrKVxuICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpO1xuXG4gIHJldHVybiB0ZXh0O1xufTtcblxuT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcgPSBmdW5jdGlvbihvYmopIHtcbiAgLy8gU29ydCBrZXlzIGFuZCBlbmNvZGUgdmFsdWVzXG4gIGlmIChvYmopIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaikuc29ydCgpO1xuXG4gICAgLy8gTWFwIGtleT12YWx1ZSwgam9pbiB0aGVtIGJ5ICZcbiAgICByZXR1cm4ga2V5c1xuICAgICAgLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSArICc9JyArIE9BdXRoLmVuY29kZShvYmpba2V5XSk7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJyYnKTtcbiAgfVxuXG4gIHJldHVybiAnJztcbn07XG5cbi8qXG5cdEJ1aWxkIHRoZSBzaWduYXR1cmUgc3RyaW5nIGZyb20gdGhlIG9iamVjdFxuKi9cblxuT0F1dGguYnVpbGRTaWduYXR1cmVTdHJpbmcgPSBmdW5jdGlvbihtZXRob2QsIHVybCwgcGFyYW1ldGVycykge1xuICByZXR1cm4gW1xuICAgIG1ldGhvZC50b1VwcGVyQ2FzZSgpLFxuICAgIE9BdXRoLmVuY29kZSh1cmwpLFxuICAgIE9BdXRoLmVuY29kZShwYXJhbWV0ZXJzKSxcbiAgXS5qb2luKCcmJyk7XG59O1xuXG4vKlxuXHRSZXR1bnMgZW5jb2RlZCBITUFDLVNIQTEgZnJvbSBrZXkgYW5kIHRleHRcbiovXG5PQXV0aC5zaWduYXR1cmUgPSBmdW5jdGlvbih0ZXh0LCBrZXkpIHtcbiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG4gIHJldHVybiBPQXV0aC5lbmNvZGUoXG4gICAgY3J5cHRvXG4gICAgICAuY3JlYXRlSG1hYygnc2hhMScsIGtleSlcbiAgICAgIC51cGRhdGUodGV4dClcbiAgICAgIC5kaWdlc3QoJ2Jhc2U2NCcpXG4gICk7XG59O1xuXG5PQXV0aC5zaWduUmVxdWVzdCA9IGZ1bmN0aW9uKFxuICByZXF1ZXN0LFxuICBvYXV0aF9wYXJhbWV0ZXJzLFxuICBjb25zdW1lcl9zZWNyZXQsXG4gIGF1dGhfdG9rZW5fc2VjcmV0XG4pIHtcbiAgb2F1dGhfcGFyYW1ldGVycyA9IG9hdXRoX3BhcmFtZXRlcnMgfHwge307XG5cbiAgLy8gU2V0IGRlZmF1bHQgdmFsdWVzXG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9ub25jZSkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfbm9uY2UgPSBPQXV0aC5ub25jZSgpO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF90aW1lc3RhbXApIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3RpbWVzdGFtcCA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCA9IE9BdXRoLnNpZ25hdHVyZU1ldGhvZDtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbikge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbiA9IE9BdXRoLnZlcnNpb247XG4gIH1cblxuICBpZiAoIWF1dGhfdG9rZW5fc2VjcmV0KSB7XG4gICAgYXV0aF90b2tlbl9zZWNyZXQgPSAnJztcbiAgfVxuICAvLyBGb3JjZSBHRVQgbWV0aG9kIGlmIHVuc2V0XG4gIGlmICghcmVxdWVzdC5tZXRob2QpIHtcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdHRVQnO1xuICB9XG5cbiAgLy8gQ29sbGVjdCAgYWxsIHRoZSBwYXJhbWV0ZXJzIGluIG9uZSBzaWduYXR1cmVQYXJhbWV0ZXJzIG9iamVjdFxuICB2YXIgc2lnbmF0dXJlUGFyYW1zID0ge307XG4gIHZhciBwYXJhbWV0ZXJzVG9NZXJnZSA9IFtyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdC5ib2R5LCBvYXV0aF9wYXJhbWV0ZXJzXTtcbiAgZm9yICh2YXIgaSBpbiBwYXJhbWV0ZXJzVG9NZXJnZSkge1xuICAgIHZhciBwYXJhbWV0ZXJzID0gcGFyYW1ldGVyc1RvTWVyZ2VbaV07XG4gICAgZm9yICh2YXIgayBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICBzaWduYXR1cmVQYXJhbXNba10gPSBwYXJhbWV0ZXJzW2tdO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHN0cmluZyBiYXNlZCBvbiB0aGUgcGFyYW1ldGVyc1xuICB2YXIgcGFyYW1ldGVyU3RyaW5nID0gT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcoc2lnbmF0dXJlUGFyYW1zKTtcblxuICAvLyBCdWlsZCB0aGUgc2lnbmF0dXJlIHN0cmluZ1xuICB2YXIgdXJsID0gJ2h0dHBzOi8vJyArIHJlcXVlc3QuaG9zdCArICcnICsgcmVxdWVzdC5wYXRoO1xuXG4gIHZhciBzaWduYXR1cmVTdHJpbmcgPSBPQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyhcbiAgICByZXF1ZXN0Lm1ldGhvZCxcbiAgICB1cmwsXG4gICAgcGFyYW1ldGVyU3RyaW5nXG4gICk7XG4gIC8vIEhhc2ggdGhlIHNpZ25hdHVyZSBzdHJpbmdcbiAgdmFyIHNpZ25hdHVyZUtleSA9IFtcbiAgICBPQXV0aC5lbmNvZGUoY29uc3VtZXJfc2VjcmV0KSxcbiAgICBPQXV0aC5lbmNvZGUoYXV0aF90b2tlbl9zZWNyZXQpLFxuICBdLmpvaW4oJyYnKTtcblxuICB2YXIgc2lnbmF0dXJlID0gT0F1dGguc2lnbmF0dXJlKHNpZ25hdHVyZVN0cmluZywgc2lnbmF0dXJlS2V5KTtcblxuICAvLyBTZXQgdGhlIHNpZ25hdHVyZSBpbiB0aGUgcGFyYW1zXG4gIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICBpZiAoIXJlcXVlc3QuaGVhZGVycykge1xuICAgIHJlcXVlc3QuaGVhZGVycyA9IHt9O1xuICB9XG5cbiAgLy8gU2V0IHRoZSBhdXRob3JpemF0aW9uIGhlYWRlclxuICB2YXIgYXV0aEhlYWRlciA9IE9iamVjdC5rZXlzKG9hdXRoX3BhcmFtZXRlcnMpXG4gICAgLnNvcnQoKVxuICAgIC5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICB2YXIgdmFsdWUgPSBvYXV0aF9wYXJhbWV0ZXJzW2tleV07XG4gICAgICByZXR1cm4ga2V5ICsgJz1cIicgKyB2YWx1ZSArICdcIic7XG4gICAgfSlcbiAgICAuam9pbignLCAnKTtcblxuICByZXF1ZXN0LmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdPQXV0aCAnICsgYXV0aEhlYWRlcjtcblxuICAvLyBTZXQgdGhlIGNvbnRlbnQgdHlwZSBoZWFkZXJcbiAgcmVxdWVzdC5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnO1xuICByZXR1cm4gcmVxdWVzdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT0F1dGg7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/apple.js b/lib/Adapters/Auth/apple.js new file mode 100644 index 0000000000..b73bffde57 --- /dev/null +++ b/lib/Adapters/Auth/apple.js @@ -0,0 +1,105 @@ +"use strict"; + +// Apple SignIn Auth +// https://developer.apple.com/documentation/signinwithapplerestapi +const Parse = require('parse/node').Parse; + +const jwksClient = require('jwks-rsa'); + +const util = require('util'); + +const jwt = require('jsonwebtoken'); + +const TOKEN_ISSUER = 'https://appleid.apple.com'; + +const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { + const client = jwksClient({ + jwksUri: `${TOKEN_ISSUER}/auth/keys`, + cache: true, + cacheMaxEntries, + cacheMaxAge + }); + const asyncGetSigningKeyFunction = util.promisify(client.getSigningKey); + let key; + + try { + key = await asyncGetSigningKeyFunction(keyId); + } catch (error) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`); + } + + return key; +}; + +const getHeaderFromToken = token => { + const decodedToken = jwt.decode(token, { + complete: true + }); + + if (!decodedToken) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); + } + + return decodedToken.header; +}; + +const verifyIdToken = async ({ + token, + id +}, { + clientId, + cacheMaxEntries, + cacheMaxAge +}) => { + if (!token) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); + } + + const { + kid: keyId, + alg: algorithm + } = getHeaderFromToken(token); + const ONE_HOUR_IN_MS = 3600000; + let jwtClaims; + cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS; + cacheMaxEntries = cacheMaxEntries || 5; + const appleKey = await getAppleKeyByKeyId(keyId, cacheMaxEntries, cacheMaxAge); + const signingKey = appleKey.publicKey || appleKey.rsaPublicKey; + + try { + jwtClaims = jwt.verify(token, signingKey, { + algorithms: algorithm, + // the audience can be checked against a string, a regular expression or a list of strings and/or regular expressions. + audience: clientId + }); + } catch (exception) { + const message = exception.message; + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); + } + + if (jwtClaims.iss !== TOKEN_ISSUER) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`); + } + + if (jwtClaims.sub !== id) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); + } + + return jwtClaims; +}; // Returns a promise that fulfills if this id token is valid + + +function validateAuthData(authData, options = {}) { + return verifyIdToken(authData, options); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2FwcGxlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImp3a3NDbGllbnQiLCJ1dGlsIiwiand0IiwiVE9LRU5fSVNTVUVSIiwiZ2V0QXBwbGVLZXlCeUtleUlkIiwia2V5SWQiLCJjYWNoZU1heEVudHJpZXMiLCJjYWNoZU1heEFnZSIsImNsaWVudCIsImp3a3NVcmkiLCJjYWNoZSIsImFzeW5jR2V0U2lnbmluZ0tleUZ1bmN0aW9uIiwicHJvbWlzaWZ5IiwiZ2V0U2lnbmluZ0tleSIsImtleSIsImVycm9yIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0SGVhZGVyRnJvbVRva2VuIiwidG9rZW4iLCJkZWNvZGVkVG9rZW4iLCJkZWNvZGUiLCJjb21wbGV0ZSIsImhlYWRlciIsInZlcmlmeUlkVG9rZW4iLCJpZCIsImNsaWVudElkIiwia2lkIiwiYWxnIiwiYWxnb3JpdGhtIiwiT05FX0hPVVJfSU5fTVMiLCJqd3RDbGFpbXMiLCJhcHBsZUtleSIsInNpZ25pbmdLZXkiLCJwdWJsaWNLZXkiLCJyc2FQdWJsaWNLZXkiLCJ2ZXJpZnkiLCJhbGdvcml0aG1zIiwiYXVkaWVuY2UiLCJleGNlcHRpb24iLCJtZXNzYWdlIiwiaXNzIiwic3ViIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUVBLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBcEM7O0FBQ0EsTUFBTUUsVUFBVSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUExQjs7QUFDQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLE1BQU1HLEdBQUcsR0FBR0gsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7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LENBQU47QUFDRDs7QUFFRCxNQUFJVCxTQUFTLENBQUNVLEdBQVYsS0FBa0J0QyxZQUF0QixFQUFvQztBQUNsQyxVQUFNLElBQUlMLEtBQUssQ0FBQ2tCLEtBQVYsQ0FDSmxCLEtBQUssQ0FBQ2tCLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSCw4REFBNkRkLFlBQWEsWUFBVzRCLFNBQVMsQ0FBQ1UsR0FBSSxFQUZoRyxDQUFOO0FBSUQ7O0FBRUQsTUFBSVYsU0FBUyxDQUFDVyxHQUFWLEtBQWtCakIsRUFBdEIsRUFBMEI7QUFDeEIsVUFBTSxJQUFJM0IsS0FBSyxDQUFDa0IsS0FBVixDQUNKbEIsS0FBSyxDQUFDa0IsS0FBTixDQUFZQyxnQkFEUixFQUVILHFDQUZHLENBQU47QUFJRDs7QUFDRCxTQUFPYyxTQUFQO0FBQ0QsQ0FuREQsQyxDQXFEQTs7O0FBQ0EsU0FBU1ksZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DQyxPQUFPLEdBQUcsRUFBOUMsRUFBa0Q7QUFDaEQsU0FBT3JCLGFBQWEsQ0FBQ29CLFFBQUQsRUFBV0MsT0FBWCxDQUFwQjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmSCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQXBwbGUgU2lnbkluIEF1dGhcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9kb2N1bWVudGF0aW9uL3NpZ25pbndpdGhhcHBsZXJlc3RhcGlcblxuY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBqd2tzQ2xpZW50ID0gcmVxdWlyZSgnandrcy1yc2EnKTtcbmNvbnN0IHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5jb25zdCBqd3QgPSByZXF1aXJlKCdqc29ud2VidG9rZW4nKTtcblxuY29uc3QgVE9LRU5fSVNTVUVSID0gJ2h0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20nO1xuXG5jb25zdCBnZXRBcHBsZUtleUJ5S2V5SWQgPSBhc3luYyAoa2V5SWQsIGNhY2hlTWF4RW50cmllcywgY2FjaGVNYXhBZ2UpID0+IHtcbiAgY29uc3QgY2xpZW50ID0gandrc0NsaWVudCh7XG4gICAgandrc1VyaTogYCR7VE9LRU5fSVNTVUVSfS9hdXRoL2tleXNgLFxuICAgIGNhY2hlOiB0cnVlLFxuICAgIGNhY2hlTWF4RW50cmllcyxcbiAgICBjYWNoZU1heEFnZSxcbiAgfSk7XG5cbiAgY29uc3QgYXN5bmNHZXRTaWduaW5nS2V5RnVuY3Rpb24gPSB1dGlsLnByb21pc2lmeShjbGllbnQuZ2V0U2lnbmluZ0tleSk7XG5cbiAgbGV0IGtleTtcbiAgdHJ5IHtcbiAgICBrZXkgPSBhd2FpdCBhc3luY0dldFNpZ25pbmdLZXlGdW5jdGlvbihrZXlJZCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBVbmFibGUgdG8gZmluZCBtYXRjaGluZyBrZXkgZm9yIEtleSBJRDogJHtrZXlJZH1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4ga2V5O1xufTtcblxuY29uc3QgZ2V0SGVhZGVyRnJvbVRva2VuID0gdG9rZW4gPT4ge1xuICBjb25zdCBkZWNvZGVkVG9rZW4gPSBqd3QuZGVjb2RlKHRva2VuLCB7IGNvbXBsZXRlOiB0cnVlIH0pO1xuICBpZiAoIWRlY29kZWRUb2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgcHJvdmlkZWQgdG9rZW4gZG9lcyBub3QgZGVjb2RlIGFzIEpXVGBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGRlY29kZWRUb2tlbi5oZWFkZXI7XG59O1xuXG5jb25zdCB2ZXJpZnlJZFRva2VuID0gYXN5bmMgKFxuICB7IHRva2VuLCBpZCB9LFxuICB7IGNsaWVudElkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlIH1cbikgPT4ge1xuICBpZiAoIXRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuYFxuICAgICk7XG4gIH1cblxuICBjb25zdCB7IGtpZDoga2V5SWQsIGFsZzogYWxnb3JpdGhtIH0gPSBnZXRIZWFkZXJGcm9tVG9rZW4odG9rZW4pO1xuICBjb25zdCBPTkVfSE9VUl9JTl9NUyA9IDM2MDAwMDA7XG4gIGxldCBqd3RDbGFpbXM7XG5cbiAgY2FjaGVNYXhBZ2UgPSBjYWNoZU1heEFnZSB8fCBPTkVfSE9VUl9JTl9NUztcbiAgY2FjaGVNYXhFbnRyaWVzID0gY2FjaGVNYXhFbnRyaWVzIHx8IDU7XG5cbiAgY29uc3QgYXBwbGVLZXkgPSBhd2FpdCBnZXRBcHBsZUtleUJ5S2V5SWQoXG4gICAga2V5SWQsXG4gICAgY2FjaGVNYXhFbnRyaWVzLFxuICAgIGNhY2hlTWF4QWdlXG4gICk7XG4gIGNvbnN0IHNpZ25pbmdLZXkgPSBhcHBsZUtleS5wdWJsaWNLZXkgfHwgYXBwbGVLZXkucnNhUHVibGljS2V5O1xuXG4gIHRyeSB7XG4gICAgand0Q2xhaW1zID0gand0LnZlcmlmeSh0b2tlbiwgc2lnbmluZ0tleSwge1xuICAgICAgYWxnb3JpdGhtczogYWxnb3JpdGhtLFxuICAgICAgLy8gdGhlIGF1ZGllbmNlIGNhbiBiZSBjaGVja2VkIGFnYWluc3QgYSBzdHJpbmcsIGEgcmVndWxhciBleHByZXNzaW9uIG9yIGEgbGlzdCBvZiBzdHJpbmdzIGFuZC9vciByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgICAgYXVkaWVuY2U6IGNsaWVudElkLFxuICAgIH0pO1xuICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXhjZXB0aW9uLm1lc3NhZ2U7XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYCR7bWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuaXNzICE9PSBUT0tFTl9JU1NVRVIpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYGlkIHRva2VuIG5vdCBpc3N1ZWQgYnkgY29ycmVjdCBPcGVuSUQgcHJvdmlkZXIgLSBleHBlY3RlZDogJHtUT0tFTl9JU1NVRVJ9IHwgZnJvbTogJHtqd3RDbGFpbXMuaXNzfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5zdWIgIT09IGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBhdXRoIGRhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmBcbiAgICApO1xuICB9XG4gIHJldHVybiBqd3RDbGFpbXM7XG59O1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgaWQgdG9rZW4gaXMgdmFsaWRcbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gdmVyaWZ5SWRUb2tlbihhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/facebook.js b/lib/Adapters/Auth/facebook.js new file mode 100644 index 0000000000..61bd1b0d5b --- /dev/null +++ b/lib/Adapters/Auth/facebook.js @@ -0,0 +1,62 @@ +"use strict"; + +// Helper functions for accessing the Facebook Graph API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; + +const crypto = require('crypto'); + +function getAppSecretPath(authData, options = {}) { + const appSecret = options.appSecret; + + if (!appSecret) { + return ''; + } + + const appsecret_proof = crypto.createHmac('sha256', appSecret).update(authData.access_token).digest('hex'); + return `&appsecret_proof=${appsecret_proof}`; +} // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + return graphRequest('me?fields=id&access_token=' + authData.access_token + getAppSecretPath(authData, options)).then(data => { + if (data && data.id == authData.id || process.env.TESTING && authData.id === 'test') { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId(appIds, authData, options) { + var access_token = authData.access_token; + + if (process.env.TESTING && access_token === 'test') { + return Promise.resolve(); + } + + if (!appIds.length) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.'); + } + + return graphRequest('app?access_token=' + access_token + getAppSecretPath(authData, options)).then(data => { + if (data && appIds.indexOf(data.id) != -1) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); + }); +} // A promisey wrapper for FB graph requests. + + +function graphRequest(path) { + return httpsRequest.get('https://graph.facebook.com/' + path); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2ZhY2Vib29rLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsImNyeXB0byIsImdldEFwcFNlY3JldFBhdGgiLCJhdXRoRGF0YSIsIm9wdGlvbnMiLCJhcHBTZWNyZXQiLCJhcHBzZWNyZXRfcHJvb2YiLCJjcmVhdGVIbWFjIiwidXBkYXRlIiwiYWNjZXNzX3Rva2VuIiwiZGlnZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsInRoZW4iLCJkYXRhIiwiaWQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJhcHBJZHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsImluZGV4T2YiLCJwYXRoIiwiZ2V0IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLE1BQU1BLFlBQVksR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEM7O0FBQ0EsTUFBTUMsTUFBTSxHQUFHRixPQUFPLENBQUMsUUFBRCxDQUF0Qjs7QUFFQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQU8sR0FBRyxFQUE5QyxFQUFrRDtBQUNoRCxRQUFNQyxTQUFTLEdBQUdELE9BQU8sQ0FBQ0MsU0FBMUI7O0FBQ0EsTUFBSSxDQUFDQSxTQUFMLEVBQWdCO0FBQ2QsV0FBTyxFQUFQO0FBQ0Q7O0FBQ0QsUUFBTUMsZUFBZSxHQUFHTCxNQUFNLENBQzNCTSxVQURxQixDQUNWLFFBRFUsRUFDQUYsU0FEQSxFQUVyQkcsTUFGcUIsQ0FFZEwsUUFBUSxDQUFDTSxZQUZLLEVBR3JCQyxNQUhxQixDQUdkLEtBSGMsQ0FBeEI7QUFLQSxTQUFRLG9CQUFtQkosZUFBZ0IsRUFBM0M7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNLLGdCQUFULENBQTBCUixRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT1EsWUFBWSxDQUNqQiwrQkFDRVQsUUFBUSxDQUFDTSxZQURYLEdBRUVQLGdCQUFnQixDQUFDQyxRQUFELEVBQVdDLE9BQVgsQ0FIRCxDQUFaLENBSUxTLElBSkssQ0FJQUMsSUFBSSxJQUFJO0FBQ2IsUUFDR0EsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV1osUUFBUSxDQUFDWSxFQUE3QixJQUNDQyxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBWixJQUF1QmYsUUFBUSxDQUFDWSxFQUFULEtBQWdCLE1BRjFDLEVBR0U7QUFDQTtBQUNEOztBQUNELFVBQU0sSUFBSWYsS0FBSyxDQUFDbUIsS0FBVixDQUNKbkIsS0FBSyxDQUFDbUIsS0FBTixDQUFZQyxnQkFEUixFQUVKLHlDQUZJLENBQU47QUFJRCxHQWZNLENBQVA7QUFnQkQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQm5CLFFBQS9CLEVBQXlDQyxPQUF6QyxFQUFrRDtBQUNoRCxNQUFJSyxZQUFZLEdBQUdOLFFBQVEsQ0FBQ00sWUFBNUI7O0FBQ0EsTUFBSU8sT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQVosSUFBdUJULFlBQVksS0FBSyxNQUE1QyxFQUFvRDtBQUNsRCxXQUFPYyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELE1BQUksQ0FBQ0YsTUFBTSxDQUFDRyxNQUFaLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSXpCLEtBQUssQ0FBQ21CLEtBQVYsQ0FDSm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixrQ0FGSSxDQUFOO0FBSUQ7O0FBQ0QsU0FBT1IsWUFBWSxDQUNqQixzQkFBc0JILFlBQXRCLEdBQXFDUCxnQkFBZ0IsQ0FBQ0MsUUFBRCxFQUFXQyxPQUFYLENBRHBDLENBQVosQ0FFTFMsSUFGSyxDQUVBQyxJQUFJLElBQUk7QUFDYixRQUFJQSxJQUFJLElBQUlRLE1BQU0sQ0FBQ0ksT0FBUCxDQUFlWixJQUFJLENBQUNDLEVBQXBCLEtBQTJCLENBQUMsQ0FBeEMsRUFBMkM7QUFDekM7QUFDRDs7QUFDRCxVQUFNLElBQUlmLEtBQUssQ0FBQ21CLEtBQVYsQ0FDSm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5Q0FGSSxDQUFOO0FBSUQsR0FWTSxDQUFQO0FBV0QsQyxDQUVEOzs7QUFDQSxTQUFTUixZQUFULENBQXNCZSxJQUF0QixFQUE0QjtBQUMxQixTQUFPN0IsWUFBWSxDQUFDOEIsR0FBYixDQUFpQixnQ0FBZ0NELElBQWpELENBQVA7QUFDRDs7QUFFREUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVixFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgRmFjZWJvb2sgR3JhcGggQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG5mdW5jdGlvbiBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgYXBwU2VjcmV0ID0gb3B0aW9ucy5hcHBTZWNyZXQ7XG4gIGlmICghYXBwU2VjcmV0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IGFwcHNlY3JldF9wcm9vZiA9IGNyeXB0b1xuICAgIC5jcmVhdGVIbWFjKCdzaGEyNTYnLCBhcHBTZWNyZXQpXG4gICAgLnVwZGF0ZShhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pXG4gICAgLmRpZ2VzdCgnaGV4Jyk7XG5cbiAgcmV0dXJuIGAmYXBwc2VjcmV0X3Byb29mPSR7YXBwc2VjcmV0X3Byb29mfWA7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChcbiAgICAnbWU/ZmllbGRzPWlkJmFjY2Vzc190b2tlbj0nICtcbiAgICAgIGF1dGhEYXRhLmFjY2Vzc190b2tlbiArXG4gICAgICBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zKVxuICApLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKFxuICAgICAgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkgfHxcbiAgICAgIChwcm9jZXNzLmVudi5URVNUSU5HICYmIGF1dGhEYXRhLmlkID09PSAndGVzdCcpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnRmFjZWJvb2sgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoYXBwSWRzLCBhdXRoRGF0YSwgb3B0aW9ucykge1xuICB2YXIgYWNjZXNzX3Rva2VuID0gYXV0aERhdGEuYWNjZXNzX3Rva2VuO1xuICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyAmJiBhY2Nlc3NfdG9rZW4gPT09ICd0ZXN0Jykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICBpZiAoIWFwcElkcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0ZhY2Vib29rIGF1dGggaXMgbm90IGNvbmZpZ3VyZWQuJ1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChcbiAgICAnYXBwP2FjY2Vzc190b2tlbj0nICsgYWNjZXNzX3Rva2VuICsgZ2V0QXBwU2VjcmV0UGF0aChhdXRoRGF0YSwgb3B0aW9ucylcbiAgKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGFwcElkcy5pbmRleE9mKGRhdGEuaWQpICE9IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnRmFjZWJvb2sgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIEZCIGdyYXBoIHJlcXVlc3RzLlxuZnVuY3Rpb24gZ3JhcGhSZXF1ZXN0KHBhdGgpIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoJ2h0dHBzOi8vZ3JhcGguZmFjZWJvb2suY29tLycgKyBwYXRoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/gcenter.js b/lib/Adapters/Auth/gcenter.js new file mode 100644 index 0000000000..1145b1e4eb --- /dev/null +++ b/lib/Adapters/Auth/gcenter.js @@ -0,0 +1,126 @@ +"use strict"; + +/* Apple Game Center Auth +https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign#discussion + +const authData = { + publicKeyUrl: 'https://valid.apple.com/public/timeout.cer', + timestamp: 1460981421303, + signature: 'PoDwf39DCN464B49jJCU0d9Y0J', + salt: 'saltST==', + bundleId: 'com.valid.app' + id: 'playerId', +}; +*/ +const { + Parse +} = require('parse/node'); + +const crypto = require('crypto'); + +const https = require('https'); + +const url = require('url'); + +const cache = {}; // (publicKey -> cert) cache + +function verifyPublicKeyUrl(publicKeyUrl) { + const parsedUrl = url.parse(publicKeyUrl); + + if (parsedUrl.protocol !== 'https:') { + return false; + } + + const hostnameParts = parsedUrl.hostname.split('.'); + const length = hostnameParts.length; + const domainParts = hostnameParts.slice(length - 2, length); + const domain = domainParts.join('.'); + return domain === 'apple.com'; +} + +function convertX509CertToPEM(X509Cert) { + const pemPreFix = '-----BEGIN CERTIFICATE-----\n'; + const pemPostFix = '-----END CERTIFICATE-----'; + const base64 = X509Cert; + const certBody = base64.match(new RegExp('.{0,64}', 'g')).join('\n'); + return pemPreFix + certBody + pemPostFix; +} + +function getAppleCertificate(publicKeyUrl) { + if (!verifyPublicKeyUrl(publicKeyUrl)) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`); + } + + if (cache[publicKeyUrl]) { + return cache[publicKeyUrl]; + } + + return new Promise((resolve, reject) => { + https.get(publicKeyUrl, res => { + let data = ''; + res.on('data', chunk => { + data += chunk.toString('base64'); + }); + res.on('end', () => { + const cert = convertX509CertToPEM(data); + + if (res.headers['cache-control']) { + var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); + + if (expire) { + cache[publicKeyUrl] = cert; // we'll expire the cache entry later, as per max-age + + setTimeout(() => { + delete cache[publicKeyUrl]; + }, parseInt(expire[1], 10) * 1000); + } + } + + resolve(cert); + }); + }).on('error', reject); + }); +} + +function convertTimestampToBigEndian(timestamp) { + const buffer = Buffer.alloc(8); + const high = ~~(timestamp / 0xffffffff); + const low = timestamp % (0xffffffff + 0x1); + buffer.writeUInt32BE(parseInt(high, 10), 0); + buffer.writeUInt32BE(parseInt(low, 10), 4); + return buffer; +} + +function verifySignature(publicKey, authData) { + const verifier = crypto.createVerify('sha256'); + verifier.update(authData.playerId, 'utf8'); + verifier.update(authData.bundleId, 'utf8'); + verifier.update(convertTimestampToBigEndian(authData.timestamp)); + verifier.update(authData.salt, 'base64'); + + if (!verifier.verify(publicKey, authData.signature, 'base64')) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - invalid signature'); + } +} // Returns a promise that fulfills if this user id is valid. + + +async function validateAuthData(authData) { + if (!authData.id) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - authData id missing'); + } + + authData.playerId = authData.id; + const publicKey = await getAppleCertificate(authData.publicKeyUrl); + return verifySignature(publicKey, authData); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2djZW50ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiY3J5cHRvIiwiaHR0cHMiLCJ1cmwiLCJjYWNoZSIsInZlcmlmeVB1YmxpY0tleVVybCIsInB1YmxpY0tleVVybCIsInBhcnNlZFVybCIsInBhcnNlIiwicHJvdG9jb2wiLCJob3N0bmFtZVBhcnRzIiwiaG9zdG5hbWUiLCJzcGxpdCIsImxlbmd0aCIsImRvbWFpblBhcnRzIiwic2xpY2UiLCJkb21haW4iLCJqb2luIiwiY29udmVydFg1MDlDZXJ0VG9QRU0iLCJYNTA5Q2VydCIsInBlbVByZUZpeCIsInBlbVBvc3RGaXgiLCJiYXNlNjQiLCJjZXJ0Qm9keSIsIm1hdGNoIiwiUmVnRXhwIiwiZ2V0QXBwbGVDZXJ0aWZpY2F0ZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImNlcnQiLCJoZWFkZXJzIiwiZXhwaXJlIiwic2V0VGltZW91dCIsInBhcnNlSW50IiwiY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuIiwidGltZXN0YW1wIiwiYnVmZmVyIiwiQnVmZmVyIiwiYWxsb2MiLCJoaWdoIiwibG93Iiwid3JpdGVVSW50MzJCRSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJwbGF5ZXJJZCIsImJ1bmRsZUlkIiwic2FsdCIsInZlcmlmeSIsInNpZ25hdHVyZSIsInZhbGlkYXRlQXV0aERhdGEiLCJpZCIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7Ozs7Ozs7QUFhQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQs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QWdCSCxRQUFRLENBQUNNLElBQXpCLEVBQStCLFFBQS9COztBQUVBLE1BQUksQ0FBQ0wsUUFBUSxDQUFDTSxNQUFULENBQWdCUixTQUFoQixFQUEyQkMsUUFBUSxDQUFDUSxTQUFwQyxFQUErQyxRQUEvQyxDQUFMLEVBQStEO0FBQzdELFVBQU0sSUFBSTlELEtBQUssQ0FBQzRCLEtBQVYsQ0FDSjVCLEtBQUssQ0FBQzRCLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix1Q0FGSSxDQUFOO0FBSUQ7QUFDRixDLENBRUQ7OztBQUNBLGVBQWVrQyxnQkFBZixDQUFnQ1QsUUFBaEMsRUFBMEM7QUFDeEMsTUFBSSxDQUFDQSxRQUFRLENBQUNVLEVBQWQsRUFBa0I7QUFDaEIsVUFBTSxJQUFJaEUsS0FBSyxDQUFDNEIsS0FBVixDQUNKNUIsS0FBSyxDQUFDNEIsS0FBTixDQUFZQyxnQkFEUixFQUVKLHlDQUZJLENBQU47QUFJRDs7QUFDRHlCLEVBQUFBLFFBQVEsQ0FBQ0ksUUFBVCxHQUFvQkosUUFBUSxDQUFDVSxFQUE3QjtBQUNBLFFBQU1YLFNBQVMsR0FBRyxNQUFNMUIsbUJBQW1CLENBQUMyQixRQUFRLENBQUMvQyxZQUFWLENBQTNDO0FBQ0EsU0FBTzZDLGVBQWUsQ0FBQ0MsU0FBRCxFQUFZQyxRQUFaLENBQXRCO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9uQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEbUMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZGLEVBQUFBLGFBRGU7QUFFZkYsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIEFwcGxlIEdhbWUgQ2VudGVyIEF1dGhcbmh0dHBzOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9kb2N1bWVudGF0aW9uL2dhbWVraXQvZ2tsb2NhbHBsYXllci8xNTE1NDA3LWdlbmVyYXRlaWRlbnRpdHl2ZXJpZmljYXRpb25zaWduI2Rpc2N1c3Npb25cblxuY29uc3QgYXV0aERhdGEgPSB7XG4gIHB1YmxpY0tleVVybDogJ2h0dHBzOi8vdmFsaWQuYXBwbGUuY29tL3B1YmxpYy90aW1lb3V0LmNlcicsXG4gIHRpbWVzdGFtcDogMTQ2MDk4MTQyMTMwMyxcbiAgc2lnbmF0dXJlOiAnUG9Ed2YzOURDTjQ2NEI0OWpKQ1UwZDlZMEonLFxuICBzYWx0OiAnc2FsdFNUPT0nLFxuICBidW5kbGVJZDogJ2NvbS52YWxpZC5hcHAnXG4gIGlkOiAncGxheWVySWQnLFxufTtcbiovXG5cbmNvbnN0IHsgUGFyc2UgfSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuY29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5cbmNvbnN0IGNhY2hlID0ge307IC8vIChwdWJsaWNLZXkgLT4gY2VydCkgY2FjaGVcblxuZnVuY3Rpb24gdmVyaWZ5UHVibGljS2V5VXJsKHB1YmxpY0tleVVybCkge1xuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocHVibGljS2V5VXJsKTtcbiAgaWYgKHBhcnNlZFVybC5wcm90b2NvbCAhPT0gJ2h0dHBzOicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgaG9zdG5hbWVQYXJ0cyA9IHBhcnNlZFVybC5ob3N0bmFtZS5zcGxpdCgnLicpO1xuICBjb25zdCBsZW5ndGggPSBob3N0bmFtZVBhcnRzLmxlbmd0aDtcbiAgY29uc3QgZG9tYWluUGFydHMgPSBob3N0bmFtZVBhcnRzLnNsaWNlKGxlbmd0aCAtIDIsIGxlbmd0aCk7XG4gIGNvbnN0IGRvbWFpbiA9IGRvbWFpblBhcnRzLmpvaW4oJy4nKTtcbiAgcmV0dXJuIGRvbWFpbiA9PT0gJ2FwcGxlLmNvbSc7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRYNTA5Q2VydFRvUEVNKFg1MDlDZXJ0KSB7XG4gIGNvbnN0IHBlbVByZUZpeCA9ICctLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cXG4nO1xuICBjb25zdCBwZW1Qb3N0Rml4ID0gJy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0nO1xuXG4gIGNvbnN0IGJhc2U2NCA9IFg1MDlDZXJ0O1xuICBjb25zdCBjZXJ0Qm9keSA9IGJhc2U2NC5tYXRjaChuZXcgUmVnRXhwKCcuezAsNjR9JywgJ2cnKSkuam9pbignXFxuJyk7XG5cbiAgcmV0dXJuIHBlbVByZUZpeCArIGNlcnRCb2R5ICsgcGVtUG9zdEZpeDtcbn1cblxuZnVuY3Rpb24gZ2V0QXBwbGVDZXJ0aWZpY2F0ZShwdWJsaWNLZXlVcmwpIHtcbiAgaWYgKCF2ZXJpZnlQdWJsaWNLZXlVcmwocHVibGljS2V5VXJsKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgQXBwbGUgR2FtZSBDZW50ZXIgLSBpbnZhbGlkIHB1YmxpY0tleVVybDogJHtwdWJsaWNLZXlVcmx9YFxuICAgICk7XG4gIH1cbiAgaWYgKGNhY2hlW3B1YmxpY0tleVVybF0pIHtcbiAgICByZXR1cm4gY2FjaGVbcHVibGljS2V5VXJsXTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGh0dHBzXG4gICAgICAuZ2V0KHB1YmxpY0tleVVybCwgcmVzID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bmsudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2VydCA9IGNvbnZlcnRYNTA5Q2VydFRvUEVNKGRhdGEpO1xuICAgICAgICAgIGlmIChyZXMuaGVhZGVyc1snY2FjaGUtY29udHJvbCddKSB7XG4gICAgICAgICAgICB2YXIgZXhwaXJlID0gcmVzLmhlYWRlcnNbJ2NhY2hlLWNvbnRyb2wnXS5tYXRjaCgvbWF4LWFnZT0oWzAtOV0rKS8pO1xuICAgICAgICAgICAgaWYgKGV4cGlyZSkge1xuICAgICAgICAgICAgICBjYWNoZVtwdWJsaWNLZXlVcmxdID0gY2VydDtcbiAgICAgICAgICAgICAgLy8gd2UnbGwgZXhwaXJlIHRoZSBjYWNoZSBlbnRyeSBsYXRlciwgYXMgcGVyIG1heC1hZ2VcbiAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNhY2hlW3B1YmxpY0tleVVybF07XG4gICAgICAgICAgICAgIH0sIHBhcnNlSW50KGV4cGlyZVsxXSwgMTApICogMTAwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoY2VydCk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCByZWplY3QpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKHRpbWVzdGFtcCkge1xuICBjb25zdCBidWZmZXIgPSBCdWZmZXIuYWxsb2MoOCk7XG5cbiAgY29uc3QgaGlnaCA9IH5+KHRpbWVzdGFtcCAvIDB4ZmZmZmZmZmYpO1xuICBjb25zdCBsb3cgPSB0aW1lc3RhbXAgJSAoMHhmZmZmZmZmZiArIDB4MSk7XG5cbiAgYnVmZmVyLndyaXRlVUludDMyQkUocGFyc2VJbnQoaGlnaCwgMTApLCAwKTtcbiAgYnVmZmVyLndyaXRlVUludDMyQkUocGFyc2VJbnQobG93LCAxMCksIDQpO1xuXG4gIHJldHVybiBidWZmZXI7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeVNpZ25hdHVyZShwdWJsaWNLZXksIGF1dGhEYXRhKSB7XG4gIGNvbnN0IHZlcmlmaWVyID0gY3J5cHRvLmNyZWF0ZVZlcmlmeSgnc2hhMjU2Jyk7XG4gIHZlcmlmaWVyLnVwZGF0ZShhdXRoRGF0YS5wbGF5ZXJJZCwgJ3V0ZjgnKTtcbiAgdmVyaWZpZXIudXBkYXRlKGF1dGhEYXRhLmJ1bmRsZUlkLCAndXRmOCcpO1xuICB2ZXJpZmllci51cGRhdGUoY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKGF1dGhEYXRhLnRpbWVzdGFtcCkpO1xuICB2ZXJpZmllci51cGRhdGUoYXV0aERhdGEuc2FsdCwgJ2Jhc2U2NCcpO1xuXG4gIGlmICghdmVyaWZpZXIudmVyaWZ5KHB1YmxpY0tleSwgYXV0aERhdGEuc2lnbmF0dXJlLCAnYmFzZTY0JykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0FwcGxlIEdhbWUgQ2VudGVyIC0gaW52YWxpZCBzaWduYXR1cmUnXG4gICAgKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgaWYgKCFhdXRoRGF0YS5pZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnQXBwbGUgR2FtZSBDZW50ZXIgLSBhdXRoRGF0YSBpZCBtaXNzaW5nJ1xuICAgICk7XG4gIH1cbiAgYXV0aERhdGEucGxheWVySWQgPSBhdXRoRGF0YS5pZDtcbiAgY29uc3QgcHVibGljS2V5ID0gYXdhaXQgZ2V0QXBwbGVDZXJ0aWZpY2F0ZShhdXRoRGF0YS5wdWJsaWNLZXlVcmwpO1xuICByZXR1cm4gdmVyaWZ5U2lnbmF0dXJlKHB1YmxpY0tleSwgYXV0aERhdGEpO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/github.js b/lib/Adapters/Auth/github.js new file mode 100644 index 0000000000..686d718a9c --- /dev/null +++ b/lib/Adapters/Auth/github.js @@ -0,0 +1,40 @@ +"use strict"; + +// Helper functions for accessing the github API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('user', authData.access_token).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Github auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'api.github.com', + path: '/' + path, + headers: { + Authorization: 'bearer ' + access_token, + 'User-Agent': 'parse-server' + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dpdGh1Yi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsTUFBRCxFQUFTRCxRQUFRLENBQUNFLFlBQWxCLENBQVAsQ0FBdUNDLElBQXZDLENBQTRDQyxJQUFJLElBQUk7QUFDekQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVQsS0FBSyxDQUFDVSxLQUFWLENBQ0pWLEtBQUssQ0FBQ1UsS0FBTixDQUFZQyxnQkFEUixFQUVKLHVDQUZJLENBQU47QUFJRCxHQVJNLENBQVA7QUFTRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNULE9BQVQsQ0FBaUJVLElBQWpCLEVBQXVCVCxZQUF2QixFQUFxQztBQUNuQyxTQUFPSixZQUFZLENBQUNjLEdBQWIsQ0FBaUI7QUFDdEJDLElBQUFBLElBQUksRUFBRSxnQkFEZ0I7QUFFdEJGLElBQUFBLElBQUksRUFBRSxNQUFNQSxJQUZVO0FBR3RCRyxJQUFBQSxPQUFPLEVBQUU7QUFDUEMsTUFBQUEsYUFBYSxFQUFFLFlBQVliLFlBRHBCO0FBRVAsb0JBQWM7QUFGUDtBQUhhLEdBQWpCLENBQVA7QUFRRDs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgZ2l0aHViIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ3VzZXInLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0dpdGh1YiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuZ2l0aHViLmNvbScsXG4gICAgcGF0aDogJy8nICsgcGF0aCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiAnYmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICAnVXNlci1BZ2VudCc6ICdwYXJzZS1zZXJ2ZXInLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/google.js b/lib/Adapters/Auth/google.js new file mode 100644 index 0000000000..91f9c720f5 --- /dev/null +++ b/lib/Adapters/Auth/google.js @@ -0,0 +1,167 @@ +'use strict'; // Helper functions for accessing the google API. + +var Parse = require('parse/node').Parse; + +const https = require('https'); + +const jwt = require('jsonwebtoken'); + +const TOKEN_ISSUER = 'accounts.google.com'; +const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com'; +let cache = {}; // Retrieve Google Signin Keys (with cache control) + +function getGoogleKeyByKeyId(keyId) { + if (cache[keyId] && cache.expiresAt > new Date()) { + return cache[keyId]; + } + + return new Promise((resolve, reject) => { + https.get(`https://www.googleapis.com/oauth2/v3/certs`, res => { + let data = ''; + res.on('data', chunk => { + data += chunk.toString('utf8'); + }); + res.on('end', () => { + const { + keys + } = JSON.parse(data); + const pems = keys.reduce((pems, { + n: modulus, + e: exposant, + kid + }) => Object.assign(pems, { + [kid]: rsaPublicKeyToPEM(modulus, exposant) + }), {}); + + if (res.headers['cache-control']) { + var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); + + if (expire) { + cache = Object.assign({}, pems, { + expiresAt: new Date(new Date().getTime() + Number(expire[1]) * 1000) + }); + } + } + + resolve(pems[keyId]); + }); + }).on('error', reject); + }); +} + +function getHeaderFromToken(token) { + const decodedToken = jwt.decode(token, { + complete: true + }); + + if (!decodedToken) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); + } + + return decodedToken.header; +} + +async function verifyIdToken({ + id_token: token, + id +}, { + clientId +}) { + if (!token) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); + } + + const { + kid: keyId, + alg: algorithm + } = getHeaderFromToken(token); + let jwtClaims; + const googleKey = await getGoogleKeyByKeyId(keyId); + + try { + jwtClaims = jwt.verify(token, googleKey, { + algorithms: algorithm, + audience: clientId + }); + } catch (exception) { + const message = exception.message; + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); + } + + if (jwtClaims.iss !== TOKEN_ISSUER && jwtClaims.iss !== HTTPS_TOKEN_ISSUER) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct provider - expected: ${TOKEN_ISSUER} or ${HTTPS_TOKEN_ISSUER} | from: ${jwtClaims.iss}`); + } + + if (jwtClaims.sub !== id) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); + } + + if (clientId && jwtClaims.aud !== clientId) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not authorized for this clientId.`); + } + + return jwtClaims; +} // Returns a promise that fulfills if this user id is valid. + + +function validateAuthData(authData, options = {}) { + return verifyIdToken(authData, options); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; // Helpers functions to convert the RSA certs to PEM (from jwks-rsa) + +function rsaPublicKeyToPEM(modulusB64, exponentB64) { + const modulus = new Buffer(modulusB64, 'base64'); + const exponent = new Buffer(exponentB64, 'base64'); + const modulusHex = prepadSigned(modulus.toString('hex')); + const exponentHex = prepadSigned(exponent.toString('hex')); + const modlen = modulusHex.length / 2; + const explen = exponentHex.length / 2; + const encodedModlen = encodeLengthHex(modlen); + const encodedExplen = encodeLengthHex(explen); + const encodedPubkey = '30' + encodeLengthHex(modlen + explen + encodedModlen.length / 2 + encodedExplen.length / 2 + 2) + '02' + encodedModlen + modulusHex + '02' + encodedExplen + exponentHex; + const der = new Buffer(encodedPubkey, 'hex').toString('base64'); + let pem = '-----BEGIN RSA PUBLIC KEY-----\n'; + pem += `${der.match(/.{1,64}/g).join('\n')}`; + pem += '\n-----END RSA PUBLIC KEY-----\n'; + return pem; +} + +function prepadSigned(hexStr) { + const msb = hexStr[0]; + + if (msb < '0' || msb > '7') { + return `00${hexStr}`; + } + + return hexStr; +} + +function toHex(number) { + const nstr = number.toString(16); + + if (nstr.length % 2) { + return `0${nstr}`; + } + + return nstr; +} + +function encodeLengthHex(n) { + if (n <= 127) { + return toHex(n); + } + + const nHex = toHex(n); + const lengthOfLengthByte = 128 + nHex.length / 2; + return toHex(lengthOfLengthByte) + nHex; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dvb2dsZS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwcyIsImp3dCIsIlRPS0VOX0lTU1VFUiIsIkhUVFBTX1RPS0VOX0lTU1VFUiIsImNhY2hlIiwiZ2V0R29vZ2xlS2V5QnlLZXlJZCIsImtleUlkIiwiZXhwaXJlc0F0IiwiRGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImtleXMiLCJKU09OIiwicGFyc2UiLCJwZW1zIiwicmVkdWNlIiwibiIsIm1vZHVsdXMiLCJlIiwiZXhwb3NhbnQiLCJraWQiLCJPYmplY3QiLCJhc3NpZ24iLCJyc2FQdWJsaWNLZXlUb1BFTSIsImhlYWRlcnMiLCJleHBpcmUiLCJtYXRjaCIsImdldFRpbWUiLCJOdW1iZXIiLCJnZXRIZWFkZXJGcm9tVG9rZW4iLCJ0b2tlbiIsImRlY29kZWRUb2tlbiIsImRlY29kZSIsImNvbXBsZXRlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiaGVhZGVyIiwidmVyaWZ5SWRUb2tlbiIsImlkX3Rva2VuIiwiaWQiLCJjbGllbnRJZCIsImFsZyIsImFsZ29yaXRobSIsImp3dENsYWltcyIsImdvb2dsZUtleSIsInZlcmlmeSIsImFsZ29yaXRobXMiLCJhdWRpZW5jZSIsImV4Y2VwdGlvbiIsIm1lc3NhZ2UiLCJpc3MiLCJzdWIiLCJhdWQiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwidmFsaWRhdGVBcHBJZCIsIm1vZHVsZSIsImV4cG9ydHMiLCJtb2R1bHVzQjY0IiwiZXhwb25lbnRCNjQiLCJCdWZmZXIiLCJleHBvbmVudCIsIm1vZHVsdXNIZXgiLCJwcmVwYWRTaWduZWQiLCJleHBvbmVudEhleCIsIm1vZGxlbiIsImxlbmd0aCIsImV4cGxlbiIsImVuY29kZWRNb2RsZW4iLCJlbmNvZGVMZW5ndGhIZXgiLCJlbmNvZGVkRXhwbGVuIiwiZW5jb2RlZFB1YmtleSIsImRlciIsInBlbSIsImpvaW4iLCJoZXhTdHIiLCJtc2IiLCJ0b0hleCIsIm51bWJlciIsIm5zdHIiLCJuSGV4IiwibGVuZ3RoT2ZMZW5ndGhCeXRlIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxNQUFNRSxLQUFLLEdBQUdELE9BQU8sQ0FBQyxPQUFELENBQXJCOztBQUNBLE1BQU1FLEdBQUcsR0FBR0YsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7O0FBRUEsTUFBTUcsWUFBWSxHQUFHLHFCQUFyQjtBQUNBLE1BQU1DLGtCQUFrQixHQUFHLDZCQUEzQjtBQUVBLElBQUlDLEtBQUssR0FBRyxFQUFaLEMsQ0FFQTs7QUFDQSxTQUFTQyxtQkFBVCxDQUE2QkMsS0FBN0IsRUFBb0M7QUFDbEMsTUFBSUYsS0FBSyxDQUFDRSxLQUFELENBQUwsSUFBZ0JGLEtBQUssQ0FBQ0csU0FBTixHQUFrQixJQUFJQyxJQUFKLEVBQXRDLEVBQWtEO0FBQ2hELFdBQU9KLEtBQUssQ0FBQ0UsS0FBRCxDQUFaO0FBQ0Q7O0FBRUQsU0FBTyxJQUFJRyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDWCxJQUFBQSxLQUFLLENBQ0ZZLEdBREgsQ0FDUSw0Q0FEUixFQUNxREMsR0FBRyxJQUFJO0FBQ3hELFVBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELE1BQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixRQUFBQSxJQUFJLElBQUlFLEtBQUssQ0FBQ0MsUUFBTixDQUFlLE1BQWYsQ0FBUjtBQUNELE9BRkQ7QUFHQUosTUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sS0FBUCxFQUFjLE1BQU07QUFDbEIsY0FBTTtBQUFFRyxVQUFBQTtBQUFGLFlBQVdDLElBQUksQ0FBQ0Ms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R0FBUDtBQUNEOztBQUVELFNBQVNWLFlBQVQsQ0FBc0JZLE1BQXRCLEVBQThCO0FBQzVCLFFBQU1DLEdBQUcsR0FBR0QsTUFBTSxDQUFDLENBQUQsQ0FBbEI7O0FBQ0EsTUFBSUMsR0FBRyxHQUFHLEdBQU4sSUFBYUEsR0FBRyxHQUFHLEdBQXZCLEVBQTRCO0FBQzFCLFdBQVEsS0FBSUQsTUFBTyxFQUFuQjtBQUNEOztBQUNELFNBQU9BLE1BQVA7QUFDRDs7QUFFRCxTQUFTRSxLQUFULENBQWVDLE1BQWYsRUFBdUI7QUFDckIsUUFBTUMsSUFBSSxHQUFHRCxNQUFNLENBQUNyRSxRQUFQLENBQWdCLEVBQWhCLENBQWI7O0FBQ0EsTUFBSXNFLElBQUksQ0FBQ2IsTUFBTCxHQUFjLENBQWxCLEVBQXFCO0FBQ25CLFdBQVEsSUFBR2EsSUFBSyxFQUFoQjtBQUNEOztBQUNELFNBQU9BLElBQVA7QUFDRDs7QUFFRCxTQUFTVixlQUFULENBQXlCdEQsQ0FBekIsRUFBNEI7QUFDMUIsTUFBSUEsQ0FBQyxJQUFJLEdBQVQsRUFBYztBQUNaLFdBQU84RCxLQUFLLENBQUM5RCxDQUFELENBQVo7QUFDRDs7QUFDRCxRQUFNaUUsSUFBSSxHQUFHSCxLQUFLLENBQUM5RCxDQUFELENBQWxCO0FBQ0EsUUFBTWtFLGtCQUFrQixHQUFHLE1BQU1ELElBQUksQ0FBQ2QsTUFBTCxHQUFjLENBQS9DO0FBQ0EsU0FBT1csS0FBSyxDQUFDSSxrQkFBRCxDQUFMLEdBQTRCRCxJQUFuQztBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGdvb2dsZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IGp3dCA9IHJlcXVpcmUoJ2pzb253ZWJ0b2tlbicpO1xuXG5jb25zdCBUT0tFTl9JU1NVRVIgPSAnYWNjb3VudHMuZ29vZ2xlLmNvbSc7XG5jb25zdCBIVFRQU19UT0tFTl9JU1NVRVIgPSAnaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tJztcblxubGV0IGNhY2hlID0ge307XG5cbi8vIFJldHJpZXZlIEdvb2dsZSBTaWduaW4gS2V5cyAod2l0aCBjYWNoZSBjb250cm9sKVxuZnVuY3Rpb24gZ2V0R29vZ2xlS2V5QnlLZXlJZChrZXlJZCkge1xuICBpZiAoY2FjaGVba2V5SWRdICYmIGNhY2hlLmV4cGlyZXNBdCA+IG5ldyBEYXRlKCkpIHtcbiAgICByZXR1cm4gY2FjaGVba2V5SWRdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YzL2NlcnRzYCwgcmVzID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bmsudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsga2V5cyB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICBjb25zdCBwZW1zID0ga2V5cy5yZWR1Y2UoXG4gICAgICAgICAgICAocGVtcywgeyBuOiBtb2R1bHVzLCBlOiBleHBvc2FudCwga2lkIH0pID0+XG4gICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocGVtcywge1xuICAgICAgICAgICAgICAgIFtraWRdOiByc2FQdWJsaWNLZXlUb1BFTShtb2R1bHVzLCBleHBvc2FudCksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAge31cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHJlcy5oZWFkZXJzWydjYWNoZS1jb250cm9sJ10pIHtcbiAgICAgICAgICAgIHZhciBleHBpcmUgPSByZXMuaGVhZGVyc1snY2FjaGUtY29udHJvbCddLm1hdGNoKC9tYXgtYWdlPShbMC05XSspLyk7XG5cbiAgICAgICAgICAgIGlmIChleHBpcmUpIHtcbiAgICAgICAgICAgICAgY2FjaGUgPSBPYmplY3QuYXNzaWduKHt9LCBwZW1zLCB7XG4gICAgICAgICAgICAgICAgZXhwaXJlc0F0OiBuZXcgRGF0ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgTnVtYmVyKGV4cGlyZVsxXSkgKiAxMDAwXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzb2x2ZShwZW1zW2tleUlkXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCByZWplY3QpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhZGVyRnJvbVRva2VuKHRva2VuKSB7XG4gIGNvbnN0IGRlY29kZWRUb2tlbiA9IGp3dC5kZWNvZGUodG9rZW4sIHsgY29tcGxldGU6IHRydWUgfSk7XG5cbiAgaWYgKCFkZWNvZGVkVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYHByb3ZpZGVkIHRva2VuIGRvZXMgbm90IGRlY29kZSBhcyBKV1RgXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVkVG9rZW4uaGVhZGVyO1xufVxuXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlJZFRva2VuKHsgaWRfdG9rZW46IHRva2VuLCBpZCB9LCB7IGNsaWVudElkIH0pIHtcbiAgaWYgKCF0b2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgaWQgdG9rZW4gaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgeyBraWQ6IGtleUlkLCBhbGc6IGFsZ29yaXRobSB9ID0gZ2V0SGVhZGVyRnJvbVRva2VuKHRva2VuKTtcbiAgbGV0IGp3dENsYWltcztcbiAgY29uc3QgZ29vZ2xlS2V5ID0gYXdhaXQgZ2V0R29vZ2xlS2V5QnlLZXlJZChrZXlJZCk7XG5cbiAgdHJ5IHtcbiAgICBqd3RDbGFpbXMgPSBqd3QudmVyaWZ5KHRva2VuLCBnb29nbGVLZXksIHtcbiAgICAgIGFsZ29yaXRobXM6IGFsZ29yaXRobSxcbiAgICAgIGF1ZGllbmNlOiBjbGllbnRJZCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGV4Y2VwdGlvbi5tZXNzYWdlO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgJHttZXNzYWdlfWApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5pc3MgIT09IFRPS0VOX0lTU1VFUiAmJiBqd3RDbGFpbXMuaXNzICE9PSBIVFRQU19UT0tFTl9JU1NVRVIpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYGlkIHRva2VuIG5vdCBpc3N1ZWQgYnkgY29ycmVjdCBwcm92aWRlciAtIGV4cGVjdGVkOiAke1RPS0VOX0lTU1VFUn0gb3IgJHtIVFRQU19UT0tFTl9JU1NVRVJ9IHwgZnJvbTogJHtqd3RDbGFpbXMuaXNzfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5zdWIgIT09IGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBhdXRoIGRhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmBcbiAgICApO1xuICB9XG5cbiAgaWYgKGNsaWVudElkICYmIGp3dENsYWltcy5hdWQgIT09IGNsaWVudElkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBub3QgYXV0aG9yaXplZCBmb3IgdGhpcyBjbGllbnRJZC5gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBqd3RDbGFpbXM7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiB2ZXJpZnlJZFRva2VuKGF1dGhEYXRhLCBvcHRpb25zKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuXG4vLyBIZWxwZXJzIGZ1bmN0aW9ucyB0byBjb252ZXJ0IHRoZSBSU0EgY2VydHMgdG8gUEVNIChmcm9tIGp3a3MtcnNhKVxuZnVuY3Rpb24gcnNhUHVibGljS2V5VG9QRU0obW9kdWx1c0I2NCwgZXhwb25lbnRCNjQpIHtcbiAgY29uc3QgbW9kdWx1cyA9IG5ldyBCdWZmZXIobW9kdWx1c0I2NCwgJ2Jhc2U2NCcpO1xuICBjb25zdCBleHBvbmVudCA9IG5ldyBCdWZmZXIoZXhwb25lbnRCNjQsICdiYXNlNjQnKTtcbiAgY29uc3QgbW9kdWx1c0hleCA9IHByZXBhZFNpZ25lZChtb2R1bHVzLnRvU3RyaW5nKCdoZXgnKSk7XG4gIGNvbnN0IGV4cG9uZW50SGV4ID0gcHJlcGFkU2lnbmVkKGV4cG9uZW50LnRvU3RyaW5nKCdoZXgnKSk7XG4gIGNvbnN0IG1vZGxlbiA9IG1vZHVsdXNIZXgubGVuZ3RoIC8gMjtcbiAgY29uc3QgZXhwbGVuID0gZXhwb25lbnRIZXgubGVuZ3RoIC8gMjtcblxuICBjb25zdCBlbmNvZGVkTW9kbGVuID0gZW5jb2RlTGVuZ3RoSGV4KG1vZGxlbik7XG4gIGNvbnN0IGVuY29kZWRFeHBsZW4gPSBlbmNvZGVMZW5ndGhIZXgoZXhwbGVuKTtcbiAgY29uc3QgZW5jb2RlZFB1YmtleSA9XG4gICAgJzMwJyArXG4gICAgZW5jb2RlTGVuZ3RoSGV4KFxuICAgICAgbW9kbGVuICsgZXhwbGVuICsgZW5jb2RlZE1vZGxlbi5sZW5ndGggLyAyICsgZW5jb2RlZEV4cGxlbi5sZW5ndGggLyAyICsgMlxuICAgICkgK1xuICAgICcwMicgK1xuICAgIGVuY29kZWRNb2RsZW4gK1xuICAgIG1vZHVsdXNIZXggK1xuICAgICcwMicgK1xuICAgIGVuY29kZWRFeHBsZW4gK1xuICAgIGV4cG9uZW50SGV4O1xuXG4gIGNvbnN0IGRlciA9IG5ldyBCdWZmZXIoZW5jb2RlZFB1YmtleSwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKTtcblxuICBsZXQgcGVtID0gJy0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLVxcbic7XG4gIHBlbSArPSBgJHtkZXIubWF0Y2goLy57MSw2NH0vZykuam9pbignXFxuJyl9YDtcbiAgcGVtICs9ICdcXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXFxuJztcbiAgcmV0dXJuIHBlbTtcbn1cblxuZnVuY3Rpb24gcHJlcGFkU2lnbmVkKGhleFN0cikge1xuICBjb25zdCBtc2IgPSBoZXhTdHJbMF07XG4gIGlmIChtc2IgPCAnMCcgfHwgbXNiID4gJzcnKSB7XG4gICAgcmV0dXJuIGAwMCR7aGV4U3RyfWA7XG4gIH1cbiAgcmV0dXJuIGhleFN0cjtcbn1cblxuZnVuY3Rpb24gdG9IZXgobnVtYmVyKSB7XG4gIGNvbnN0IG5zdHIgPSBudW1iZXIudG9TdHJpbmcoMTYpO1xuICBpZiAobnN0ci5sZW5ndGggJSAyKSB7XG4gICAgcmV0dXJuIGAwJHtuc3RyfWA7XG4gIH1cbiAgcmV0dXJuIG5zdHI7XG59XG5cbmZ1bmN0aW9uIGVuY29kZUxlbmd0aEhleChuKSB7XG4gIGlmIChuIDw9IDEyNykge1xuICAgIHJldHVybiB0b0hleChuKTtcbiAgfVxuICBjb25zdCBuSGV4ID0gdG9IZXgobik7XG4gIGNvbnN0IGxlbmd0aE9mTGVuZ3RoQnl0ZSA9IDEyOCArIG5IZXgubGVuZ3RoIC8gMjtcbiAgcmV0dXJuIHRvSGV4KGxlbmd0aE9mTGVuZ3RoQnl0ZSkgKyBuSGV4O1xufVxuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/gpgames.js b/lib/Adapters/Auth/gpgames.js new file mode 100644 index 0000000000..57d5686d06 --- /dev/null +++ b/lib/Adapters/Auth/gpgames.js @@ -0,0 +1,35 @@ +"use strict"; + +/* Google Play Game Services +https://developers.google.com/games/services/web/api/players/get + +const authData = { + id: 'playerId', + access_token: 'token', +}; +*/ +const { + Parse +} = require('parse/node'); + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. + + +async function validateAuthData(authData) { + const response = await httpsRequest.get(`https://www.googleapis.com/games/v1/players/${authData.id}?access_token=${authData.access_token}`); + + if (!(response && response.playerId === authData.id)) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Google Play Games Services - authData is invalid for this user.'); + } +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dwZ2FtZXMuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVzcG9uc2UiLCJnZXQiLCJpZCIsImFjY2Vzc190b2tlbiIsInBsYXllcklkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7Ozs7Ozs7QUFRQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxlQUFlRSxnQkFBZixDQUFnQ0MsUUFBaEMsRUFBMEM7QUFDeEMsUUFBTUMsUUFBUSxHQUFHLE1BQU1ILFlBQVksQ0FBQ0ksR0FBYixDQUNwQiwrQ0FBOENGLFFBQVEsQ0FBQ0csRUFBRyxpQkFBZ0JILFFBQVEsQ0FBQ0ksWUFBYSxFQUQ1RSxDQUF2Qjs7QUFHQSxNQUFJLEVBQUVILFFBQVEsSUFBSUEsUUFBUSxDQUFDSSxRQUFULEtBQXNCTCxRQUFRLENBQUNHLEVBQTdDLENBQUosRUFBc0Q7QUFDcEQsVUFBTSxJQUFJUCxLQUFLLENBQUNVLEtBQVYsQ0FDSlYsS0FBSyxDQUFDVSxLQUFOLENBQVlDLGdCQURSLEVBRUosaUVBRkksQ0FBTjtBQUlEO0FBQ0YsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRURDLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmSixFQUFBQSxhQURlO0FBRWZULEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBHb29nbGUgUGxheSBHYW1lIFNlcnZpY2VzXG5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9nYW1lcy9zZXJ2aWNlcy93ZWIvYXBpL3BsYXllcnMvZ2V0XG5cbmNvbnN0IGF1dGhEYXRhID0ge1xuICBpZDogJ3BsYXllcklkJyxcbiAgYWNjZXNzX3Rva2VuOiAndG9rZW4nLFxufTtcbiovXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBodHRwc1JlcXVlc3QuZ2V0KFxuICAgIGBodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9nYW1lcy92MS9wbGF5ZXJzLyR7YXV0aERhdGEuaWR9P2FjY2Vzc190b2tlbj0ke2F1dGhEYXRhLmFjY2Vzc190b2tlbn1gXG4gICk7XG4gIGlmICghKHJlc3BvbnNlICYmIHJlc3BvbnNlLnBsYXllcklkID09PSBhdXRoRGF0YS5pZCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0dvb2dsZSBQbGF5IEdhbWVzIFNlcnZpY2VzIC0gYXV0aERhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/httpsRequest.js b/lib/Adapters/Auth/httpsRequest.js new file mode 100644 index 0000000000..ba7cba94ca --- /dev/null +++ b/lib/Adapters/Auth/httpsRequest.js @@ -0,0 +1,47 @@ +"use strict"; + +const https = require('https'); + +function makeCallback(resolve, reject, noJSON) { + return function (res) { + let data = ''; + res.on('data', chunk => { + data += chunk; + }); + res.on('end', () => { + if (noJSON) { + return resolve(data); + } + + try { + data = JSON.parse(data); + } catch (e) { + return reject(e); + } + + resolve(data); + }); + res.on('error', reject); + }; +} + +function get(options, noJSON = false) { + return new Promise((resolve, reject) => { + https.get(options, makeCallback(resolve, reject, noJSON)).on('error', reject); + }); +} + +function request(options, postData) { + return new Promise((resolve, reject) => { + const req = https.request(options, makeCallback(resolve, reject)); + req.on('error', reject); + req.write(postData); + req.end(); + }); +} + +module.exports = { + get, + request +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2h0dHBzUmVxdWVzdC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0Iiwibm9KU09OIiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJlIiwiZ2V0Iiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXF1ZXN0IiwicG9zdERhdGEiLCJyZXEiLCJ3cml0ZSIsImVuZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsT0FBRCxDQUFyQjs7QUFFQSxTQUFTQyxZQUFULENBQXNCQyxPQUF0QixFQUErQkMsTUFBL0IsRUFBdUNDLE1BQXZDLEVBQStDO0FBQzdDLFNBQU8sVUFBU0MsR0FBVCxFQUFjO0FBQ25CLFFBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixNQUFBQSxJQUFJLElBQUlFLEtBQVI7QUFDRCxLQUZEO0FBR0FILElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLEtBQVAsRUFBYyxNQUFNO0FBQ2xCLFVBQUlILE1BQUosRUFBWTtBQUNWLGVBQU9GLE9BQU8sQ0FBQ0ksSUFBRCxDQUFkO0FBQ0Q7O0FBQ0QsVUFBSTtBQUNGQSxRQUFBQSxJQUFJLEdBQUdHLElBQUksQ0FBQ0MsS0FBTCxDQUFXSixJQUFYLENBQVA7QUFDRCxPQUZELENBRUUsT0FBT0ssQ0FBUCxFQUFVO0FBQ1YsZUFBT1IsTUFBTSxDQUFDUSxDQUFELENBQWI7QUFDRDs7QUFDRFQsTUFBQUEsT0FBTyxDQUFDSSxJQUFELENBQVA7QUFDRCxLQVZEO0FBV0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE9BQVAsRUFBZ0JKLE1BQWhCO0FBQ0QsR0FqQkQ7QUFrQkQ7O0FBRUQsU0FBU1MsR0FBVCxDQUFhQyxPQUFiLEVBQXNCVCxNQUFNLEdBQUcsS0FBL0IsRUFBc0M7QUFDcEMsU0FBTyxJQUFJVSxPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDSixJQUFBQSxLQUFLLENBQ0ZhLEdBREgsQ0FDT0MsT0FEUCxFQUNnQlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsRUFBa0JDLE1BQWxCLENBRDVCLEVBRUdHLEVBRkgsQ0FFTSxPQUZOLEVBRWVKLE1BRmY7QUFHRCxHQUpNLENBQVA7QUFLRDs7QUFFRCxTQUFTWSxPQUFULENBQWlCRixPQUFqQixFQUEwQkcsUUFBMUIsRUFBb0M7QUFDbEMsU0FBTyxJQUFJRixPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDLFVBQU1jLEdBQUcsR0FBR2xCLEtBQUssQ0FBQ2dCLE9BQU4sQ0FBY0YsT0FBZCxFQUF1QlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsQ0FBbkMsQ0FBWjtBQUNBYyxJQUFBQSxHQUFHLENBQUNWLEVBQUosQ0FBTyxPQUFQLEVBQWdCSixNQUFoQjtBQUNBYyxJQUFBQSxHQUFHLENBQUNDLEtBQUosQ0FBVUYsUUFBVjtBQUNBQyxJQUFBQSxHQUFHLENBQUNFLEdBQUo7QUFDRCxHQUxNLENBQVA7QUFNRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQUVULEVBQUFBLEdBQUY7QUFBT0csRUFBQUE7QUFBUCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcblxuZnVuY3Rpb24gbWFrZUNhbGxiYWNrKHJlc29sdmUsIHJlamVjdCwgbm9KU09OKSB7XG4gIHJldHVybiBmdW5jdGlvbihyZXMpIHtcbiAgICBsZXQgZGF0YSA9ICcnO1xuICAgIHJlcy5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgfSk7XG4gICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBpZiAobm9KU09OKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGRhdGEpO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoZSk7XG4gICAgICB9XG4gICAgICByZXNvbHZlKGRhdGEpO1xuICAgIH0pO1xuICAgIHJlcy5vbignZXJyb3InLCByZWplY3QpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBnZXQob3B0aW9ucywgbm9KU09OID0gZmFsc2UpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChvcHRpb25zLCBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0LCBub0pTT04pKVxuICAgICAgLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0KG9wdGlvbnMsIHBvc3REYXRhKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gaHR0cHMucmVxdWVzdChvcHRpb25zLCBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSk7XG4gICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgcmVxLndyaXRlKHBvc3REYXRhKTtcbiAgICByZXEuZW5kKCk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHsgZ2V0LCByZXF1ZXN0IH07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/index.js b/lib/Adapters/Auth/index.js new file mode 100755 index 0000000000..00dced2172 --- /dev/null +++ b/lib/Adapters/Auth/index.js @@ -0,0 +1,173 @@ +"use strict"; + +var _AdapterLoader = _interopRequireDefault(require("../AdapterLoader")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const apple = require('./apple'); + +const gcenter = require('./gcenter'); + +const gpgames = require('./gpgames'); + +const facebook = require('./facebook'); + +const instagram = require('./instagram'); + +const linkedin = require('./linkedin'); + +const meetup = require('./meetup'); + +const google = require('./google'); + +const github = require('./github'); + +const twitter = require('./twitter'); + +const spotify = require('./spotify'); + +const digits = require('./twitter'); // digits tokens are validated by twitter + + +const janrainengage = require('./janrainengage'); + +const janraincapture = require('./janraincapture'); + +const line = require('./line'); + +const vkontakte = require('./vkontakte'); + +const qq = require('./qq'); + +const wechat = require('./wechat'); + +const weibo = require('./weibo'); + +const oauth2 = require('./oauth2'); + +const phantauth = require('./phantauth'); + +const microsoft = require('./microsoft'); + +const keycloak = require('./keycloak'); + +const ldap = require('./ldap'); + +const anonymous = { + validateAuthData: () => { + return Promise.resolve(); + }, + validateAppId: () => { + return Promise.resolve(); + } +}; +const providers = { + apple, + gcenter, + gpgames, + facebook, + instagram, + linkedin, + meetup, + google, + github, + twitter, + spotify, + anonymous, + digits, + janrainengage, + janraincapture, + line, + vkontakte, + qq, + wechat, + weibo, + phantauth, + microsoft, + keycloak, + ldap +}; + +function authDataValidator(adapter, appIds, options) { + return function (authData) { + return adapter.validateAuthData(authData, options).then(() => { + if (appIds) { + return adapter.validateAppId(appIds, authData, options); + } + + return Promise.resolve(); + }); + }; +} + +function loadAuthAdapter(provider, authOptions) { + let defaultAdapter = providers[provider]; + const providerOptions = authOptions[provider]; + + if (providerOptions && Object.prototype.hasOwnProperty.call(providerOptions, 'oauth2') && providerOptions['oauth2'] === true) { + defaultAdapter = oauth2; + } + + if (!defaultAdapter && !providerOptions) { + return; + } + + const adapter = Object.assign({}, defaultAdapter); + const appIds = providerOptions ? providerOptions.appIds : undefined; // Try the configuration methods + + if (providerOptions) { + const optionalAdapter = (0, _AdapterLoader.default)(providerOptions, undefined, providerOptions); + + if (optionalAdapter) { + ['validateAuthData', 'validateAppId'].forEach(key => { + if (optionalAdapter[key]) { + adapter[key] = optionalAdapter[key]; + } + }); + } + } // TODO: create a new module from validateAdapter() in + // src/Controllers/AdaptableController.js so we can use it here for adapter + // validation based on the src/Adapters/Auth/AuthAdapter.js expected class + // signature. + + + if (!adapter.validateAuthData || !adapter.validateAppId) { + return; + } + + return { + adapter, + appIds, + providerOptions + }; +} + +module.exports = function (authOptions = {}, enableAnonymousUsers = true) { + let _enableAnonymousUsers = enableAnonymousUsers; + + const setEnableAnonymousUsers = function (enable) { + _enableAnonymousUsers = enable; + }; // To handle the test cases on configuration + + + const getValidatorForProvider = function (provider) { + if (provider === 'anonymous' && !_enableAnonymousUsers) { + return; + } + + const { + adapter, + appIds, + providerOptions + } = loadAuthAdapter(provider, authOptions); + return authDataValidator(adapter, appIds, providerOptions); + }; + + return Object.freeze({ + getValidatorForProvider, + setEnableAnonymousUsers + }); +}; + +module.exports.loadAuthAdapter = loadAuthAdapter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luZGV4LmpzIl0sIm5hbWVzIjpbImFwcGxlIiwicmVxdWlyZSIsImdjZW50ZXIiLCJncGdhbWVzIiwiZmFjZWJvb2siLCJpbnN0YWdyYW0iLCJsaW5rZWRpbiIsIm1lZXR1cCIsImdvb2dsZSIsImdpdGh1YiIsInR3aXR0ZXIiLCJzcG90aWZ5IiwiZGlnaXRzIiwiamFucmFpbmVuZ2FnZSIsImphbnJhaW5jYXB0dXJlIiwibGluZSIsInZrb250YWt0ZSIsInFxIiwid2VjaGF0Iiwid2VpYm8iLCJvYXV0aDIiLCJwaGFudGF1dGgiLCJtaWNyb3NvZnQiLCJrZXljbG9hayIsImxkYXAiLCJhbm9ueW1vdXMiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUFwcElkIiwicHJvdmlkZXJzIiwiYXV0aERhdGFWYWxpZGF0b3IiLCJhZGFwdGVyIiwiYXBwSWRzIiwib3B0aW9ucyIsImF1dGhEYXRhIiwidGhlbiIsImxvYWRBdXRoQWRhcHRlciIsInByb3ZpZGVyIiwiYXV0aE9wdGlvbnMiLCJkZWZhdWx0QWRhcHRlciIsInByb3ZpZGVyT3B0aW9ucyIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFzc2lnbiIsInVuZGVmaW5lZCIsIm9wdGlvbmFsQWRhcHRlciIsImZvckVhY2giLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIiwiZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJfZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJzZXRFbmFibGVBbm9ueW1vdXNVc2VycyIsImVuYWJsZSIsImdldFZhbGlkYXRvckZvclByb3ZpZGVyIiwiZnJlZXplIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0FBRUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsU0FBRCxDQUFyQjs7QUFDQSxNQUFNQyxPQUFPLEdBQUdELE9BQU8sQ0FBQyxXQUFELENBQXZCOztBQUNB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Q0FBQ0MsT0FBUCxDQUFlZixlQUFmLEdBQWlDQSxlQUFqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2FkQWRhcHRlciBmcm9tICcuLi9BZGFwdGVyTG9hZGVyJztcblxuY29uc3QgYXBwbGUgPSByZXF1aXJlKCcuL2FwcGxlJyk7XG5jb25zdCBnY2VudGVyID0gcmVxdWlyZSgnLi9nY2VudGVyJyk7XG5jb25zdCBncGdhbWVzID0gcmVxdWlyZSgnLi9ncGdhbWVzJyk7XG5jb25zdCBmYWNlYm9vayA9IHJlcXVpcmUoJy4vZmFjZWJvb2snKTtcbmNvbnN0IGluc3RhZ3JhbSA9IHJlcXVpcmUoJy4vaW5zdGFncmFtJyk7XG5jb25zdCBsaW5rZWRpbiA9IHJlcXVpcmUoJy4vbGlua2VkaW4nKTtcbmNvbnN0IG1lZXR1cCA9IHJlcXVpcmUoJy4vbWVldHVwJyk7XG5jb25zdCBnb29nbGUgPSByZXF1aXJlKCcuL2dvb2dsZScpO1xuY29uc3QgZ2l0aHViID0gcmVxdWlyZSgnLi9naXRodWInKTtcbmNvbnN0IHR3aXR0ZXIgPSByZXF1aXJlKCcuL3R3aXR0ZXInKTtcbmNvbnN0IHNwb3RpZnkgPSByZXF1aXJlKCcuL3Nwb3RpZnknKTtcbmNvbnN0IGRpZ2l0cyA9IHJlcXVpcmUoJy4vdHdpdHRlcicpOyAvLyBkaWdpdHMgdG9rZW5zIGFyZSB2YWxpZGF0ZWQgYnkgdHdpdHRlclxuY29uc3QgamFucmFpbmVuZ2FnZSA9IHJlcXVpcmUoJy4vamFucmFpbmVuZ2FnZScpO1xuY29uc3QgamFucmFpbmNhcHR1cmUgPSByZXF1aXJlKCcuL2phbnJhaW5jYXB0dXJlJyk7XG5jb25zdCBsaW5lID0gcmVxdWlyZSgnLi9saW5lJyk7XG5jb25zdCB2a29udGFrdGUgPSByZXF1aXJlKCcuL3Zrb250YWt0ZScpO1xuY29uc3QgcXEgPSByZXF1aXJlKCcuL3FxJyk7XG5jb25zdCB3ZWNoYXQgPSByZXF1aXJlKCcuL3dlY2hhdCcpO1xuY29uc3Qgd2VpYm8gPSByZXF1aXJlKCcuL3dlaWJvJyk7XG5jb25zdCBvYXV0aDIgPSByZXF1aXJlKCcuL29hdXRoMicpO1xuY29uc3QgcGhhbnRhdXRoID0gcmVxdWlyZSgnLi9waGFudGF1dGgnKTtcbmNvbnN0IG1pY3Jvc29mdCA9IHJlcXVpcmUoJy4vbWljcm9zb2Z0Jyk7XG5jb25zdCBrZXljbG9hayA9IHJlcXVpcmUoJy4va2V5Y2xvYWsnKTtcbmNvbnN0IGxkYXAgPSByZXF1aXJlKCcuL2xkYXAnKTtcblxuY29uc3QgYW5vbnltb3VzID0ge1xuICB2YWxpZGF0ZUF1dGhEYXRhOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxuICB2YWxpZGF0ZUFwcElkOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxufTtcblxuY29uc3QgcHJvdmlkZXJzID0ge1xuICBhcHBsZSxcbiAgZ2NlbnRlcixcbiAgZ3BnYW1lcyxcbiAgZmFjZWJvb2ssXG4gIGluc3RhZ3JhbSxcbiAgbGlua2VkaW4sXG4gIG1lZXR1cCxcbiAgZ29vZ2xlLFxuICBnaXRodWIsXG4gIHR3aXR0ZXIsXG4gIHNwb3RpZnksXG4gIGFub255bW91cyxcbiAgZGlnaXRzLFxuICBqYW5yYWluZW5nYWdlLFxuICBqYW5yYWluY2FwdHVyZSxcbiAgbGluZSxcbiAgdmtvbnRha3RlLFxuICBxcSxcbiAgd2VjaGF0LFxuICB3ZWlibyxcbiAgcGhhbnRhdXRoLFxuICBtaWNyb3NvZnQsXG4gIGtleWNsb2FrLFxuICBsZGFwLFxufTtcblxuZnVuY3Rpb24gYXV0aERhdGFWYWxpZGF0b3IoYWRhcHRlciwgYXBwSWRzLCBvcHRpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgICByZXR1cm4gYWRhcHRlci52YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChhcHBJZHMpIHtcbiAgICAgICAgcmV0dXJuIGFkYXB0ZXIudmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9hZEF1dGhBZGFwdGVyKHByb3ZpZGVyLCBhdXRoT3B0aW9ucykge1xuICBsZXQgZGVmYXVsdEFkYXB0ZXIgPSBwcm92aWRlcnNbcHJvdmlkZXJdO1xuICBjb25zdCBwcm92aWRlck9wdGlvbnMgPSBhdXRoT3B0aW9uc1twcm92aWRlcl07XG4gIGlmIChcbiAgICBwcm92aWRlck9wdGlvbnMgJiZcbiAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocHJvdmlkZXJPcHRpb25zLCAnb2F1dGgyJykgJiZcbiAgICBwcm92aWRlck9wdGlvbnNbJ29hdXRoMiddID09PSB0cnVlXG4gICkge1xuICAgIGRlZmF1bHRBZGFwdGVyID0gb2F1dGgyO1xuICB9XG5cbiAgaWYgKCFkZWZhdWx0QWRhcHRlciAmJiAhcHJvdmlkZXJPcHRpb25zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgYWRhcHRlciA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRBZGFwdGVyKTtcbiAgY29uc3QgYXBwSWRzID0gcHJvdmlkZXJPcHRpb25zID8gcHJvdmlkZXJPcHRpb25zLmFwcElkcyA6IHVuZGVmaW5lZDtcblxuICAvLyBUcnkgdGhlIGNvbmZpZ3VyYXRpb24gbWV0aG9kc1xuICBpZiAocHJvdmlkZXJPcHRpb25zKSB7XG4gICAgY29uc3Qgb3B0aW9uYWxBZGFwdGVyID0gbG9hZEFkYXB0ZXIoXG4gICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBwcm92aWRlck9wdGlvbnNcbiAgICApO1xuICAgIGlmIChvcHRpb25hbEFkYXB0ZXIpIHtcbiAgICAgIFsndmFsaWRhdGVBdXRoRGF0YScsICd2YWxpZGF0ZUFwcElkJ10uZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBpZiAob3B0aW9uYWxBZGFwdGVyW2tleV0pIHtcbiAgICAgICAgICBhZGFwdGVyW2tleV0gPSBvcHRpb25hbEFkYXB0ZXJba2V5XTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETzogY3JlYXRlIGEgbmV3IG1vZHVsZSBmcm9tIHZhbGlkYXRlQWRhcHRlcigpIGluXG4gIC8vIHNyYy9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyLmpzIHNvIHdlIGNhbiB1c2UgaXQgaGVyZSBmb3IgYWRhcHRlclxuICAvLyB2YWxpZGF0aW9uIGJhc2VkIG9uIHRoZSBzcmMvQWRhcHRlcnMvQXV0aC9BdXRoQWRhcHRlci5qcyBleHBlY3RlZCBjbGFzc1xuICAvLyBzaWduYXR1cmUuXG4gIGlmICghYWRhcHRlci52YWxpZGF0ZUF1dGhEYXRhIHx8ICFhZGFwdGVyLnZhbGlkYXRlQXBwSWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4geyBhZGFwdGVyLCBhcHBJZHMsIHByb3ZpZGVyT3B0aW9ucyB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhdXRoT3B0aW9ucyA9IHt9LCBlbmFibGVBbm9ueW1vdXNVc2VycyA9IHRydWUpIHtcbiAgbGV0IF9lbmFibGVBbm9ueW1vdXNVc2VycyA9IGVuYWJsZUFub255bW91c1VzZXJzO1xuICBjb25zdCBzZXRFbmFibGVBbm9ueW1vdXNVc2VycyA9IGZ1bmN0aW9uIChlbmFibGUpIHtcbiAgICBfZW5hYmxlQW5vbnltb3VzVXNlcnMgPSBlbmFibGU7XG4gIH07XG4gIC8vIFRvIGhhbmRsZSB0aGUgdGVzdCBjYXNlcyBvbiBjb25maWd1cmF0aW9uXG4gIGNvbnN0IGdldFZhbGlkYXRvckZvclByb3ZpZGVyID0gZnVuY3Rpb24gKHByb3ZpZGVyKSB7XG4gICAgaWYgKHByb3ZpZGVyID09PSAnYW5vbnltb3VzJyAmJiAhX2VuYWJsZUFub255bW91c1VzZXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBhZGFwdGVyLCBhcHBJZHMsIHByb3ZpZGVyT3B0aW9ucyB9ID0gbG9hZEF1dGhBZGFwdGVyKFxuICAgICAgcHJvdmlkZXIsXG4gICAgICBhdXRoT3B0aW9uc1xuICAgICk7XG5cbiAgICByZXR1cm4gYXV0aERhdGFWYWxpZGF0b3IoYWRhcHRlciwgYXBwSWRzLCBwcm92aWRlck9wdGlvbnMpO1xuICB9O1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBnZXRWYWxpZGF0b3JGb3JQcm92aWRlcixcbiAgICBzZXRFbmFibGVBbm9ueW1vdXNVc2VycyxcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5sb2FkQXV0aEFkYXB0ZXIgPSBsb2FkQXV0aEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/instagram.js b/lib/Adapters/Auth/instagram.js new file mode 100644 index 0000000000..46032bbada --- /dev/null +++ b/lib/Adapters/Auth/instagram.js @@ -0,0 +1,31 @@ +"use strict"; + +// Helper functions for accessing the instagram API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); + +const defaultURL = 'https://graph.instagram.com/'; // Returns a promise that fulfills if this user id is valid. + +function validateAuthData(authData) { + const apiURL = authData.apiURL || defaultURL; + const path = `${apiURL}me?fields=id&access_token=${authData.access_token}`; + return httpsRequest.get(path).then(response => { + if (response && response.data && response.data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Instagram auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luc3RhZ3JhbS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJkZWZhdWx0VVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiYXBpVVJMIiwicGF0aCIsImFjY2Vzc190b2tlbiIsImdldCIsInRoZW4iLCJyZXNwb25zZSIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JELEtBQWxDOztBQUNBLE1BQU1FLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLE1BQU1FLFVBQVUsR0FBRyw4QkFBbkIsQyxDQUVBOztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxRQUFNQyxNQUFNLEdBQUdELFFBQVEsQ0FBQ0MsTUFBVCxJQUFtQkgsVUFBbEM7QUFDQSxRQUFNSSxJQUFJLEdBQUksR0FBRUQsTUFBTyw2QkFBNEJELFFBQVEsQ0FBQ0csWUFBYSxFQUF6RTtBQUNBLFNBQU9OLFlBQVksQ0FBQ08sR0FBYixDQUFpQkYsSUFBakIsRUFBdUJHLElBQXZCLENBQTRCQyxRQUFRLElBQUk7QUFDN0MsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLElBQXJCLElBQTZCRCxRQUFRLENBQUNDLElBQVQsQ0FBY0MsRUFBZCxJQUFvQlIsUUFBUSxDQUFDUSxFQUE5RCxFQUFrRTtBQUNoRTtBQUNEOztBQUNELFVBQU0sSUFBSWIsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZQyxnQkFEUixFQUVKLDBDQUZJLENBQU47QUFJRCxHQVJNLENBQVA7QUFTRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZKLEVBQUFBLGFBRGU7QUFFZlosRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgaW5zdGFncmFtIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5jb25zdCBkZWZhdWx0VVJMID0gJ2h0dHBzOi8vZ3JhcGguaW5zdGFncmFtLmNvbS8nO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgY29uc3QgYXBpVVJMID0gYXV0aERhdGEuYXBpVVJMIHx8IGRlZmF1bHRVUkw7XG4gIGNvbnN0IHBhdGggPSBgJHthcGlVUkx9bWU/ZmllbGRzPWlkJmFjY2Vzc190b2tlbj0ke2F1dGhEYXRhLmFjY2Vzc190b2tlbn1gO1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldChwYXRoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuZGF0YSAmJiByZXNwb25zZS5kYXRhLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnSW5zdGFncmFtIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/janraincapture.js b/lib/Adapters/Auth/janraincapture.js new file mode 100644 index 0000000000..d113cc5285 --- /dev/null +++ b/lib/Adapters/Auth/janraincapture.js @@ -0,0 +1,46 @@ +"use strict"; + +// Helper functions for accessing the Janrain Capture API. +var Parse = require('parse/node').Parse; + +var querystring = require('querystring'); + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + return request(options.janrain_capture_host, authData.access_token).then(data => { + //successful response will have a "stat" (status) of 'ok' and a result node that stores the uuid, because that's all we asked for + //see: https://docs.janrain.com/api/registration/entity/#entity + if (data && data.stat == 'ok' && data.result == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain capture auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + //no-op + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(host, access_token) { + var query_string_data = querystring.stringify({ + access_token: access_token, + attribute_name: 'uuid' // we only need to pull the uuid for this access token to make sure it matches + + }); + return httpsRequest.get({ + host: host, + path: '/entity?' + query_string_data + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5jYXB0dXJlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsInF1ZXJ5c3RyaW5nIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3QiLCJqYW5yYWluX2NhcHR1cmVfaG9zdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwic3RhdCIsInJlc3VsdCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiaG9zdCIsInF1ZXJ5X3N0cmluZ19kYXRhIiwic3RyaW5naWZ5IiwiYXR0cmlidXRlX25hbWUiLCJnZXQiLCJwYXRoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsSUFBSUUsV0FBVyxHQUFHRCxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFDQSxNQUFNRSxZQUFZLEdBQUdGLE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNHLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT0MsT0FBTyxDQUFDRCxPQUFPLENBQUNFLG9CQUFULEVBQStCSCxRQUFRLENBQUNJLFlBQXhDLENBQVAsQ0FBNkRDLElBQTdELENBQ0xDLElBQUksSUFBSTtBQUNOO0FBQ0E7QUFDQSxRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsSUFBTCxJQUFhLElBQXJCLElBQTZCRCxJQUFJLENBQUNFLE1BQUwsSUFBZVIsUUFBUSxDQUFDUyxFQUF6RCxFQUE2RDtBQUMzRDtBQUNEOztBQUNELFVBQU0sSUFBSWQsS0FBSyxDQUFDZSxLQUFWLENBQ0pmLEtBQUssQ0FBQ2UsS0FBTixDQUFZQyxnQkFEUixFQUVKLGdEQUZJLENBQU47QUFJRCxHQVhJLENBQVA7QUFhRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkI7QUFDQSxTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1osT0FBVCxDQUFpQmEsSUFBakIsRUFBdUJYLFlBQXZCLEVBQXFDO0FBQ25DLE1BQUlZLGlCQUFpQixHQUFHbkIsV0FBVyxDQUFDb0IsU0FBWixDQUFzQjtBQUM1Q2IsSUFBQUEsWUFBWSxFQUFFQSxZQUQ4QjtBQUU1Q2MsSUFBQUEsY0FBYyxFQUFFLE1BRjRCLENBRXBCOztBQUZvQixHQUF0QixDQUF4QjtBQUtBLFNBQU9wQixZQUFZLENBQUNxQixHQUFiLENBQWlCO0FBQUVKLElBQUFBLElBQUksRUFBRUEsSUFBUjtBQUFjSyxJQUFBQSxJQUFJLEVBQUUsYUFBYUo7QUFBakMsR0FBakIsQ0FBUDtBQUNEOztBQUVESyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlYsRUFBQUEsYUFBYSxFQUFFQSxhQURBO0FBRWZiLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBKYW5yYWluIENhcHR1cmUgQVBJLlxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xudmFyIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHJlcXVlc3Qob3B0aW9ucy5qYW5yYWluX2NhcHR1cmVfaG9zdCwgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKFxuICAgIGRhdGEgPT4ge1xuICAgICAgLy9zdWNjZXNzZnVsIHJlc3BvbnNlIHdpbGwgaGF2ZSBhIFwic3RhdFwiIChzdGF0dXMpIG9mICdvaycgYW5kIGEgcmVzdWx0IG5vZGUgdGhhdCBzdG9yZXMgdGhlIHV1aWQsIGJlY2F1c2UgdGhhdCdzIGFsbCB3ZSBhc2tlZCBmb3JcbiAgICAgIC8vc2VlOiBodHRwczovL2RvY3MuamFucmFpbi5jb20vYXBpL3JlZ2lzdHJhdGlvbi9lbnRpdHkvI2VudGl0eVxuICAgICAgaWYgKGRhdGEgJiYgZGF0YS5zdGF0ID09ICdvaycgJiYgZGF0YS5yZXN1bHQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAnSmFucmFpbiBjYXB0dXJlIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICAgICk7XG4gICAgfVxuICApO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIC8vbm8tb3BcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChob3N0LCBhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIHF1ZXJ5X3N0cmluZ19kYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICBhY2Nlc3NfdG9rZW46IGFjY2Vzc190b2tlbixcbiAgICBhdHRyaWJ1dGVfbmFtZTogJ3V1aWQnLCAvLyB3ZSBvbmx5IG5lZWQgdG8gcHVsbCB0aGUgdXVpZCBmb3IgdGhpcyBhY2Nlc3MgdG9rZW4gdG8gbWFrZSBzdXJlIGl0IG1hdGNoZXNcbiAgfSk7XG5cbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoeyBob3N0OiBob3N0LCBwYXRoOiAnL2VudGl0eT8nICsgcXVlcnlfc3RyaW5nX2RhdGEgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/janrainengage.js b/lib/Adapters/Auth/janrainengage.js new file mode 100644 index 0000000000..d7c4774377 --- /dev/null +++ b/lib/Adapters/Auth/janrainengage.js @@ -0,0 +1,52 @@ +"use strict"; + +// Helper functions for accessing the Janrain Engage API. +var httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; + +var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + return apiRequest(options.api_key, authData.auth_token).then(data => { + //successful response will have a "stat" (status) of 'ok' and a profile node with an identifier + //see: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data + if (data && data.stat == 'ok' && data.profile.identifier == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain engage auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + //no-op + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function apiRequest(api_key, auth_token) { + var post_data = querystring.stringify({ + token: auth_token, + apiKey: api_key, + format: 'json' + }); + var post_options = { + host: 'rpxnow.com', + path: '/api/v2/auth_info', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': post_data.length + } + }; + return httpsRequest.request(post_options, post_data); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5lbmdhZ2UuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwicXVlcnlzdHJpbmciLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiYXBpUmVxdWVzdCIsImFwaV9rZXkiLCJhdXRoX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdGF0IiwicHJvZmlsZSIsImlkZW50aWZpZXIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3RfZGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiYXBpS2V5IiwiZm9ybWF0IiwicG9zdF9vcHRpb25zIiwiaG9zdCIsInBhdGgiLCJtZXRob2QiLCJoZWFkZXJzIiwibGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLFNBQU9DLFVBQVUsQ0FBQ0QsT0FBTyxDQUFDRSxPQUFULEVBQWtCSCxRQUFRLENBQUNJLFVBQTNCLENBQVYsQ0FBaURDLElBQWpELENBQXNEQyxJQUFJLElBQUk7QUFDbkU7QUFDQTtBQUNBLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxJQUFMLElBQWEsSUFBckIsSUFBNkJELElBQUksQ0FBQ0UsT0FBTCxDQUFhQyxVQUFiLElBQTJCVCxRQUFRLENBQUNVLEVBQXJFLEVBQXlFO0FBQ3ZFO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJYixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLGdCQURSLEVBRUosK0NBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QjtBQUNBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTYixVQUFULENBQW9CQyxPQUFwQixFQUE2QkMsVUFBN0IsRUFBeUM7QUFDdkMsTUFBSVksU0FBUyxHQUFHbEIsV0FBVyxDQUFDbUIsU0FBWixDQUFzQjtBQUNwQ0MsSUFBQUEsS0FBSyxFQUFFZCxVQUQ2QjtBQUVwQ2UsSUFBQUEsTUFBTSxFQUFFaEIsT0FGNEI7QUFHcENpQixJQUFBQSxNQUFNLEVBQUU7QUFINEIsR0FBdEIsQ0FBaEI7QUFNQSxNQUFJQyxZQUFZLEdBQUc7QUFDakJDLElBQUFBLElBQUksRUFBRSxZQURXO0FBRWpCQyxJQUFBQSxJQUFJLEVBQUUsbUJBRlc7QUFHakJDLElBQUFBLE1BQU0sRUFBRSxNQUhTO0FBSWpCQyxJQUFBQSxPQUFPLEVBQUU7QUFDUCxzQkFBZ0IsbUNBRFQ7QUFFUCx3QkFBa0JULFNBQVMsQ0FBQ1U7QUFGckI7QUFKUSxHQUFuQjtBQVVBLFNBQU8vQixZQUFZLENBQUNnQyxPQUFiLENBQXFCTixZQUFyQixFQUFtQ0wsU0FBbkMsQ0FBUDtBQUNEOztBQUVEWSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmhCLEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmZCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgSmFucmFpbiBFbmdhZ2UgQVBJLlxudmFyIGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIHJldHVybiBhcGlSZXF1ZXN0KG9wdGlvbnMuYXBpX2tleSwgYXV0aERhdGEuYXV0aF90b2tlbikudGhlbihkYXRhID0+IHtcbiAgICAvL3N1Y2Nlc3NmdWwgcmVzcG9uc2Ugd2lsbCBoYXZlIGEgXCJzdGF0XCIgKHN0YXR1cykgb2YgJ29rJyBhbmQgYSBwcm9maWxlIG5vZGUgd2l0aCBhbiBpZGVudGlmaWVyXG4gICAgLy9zZWU6IGh0dHA6Ly9kZXZlbG9wZXJzLmphbnJhaW4uY29tL292ZXJ2aWV3L3NvY2lhbC1sb2dpbi9pZGVudGl0eS1wcm92aWRlcnMvdXNlci1wcm9maWxlLWRhdGEvI25vcm1hbGl6ZWQtdXNlci1wcm9maWxlLWRhdGFcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnN0YXQgPT0gJ29rJyAmJiBkYXRhLnByb2ZpbGUuaWRlbnRpZmllciA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0phbnJhaW4gZW5nYWdlIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICAvL25vLW9wXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIGFwaVJlcXVlc3QoYXBpX2tleSwgYXV0aF90b2tlbikge1xuICB2YXIgcG9zdF9kYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICB0b2tlbjogYXV0aF90b2tlbixcbiAgICBhcGlLZXk6IGFwaV9rZXksXG4gICAgZm9ybWF0OiAnanNvbicsXG4gIH0pO1xuXG4gIHZhciBwb3N0X29wdGlvbnMgPSB7XG4gICAgaG9zdDogJ3JweG5vdy5jb20nLFxuICAgIHBhdGg6ICcvYXBpL3YyL2F1dGhfaW5mbycsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogcG9zdF9kYXRhLmxlbmd0aCxcbiAgICB9LFxuICB9O1xuXG4gIHJldHVybiBodHRwc1JlcXVlc3QucmVxdWVzdChwb3N0X29wdGlvbnMsIHBvc3RfZGF0YSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/keycloak.js b/lib/Adapters/Auth/keycloak.js new file mode 100644 index 0000000000..ab5a498102 --- /dev/null +++ b/lib/Adapters/Auth/keycloak.js @@ -0,0 +1,125 @@ +"use strict"; + +/* + # Parse Server Keycloak Authentication + + ## Keycloak `authData` + + ``` + { + "keycloak": { + "access_token": "access token you got from keycloak JS client authentication", + "id": "the id retrieved from client authentication in Keycloak", + "roles": ["the roles retrieved from client authentication in Keycloak"], + "groups": ["the groups retrieved from client authentication in Keycloak"] + } + } + ``` + + The authentication module will test if the authData is the same as the + userinfo oauth call, comparing the attributes + + Copy the JSON config file generated on Keycloak (https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter) + and paste it inside of a folder (Ex.: `auth/keycloak.json`) in your server. + + The options passed to Parse server: + + ``` + { + auth: { + keycloak: { + config: require(`./auth/keycloak.json`) + } + } + } + ``` +*/ +const { + Parse +} = require('parse/node'); + +const httpsRequest = require('./httpsRequest'); + +const arraysEqual = (_arr1, _arr2) => { + if (!Array.isArray(_arr1) || !Array.isArray(_arr2) || _arr1.length !== _arr2.length) return false; + + var arr1 = _arr1.concat().sort(); + + var arr2 = _arr2.concat().sort(); + + for (var i = 0; i < arr1.length; i++) { + if (arr1[i] !== arr2[i]) return false; + } + + return true; +}; + +const handleAuth = async ({ + access_token, + id, + roles, + groups +} = {}, { + config +} = {}) => { + if (!(access_token && id)) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing access token and/or User id'); + } + + if (!config || !(config['auth-server-url'] && config['realm'])) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing keycloak configuration'); + } + + try { + const response = await httpsRequest.get({ + host: config['auth-server-url'], + path: `/realms/${config['realm']}/protocol/openid-connect/userinfo`, + headers: { + Authorization: 'Bearer ' + access_token + } + }); + + if (response && response.data && response.data.sub == id && arraysEqual(response.data.roles, roles) && arraysEqual(response.data.groups, groups)) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication'); + } catch (e) { + if (e instanceof Parse.Error) { + throw e; + } + + const error = JSON.parse(e.text); + + if (error.error_description) { + throw new Parse.Error(Parse.Error.HOSTING_ERROR, error.error_description); + } else { + throw new Parse.Error(Parse.Error.HOSTING_ERROR, 'Could not connect to the authentication server'); + } + } +}; +/* + @param {Object} authData: the client provided authData + @param {string} authData.access_token: the access_token retrieved from client authentication in Keycloak + @param {string} authData.id: the id retrieved from client authentication in Keycloak + @param {Array} authData.roles: the roles retrieved from client authentication in Keycloak + @param {Array} authData.groups: the groups retrieved from client authentication in Keycloak + @param {Object} options: additional options + @param {Object} options.config: the config object passed during Parse Server instantiation +*/ + + +function validateAuthData(authData, options = {}) { + return handleAuth(authData, options); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2tleWNsb2FrLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsImFycmF5c0VxdWFsIiwiX2FycjEiLCJfYXJyMiIsIkFycmF5IiwiaXNBcnJheSIsImxlbmd0aCIsImFycjEiLCJjb25jYXQiLCJzb3J0IiwiYXJyMiIsImkiLCJoYW5kbGVBdXRoIiwiYWNjZXNzX3Rva2VuIiwiaWQiLCJyb2xlcyIsImdyb3VwcyIsImNvbmZpZyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInJlc3BvbnNlIiwiZ2V0IiwiaG9zdCIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImRhdGEiLCJzdWIiLCJlIiwiZXJyb3IiLCJKU09OIiwicGFyc2UiLCJ0ZXh0IiwiZXJyb3JfZGVzY3JpcHRpb24iLCJIT1NUSU5HX0VSUk9SIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQVlDLE9BQU8sQ0FBQyxZQUFELENBQXpCOztBQUNBLE1BQU1DLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUVBLE1BQU1FLFdBQVcsR0FBRyxDQUFDQyxLQUFELEVBQVFDLEtBQVIsS0FBa0I7QUFDcEMsTUFDRSxDQUFDQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0gsS0FBZCxDQUFELElBQ0EsQ0FBQ0UsS0FBSyxDQUFDQyxPQUFOLENBQWNGLEtBQWQsQ0FERCxJQUVBRCxLQUFLLENBQUNJLE1BQU4sS0FBaUJILEtBQUssQ0FBQ0csTUFIekIsRUFLRSxPQUFPLEtBQVA7O0FBRUYsTUFBSUMsSUFBSSxHQUFHTCxL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QUcsRUFBOUMsRUFBa0Q7QUFDaEQsU0FBT3pCLFVBQVUsQ0FBQ3dCLFFBQUQsRUFBV0MsT0FBWCxDQUFqQjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmSCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgIyBQYXJzZSBTZXJ2ZXIgS2V5Y2xvYWsgQXV0aGVudGljYXRpb25cblxuICAjIyBLZXljbG9hayBgYXV0aERhdGFgXG5cbiAgYGBgXG4gICAge1xuICAgICAgXCJrZXljbG9ha1wiOiB7XG4gICAgICAgIFwiYWNjZXNzX3Rva2VuXCI6IFwiYWNjZXNzIHRva2VuIHlvdSBnb3QgZnJvbSBrZXljbG9hayBKUyBjbGllbnQgYXV0aGVudGljYXRpb25cIixcbiAgICAgICAgXCJpZFwiOiBcInRoZSBpZCByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcIixcbiAgICAgICAgXCJyb2xlc1wiOiBbXCJ0aGUgcm9sZXMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXCJdLFxuICAgICAgICBcImdyb3Vwc1wiOiBbXCJ0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1wiXVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG5cbiAgVGhlIGF1dGhlbnRpY2F0aW9uIG1vZHVsZSB3aWxsIHRlc3QgaWYgdGhlIGF1dGhEYXRhIGlzIHRoZSBzYW1lIGFzIHRoZVxuICB1c2VyaW5mbyBvYXV0aCBjYWxsLCBjb21wYXJpbmcgdGhlIGF0dHJpYnV0ZXNcblxuICBDb3B5IHRoZSBKU09OIGNvbmZpZyBmaWxlIGdlbmVyYXRlZCBvbiBLZXljbG9hayAoaHR0cHM6Ly93d3cua2V5Y2xvYWsub3JnL2RvY3MvbGF0ZXN0L3NlY3VyaW5nX2FwcHMvaW5kZXguaHRtbCNfamF2YXNjcmlwdF9hZGFwdGVyKVxuICBhbmQgcGFzdGUgaXQgaW5zaWRlIG9mIGEgZm9sZGVyIChFeC46IGBhdXRoL2tleWNsb2FrLmpzb25gKSBpbiB5b3VyIHNlcnZlci5cblxuICBUaGUgb3B0aW9ucyBwYXNzZWQgdG8gUGFyc2Ugc2VydmVyOlxuXG4gIGBgYFxuICAgIHtcbiAgICAgIGF1dGg6IHtcbiAgICAgICAga2V5Y2xvYWs6IHtcbiAgICAgICAgICBjb25maWc6IHJlcXVpcmUoYC4vYXV0aC9rZXljbG9hay5qc29uYClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG5jb25zdCBhcnJheXNFcXVhbCA9IChfYXJyMSwgX2FycjIpID0+IHtcbiAgaWYgKFxuICAgICFBcnJheS5pc0FycmF5KF9hcnIxKSB8fFxuICAgICFBcnJheS5pc0FycmF5KF9hcnIyKSB8fFxuICAgIF9hcnIxLmxlbmd0aCAhPT0gX2FycjIubGVuZ3RoXG4gIClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGFycjEgPSBfYXJyMS5jb25jYXQoKS5zb3J0KCk7XG4gIHZhciBhcnIyID0gX2FycjIuY29uY2F0KCkuc29ydCgpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhcnIxW2ldICE9PSBhcnIyW2ldKSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmNvbnN0IGhhbmRsZUF1dGggPSBhc3luYyAoXG4gIHsgYWNjZXNzX3Rva2VuLCBpZCwgcm9sZXMsIGdyb3VwcyB9ID0ge30sXG4gIHsgY29uZmlnIH0gPSB7fVxuKSA9PiB7XG4gIGlmICghKGFjY2Vzc190b2tlbiAmJiBpZCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ01pc3NpbmcgYWNjZXNzIHRva2VuIGFuZC9vciBVc2VyIGlkJ1xuICAgICk7XG4gIH1cbiAgaWYgKCFjb25maWcgfHwgIShjb25maWdbJ2F1dGgtc2VydmVyLXVybCddICYmIGNvbmZpZ1sncmVhbG0nXSkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ01pc3Npbmcga2V5Y2xvYWsgY29uZmlndXJhdGlvbidcbiAgICApO1xuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICAgIGhvc3Q6IGNvbmZpZ1snYXV0aC1zZXJ2ZXItdXJsJ10sXG4gICAgICBwYXRoOiBgL3JlYWxtcy8ke2NvbmZpZ1sncmVhbG0nXX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdXNlcmluZm9gLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGlmIChcbiAgICAgIHJlc3BvbnNlICYmXG4gICAgICByZXNwb25zZS5kYXRhICYmXG4gICAgICByZXNwb25zZS5kYXRhLnN1YiA9PSBpZCAmJlxuICAgICAgYXJyYXlzRXF1YWwocmVzcG9uc2UuZGF0YS5yb2xlcywgcm9sZXMpICYmXG4gICAgICBhcnJheXNFcXVhbChyZXNwb25zZS5kYXRhLmdyb3VwcywgZ3JvdXBzKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0ludmFsaWQgYXV0aGVudGljYXRpb24nXG4gICAgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIGNvbnN0IGVycm9yID0gSlNPTi5wYXJzZShlLnRleHQpO1xuICAgIGlmIChlcnJvci5lcnJvcl9kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkhPU1RJTkdfRVJST1IsIGVycm9yLmVycm9yX2Rlc2NyaXB0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5IT1NUSU5HX0VSUk9SLFxuICAgICAgICAnQ291bGQgbm90IGNvbm5lY3QgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIHNlcnZlcidcbiAgICAgICk7XG4gICAgfVxuICB9XG59O1xuXG4vKlxuICBAcGFyYW0ge09iamVjdH0gYXV0aERhdGE6IHRoZSBjbGllbnQgcHJvdmlkZWQgYXV0aERhdGFcbiAgQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjogdGhlIGFjY2Vzc190b2tlbiByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcbiAgQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmlkOiB0aGUgaWQgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7QXJyYXl9ICBhdXRoRGF0YS5yb2xlczogdGhlIHJvbGVzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge0FycmF5fSAgYXV0aERhdGEuZ3JvdXBzOiB0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge09iamVjdH0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmNvbmZpZzogdGhlIGNvbmZpZyBvYmplY3QgcGFzc2VkIGR1cmluZyBQYXJzZSBTZXJ2ZXIgaW5zdGFudGlhdGlvblxuKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gaGFuZGxlQXV0aChhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/ldap.js b/lib/Adapters/Auth/ldap.js new file mode 100644 index 0000000000..4990603518 --- /dev/null +++ b/lib/Adapters/Auth/ldap.js @@ -0,0 +1,83 @@ +"use strict"; + +const ldapjs = require('ldapjs'); + +const Parse = require('parse/node').Parse; + +function validateAuthData(authData, options) { + if (!optionsAreValid(options)) { + return new Promise((_, reject) => { + reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP auth configuration missing')); + }); + } + + const client = ldapjs.createClient({ + url: options.url + }); + const userCn = typeof options.dn === 'string' ? options.dn.replace('{{id}}', authData.id) : `uid=${authData.id},${options.suffix}`; + return new Promise((resolve, reject) => { + client.bind(userCn, authData.password, err => { + if (err) { + client.destroy(err); + return reject(new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Wrong username or password')); + } + + if (typeof options.groupCn === 'string' && typeof options.groupFilter === 'string') { + searchForGroup(client, options, authData.id, resolve, reject); + } else { + client.unbind(); + client.destroy(); + resolve(); + } + }); + }); +} + +function optionsAreValid(options) { + return typeof options === 'object' && typeof options.suffix === 'string' && typeof options.url === 'string' && options.url.startsWith('ldap://'); +} + +function searchForGroup(client, options, id, resolve, reject) { + const filter = options.groupFilter.replace(/{{id}}/gi, id); + const opts = { + scope: 'sub', + filter: filter + }; + let found = false; + client.search(options.suffix, opts, (searchError, res) => { + if (searchError) { + client.unbind(); + client.destroy(); + return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); + } + + res.on('searchEntry', entry => { + if (entry.object.cn === options.groupCn) { + found = true; + client.unbind(); + client.destroy(); + return resolve(); + } + }); + res.on('end', () => { + if (!found) { + client.unbind(); + client.destroy(); + return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP: User not in group')); + } + }); + res.on('error', () => { + return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); + }); + }); +} + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xkYXAuanMiXSwibmFtZXMiOlsibGRhcGpzIiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsIm9wdGlvbnNBcmVWYWxpZCIsIlByb21pc2UiLCJfIiwicmVqZWN0IiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjbGllbnQiLCJjcmVhdGVDbGllbnQiLCJ1cmwiLCJ1c2VyQ24iLCJkbiIsInJlcGxhY2UiLCJpZCIsInN1ZmZpeCIsInJlc29sdmUiLCJiaW5kIiwicGFzc3dvcmQiLCJlcnIiLCJkZXN0cm95IiwiT0JKRUNUX05PVF9GT1VORCIsImdyb3VwQ24iLCJncm91cEZpbHRlciIsInNlYXJjaEZvckdyb3VwIiwidW5iaW5kIiwic3RhcnRzV2l0aCIsImZpbHRlciIsIm9wdHMiLCJzY29wZSIsImZvdW5kIiwic2VhcmNoIiwic2VhcmNoRXJyb3IiLCJyZXMiLCJvbiIsImVudHJ5Iiwib2JqZWN0IiwiY24iLCJ2YWxpZGF0ZUFwcElkIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFNQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUNBLE1BQU1DLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBcEM7O0FBRUEsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DQyxPQUFwQyxFQUE2QztBQUMzQyxNQUFJLENBQUNDLGVBQWUsQ0FBQ0QsT0FBRCxDQUFwQixFQUErQjtBQUM3QixXQUFPLElBQUlFLE9BQUosQ0FBWSxDQUFDQyxDQUFELEVBQUlDLE1BQUosS0FBZTtBQUNoQ0EsTUFBQUEsTUFBTSxDQUNKLElBQUlQLEtBQUssQ0FBQ1EsS0FBVixDQUNFUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMscUJBRGQsRUFFRSxpQ0FGRixDQURJLENBQU47QUFNRCxLQVBN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RUFBeUM7QUFDdkNRLFFBQUFBLEtBQUssR0FBRyxJQUFSO0FBQ0F0QixRQUFBQSxNQUFNLENBQUNpQixNQUFQO0FBQ0FqQixRQUFBQSxNQUFNLENBQUNZLE9BQVA7QUFDQSxlQUFPSixPQUFPLEVBQWQ7QUFDRDtBQUNGLEtBUEQ7QUFRQWlCLElBQUFBLEdBQUcsQ0FBQ0MsRUFBSixDQUFPLEtBQVAsRUFBYyxNQUFNO0FBQ2xCLFVBQUksQ0FBQ0osS0FBTCxFQUFZO0FBQ1Z0QixRQUFBQSxNQUFNLENBQUNpQixNQUFQO0FBQ0FqQixRQUFBQSxNQUFNLENBQUNZLE9BQVA7QUFDQSxlQUFPZixNQUFNLENBQ1gsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQ0VSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxxQkFEZCxFQUVFLHlCQUZGLENBRFcsQ0FBYjtBQU1EO0FBQ0YsS0FYRDtBQVlBMEIsSUFBQUEsR0FBRyxDQUFDQyxFQUFKLENBQU8sT0FBUCxFQUFnQixNQUFNO0FBQ3BCLGFBQU83QixNQUFNLENBQ1gsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQ0VSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxxQkFEZCxFQUVFLDBCQUZGLENBRFcsQ0FBYjtBQU1ELEtBUEQ7QUFRRCxHQXZDRDtBQXdDRDs7QUFFRCxTQUFTK0IsYUFBVCxHQUF5QjtBQUN2QixTQUFPbkMsT0FBTyxDQUFDYSxPQUFSLEVBQVA7QUFDRDs7QUFFRHVCLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmRixFQUFBQSxhQURlO0FBRWZ2QyxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgbGRhcGpzID0gcmVxdWlyZSgnbGRhcGpzJyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnNBcmVWYWxpZChvcHRpb25zKSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoXywgcmVqZWN0KSA9PiB7XG4gICAgICByZWplY3QoXG4gICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgJ0xEQVAgYXV0aCBjb25maWd1cmF0aW9uIG1pc3NpbmcnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBjbGllbnQgPSBsZGFwanMuY3JlYXRlQ2xpZW50KHsgdXJsOiBvcHRpb25zLnVybCB9KTtcbiAgY29uc3QgdXNlckNuID1cbiAgICB0eXBlb2Ygb3B0aW9ucy5kbiA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9ucy5kbi5yZXBsYWNlKCd7e2lkfX0nLCBhdXRoRGF0YS5pZClcbiAgICAgIDogYHVpZD0ke2F1dGhEYXRhLmlkfSwke29wdGlvbnMuc3VmZml4fWA7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjbGllbnQuYmluZCh1c2VyQ24sIGF1dGhEYXRhLnBhc3N3b3JkLCBlcnIgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBjbGllbnQuZGVzdHJveShlcnIpO1xuICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAnTERBUDogV3JvbmcgdXNlcm5hbWUgb3IgcGFzc3dvcmQnXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyb3VwQ24gPT09ICdzdHJpbmcnICYmXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyb3VwRmlsdGVyID09PSAnc3RyaW5nJ1xuICAgICAgKSB7XG4gICAgICAgIHNlYXJjaEZvckdyb3VwKGNsaWVudCwgb3B0aW9ucywgYXV0aERhdGEuaWQsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbGllbnQudW5iaW5kKCk7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG9wdGlvbnNBcmVWYWxpZChvcHRpb25zKSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnICYmXG4gICAgdHlwZW9mIG9wdGlvbnMuc3VmZml4ID09PSAnc3RyaW5nJyAmJlxuICAgIHR5cGVvZiBvcHRpb25zLnVybCA9PT0gJ3N0cmluZycgJiZcbiAgICBvcHRpb25zLnVybC5zdGFydHNXaXRoKCdsZGFwOi8vJylcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2VhcmNoRm9yR3JvdXAoY2xpZW50LCBvcHRpb25zLCBpZCwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIGNvbnN0IGZpbHRlciA9IG9wdGlvbnMuZ3JvdXBGaWx0ZXIucmVwbGFjZSgve3tpZH19L2dpLCBpZCk7XG4gIGNvbnN0IG9wdHMgPSB7XG4gICAgc2NvcGU6ICdzdWInLFxuICAgIGZpbHRlcjogZmlsdGVyLFxuICB9O1xuICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgY2xpZW50LnNlYXJjaChvcHRpb25zLnN1ZmZpeCwgb3B0cywgKHNlYXJjaEVycm9yLCByZXMpID0+IHtcbiAgICBpZiAoc2VhcmNoRXJyb3IpIHtcbiAgICAgIGNsaWVudC51bmJpbmQoKTtcbiAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdMREFQIGdyb3VwIHNlYXJjaCBmYWlsZWQnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICAgIHJlcy5vbignc2VhcmNoRW50cnknLCBlbnRyeSA9PiB7XG4gICAgICBpZiAoZW50cnkub2JqZWN0LmNuID09PSBvcHRpb25zLmdyb3VwQ24pIHtcbiAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICBjbGllbnQudW5iaW5kKCk7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgIGNsaWVudC51bmJpbmQoKTtcbiAgICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgICAnTERBUDogVXNlciBub3QgaW4gZ3JvdXAnXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJlcy5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdMREFQIGdyb3VwIHNlYXJjaCBmYWlsZWQnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/line.js b/lib/Adapters/Auth/line.js new file mode 100644 index 0000000000..63b271cc2d --- /dev/null +++ b/lib/Adapters/Auth/line.js @@ -0,0 +1,41 @@ +"use strict"; + +// Helper functions for accessing the line API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. + + +function validateAuthData(authData) { + return request('profile', authData.access_token).then(response => { + if (response && response.userId && response.userId === authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Line auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + var options = { + host: 'api.line.me', + path: '/v2/' + path, + method: 'GET', + headers: { + Authorization: 'Bearer ' + access_token + } + }; + return httpsRequest.get(options); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmUuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJyZXNwb25zZSIsInVzZXJJZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicGF0aCIsIm9wdGlvbnMiLCJob3N0IiwibWV0aG9kIiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsU0FBRCxFQUFZRCxRQUFRLENBQUNFLFlBQXJCLENBQVAsQ0FBMENDLElBQTFDLENBQStDQyxRQUFRLElBQUk7QUFDaEUsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLE1BQXJCLElBQStCRCxRQUFRLENBQUNDLE1BQVQsS0FBb0JMLFFBQVEsQ0FBQ00sRUFBaEUsRUFBb0U7QUFDbEU7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUNKWCxLQUFLLENBQUNXLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixxQ0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUM7QUFDbkMsTUFBSVcsT0FBTyxHQUFHO0FBQ1pDLElBQUFBLElBQUksRUFBRSxhQURNO0FBRVpGLElBQUFBLElBQUksRUFBRSxTQUFTQSxJQUZIO0FBR1pHLElBQUFBLE1BQU0sRUFBRSxLQUhJO0FBSVpDLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWY7QUFEcEI7QUFKRyxHQUFkO0FBUUEsU0FBT0osWUFBWSxDQUFDb0IsR0FBYixDQUFpQkwsT0FBakIsQ0FBUDtBQUNEOztBQUVETSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlgsRUFBQUEsYUFBYSxFQUFFQSxhQURBO0FBRWZWLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBsaW5lIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgncHJvZmlsZScsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnVzZXJJZCAmJiByZXNwb25zZS51c2VySWQgPT09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnTGluZSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIG9wdGlvbnMgPSB7XG4gICAgaG9zdDogJ2FwaS5saW5lLm1lJyxcbiAgICBwYXRoOiAnL3YyLycgKyBwYXRoLFxuICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH07XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KG9wdGlvbnMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/linkedin.js b/lib/Adapters/Auth/linkedin.js new file mode 100644 index 0000000000..61945e2867 --- /dev/null +++ b/lib/Adapters/Auth/linkedin.js @@ -0,0 +1,46 @@ +"use strict"; + +// Helper functions for accessing the linkedin API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('me', authData.access_token, authData.is_mobile_sdk).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Linkedin auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token, is_mobile_sdk) { + var headers = { + Authorization: 'Bearer ' + access_token, + 'x-li-format': 'json' + }; + + if (is_mobile_sdk) { + headers['x-li-src'] = 'msdk'; + } + + return httpsRequest.get({ + host: 'api.linkedin.com', + path: '/v2/' + path, + headers: headers + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmtlZGluLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsInJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpc19tb2JpbGVfc2RrIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImdldCIsImhvc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLEVBQThCRixRQUFRLENBQUNHLGFBQXZDLENBQVAsQ0FBNkRDLElBQTdELENBQ0xDLElBQUksSUFBSTtBQUNOLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdOLFFBQVEsQ0FBQ00sRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUNKWCxLQUFLLENBQUNXLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5Q0FGSSxDQUFOO0FBSUQsR0FUSSxDQUFQO0FBV0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUNDLGFBQXJDLEVBQW9EO0FBQ2xELE1BQUlVLE9BQU8sR0FBRztBQUNaQyxJQUFBQSxhQUFhLEVBQUUsWUFBWVosWUFEZjtBQUVaLG1CQUFlO0FBRkgsR0FBZDs7QUFLQSxNQUFJQyxhQUFKLEVBQW1CO0FBQ2pCVSxJQUFBQSxPQUFPLENBQUMsVUFBRCxDQUFQLEdBQXNCLE1BQXRCO0FBQ0Q7O0FBQ0QsU0FBT2YsWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGtCQURnQjtBQUV0QkosSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJDLElBQUFBLE9BQU8sRUFBRUE7QUFIYSxHQUFqQixDQUFQO0FBS0Q7O0FBRURJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGxpbmtlZGluIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ21lJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuLCBhdXRoRGF0YS5pc19tb2JpbGVfc2RrKS50aGVuKFxuICAgIGRhdGEgPT4ge1xuICAgICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdMaW5rZWRpbiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICApO1xuICAgIH1cbiAgKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgYXBpIHJlcXVlc3RzXG5mdW5jdGlvbiByZXF1ZXN0KHBhdGgsIGFjY2Vzc190b2tlbiwgaXNfbW9iaWxlX3Nkaykge1xuICB2YXIgaGVhZGVycyA9IHtcbiAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgJ3gtbGktZm9ybWF0JzogJ2pzb24nLFxuICB9O1xuXG4gIGlmIChpc19tb2JpbGVfc2RrKSB7XG4gICAgaGVhZGVyc1sneC1saS1zcmMnXSA9ICdtc2RrJztcbiAgfVxuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7XG4gICAgaG9zdDogJ2FwaS5saW5rZWRpbi5jb20nLFxuICAgIHBhdGg6ICcvdjIvJyArIHBhdGgsXG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/meetup.js b/lib/Adapters/Auth/meetup.js new file mode 100644 index 0000000000..9065517d05 --- /dev/null +++ b/lib/Adapters/Auth/meetup.js @@ -0,0 +1,39 @@ +"use strict"; + +// Helper functions for accessing the meetup API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('member/self', authData.access_token).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Meetup auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'api.meetup.com', + path: '/2/' + path, + headers: { + Authorization: 'bearer ' + access_token + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21lZXR1cC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsYUFBRCxFQUFnQkQsUUFBUSxDQUFDRSxZQUF6QixDQUFQLENBQThDQyxJQUE5QyxDQUFtREMsSUFBSSxJQUFJO0FBQ2hFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdMLFFBQVEsQ0FBQ0ssRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUNKVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix1Q0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVCxPQUFULENBQWlCVSxJQUFqQixFQUF1QlQsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT0osWUFBWSxDQUFDYyxHQUFiLENBQWlCO0FBQ3RCQyxJQUFBQSxJQUFJLEVBQUUsZ0JBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsUUFBUUEsSUFGUTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZYjtBQURwQjtBQUhhLEdBQWpCLENBQVA7QUFPRDs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgbWVldHVwIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ21lbWJlci9zZWxmJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdNZWV0dXAgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnYXBpLm1lZXR1cC5jb20nLFxuICAgIHBhdGg6ICcvMi8nICsgcGF0aCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiAnYmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/microsoft.js b/lib/Adapters/Auth/microsoft.js new file mode 100644 index 0000000000..d88bb3cf0e --- /dev/null +++ b/lib/Adapters/Auth/microsoft.js @@ -0,0 +1,39 @@ +"use strict"; + +// Helper functions for accessing the microsoft graph API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user mail is valid. + + +function validateAuthData(authData) { + return request('me', authData.access_token).then(response => { + if (response && response.id && response.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Microsoft Graph auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'graph.microsoft.com', + path: '/v1.0/' + path, + headers: { + Authorization: 'Bearer ' + access_token + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21pY3Jvc29mdC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwiaG9zdCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsTUFBTUUsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxTQUFTRSxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsT0FBTyxDQUFDLElBQUQsRUFBT0QsUUFBUSxDQUFDRSxZQUFoQixDQUFQLENBQXFDQyxJQUFyQyxDQUNMQyxRQUFRLElBQUk7QUFDVixRQUFJQSxRQUFRLElBQUlBLFFBQVEsQ0FBQ0MsRUFBckIsSUFBMkJELFFBQVEsQ0FBQ0MsRUFBVCxJQUFlTCxRQUFRLENBQUNLLEVBQXZELEVBQTJEO0FBQ3pEO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJVCxLQUFLLENBQUNVLEtBQVYsQ0FDSlYsS0FBSyxDQUFDVSxLQUFOLENBQVlDLGdCQURSLEVBRUosZ0RBRkksQ0FBTjtBQUlELEdBVEksQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1QsT0FBVCxDQUFpQlUsSUFBakIsRUFBdUJULFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2MsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLHFCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFdBQVdBLElBRks7QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWI7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURjLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIG1pY3Jvc29mdCBncmFwaCBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBtYWlsIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oXG4gICAgcmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmlkICYmIHJlc3BvbnNlLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ01pY3Jvc29mdCBHcmFwaCBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICApO1xuICAgIH1cbiAgKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnZ3JhcGgubWljcm9zb2Z0LmNvbScsXG4gICAgcGF0aDogJy92MS4wLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICB9LFxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/oauth2.js b/lib/Adapters/Auth/oauth2.js new file mode 100644 index 0000000000..a7863a5c3f --- /dev/null +++ b/lib/Adapters/Auth/oauth2.js @@ -0,0 +1,142 @@ +"use strict"; + +/* + * This auth adapter is based on the OAuth 2.0 Token Introspection specification. + * See RFC 7662 for details (https://tools.ietf.org/html/rfc7662). + * It's purpose is to validate OAuth2 access tokens using the OAuth2 provider's + * token introspection endpoint (if implemented by the provider). + * + * The adapter accepts the following config parameters: + * + * 1. "tokenIntrospectionEndpointUrl" (string, required) + * The URL of the token introspection endpoint of the OAuth2 provider that + * issued the access token to the client that is to be validated. + * + * 2. "useridField" (string, optional) + * The name of the field in the token introspection response that contains + * the userid. If specified, it will be used to verify the value of the "id" + * field in the "authData" JSON that is coming from the client. + * This can be the "aud" (i.e. audience), the "sub" (i.e. subject) or the + * "username" field in the introspection response, but since only the + * "active" field is required and all other reponse fields are optional + * in the RFC, it has to be optional in this adapter as well. + * Default: - (undefined) + * + * 3. "appidField" (string, optional) + * The name of the field in the token introspection response that contains + * the appId of the client. If specified, it will be used to verify it's + * value against the set of appIds in the adapter config. The concept of + * appIds comes from the two major social login providers + * (Google and Facebook). They have not yet implemented the token + * introspection endpoint, but the concept can be valid for any OAuth2 + * provider. + * Default: - (undefined) + * + * 4. "appIds" (array of strings, required if appidField is defined) + * A set of appIds that are used to restrict accepted access tokens based + * on a specific field's value in the token introspection response. + * Default: - (undefined) + * + * 5. "authorizationHeader" (string, optional) + * The value of the "Authorization" HTTP header in requests sent to the + * introspection endpoint. It must contain the raw value. + * Thus if HTTP Basic authorization is to be used, it must contain the + * "Basic" string, followed by whitespace, then by the base64 encoded + * version of the concatenated + ":" + string. + * Eg. "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + * + * The adapter expects requests with the following authData JSON: + * + * { + * "someadapter": { + * "id": "user's OAuth2 provider-specific id as a string", + * "access_token": "an authorized OAuth2 access token for the user", + * } + * } + */ +const Parse = require('parse/node').Parse; + +const url = require('url'); + +const querystring = require('querystring'); + +const httpsRequest = require('./httpsRequest'); + +const INVALID_ACCESS = 'OAuth2 access token is invalid for this user.'; +const INVALID_ACCESS_APPID = "OAuth2: the access_token's appID is empty or is not in the list of permitted appIDs in the auth configuration."; +const MISSING_APPIDS = 'OAuth2 configuration is missing the client app IDs ("appIds" config parameter).'; +const MISSING_URL = 'OAuth2 token introspection endpoint URL is missing from configuration!'; // Returns a promise that fulfills if this user id is valid. + +function validateAuthData(authData, options) { + return requestTokenInfo(options, authData.access_token).then(response => { + if (!response || !response.active || options.useridField && authData.id !== response[options.useridField]) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); + } + }); +} + +function validateAppId(appIds, authData, options) { + if (!options || !options.appidField) { + return Promise.resolve(); + } + + if (!appIds || appIds.length === 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_APPIDS); + } + + return requestTokenInfo(options, authData.access_token).then(response => { + if (!response || !response.active) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); + } + + const appidField = options.appidField; + + if (!response[appidField]) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); + } + + const responseValue = response[appidField]; + + if (!Array.isArray(responseValue) && appIds.includes(responseValue)) { + return; + } else if (Array.isArray(responseValue) && responseValue.some(appId => appIds.includes(appId))) { + return; + } else { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); + } + }); +} // A promise wrapper for requests to the OAuth2 token introspection endpoint. + + +function requestTokenInfo(options, access_token) { + if (!options || !options.tokenIntrospectionEndpointUrl) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_URL); + } + + const parsedUrl = url.parse(options.tokenIntrospectionEndpointUrl); + const postData = querystring.stringify({ + token: access_token + }); + const headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': Buffer.byteLength(postData) + }; + + if (options.authorizationHeader) { + headers['Authorization'] = options.authorizationHeader; + } + + const postOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.pathname, + method: 'POST', + headers: headers + }; + return httpsRequest.request(postOptions, postData); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL29hdXRoMi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJxdWVyeXN0cmluZyIsImh0dHBzUmVxdWVzdCIsIklOVkFMSURfQUNDRVNTIiwiSU5WQUxJRF9BQ0NFU1NfQVBQSUQiLCJNSVNTSU5HX0FQUElEUyIsIk1JU1NJTkdfVVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3RUb2tlbkluZm8iLCJhY2Nlc3NfdG9rZW4iLCJ0aGVuIiwicmVzcG9uc2UiLCJhY3RpdmUiLCJ1c2VyaWRGaWVsZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImFwcGlkRmllbGQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsInJlc3BvbnNlVmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJpbmNsdWRlcyIsInNvbWUiLCJhcHBJZCIsInRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsIiwicGFyc2VkVXJsIiwicGFyc2UiLCJwb3N0RGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiaGVhZGVycyIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJhdXRob3JpemF0aW9uSGVhZGVyIiwicG9zdE9wdGlvbnMiLCJob3N0bmFtZSIsInBhdGgiLCJwYXRobmFtZSIsIm1ldGhvZCIsInJlcXVlc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF1REEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFwQzs7QUFDQSxNQUFNRSxHQUFHLEdBQUdELE9BQU8sQ0FBQyxLQUFELENBQW5COztBQUNBLE1BQU1FLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQs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QUQsSUFBWSxDQUFDQSxPQUFPLENBQUNzQiw2QkFBekIsRUFBd0Q7QUFDdEQsVUFBTSxJQUFJakMsS0FBSyxDQUFDbUIsS0FBVixDQUFnQm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDWixXQUE5QyxDQUFOO0FBQ0Q7O0FBQ0QsUUFBTTBCLFNBQVMsR0FBR2hDLEdBQUcsQ0FBQ2lDLEtBQUosQ0FBVXhCLE9BQU8sQ0FBQ3NCLDZCQUFsQixDQUFsQjtBQUNBLFFBQU1HLFFBQVEsR0FBR2pDLFdBQVcsQ0FBQ2tDLFNBQVosQ0FBc0I7QUFDckNDLElBQUFBLEtBQUssRUFBRXpCO0FBRDhCLEdBQXRCLENBQWpCO0FBR0EsUUFBTTBCLE9BQU8sR0FBRztBQUNkLG9CQUFnQixtQ0FERjtBQUVkLHNCQUFrQkMsTUFBTSxDQUFDQyxVQUFQLENBQWtCTCxRQUFsQjtBQUZKLEdBQWhCOztBQUlBLE1BQUl6QixPQUFPLENBQUMrQixtQkFBWixFQUFpQztBQUMvQkgsSUFBQUEsT0FBTyxDQUFDLGVBQUQsQ0FBUCxHQUEyQjVCLE9BQU8sQ0FBQytCLG1CQUFuQztBQUNEOztBQUNELFFBQU1DLFdBQVcsR0FBRztBQUNsQkMsSUFBQUEsUUFBUSxFQUFFVixTQUFTLENBQUNVLFFBREY7QUFFbEJDLElBQUFBLElBQUksRUFBRVgsU0FBUyxDQUFDWSxRQUZFO0FBR2xCQyxJQUFBQSxNQUFNLEVBQUUsTUFIVTtBQUlsQlIsSUFBQUEsT0FBTyxFQUFFQTtBQUpTLEdBQXBCO0FBTUEsU0FBT25DLFlBQVksQ0FBQzRDLE9BQWIsQ0FBcUJMLFdBQXJCLEVBQWtDUCxRQUFsQyxDQUFQO0FBQ0Q7O0FBRURhLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmN0IsRUFBQUEsYUFBYSxFQUFFQSxhQURBO0FBRWZaLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFRoaXMgYXV0aCBhZGFwdGVyIGlzIGJhc2VkIG9uIHRoZSBPQXV0aCAyLjAgVG9rZW4gSW50cm9zcGVjdGlvbiBzcGVjaWZpY2F0aW9uLlxuICogU2VlIFJGQyA3NjYyIGZvciBkZXRhaWxzIChodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzY2MikuXG4gKiBJdCdzIHB1cnBvc2UgaXMgdG8gdmFsaWRhdGUgT0F1dGgyIGFjY2VzcyB0b2tlbnMgdXNpbmcgdGhlIE9BdXRoMiBwcm92aWRlcidzXG4gKiB0b2tlbiBpbnRyb3NwZWN0aW9uIGVuZHBvaW50IChpZiBpbXBsZW1lbnRlZCBieSB0aGUgcHJvdmlkZXIpLlxuICpcbiAqIFRoZSBhZGFwdGVyIGFjY2VwdHMgdGhlIGZvbGxvd2luZyBjb25maWcgcGFyYW1ldGVyczpcbiAqXG4gKiAxLiBcInRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsXCIgKHN0cmluZywgcmVxdWlyZWQpXG4gKiAgICAgIFRoZSBVUkwgb2YgdGhlIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQgb2YgdGhlIE9BdXRoMiBwcm92aWRlciB0aGF0XG4gKiAgICAgIGlzc3VlZCB0aGUgYWNjZXNzIHRva2VuIHRvIHRoZSBjbGllbnQgdGhhdCBpcyB0byBiZSB2YWxpZGF0ZWQuXG4gKlxuICogMi4gXCJ1c2VyaWRGaWVsZFwiIChzdHJpbmcsIG9wdGlvbmFsKVxuICogICAgICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaW4gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gcmVzcG9uc2UgdGhhdCBjb250YWluc1xuICogICAgICB0aGUgdXNlcmlkLiBJZiBzcGVjaWZpZWQsIGl0IHdpbGwgYmUgdXNlZCB0byB2ZXJpZnkgdGhlIHZhbHVlIG9mIHRoZSBcImlkXCJcbiAqICAgICAgZmllbGQgaW4gdGhlIFwiYXV0aERhdGFcIiBKU09OIHRoYXQgaXMgY29taW5nIGZyb20gdGhlIGNsaWVudC5cbiAqICAgICAgVGhpcyBjYW4gYmUgdGhlIFwiYXVkXCIgKGkuZS4gYXVkaWVuY2UpLCB0aGUgXCJzdWJcIiAoaS5lLiBzdWJqZWN0KSBvciB0aGVcbiAqICAgICAgXCJ1c2VybmFtZVwiIGZpZWxkIGluIHRoZSBpbnRyb3NwZWN0aW9uIHJlc3BvbnNlLCBidXQgc2luY2Ugb25seSB0aGVcbiAqICAgICAgXCJhY3RpdmVcIiBmaWVsZCBpcyByZXF1aXJlZCBhbmQgYWxsIG90aGVyIHJlcG9uc2UgZmllbGRzIGFyZSBvcHRpb25hbFxuICogICAgICBpbiB0aGUgUkZDLCBpdCBoYXMgdG8gYmUgb3B0aW9uYWwgaW4gdGhpcyBhZGFwdGVyIGFzIHdlbGwuXG4gKiAgICAgIERlZmF1bHQ6IC0gKHVuZGVmaW5lZClcbiAqXG4gKiAzLiBcImFwcGlkRmllbGRcIiAoc3RyaW5nLCBvcHRpb25hbClcbiAqICAgICAgVGhlIG5hbWUgb2YgdGhlIGZpZWxkIGluIHRoZSB0b2tlbiBpbnRyb3NwZWN0aW9uIHJlc3BvbnNlIHRoYXQgY29udGFpbnNcbiAqICAgICAgdGhlIGFwcElkIG9mIHRoZSBjbGllbnQuIElmIHNwZWNpZmllZCwgaXQgd2lsbCBiZSB1c2VkIHRvIHZlcmlmeSBpdCdzXG4gKiAgICAgIHZhbHVlIGFnYWluc3QgdGhlIHNldCBvZiBhcHBJZHMgaW4gdGhlIGFkYXB0ZXIgY29uZmlnLiBUaGUgY29uY2VwdCBvZlxuICogICAgICBhcHBJZHMgY29tZXMgZnJvbSB0aGUgdHdvIG1ham9yIHNvY2lhbCBsb2dpbiBwcm92aWRlcnNcbiAqICAgICAgKEdvb2dsZSBhbmQgRmFjZWJvb2spLiBUaGV5IGhhdmUgbm90IHlldCBpbXBsZW1lbnRlZCB0aGUgdG9rZW5cbiAqICAgICAgaW50cm9zcGVjdGlvbiBlbmRwb2ludCwgYnV0IHRoZSBjb25jZXB0IGNhbiBiZSB2YWxpZCBmb3IgYW55IE9BdXRoMlxuICogICAgICBwcm92aWRlci5cbiAqICAgICAgRGVmYXVsdDogLSAodW5kZWZpbmVkKVxuICpcbiAqIDQuIFwiYXBwSWRzXCIgKGFycmF5IG9mIHN0cmluZ3MsIHJlcXVpcmVkIGlmIGFwcGlkRmllbGQgaXMgZGVmaW5lZClcbiAqICAgICAgQSBzZXQgb2YgYXBwSWRzIHRoYXQgYXJlIHVzZWQgdG8gcmVzdHJpY3QgYWNjZXB0ZWQgYWNjZXNzIHRva2VucyBiYXNlZFxuICogICAgICBvbiBhIHNwZWNpZmljIGZpZWxkJ3MgdmFsdWUgaW4gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gcmVzcG9uc2UuXG4gKiAgICAgIERlZmF1bHQ6IC0gKHVuZGVmaW5lZClcbiAqXG4gKiA1LiBcImF1dGhvcml6YXRpb25IZWFkZXJcIiAoc3RyaW5nLCBvcHRpb25hbClcbiAqICAgICAgVGhlIHZhbHVlIG9mIHRoZSBcIkF1dGhvcml6YXRpb25cIiBIVFRQIGhlYWRlciBpbiByZXF1ZXN0cyBzZW50IHRvIHRoZVxuICogICAgICBpbnRyb3NwZWN0aW9uIGVuZHBvaW50LiBJdCBtdXN0IGNvbnRhaW4gdGhlIHJhdyB2YWx1ZS5cbiAqICAgICAgVGh1cyBpZiBIVFRQIEJhc2ljIGF1dGhvcml6YXRpb24gaXMgdG8gYmUgdXNlZCwgaXQgbXVzdCBjb250YWluIHRoZVxuICogICAgICBcIkJhc2ljXCIgc3RyaW5nLCBmb2xsb3dlZCBieSB3aGl0ZXNwYWNlLCB0aGVuIGJ5IHRoZSBiYXNlNjQgZW5jb2RlZFxuICogICAgICB2ZXJzaW9uIG9mIHRoZSBjb25jYXRlbmF0ZWQgPHVzZXJuYW1lPiArIFwiOlwiICsgPHBhc3N3b3JkPiBzdHJpbmcuXG4gKiAgICAgIEVnLiBcIkJhc2ljIGRYTmxjbTVoYldVNmNHRnpjM2R2Y21RPVwiXG4gKlxuICogVGhlIGFkYXB0ZXIgZXhwZWN0cyByZXF1ZXN0cyB3aXRoIHRoZSBmb2xsb3dpbmcgYXV0aERhdGEgSlNPTjpcbiAqXG4gKiB7XG4gKiAgIFwic29tZWFkYXB0ZXJcIjoge1xuICogICAgIFwiaWRcIjogXCJ1c2VyJ3MgT0F1dGgyIHByb3ZpZGVyLXNwZWNpZmljIGlkIGFzIGEgc3RyaW5nXCIsXG4gKiAgICAgXCJhY2Nlc3NfdG9rZW5cIjogXCJhbiBhdXRob3JpemVkIE9BdXRoMiBhY2Nlc3MgdG9rZW4gZm9yIHRoZSB1c2VyXCIsXG4gKiAgIH1cbiAqIH1cbiAqL1xuXG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcblxuY29uc3QgSU5WQUxJRF9BQ0NFU1MgPSAnT0F1dGgyIGFjY2VzcyB0b2tlbiBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJztcbmNvbnN0IElOVkFMSURfQUNDRVNTX0FQUElEID1cbiAgXCJPQXV0aDI6IHRoZSBhY2Nlc3NfdG9rZW4ncyBhcHBJRCBpcyBlbXB0eSBvciBpcyBub3QgaW4gdGhlIGxpc3Qgb2YgcGVybWl0dGVkIGFwcElEcyBpbiB0aGUgYXV0aCBjb25maWd1cmF0aW9uLlwiO1xuY29uc3QgTUlTU0lOR19BUFBJRFMgPVxuICAnT0F1dGgyIGNvbmZpZ3VyYXRpb24gaXMgbWlzc2luZyB0aGUgY2xpZW50IGFwcCBJRHMgKFwiYXBwSWRzXCIgY29uZmlnIHBhcmFtZXRlcikuJztcbmNvbnN0IE1JU1NJTkdfVVJMID1cbiAgJ09BdXRoMiB0b2tlbiBpbnRyb3NwZWN0aW9uIGVuZHBvaW50IFVSTCBpcyBtaXNzaW5nIGZyb20gY29uZmlndXJhdGlvbiEnO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHJlcXVlc3RUb2tlbkluZm8ob3B0aW9ucywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICBpZiAoXG4gICAgICAhcmVzcG9uc2UgfHxcbiAgICAgICFyZXNwb25zZS5hY3RpdmUgfHxcbiAgICAgIChvcHRpb25zLnVzZXJpZEZpZWxkICYmIGF1dGhEYXRhLmlkICE9PSByZXNwb25zZVtvcHRpb25zLnVzZXJpZEZpZWxkXSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTUyk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCAhb3B0aW9ucy5hcHBpZEZpZWxkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIGlmICghYXBwSWRzIHx8IGFwcElkcy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgTUlTU0lOR19BUFBJRFMpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0VG9rZW5JbmZvKG9wdGlvbnMsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UuYWN0aXZlKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgSU5WQUxJRF9BQ0NFU1MpO1xuICAgIH1cbiAgICBjb25zdCBhcHBpZEZpZWxkID0gb3B0aW9ucy5hcHBpZEZpZWxkO1xuICAgIGlmICghcmVzcG9uc2VbYXBwaWRGaWVsZF0pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTU19BUFBJRCk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3BvbnNlVmFsdWUgPSByZXNwb25zZVthcHBpZEZpZWxkXTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVzcG9uc2VWYWx1ZSkgJiYgYXBwSWRzLmluY2x1ZGVzKHJlc3BvbnNlVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkocmVzcG9uc2VWYWx1ZSkgJiZcbiAgICAgIHJlc3BvbnNlVmFsdWUuc29tZShhcHBJZCA9PiBhcHBJZHMuaW5jbHVkZXMoYXBwSWQpKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgSU5WQUxJRF9BQ0NFU1NfQVBQSUQpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIEEgcHJvbWlzZSB3cmFwcGVyIGZvciByZXF1ZXN0cyB0byB0aGUgT0F1dGgyIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQuXG5mdW5jdGlvbiByZXF1ZXN0VG9rZW5JbmZvKG9wdGlvbnMsIGFjY2Vzc190b2tlbikge1xuICBpZiAoIW9wdGlvbnMgfHwgIW9wdGlvbnMudG9rZW5JbnRyb3NwZWN0aW9uRW5kcG9pbnRVcmwpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgTUlTU0lOR19VUkwpO1xuICB9XG4gIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShvcHRpb25zLnRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsKTtcbiAgY29uc3QgcG9zdERhdGEgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoe1xuICAgIHRva2VuOiBhY2Nlc3NfdG9rZW4sXG4gIH0pO1xuICBjb25zdCBoZWFkZXJzID0ge1xuICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAnQ29udGVudC1MZW5ndGgnOiBCdWZmZXIuYnl0ZUxlbmd0aChwb3N0RGF0YSksXG4gIH07XG4gIGlmIChvcHRpb25zLmF1dGhvcml6YXRpb25IZWFkZXIpIHtcbiAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSBvcHRpb25zLmF1dGhvcml6YXRpb25IZWFkZXI7XG4gIH1cbiAgY29uc3QgcG9zdE9wdGlvbnMgPSB7XG4gICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aG5hbWUsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgfTtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5yZXF1ZXN0KHBvc3RPcHRpb25zLCBwb3N0RGF0YSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/phantauth.js b/lib/Adapters/Auth/phantauth.js new file mode 100644 index 0000000000..a85547aa55 --- /dev/null +++ b/lib/Adapters/Auth/phantauth.js @@ -0,0 +1,47 @@ +"use strict"; + +/* + * PhantAuth was designed to simplify testing for applications using OpenID Connect + * authentication by making use of random generated users. + * + * To learn more, please go to: https://www.phantauth.net + */ +const { + Parse +} = require('parse/node'); + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. + + +function validateAuthData(authData) { + return request('auth/userinfo', authData.access_token).then(data => { + if (data && data.sub == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'PhantAuth auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'phantauth.net', + path: '/' + path, + headers: { + Authorization: 'bearer ' + access_token, + 'User-Agent': 'parse-server' + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3BoYW50YXV0aC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdWIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7QUFPQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxTQUFTRSxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsT0FBTyxDQUFDLGVBQUQsRUFBa0JELFFBQVEsQ0FBQ0UsWUFBM0IsQ0FBUCxDQUFnREMsSUFBaEQsQ0FBcURDLElBQUksSUFBSTtBQUNsRSxRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsR0FBTCxJQUFZTCxRQUFRLENBQUNNLEVBQWpDLEVBQXFDO0FBQ25DO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJVixLQUFLLENBQUNXLEtBQVYsQ0FDSlgsS0FBSyxDQUFDVyxLQUFOLENBQVlDLGdCQURSLEVBRUosMENBRkksQ0FBTjtBQUlELEdBUk0sQ0FBUDtBQVNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsT0FBVCxDQUFpQlcsSUFBakIsRUFBdUJWLFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2UsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGVBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsTUFBTUEsSUFGVTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZZCxZQURwQjtBQUVQLG9CQUFjO0FBRlA7QUFIYSxHQUFqQixDQUFQO0FBUUQ7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUGhhbnRBdXRoIHdhcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0ZXN0aW5nIGZvciBhcHBsaWNhdGlvbnMgdXNpbmcgT3BlbklEIENvbm5lY3RcbiAqIGF1dGhlbnRpY2F0aW9uIGJ5IG1ha2luZyB1c2Ugb2YgcmFuZG9tIGdlbmVyYXRlZCB1c2Vycy5cbiAqXG4gKiBUbyBsZWFybiBtb3JlLCBwbGVhc2UgZ28gdG86IGh0dHBzOi8vd3d3LnBoYW50YXV0aC5uZXRcbiAqL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ2F1dGgvdXNlcmluZm8nLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5zdWIgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdQaGFudEF1dGggYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdwaGFudGF1dGgubmV0JyxcbiAgICBwYXRoOiAnLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdiZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgICdVc2VyLUFnZW50JzogJ3BhcnNlLXNlcnZlcicsXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/qq.js b/lib/Adapters/Auth/qq.js new file mode 100644 index 0000000000..4d57399ed2 --- /dev/null +++ b/lib/Adapters/Auth/qq.js @@ -0,0 +1,48 @@ +"use strict"; + +// Helper functions for accessing the qq Graph API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return graphRequest('me?access_token=' + authData.access_token).then(function (data) { + if (data && data.openid == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for qq graph requests. + + +function graphRequest(path) { + return httpsRequest.get('https://graph.qq.com/oauth2.0/' + path, true).then(data => { + return parseResponseData(data); + }); +} + +function parseResponseData(data) { + const starPos = data.indexOf('('); + const endPos = data.indexOf(')'); + + if (starPos == -1 || endPos == -1) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); + } + + data = data.substring(starPos + 1, endPos - 1); + return JSON.parse(data); +} + +module.exports = { + validateAppId, + validateAuthData, + parseResponseData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3FxLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwib3BlbmlkIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwicGFyc2VSZXNwb25zZURhdGEiLCJzdGFyUG9zIiwiaW5kZXhPZiIsImVuZFBvcyIsInN1YnN0cmluZyIsIkpTT04iLCJwYXJzZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxNQUFNQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUE1Qjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDLEMsQ0FFQTs7O0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DO0FBQ2xDLFNBQU9DLFlBQVksQ0FBQyxxQkFBcUJELFFBQVEsQ0FBQ0UsWUFBL0IsQ0FBWixDQUF5REMsSUFBekQsQ0FBOEQsVUFDbkVDLElBRG1FLEVBRW5FO0FBQ0EsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLE1BQUwsSUFBZUwsUUFBUSxDQUFDTSxFQUFwQyxFQUF3QztBQUN0QztBQUNEOztBQUNELFVBQU0sSUFBSVIsS0FBSyxDQUFDUyxLQUFWLENBQ0pULEtBQUssQ0FBQ1MsS0FBTixDQUFZQyxnQkFEUixFQUVKLG1DQUZJLENBQU47QUFJRCxHQVZNLENBQVA7QUFXRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNWLFlBQVQsQ0FBc0JXLElBQXRCLEVBQTRCO0FBQzFCLFNBQU9oQixZQUFZLENBQ2hCaUIsR0FESSxDQUNBLG1DQUFtQ0QsSUFEbkMsRUFDeUMsSUFEekMsRUFFSlQsSUFGSSxDQUVDQyxJQUFJLElBQUk7QUFDWixXQUFPVSxpQkFBaUIsQ0FBQ1YsSUFBRCxDQUF4QjtBQUNELEdBSkksQ0FBUDtBQUtEOztBQUVELFNBQVNVLGlCQUFULENBQTJCVixJQUEzQixFQUFpQztBQUMvQixRQUFNVyxPQUFPLEdBQUdYLElBQUksQ0FBQ1ksT0FBTCxDQUFhLEdBQWIsQ0FBaEI7QUFDQSxRQUFNQyxNQUFNLEdBQUdiLElBQUksQ0FBQ1ksT0FBTCxDQUFhLEdBQWIsQ0FBZjs7QUFDQSxNQUFJRCxPQUFPLElBQUksQ0FBQyxDQUFaLElBQWlCRSxNQUFNLElBQUksQ0FBQyxDQUFoQyxFQUFtQztBQUNqQyxVQUFNLElBQUluQixLQUFLLENBQUNTLEtBQVYsQ0FDSlQsS0FBSyxDQUFDUyxLQUFOLENBQVlDLGdCQURSLEVBRUosbUNBRkksQ0FBTjtBQUlEOztBQUNESixFQUFBQSxJQUFJLEdBQUdBLElBQUksQ0FBQ2MsU0FBTCxDQUFlSCxPQUFPLEdBQUcsQ0FBekIsRUFBNEJFLE1BQU0sR0FBRyxDQUFyQyxDQUFQO0FBQ0EsU0FBT0UsSUFBSSxDQUFDQyxLQUFMLENBQVdoQixJQUFYLENBQVA7QUFDRDs7QUFFRGlCLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmYixFQUFBQSxhQURlO0FBRWZWLEVBQUFBLGdCQUZlO0FBR2ZlLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHFxIEdyYXBoIEFQSS5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdCgnbWU/YWNjZXNzX3Rva2VuPScgKyBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZnVuY3Rpb24oXG4gICAgZGF0YVxuICApIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLm9wZW5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ3FxIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBxcSBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChwYXRoKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3RcbiAgICAuZ2V0KCdodHRwczovL2dyYXBoLnFxLmNvbS9vYXV0aDIuMC8nICsgcGF0aCwgdHJ1ZSlcbiAgICAudGhlbihkYXRhID0+IHtcbiAgICAgIHJldHVybiBwYXJzZVJlc3BvbnNlRGF0YShkYXRhKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VSZXNwb25zZURhdGEoZGF0YSkge1xuICBjb25zdCBzdGFyUG9zID0gZGF0YS5pbmRleE9mKCcoJyk7XG4gIGNvbnN0IGVuZFBvcyA9IGRhdGEuaW5kZXhPZignKScpO1xuICBpZiAoc3RhclBvcyA9PSAtMSB8fCBlbmRQb3MgPT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ3FxIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9XG4gIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhzdGFyUG9zICsgMSwgZW5kUG9zIC0gMSk7XG4gIHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbiAgcGFyc2VSZXNwb25zZURhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/spotify.js b/lib/Adapters/Auth/spotify.js new file mode 100644 index 0000000000..a4eda323f6 --- /dev/null +++ b/lib/Adapters/Auth/spotify.js @@ -0,0 +1,51 @@ +"use strict"; + +// Helper functions for accessing the Spotify API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('me', authData.access_token).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId(appIds, authData) { + var access_token = authData.access_token; + + if (!appIds.length) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is not configured.'); + } + + return request('me', access_token).then(data => { + if (data && appIds.indexOf(data.id) != -1) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); + }); +} // A promisey wrapper for Spotify API requests. + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'api.spotify.com', + path: '/v1/' + path, + headers: { + Authorization: 'Bearer ' + access_token + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Nwb3RpZnkuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiYXBwSWRzIiwibGVuZ3RoIiwiaW5kZXhPZiIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLENBQVAsQ0FBcUNDLElBQXJDLENBQTBDQyxJQUFJLElBQUk7QUFDdkQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQ0pSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxnQkFEUixFQUVKLHdDQUZJLENBQU47QUFJRCxHQVJNLENBQVA7QUFTRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsQ0FBdUJDLE1BQXZCLEVBQStCVCxRQUEvQixFQUF5QztBQUN2QyxNQUFJRSxZQUFZLEdBQUdGLFFBQVEsQ0FBQ0UsWUFBNUI7O0FBQ0EsTUFBSSxDQUFDTyxNQUFNLENBQUNDLE1BQVosRUFBb0I7QUFDbEIsVUFBTSxJQUFJWixLQUFLLENBQUNRLEtBQVYsQ0FDSlIsS0FBSyxDQUFDUSxLQUFOLENBQVlDLGdCQURSLEVBRUosaUNBRkksQ0FBTjtBQUlEOztBQUNELFNBQU9OLE9BQU8sQ0FBQyxJQUFELEVBQU9DLFlBQVAsQ0FBUCxDQUE0QkMsSUFBNUIsQ0FBaUNDLElBQUksSUFBSTtBQUM5QyxRQUFJQSxJQUFJLElBQUlLLE1BQU0sQ0FBQ0UsT0FBUCxDQUFlUCxJQUFJLENBQUNDLEVBQXBCLEtBQTJCLENBQUMsQ0FBeEMsRUFBMkM7QUFDekM7QUFDRDs7QUFDRCxVQUFNLElBQUlQLEtBQUssQ0FBQ1EsS0FBVixDQUNKUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix3Q0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTTixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT04sWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGlCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWQ7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFNwb3RpZnkgQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhKSB7XG4gIHZhciBhY2Nlc3NfdG9rZW4gPSBhdXRoRGF0YS5hY2Nlc3NfdG9rZW47XG4gIGlmICghYXBwSWRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnU3BvdGlmeSBhdXRoIGlzIG5vdCBjb25maWd1cmVkLidcbiAgICApO1xuICB9XG4gIHJldHVybiByZXF1ZXN0KCdtZScsIGFjY2Vzc190b2tlbikudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBhcHBJZHMuaW5kZXhPZihkYXRhLmlkKSAhPSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIFNwb3RpZnkgQVBJIHJlcXVlc3RzLlxuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuc3BvdGlmeS5jb20nLFxuICAgIHBhdGg6ICcvdjEvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/twitter.js b/lib/Adapters/Auth/twitter.js new file mode 100644 index 0000000000..75684e3834 --- /dev/null +++ b/lib/Adapters/Auth/twitter.js @@ -0,0 +1,60 @@ +"use strict"; + +// Helper functions for accessing the twitter API. +var OAuth = require('./OAuth1Client'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + if (!options) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Twitter auth configuration missing'); + } + + options = handleMultipleConfigurations(authData, options); + var client = new OAuth(options); + client.host = 'api.twitter.com'; + client.auth_token = authData.auth_token; + client.auth_token_secret = authData.auth_token_secret; + return client.get('/1.1/account/verify_credentials.json').then(data => { + if (data && data.id_str == '' + authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +function handleMultipleConfigurations(authData, options) { + if (Array.isArray(options)) { + const consumer_key = authData.consumer_key; + + if (!consumer_key) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); + } + + options = options.filter(option => { + return option.consumer_key == consumer_key; + }); + + if (options.length == 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); + } + + options = options[0]; + } + + return options; +} + +module.exports = { + validateAppId, + validateAuthData, + handleMultipleConfigurations +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3R3aXR0ZXIuanMiXSwibmFtZXMiOlsiT0F1dGgiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zIiwiY2xpZW50IiwiaG9zdCIsImF1dGhfdG9rZW4iLCJhdXRoX3Rva2VuX3NlY3JldCIsImdldCIsInRoZW4iLCJkYXRhIiwiaWRfc3RyIiwiaWQiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uc3VtZXJfa2V5IiwiZmlsdGVyIiwib3B0aW9uIiwibGVuZ3RoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQW5COztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEMsQyxDQUVBOzs7QUFDQSxTQUFTQyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLE1BQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osVUFBTSxJQUFJSCxLQUFLLENBQUNJLEtBQVYsQ0FDSkosS0FBSyxDQUFDSSxLQUFOLENBQVlDLHFCQURSLEVBRUosb0NBRkksQ0FBTjtBQUlEOztBQUNERixFQUFBQSxPQUFPLEdBQUdHLDRCQUE0QixDQUFDSixRQUFELEVBQVdDLE9BQVgsQ0FBdEM7QUFDQSxNQUFJSSxNQUFNLEdBQUcsSUFBSVQsS0FBSixDQUFVSyxPQUFWLENBQWI7QUFDQUksRUFBQUEsTUFBTSxDQUFDQyxJQUFQLEdBQWMsaUJBQWQ7QUFDQUQsRUFBQUEsTUFBTSxDQUFDRSxVQUFQLEdBQW9CUCxRQUFRLENBQUNPLFVBQTdCO0FBQ0FGLEVBQUFBLE1BQU0sQ0FBQ0csaUJBQVAsR0FBMkJSLFFBQVEsQ0FBQ1EsaUJBQXBDO0FBRUEsU0FBT0gsTUFBTSxDQUFDSSxHQUFQLENBQVcsc0NBQVgsRUFBbURDLElBQW5ELENBQXdEQyxJQUFJLElBQUk7QUFDckUsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLE1BQUwsSUFBZSxLQUFLWixRQUFRLENBQUNhLEVBQXpDLEVBQTZDO0FBQzNDO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJZixLQUFLLENBQUNJLEtBQVYsQ0FDSkosS0FBSyxDQUFDSSxLQUFOLENBQVlZLGdCQURSLEVBRUosd0NBRkksQ0FBTjtBQUlELEdBUk0sQ0FBUDtBQVNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVELFNBQVNiLDRCQUFULENBQXNDSixRQUF0QyxFQUFnREMsT0FBaEQsRUFBeUQ7QUFDdkQsTUFBSWlCLEtBQUssQ0FBQ0MsT0FBTixDQUFjbEIsT0FBZCxDQUFKLEVBQTRCO0FBQzFCLFVBQU1tQixZQUFZLEdBQUdwQixRQUFRLENBQUNvQixZQUE5Qjs7QUFDQSxRQUFJLENBQUNBLFlBQUwsRUFBbUI7QUFDakIsWUFBTSxJQUFJdEIsS0FBSyxDQUFDSSxLQUFWLENBQ0pKLEtBQUssQ0FBQ0ksS0FBTixDQUFZWSxnQkFEUixFQUVKLHdDQUZJLENBQU47QUFJRDs7QUFDRGIsSUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNvQixNQUFSLENBQWVDLE1BQU0sSUFBSTtBQUNqQyxhQUFPQSxNQUFNLENBQUNGLFlBQVAsSUFBdUJBLFlBQTlCO0FBQ0QsS0FGUyxDQUFWOztBQUlBLFFBQUluQixPQUFPLENBQUNzQixNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSXpCLEtBQUssQ0FBQ0ksS0FBVixDQUNKSixLQUFLLENBQUNJLEtBQU4sQ0FBWVksZ0JBRFIsRUFFSix3Q0FGSSxDQUFOO0FBSUQ7O0FBQ0RiLElBQUFBLE9BQU8sR0FBR0EsT0FBTyxDQUFDLENBQUQsQ0FBakI7QUFDRDs7QUFDRCxTQUFPQSxPQUFQO0FBQ0Q7O0FBRUR1QixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlYsRUFBQUEsYUFEZTtBQUVmaEIsRUFBQUEsZ0JBRmU7QUFHZkssRUFBQUE7QUFIZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgdHdpdHRlciBBUEkuXG52YXIgT0F1dGggPSByZXF1aXJlKCcuL09BdXRoMUNsaWVudCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICdUd2l0dGVyIGF1dGggY29uZmlndXJhdGlvbiBtaXNzaW5nJ1xuICAgICk7XG4gIH1cbiAgb3B0aW9ucyA9IGhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMoYXV0aERhdGEsIG9wdGlvbnMpO1xuICB2YXIgY2xpZW50ID0gbmV3IE9BdXRoKG9wdGlvbnMpO1xuICBjbGllbnQuaG9zdCA9ICdhcGkudHdpdHRlci5jb20nO1xuICBjbGllbnQuYXV0aF90b2tlbiA9IGF1dGhEYXRhLmF1dGhfdG9rZW47XG4gIGNsaWVudC5hdXRoX3Rva2VuX3NlY3JldCA9IGF1dGhEYXRhLmF1dGhfdG9rZW5fc2VjcmV0O1xuXG4gIHJldHVybiBjbGllbnQuZ2V0KCcvMS4xL2FjY291bnQvdmVyaWZ5X2NyZWRlbnRpYWxzLmpzb24nKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWRfc3RyID09ICcnICsgYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdUd2l0dGVyIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucykpIHtcbiAgICBjb25zdCBjb25zdW1lcl9rZXkgPSBhdXRoRGF0YS5jb25zdW1lcl9rZXk7XG4gICAgaWYgKCFjb25zdW1lcl9rZXkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMuZmlsdGVyKG9wdGlvbiA9PiB7XG4gICAgICByZXR1cm4gb3B0aW9uLmNvbnN1bWVyX2tleSA9PSBjb25zdW1lcl9rZXk7XG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucy5sZW5ndGggPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICApO1xuICAgIH1cbiAgICBvcHRpb25zID0gb3B0aW9uc1swXTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG4gIGhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/vkontakte.js b/lib/Adapters/Auth/vkontakte.js new file mode 100644 index 0000000000..cba090645e --- /dev/null +++ b/lib/Adapters/Auth/vkontakte.js @@ -0,0 +1,54 @@ +'use strict'; // Helper functions for accessing the vkontakte API. + +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, params) { + return vkOAuth2Request(params).then(function (response) { + if (response && response.access_token) { + return request('api.vk.com', 'method/users.get?access_token=' + authData.access_token + '&v=' + params.apiVersion).then(function (response) { + if (response && response.response && response.response.length && response.response[0].id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is invalid for this user.'); + }); + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk appIds or appSecret is incorrect.'); + }); +} + +function vkOAuth2Request(params) { + return new Promise(function (resolve) { + if (!params || !params.appIds || !params.appIds.length || !params.appSecret || !params.appSecret.length) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is not configured. Missing appIds or appSecret.'); + } + + if (!params.apiVersion) { + params.apiVersion = '5.124'; + } + + resolve(); + }).then(function () { + return request('oauth.vk.com', 'access_token?client_id=' + params.appIds + '&client_secret=' + params.appSecret + '&v=' + params.apiVersion + '&grant_type=client_credentials'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(host, path) { + return httpsRequest.get('https://' + host + '/' + path); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Zrb250YWt0ZS5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJwYXJhbXMiLCJ2a09BdXRoMlJlcXVlc3QiLCJ0aGVuIiwicmVzcG9uc2UiLCJhY2Nlc3NfdG9rZW4iLCJyZXF1ZXN0IiwiYXBpVmVyc2lvbiIsImxlbmd0aCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiUHJvbWlzZSIsInJlc29sdmUiLCJhcHBJZHMiLCJhcHBTZWNyZXQiLCJ2YWxpZGF0ZUFwcElkIiwiaG9zdCIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBRUEsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsTUFBcEMsRUFBNEM7QUFDMUMsU0FBT0MsZUFBZSxDQUFDRCxNQUFELENBQWYsQ0FBd0JFLElBQXhCLENBQTZCLFVBQVVDLFFBQVYsRUFBb0I7QUFDdEQsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLFlBQXpCLEVBQXVDO0FBQ3JDLGFBQU9DLE9BQU8sQ0FDWixZQURZLEVBRVosbUNBQ0VOLFFBQVEsQ0FBQ0ssWUFEWCxHQUVFLEtBRkYsR0FHRUosTUFBTSxDQUFDTSxVQUxHLENBQVAsQ0FNTEosSUFOSyxDQU1BLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsWUFDRUEsUUFBUSxJQUNSQSxRQUFRLENBQUNBLFFBRFQsSUFFQUEsUUFBUSxDQUFDQSxRQUFULENBQWtCSSxNQUZsQixJQUdBSixRQUFRLENBQUNBLFFBQVQsQ0FBa0IsQ0FBbEIsRUFBcUJLLEVBQXJCLElBQTJCVCxRQUFRLENBQUNTLEVBSnRDLEVBS0U7QUFDQTtBQUNEOztBQUNELGNBQU0sSUFBSVgsS0FBSyxDQUFDWSxLQUFWLENBQ0paLEtBQUssQ0FBQ1ksS0FBTixDQUFZQyxnQkFEUixFQUVKLG1DQUZJLENBQU47QUFJRCxPQW5CTSxDQUFQO0FBb0JEOztBQUNELFVBQU0sSUFBSWIsS0FBSyxDQUFDWSxLQUFWLENBQ0paLEtBQUssQ0FBQ1ksS0FBTixDQUFZQyxnQkFEUixFQUVKLHNDQUZJLENBQU47QUFJRCxHQTNCTSxDQUFQO0FBNEJEOztBQUVELFNBQVNULGVBQVQsQ0FBeUJELE1BQXpCLEVBQWlDO0FBQy9CLFNBQU8sSUFBSVcsT0FBSixDQUFZLFVBQVVDLE9BQVYsRUFBbUI7QUFDcEMsUUFDRSxDQUFDWixNQUFELElBQ0EsQ0FBQ0EsTUFBTSxDQUFDYSxNQURSLElBRUEsQ0FBQ2IsTUFBTSxDQUFDYSxNQUFQLENBQWNOLE1BRmYsSUFHQSxDQUFDUCxNQUFNLENBQUNjLFNBSFIsSUFJQSxDQUFDZCxNQUFNLENBQUNjLFNBQVAsQ0FBaUJQLE1BTHBCLEVBTUU7QUFDQSxZQUFNLElBQUlWLEtBQUssQ0FBQ1ksS0FBVixDQUNKWixLQUFLLENBQUNZLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5REFGSSxDQUFOO0FBSUQ7O0FBQ0QsUUFBSSxDQUFDVixNQUFNLENBQUNNLFVBQVosRUFBd0I7QUFDdEJOLE1BQUFBLE1BQU0sQ0FBQ00sVUFBUCxHQUFvQixPQUFwQjtBQUNEOztBQUNETSxJQUFBQSxPQUFPO0FBQ1IsR0FqQk0sRUFpQkpWLElBakJJLENBaUJDLFlBQVk7QUFDbEIsV0FBT0csT0FBTyxDQUNaLGNBRFksRUFFWiw0QkFDRUwsTUFBTSxDQUFDYSxNQURULEdBRUUsaUJBRkYsR0FHRWIsTUFBTSxDQUFDYyxTQUhULEdBSUUsS0FKRixHQUtFZCxNQUFNLENBQUNNLFVBTFQsR0FNRSxnQ0FSVSxDQUFkO0FBVUQsR0E1Qk0sQ0FBUDtBQTZCRCxDLENBRUQ7OztBQUNBLFNBQVNTLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNQLE9BQVQsQ0FBaUJXLElBQWpCLEVBQXVCQyxJQUF2QixFQUE2QjtBQUMzQixTQUFPdEIsWUFBWSxDQUFDdUIsR0FBYixDQUFpQixhQUFhRixJQUFiLEdBQW9CLEdBQXBCLEdBQTBCQyxJQUEzQyxDQUFQO0FBQ0Q7O0FBRURFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmTCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZmpCLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHZrb250YWt0ZSBBUEkuXG5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIHBhcmFtcykge1xuICByZXR1cm4gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuYWNjZXNzX3Rva2VuKSB7XG4gICAgICByZXR1cm4gcmVxdWVzdChcbiAgICAgICAgJ2FwaS52ay5jb20nLFxuICAgICAgICAnbWV0aG9kL3VzZXJzLmdldD9hY2Nlc3NfdG9rZW49JyArXG4gICAgICAgICAgYXV0aERhdGEuYWNjZXNzX3Rva2VuICtcbiAgICAgICAgICAnJnY9JyArXG4gICAgICAgICAgcGFyYW1zLmFwaVZlcnNpb25cbiAgICAgICkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlc3BvbnNlICYmXG4gICAgICAgICAgcmVzcG9uc2UucmVzcG9uc2UgJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZS5sZW5ndGggJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZVswXS5pZCA9PSBhdXRoRGF0YS5pZFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1ZrIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1ZrIGFwcElkcyBvciBhcHBTZWNyZXQgaXMgaW5jb3JyZWN0LidcbiAgICApO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICBpZiAoXG4gICAgICAhcGFyYW1zIHx8XG4gICAgICAhcGFyYW1zLmFwcElkcyB8fFxuICAgICAgIXBhcmFtcy5hcHBJZHMubGVuZ3RoIHx8XG4gICAgICAhcGFyYW1zLmFwcFNlY3JldCB8fFxuICAgICAgIXBhcmFtcy5hcHBTZWNyZXQubGVuZ3RoXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdWayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLiBNaXNzaW5nIGFwcElkcyBvciBhcHBTZWNyZXQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuYXBpVmVyc2lvbikge1xuICAgICAgcGFyYW1zLmFwaVZlcnNpb24gPSAnNS4xMjQnO1xuICAgIH1cbiAgICByZXNvbHZlKCk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZXF1ZXN0KFxuICAgICAgJ29hdXRoLnZrLmNvbScsXG4gICAgICAnYWNjZXNzX3Rva2VuP2NsaWVudF9pZD0nICtcbiAgICAgICAgcGFyYW1zLmFwcElkcyArXG4gICAgICAgICcmY2xpZW50X3NlY3JldD0nICtcbiAgICAgICAgcGFyYW1zLmFwcFNlY3JldCArXG4gICAgICAgICcmdj0nICtcbiAgICAgICAgcGFyYW1zLmFwaVZlcnNpb24gK1xuICAgICAgICAnJmdyYW50X3R5cGU9Y2xpZW50X2NyZWRlbnRpYWxzJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QoaG9zdCwgcGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly8nICsgaG9zdCArICcvJyArIHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/wechat.js b/lib/Adapters/Auth/wechat.js new file mode 100644 index 0000000000..f1c429f593 --- /dev/null +++ b/lib/Adapters/Auth/wechat.js @@ -0,0 +1,33 @@ +"use strict"; + +// Helper functions for accessing the WeChat Graph API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return graphRequest('auth?access_token=' + authData.access_token + '&openid=' + authData.id).then(function (data) { + if (data.errcode == 0) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'wechat auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for WeChat graph requests. + + +function graphRequest(path) { + return httpsRequest.get('https://api.weixin.qq.com/sns/' + path); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlY2hhdC5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJncmFwaFJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpZCIsInRoZW4iLCJkYXRhIiwiZXJyY29kZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxZQUFZLENBQ2pCLHVCQUF1QkQsUUFBUSxDQUFDRSxZQUFoQyxHQUErQyxVQUEvQyxHQUE0REYsUUFBUSxDQUFDRyxFQURwRCxDQUFaLENBRUxDLElBRkssQ0FFQSxVQUFTQyxJQUFULEVBQWU7QUFDcEIsUUFBSUEsSUFBSSxDQUFDQyxPQUFMLElBQWdCLENBQXBCLEVBQXVCO0FBQ3JCO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJUixLQUFLLENBQUNTLEtBQVYsQ0FDSlQsS0FBSyxDQUFDUyxLQUFOLENBQVlDLGdCQURSLEVBRUosdUNBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsWUFBVCxDQUFzQlcsSUFBdEIsRUFBNEI7QUFDMUIsU0FBT2hCLFlBQVksQ0FBQ2lCLEdBQWIsQ0FBaUIsbUNBQW1DRCxJQUFwRCxDQUFQO0FBQ0Q7O0FBRURFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmTixFQUFBQSxhQURlO0FBRWZWLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFdlQ2hhdCBHcmFwaCBBUEkuXG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiBncmFwaFJlcXVlc3QoXG4gICAgJ2F1dGg/YWNjZXNzX3Rva2VuPScgKyBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4gKyAnJm9wZW5pZD0nICsgYXV0aERhdGEuaWRcbiAgKS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZiAoZGF0YS5lcnJjb2RlID09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICd3ZWNoYXQgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIFdlQ2hhdCBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChwYXRoKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KCdodHRwczovL2FwaS53ZWl4aW4ucXEuY29tL3Nucy8nICsgcGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/weibo.js b/lib/Adapters/Auth/weibo.js new file mode 100644 index 0000000000..701866d6ae --- /dev/null +++ b/lib/Adapters/Auth/weibo.js @@ -0,0 +1,47 @@ +"use strict"; + +// Helper functions for accessing the weibo Graph API. +var httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; + +var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return graphRequest(authData.access_token).then(function (data) { + if (data && data.uid == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'weibo auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for weibo graph requests. + + +function graphRequest(access_token) { + var postData = querystring.stringify({ + access_token: access_token + }); + var options = { + hostname: 'api.weibo.com', + path: '/oauth2/get_token_info', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': Buffer.byteLength(postData) + } + }; + return httpsRequest.request(options, postData); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlaWJvLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInF1ZXJ5c3RyaW5nIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiZ3JhcGhSZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJ1aWQiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3REYXRhIiwic3RyaW5naWZ5Iiwib3B0aW9ucyIsImhvc3RuYW1lIiwicGF0aCIsIm1ldGhvZCIsImhlYWRlcnMiLCJCdWZmZXIiLCJieXRlTGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsWUFBWSxDQUFDRCxRQUFRLENBQUNFLFlBQVYsQ0FBWixDQUFvQ0MsSUFBcEMsQ0FBeUMsVUFBU0MsSUFBVCxFQUFlO0FBQzdELFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxHQUFMLElBQVlMLFFBQVEsQ0FBQ00sRUFBakMsRUFBcUM7QUFDbkM7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUNKVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixzQ0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixZQUFULENBQXNCQyxZQUF0QixFQUFvQztBQUNsQyxNQUFJVSxRQUFRLEdBQUdkLFdBQVcsQ0FBQ2UsU0FBWixDQUFzQjtBQUNuQ1gsSUFBQUEsWUFBWSxFQUFFQTtBQURxQixHQUF0QixDQUFmO0FBR0EsTUFBSVksT0FBTyxHQUFHO0FBQ1pDLElBQUFBLFFBQVEsRUFBRSxlQURFO0FBRVpDLElBQUFBLElBQUksRUFBRSx3QkFGTTtBQUdaQyxJQUFBQSxNQUFNLEVBQUUsTUFISTtBQUlaQyxJQUFBQSxPQUFPLEVBQUU7QUFDUCxzQkFBZ0IsbUNBRFQ7QUFFUCx3QkFBa0JDLE1BQU0sQ0FBQ0MsVUFBUCxDQUFrQlIsUUFBbEI7QUFGWDtBQUpHLEdBQWQ7QUFTQSxTQUFPakIsWUFBWSxDQUFDMEIsT0FBYixDQUFxQlAsT0FBckIsRUFBOEJGLFFBQTlCLENBQVA7QUFDRDs7QUFFRFUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZkLEVBQUFBLGFBRGU7QUFFZlYsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgd2VpYm8gR3JhcGggQVBJLlxudmFyIGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiBncmFwaFJlcXVlc3QoYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnVpZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ3dlaWJvIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciB3ZWlibyBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIHBvc3REYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICBhY2Nlc3NfdG9rZW46IGFjY2Vzc190b2tlbixcbiAgfSk7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGhvc3RuYW1lOiAnYXBpLndlaWJvLmNvbScsXG4gICAgcGF0aDogJy9vYXV0aDIvZ2V0X3Rva2VuX2luZm8nLFxuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAgICdDb250ZW50LUxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHBvc3REYXRhKSxcbiAgICB9LFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LnJlcXVlc3Qob3B0aW9ucywgcG9zdERhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/CacheAdapter.js b/lib/Adapters/Cache/CacheAdapter.js new file mode 100644 index 0000000000..60e6d6e501 --- /dev/null +++ b/lib/Adapters/Cache/CacheAdapter.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CacheAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface CacheAdapter + */ +class CacheAdapter { + /** + * Get a value in the cache + * @param {String} key Cache key to get + * @return {Promise} that will eventually resolve to the value in the cache. + */ + get(key) {} + /** + * Set a value in the cache + * @param {String} key Cache key to set + * @param {String} value Value to set the key + * @param {String} ttl Optional TTL + */ + + + put(key, value, ttl) {} + /** + * Remove a value from the cache. + * @param {String} key Cache key to remove + */ + + + del(key) {} + /** + * Empty a cache + */ + + + clear() {} + +} + +exports.CacheAdapter = CacheAdapter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9DYWNoZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiQ2FjaGVBZGFwdGVyIiwiZ2V0Iiwia2V5IiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7OztBQUdPLE1BQU1BLFlBQU4sQ0FBbUI7QUFDeEI7Ozs7O0FBS0FDLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNLENBQUU7QUFFWDs7Ozs7Ozs7QUFNQUMsRUFBQUEsR0FBRyxDQUFDRCxHQUFELEVBQU1FLEtBQU4sRUFBYUMsR0FBYixFQUFrQixDQUFFO0FBRXZCOzs7Ozs7QUFJQUMsRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU0sQ0FBRTtBQUVYOzs7OztBQUdBSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF6QmMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIENhY2hlQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGluIHRoZSBjYWNoZVxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byBnZXRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gdGhhdCB3aWxsIGV2ZW50dWFsbHkgcmVzb2x2ZSB0byB0aGUgdmFsdWUgaW4gdGhlIGNhY2hlLlxuICAgKi9cbiAgZ2V0KGtleSkge31cblxuICAvKipcbiAgICogU2V0IGEgdmFsdWUgaW4gdGhlIGNhY2hlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgQ2FjaGUga2V5IHRvIHNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVmFsdWUgdG8gc2V0IHRoZSBrZXlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR0bCBPcHRpb25hbCBUVExcbiAgICovXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHt9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHZhbHVlIGZyb20gdGhlIGNhY2hlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byByZW1vdmVcbiAgICovXG4gIGRlbChrZXkpIHt9XG5cbiAgLyoqXG4gICAqIEVtcHR5IGEgY2FjaGVcbiAgICovXG4gIGNsZWFyKCkge31cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCache.js b/lib/Adapters/Cache/InMemoryCache.js new file mode 100644 index 0000000000..b9a6543504 --- /dev/null +++ b/lib/Adapters/Cache/InMemoryCache.js @@ -0,0 +1,76 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.InMemoryCache = void 0; +const DEFAULT_CACHE_TTL = 5 * 1000; + +class InMemoryCache { + constructor({ + ttl = DEFAULT_CACHE_TTL + }) { + this.ttl = ttl; + this.cache = Object.create(null); + } + + get(key) { + const record = this.cache[key]; + + if (record == null) { + return null; + } // Has Record and isnt expired + + + if (isNaN(record.expire) || record.expire >= Date.now()) { + return record.value; + } // Record has expired + + + delete this.cache[key]; + return null; + } + + put(key, value, ttl = this.ttl) { + if (ttl < 0 || isNaN(ttl)) { + ttl = NaN; + } + + var record = { + value: value, + expire: ttl + Date.now() + }; + + if (!isNaN(record.expire)) { + record.timeout = setTimeout(() => { + this.del(key); + }, ttl); + } + + this.cache[key] = record; + } + + del(key) { + var record = this.cache[key]; + + if (record == null) { + return; + } + + if (record.timeout) { + clearTimeout(record.timeout); + } + + delete this.cache[key]; + } + + clear() { + this.cache = Object.create(null); + } + +} + +exports.InMemoryCache = InMemoryCache; +var _default = InMemoryCache; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlLmpzIl0sIm5hbWVzIjpbIkRFRkFVTFRfQ0FDSEVfVFRMIiwiSW5NZW1vcnlDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiY2FjaGUiLCJPYmplY3QiLCJjcmVhdGUiLCJnZXQiLCJrZXkiLCJyZWNvcmQiLCJpc05hTiIsImV4cGlyZSIsIkRhdGUiLCJub3ciLCJ2YWx1ZSIsInB1dCIsIk5hTiIsInRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiZGVsIiwiY2xlYXJUaW1lb3V0IiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE1BQU1BLGlCQUFpQixHQUFHLElBQUksSUFBOUI7O0FBRU8sTUFBTUMsYUFBTixDQUFvQjtBQUN6QkMsRUFBQUEsV0FBVyxDQUFDO0FBQUVDLElBQUFBLEdBQUcsR0FBR0g7QUFBUixHQUFELEVBQThCO0FBQ3ZDLFNBQUtHLEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLEtBQUwsR0FBYUMsTUFBTSxDQUFDQyxNQUFQLENBQWMsSUFBZCxDQUFiO0FBQ0Q7O0FBRURDLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsTUFBTSxHQUFHLEtBQUtMLEtBQUwsQ0FBV0ksR0FBWCxDQUFmOztBQUNBLFFBQUlDLE1BQU0sSUFBSSxJQUFkLEVBQW9CO0FBQ2xCLGFBQU8sSUFBUDtBQUNELEtBSk0sQ0FNUDs7O0FBQ0EsUUFBSUMsS0FBSyxDQUFDRCxNQUFNLENBQUNFLE1BQVIsQ0FBTCxJQUF3QkYsTUFBTSxDQUFDRSxNQUFQLElBQWlCQyxJQUFJLENBQUNDLEdBQUwsRUFBN0MsRUFBeUQ7QUFDdkQsYUFBT0osTUFBTSxDQUFDSyxLQUFkO0FBQ0QsS0FUTSxDQVdQOzs7QUFDQSxXQUFPLEtBQUtWLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0EsV0FBTyxJQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLEdBQUcsQ0FBQ1AsR0FBRCxFQUFNTSxLQUFOLEVBQWFYLEdBQUcsR0FBRyxLQUFLQSxHQUF4QixFQUE2QjtBQUM5QixRQUFJQSxHQUFHLEdBQUcsQ0FBTixJQUFXTyxLQUFLLENBQUNQLEdBQUQsQ0FBcEIsRUFBMkI7QUFDekJBLE1BQUFBLEdBQUcsR0FBR2EsR0FBTjtBQUNEOztBQUVELFFBQUlQLE1BQU0sR0FBRztBQUNYSyxNQUFBQSxLQUFLLEVBQUVBLEtBREk7QUFFWEgsTUFBQUEsTUFBTSxFQUFFUixHQUFHLEdBQUdTLElBQUksQ0FBQ0MsR0FBTDtBQUZILEtBQWI7O0FBS0EsUUFBSSxDQUFDSCxLQUFLLENBQUNELE1BQU0sQ0FBQ0UsTUFBUixDQUFWLEVBQTJCO0FBQ3pCRixNQUFBQSxNQUFNLENBQUNRLE9BQVAsR0FBaUJDLFVBQVUsQ0FBQyxNQUFNO0FBQ2hDLGFBQUtDLEdBQUwsQ0FBU1gsR0FBVDtBQUNELE9BRjBCLEVBRXhCTCxHQUZ3QixDQUEzQjtBQUdEOztBQUVELFNBQUtDLEtBQUwsQ0FBV0ksR0FBWCxJQUFrQkMsTUFBbEI7QUFDRDs7QUFFRFUsRUFBQUEsR0FBRyxDQUFDWCxHQUFELEVBQU07QUFDUCxRQUFJQyxNQUFNLEdBQUcsS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWI7O0FBQ0EsUUFBSUMsTUFBTSxJQUFJLElBQWQsRUFBb0I7QUFDbEI7QUFDRDs7QUFFRCxRQUFJQSxNQUFNLENBQUNRLE9BQVgsRUFBb0I7QUFDbEJHLE1BQUFBLFlBQVksQ0FBQ1gsTUFBTSxDQUFDUSxPQUFSLENBQVo7QUFDRDs7QUFDRCxXQUFPLEtBQUtiLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0Q7O0FBRURhLEVBQUFBLEtBQUssR0FBRztBQUNOLFNBQUtqQixLQUFMLEdBQWFDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLElBQWQsQ0FBYjtBQUNEOztBQXZEd0I7OztlQTBEWkwsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IERFRkFVTFRfQ0FDSEVfVFRMID0gNSAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBERUZBVUxUX0NBQ0hFX1RUTCB9KSB7XG4gICAgdGhpcy50dGwgPSB0dGw7XG4gICAgdGhpcy5jYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSGFzIFJlY29yZCBhbmQgaXNudCBleHBpcmVkXG4gICAgaWYgKGlzTmFOKHJlY29yZC5leHBpcmUpIHx8IHJlY29yZC5leHBpcmUgPj0gRGF0ZS5ub3coKSkge1xuICAgICAgcmV0dXJuIHJlY29yZC52YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBSZWNvcmQgaGFzIGV4cGlyZWRcbiAgICBkZWxldGUgdGhpcy5jYWNoZVtrZXldO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCA9IHRoaXMudHRsKSB7XG4gICAgaWYgKHR0bCA8IDAgfHwgaXNOYU4odHRsKSkge1xuICAgICAgdHRsID0gTmFOO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBleHBpcmU6IHR0bCArIERhdGUubm93KCksXG4gICAgfTtcblxuICAgIGlmICghaXNOYU4ocmVjb3JkLmV4cGlyZSkpIHtcbiAgICAgIHJlY29yZC50aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGVsKGtleSk7XG4gICAgICB9LCB0dGwpO1xuICAgIH1cblxuICAgIHRoaXMuY2FjaGVba2V5XSA9IHJlY29yZDtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB2YXIgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChyZWNvcmQudGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHJlY29yZC50aW1lb3V0KTtcbiAgICB9XG4gICAgZGVsZXRlIHRoaXMuY2FjaGVba2V5XTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEluTWVtb3J5Q2FjaGU7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCacheAdapter.js b/lib/Adapters/Cache/InMemoryCacheAdapter.js new file mode 100644 index 0000000000..ffc38ce5ec --- /dev/null +++ b/lib/Adapters/Cache/InMemoryCacheAdapter.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.InMemoryCacheAdapter = void 0; + +var _LRUCache = require("./LRUCache"); + +class InMemoryCacheAdapter { + constructor(ctx) { + this.cache = new _LRUCache.LRUCache(ctx); + } + + get(key) { + const record = this.cache.get(key); + + if (record === null) { + return Promise.resolve(null); + } + + return Promise.resolve(record); + } + + put(key, value, ttl) { + this.cache.put(key, value, ttl); + return Promise.resolve(); + } + + del(key) { + this.cache.del(key); + return Promise.resolve(); + } + + clear() { + this.cache.clear(); + return Promise.resolve(); + } + +} + +exports.InMemoryCacheAdapter = InMemoryCacheAdapter; +var _default = InMemoryCacheAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJJbk1lbW9yeUNhY2hlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiY3R4IiwiY2FjaGUiLCJMUlVDYWNoZSIsImdldCIsImtleSIsInJlY29yZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUVPLE1BQU1BLG9CQUFOLENBQTJCO0FBQ2hDQyxFQUFBQSxXQUFXLENBQUNDLEdBQUQsRUFBTTtBQUNmLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxrQkFBSixDQUFhRixHQUFiLENBQWI7QUFDRDs7QUFFREcsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU07QUFDUCxVQUFNQyxNQUFNLEdBQUcsS0FBS0osS0FBTCxDQUFXRSxHQUFYLENBQWVDLEdBQWYsQ0FBZjs7QUFDQSxRQUFJQyxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixhQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNEOztBQUNELFdBQU9ELE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkYsTUFBaEIsQ0FBUDtBQUNEOztBQUVERyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTUssS0FBTixFQUFhQyxHQUFiLEVBQWtCO0FBQ25CLFNBQUtULEtBQUwsQ0FBV08sR0FBWCxDQUFlSixHQUFmLEVBQW9CSyxLQUFwQixFQUEyQkMsR0FBM0I7QUFDQSxXQUFPSixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVESSxFQUFBQSxHQUFHLENBQUNQLEdBQUQsRUFBTTtBQUNQLFNBQUtILEtBQUwsQ0FBV1UsR0FBWCxDQUFlUCxHQUFmO0FBQ0EsV0FBT0UsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREssRUFBQUEsS0FBSyxHQUFHO0FBQ04sU0FBS1gsS0FBTCxDQUFXVyxLQUFYO0FBQ0EsV0FBT04sT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUExQitCOzs7ZUE2Qm5CVCxvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExSVUNhY2hlIH0gZnJvbSAnLi9MUlVDYWNoZSc7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKGN0eCkge1xuICAgIHRoaXMuY2FjaGUgPSBuZXcgTFJVQ2FjaGUoY3R4KTtcbiAgfVxuXG4gIGdldChrZXkpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgIGlmIChyZWNvcmQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVjb3JkKTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICB0aGlzLmNhY2hlLnB1dChrZXksIHZhbHVlLCB0dGwpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB0aGlzLmNhY2hlLmRlbChrZXkpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5NZW1vcnlDYWNoZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/LRUCache.js b/lib/Adapters/Cache/LRUCache.js new file mode 100644 index 0000000000..9781621ecf --- /dev/null +++ b/lib/Adapters/Cache/LRUCache.js @@ -0,0 +1,46 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LRUCache = void 0; + +var _lruCache = _interopRequireDefault(require("lru-cache")); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class LRUCache { + constructor({ + ttl = _defaults.default.cacheTTL, + maxSize = _defaults.default.cacheMaxSize + }) { + this.cache = new _lruCache.default({ + max: maxSize, + maxAge: ttl + }); + } + + get(key) { + return this.cache.get(key) || null; + } + + put(key, value, ttl = this.ttl) { + this.cache.set(key, value, ttl); + } + + del(key) { + this.cache.del(key); + } + + clear() { + this.cache.reset(); + } + +} + +exports.LRUCache = LRUCache; +var _default = LRUCache; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyJdLCJuYW1lcyI6WyJMUlVDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiZGVmYXVsdHMiLCJjYWNoZVRUTCIsIm1heFNpemUiLCJjYWNoZU1heFNpemUiLCJjYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsImdldCIsImtleSIsInB1dCIsInZhbHVlIiwic2V0IiwiZGVsIiwiY2xlYXIiLCJyZXNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sTUFBTUEsUUFBTixDQUFlO0FBQ3BCQyxFQUFBQSxXQUFXLENBQUM7QUFBRUMsSUFBQUEsR0FBRyxHQUFHQyxrQkFBU0MsUUFBakI7QUFBMkJDLElBQUFBLE9BQU8sR0FBR0Ysa0JBQVNHO0FBQTlDLEdBQUQsRUFBK0Q7QUFDeEUsU0FBS0MsS0FBTCxHQUFhLElBQUlDLGlCQUFKLENBQVE7QUFDbkJDLE1BQUFBLEdBQUcsRUFBRUosT0FEYztBQUVuQkssTUFBQUEsTUFBTSxFQUFFUjtBQUZXLEtBQVIsQ0FBYjtBQUlEOztBQUVEUyxFQUFBQSxHQUFHLENBQUNDLEdBQUQsRUFBTTtBQUNQLFdBQU8sS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWVDLEdBQWYsS0FBdUIsSUFBOUI7QUFDRDs7QUFFREMsRUFBQUEsR0FBRyxDQUFDRCxHQUFELEVBQU1FLEtBQU4sRUFBYVosR0FBRyxHQUFHLEtBQUtBLEdBQXhCLEVBQTZCO0FBQzlCLFNBQUtLLEtBQUwsQ0FBV1EsR0FBWCxDQUFlSCxHQUFmLEVBQW9CRSxLQUFwQixFQUEyQlosR0FBM0I7QUFDRDs7QUFFRGMsRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxTQUFLTCxLQUFMLENBQVdTLEdBQVgsQ0FBZUosR0FBZjtBQUNEOztBQUVESyxFQUFBQSxLQUFLLEdBQUc7QUFDTixTQUFLVixLQUFMLENBQVdXLEtBQVg7QUFDRDs7QUF0Qm1COzs7ZUF5QlBsQixRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IExSVSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGNsYXNzIExSVUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBkZWZhdWx0cy5jYWNoZVRUTCwgbWF4U2l6ZSA9IGRlZmF1bHRzLmNhY2hlTWF4U2l6ZSB9KSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0dGwsXG4gICAgfSk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGtleSkgfHwgbnVsbDtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwgPSB0aGlzLnR0bCkge1xuICAgIHRoaXMuY2FjaGUuc2V0KGtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgdGhpcy5jYWNoZS5kZWwoa2V5KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUucmVzZXQoKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMUlVDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/NullCacheAdapter.js b/lib/Adapters/Cache/NullCacheAdapter.js new file mode 100644 index 0000000000..639c544c94 --- /dev/null +++ b/lib/Adapters/Cache/NullCacheAdapter.js @@ -0,0 +1,34 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.NullCacheAdapter = void 0; + +class NullCacheAdapter { + constructor() {} + + get() { + return new Promise(resolve => { + return resolve(null); + }); + } + + put() { + return Promise.resolve(); + } + + del() { + return Promise.resolve(); + } + + clear() { + return Promise.resolve(); + } + +} + +exports.NullCacheAdapter = NullCacheAdapter; +var _default = NullCacheAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIk51bGxDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsImdldCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwiZGVsIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxNQUFNQSxnQkFBTixDQUF1QjtBQUM1QkMsRUFBQUEsV0FBVyxHQUFHLENBQUU7O0FBRWhCQyxFQUFBQSxHQUFHLEdBQUc7QUFDSixXQUFPLElBQUlDLE9BQUosQ0FBWUMsT0FBTyxJQUFJO0FBQzVCLGFBQU9BLE9BQU8sQ0FBQyxJQUFELENBQWQ7QUFDRCxLQUZNLENBQVA7QUFHRDs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0YsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREUsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0gsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREcsRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFuQjJCOzs7ZUFzQmZKLGdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE51bGxDYWNoZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgZ2V0KCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgIH0pO1xuICB9XG5cbiAgcHV0KCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbCgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTnVsbENhY2hlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js b/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js new file mode 100644 index 0000000000..d4303d8803 --- /dev/null +++ b/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js @@ -0,0 +1,59 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.KeyPromiseQueue = void 0; + +// KeyPromiseQueue is a simple promise queue +// used to queue operations per key basis. +// Once the tail promise in the key-queue fulfills, +// the chain on that key will be cleared. +class KeyPromiseQueue { + constructor() { + this.queue = {}; + } + + enqueue(key, operation) { + const tuple = this.beforeOp(key); + const toAwait = tuple[1]; + const nextOperation = toAwait.then(operation); + const wrappedOperation = nextOperation.then(result => { + this.afterOp(key); + return result; + }); + tuple[1] = wrappedOperation; + return wrappedOperation; + } + + beforeOp(key) { + let tuple = this.queue[key]; + + if (!tuple) { + tuple = [0, Promise.resolve()]; + this.queue[key] = tuple; + } + + tuple[0]++; + return tuple; + } + + afterOp(key) { + const tuple = this.queue[key]; + + if (!tuple) { + return; + } + + tuple[0]--; + + if (tuple[0] <= 0) { + delete this.queue[key]; + return; + } + } + +} + +exports.KeyPromiseQueue = KeyPromiseQueue; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9LZXlQcm9taXNlUXVldWUuanMiXSwibmFtZXMiOlsiS2V5UHJvbWlzZVF1ZXVlIiwiY29uc3RydWN0b3IiLCJxdWV1ZSIsImVucXVldWUiLCJrZXkiLCJvcGVyYXRpb24iLCJ0dXBsZSIsImJlZm9yZU9wIiwidG9Bd2FpdCIsIm5leHRPcGVyYXRpb24iLCJ0aGVuIiwid3JhcHBlZE9wZXJhdGlvbiIsInJlc3VsdCIsImFmdGVyT3AiLCJQcm9taXNlIiwicmVzb2x2ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsZUFBTixDQUFzQjtBQUMzQkMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxHQUFhLEVBQWI7QUFDRDs7QUFFREMsRUFBQUEsT0FBTyxDQUFDQyxHQUFELEVBQU1DLFNBQU4sRUFBaUI7QUFDdEIsVUFBTUMsS0FBSyxHQUFHLEtBQUtDLFFBQUwsQ0FBY0gsR0FBZCxDQUFkO0FBQ0EsVUFBTUksT0FBTyxHQUFHRixLQUFLLENBQUMsQ0FBRCxDQUFyQjtBQUNBLFVBQU1HLGFBQWEsR0FBR0QsT0FBTyxDQUFDRSxJQUFSLENBQWFMLFNBQWIsQ0FBdEI7QUFDQSxVQUFNTSxnQkFBZ0IsR0FBR0YsYUFBYSxDQUFDQyxJQUFkLENBQW1CRSxNQUFNLElBQUk7QUFDcEQsV0FBS0MsT0FBTCxDQUFhVCxHQUFiO0FBQ0EsYUFBT1EsTUFBUDtBQUNELEtBSHdCLENBQXpCO0FBSUFOLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUwsR0FBV0ssZ0JBQVg7QUFDQSxXQUFPQSxnQkFBUDtBQUNEOztBQUVESixFQUFBQSxRQUFRLENBQUNILEdBQUQsRUFBTTtBQUNaLFFBQUlFLEtBQUssR0FBRyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBWjs7QUFDQSxRQUFJLENBQUNFLEtBQUwsRUFBWTtBQUNWQSxNQUFBQSxLQUFLLEdBQUcsQ0FBQyxDQUFELEVBQUlRLE9BQU8sQ0FBQ0MsT0FBUixFQUFKLENBQVI7QUFDQSxXQUFLYixLQUFMLENBQVdFLEdBQVgsSUFBa0JFLEtBQWxCO0FBQ0Q7O0FBQ0RBLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUw7QUFDQSxXQUFPQSxLQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLE9BQU8sQ0FBQ1QsR0FBRCxFQUFNO0FBQ1gsVUFBTUUsS0FBSyxHQUFHLEtBQUtKLEtBQUwsQ0FBV0UsR0FBWCxDQUFkOztBQUNBLFFBQUksQ0FBQ0UsS0FBTCxFQUFZO0FBQ1Y7QUFDRDs7QUFDREEsSUFBQUEsS0FBSyxDQUFDLENBQUQsQ0FBTDs7QUFDQSxRQUFJQSxLQUFLLENBQUMsQ0FBRCxDQUFMLElBQVksQ0FBaEIsRUFBbUI7QUFDakIsYUFBTyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBUDtBQUNBO0FBQ0Q7QUFDRjs7QUFyQzBCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gS2V5UHJvbWlzZVF1ZXVlIGlzIGEgc2ltcGxlIHByb21pc2UgcXVldWVcbi8vIHVzZWQgdG8gcXVldWUgb3BlcmF0aW9ucyBwZXIga2V5IGJhc2lzLlxuLy8gT25jZSB0aGUgdGFpbCBwcm9taXNlIGluIHRoZSBrZXktcXVldWUgZnVsZmlsbHMsXG4vLyB0aGUgY2hhaW4gb24gdGhhdCBrZXkgd2lsbCBiZSBjbGVhcmVkLlxuZXhwb3J0IGNsYXNzIEtleVByb21pc2VRdWV1ZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMucXVldWUgPSB7fTtcbiAgfVxuXG4gIGVucXVldWUoa2V5LCBvcGVyYXRpb24pIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMuYmVmb3JlT3Aoa2V5KTtcbiAgICBjb25zdCB0b0F3YWl0ID0gdHVwbGVbMV07XG4gICAgY29uc3QgbmV4dE9wZXJhdGlvbiA9IHRvQXdhaXQudGhlbihvcGVyYXRpb24pO1xuICAgIGNvbnN0IHdyYXBwZWRPcGVyYXRpb24gPSBuZXh0T3BlcmF0aW9uLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIHRoaXMuYWZ0ZXJPcChrZXkpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbiAgICB0dXBsZVsxXSA9IHdyYXBwZWRPcGVyYXRpb247XG4gICAgcmV0dXJuIHdyYXBwZWRPcGVyYXRpb247XG4gIH1cblxuICBiZWZvcmVPcChrZXkpIHtcbiAgICBsZXQgdHVwbGUgPSB0aGlzLnF1ZXVlW2tleV07XG4gICAgaWYgKCF0dXBsZSkge1xuICAgICAgdHVwbGUgPSBbMCwgUHJvbWlzZS5yZXNvbHZlKCldO1xuICAgICAgdGhpcy5xdWV1ZVtrZXldID0gdHVwbGU7XG4gICAgfVxuICAgIHR1cGxlWzBdKys7XG4gICAgcmV0dXJuIHR1cGxlO1xuICB9XG5cbiAgYWZ0ZXJPcChrZXkpIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMucXVldWVba2V5XTtcbiAgICBpZiAoIXR1cGxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHR1cGxlWzBdLS07XG4gICAgaWYgKHR1cGxlWzBdIDw9IDApIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnF1ZXVlW2tleV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/index.js b/lib/Adapters/Cache/RedisCacheAdapter/index.js new file mode 100644 index 0000000000..df8605d5f1 --- /dev/null +++ b/lib/Adapters/Cache/RedisCacheAdapter/index.js @@ -0,0 +1,130 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.RedisCacheAdapter = void 0; + +var _redis = _interopRequireDefault(require("redis")); + +var _logger = _interopRequireDefault(require("../../../logger")); + +var _KeyPromiseQueue = require("./KeyPromiseQueue"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_REDIS_TTL = 30 * 1000; // 30 seconds in milliseconds + +const FLUSH_DB_KEY = '__flush_db__'; + +function debug() { + _logger.default.debug.apply(_logger.default, ['RedisCacheAdapter', ...arguments]); +} + +const isValidTTL = ttl => typeof ttl === 'number' && ttl > 0; + +class RedisCacheAdapter { + constructor(redisCtx, ttl = DEFAULT_REDIS_TTL) { + this.ttl = isValidTTL(ttl) ? ttl : DEFAULT_REDIS_TTL; + this.client = _redis.default.createClient(redisCtx); + this.queue = new _KeyPromiseQueue.KeyPromiseQueue(); + } + + handleShutdown() { + if (!this.client) { + return Promise.resolve(); + } + + return new Promise(resolve => { + this.client.quit(err => { + if (err) { + _logger.default.error('RedisCacheAdapter error on shutdown', { + error: err + }); + } + + resolve(); + }); + }); + } + + get(key) { + debug('get', key); + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.get(key, function (err, res) { + debug('-> get', key, res); + + if (!res) { + return resolve(null); + } + + resolve(JSON.parse(res)); + }); + })); + } + + put(key, value, ttl = this.ttl) { + value = JSON.stringify(value); + debug('put', key, value, ttl); + + if (ttl === 0) { + // ttl of zero is a logical no-op, but redis cannot set expire time of zero + return this.queue.enqueue(key, () => Promise.resolve()); + } + + if (ttl === Infinity) { + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.set(key, value, function () { + resolve(); + }); + })); + } + + if (!isValidTTL(ttl)) { + ttl = this.ttl; + } + + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.psetex(key, ttl, value, function () { + resolve(); + }); + })); + } + + del(key) { + debug('del', key); + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.del(key, function () { + resolve(); + }); + })); + } + + clear() { + debug('clear'); + return this.queue.enqueue(FLUSH_DB_KEY, () => new Promise(resolve => { + this.client.flushdb(function () { + resolve(); + }); + })); + } // Used for testing + + + async getAllKeys() { + return new Promise((resolve, reject) => { + this.client.keys('*', (err, keys) => { + if (err) { + reject(err); + } else { + resolve(keys); + } + }); + }); + } + +} + +exports.RedisCacheAdapter = RedisCacheAdapter; +var _default = RedisCacheAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9pbmRleC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX1JFRElTX1RUTCIsIkZMVVNIX0RCX0tFWSIsImRlYnVnIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJpc1ZhbGlkVFRMIiwidHRsIiwiUmVkaXNDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInJlZGlzQ3R4IiwiY2xpZW50IiwicmVkaXMiLCJjcmVhdGVDbGllbnQiLCJxdWV1ZSIsIktleVByb21pc2VRdWV1ZSIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJxdWl0IiwiZXJyIiwiZXJyb3IiLCJnZXQiLCJrZXkiLCJlbnF1ZXVlIiwicmVzIiwiSlNPTiIsInBhcnNlIiwicHV0IiwidmFsdWUiLCJzdHJpbmdpZnkiLCJJbmZpbml0eSIsInNldCIsInBzZXRleCIsImRlbCIsImNsZWFyIiwiZmx1c2hkYiIsImdldEFsbEtleXMiLCJyZWplY3QiLCJrZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxpQkFBaUIsR0FBRyxLQUFLLElBQS9CLEMsQ0FBcUM7O0FBQ3JDLE1BQU1DLFlBQVksR0FBRyxjQUFyQjs7QUFFQSxTQUFTQyxLQUFULEdBQWlCO0FBQ2ZDLGtCQUFPRCxLQUFQLENBQWFFLEtBQWIsQ0FBbUJELGVBQW5CLEVBQTJCLENBQUMsbUJBQUQsRUFBc0IsR0FBR0UsU0FBekIsQ0FBM0I7QUFDRDs7QUFFRCxNQUFNQyxVQUFVLEdBQUlDLEdBQUQsSUFBUyxPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUEyQkEsR0FBRyxHQUFHLENBQTdEOztBQUVPLE1BQU1DLGlCQUFOLENBQXdCO0FBQzdCQyxFQUFBQSxXQUFXLENBQUNDLFFBQUQsRUFBV0gsR0FBRyxHQUFHUCxpQkFBakIsRUFBb0M7QUFDN0MsU0FBS08sR0FBTCxHQUFXRCxV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Q1gsR0FBRCxFQUFNO0FBQ1ByQixJQUFBQSxLQUFLLENBQUMsS0FBRCxFQUFRcUIsR0FBUixDQUFMO0FBQ0EsV0FBTyxLQUFLVCxLQUFMLENBQVdVLE9BQVgsQ0FDTEQsR0FESyxFQUVMLE1BQ0UsSUFBSU4sT0FBSixDQUFhQyxPQUFELElBQWE7QUFDdkIsV0FBS1AsTUFBTCxDQUFZdUIsR0FBWixDQUFnQlgsR0FBaEIsRUFBcUIsWUFBWTtBQUMvQkwsUUFBQUEsT0FBTztBQUNSLE9BRkQ7QUFHRCxLQUpELENBSEcsQ0FBUDtBQVNEOztBQUVEaUIsRUFBQUEsS0FBSyxHQUFHO0FBQ05qQyxJQUFBQSxLQUFLLENBQUMsT0FBRCxDQUFMO0FBQ0EsV0FBTyxLQUFLWSxLQUFMLENBQVdVLE9BQVgsQ0FDTHZCLFlBREssRUFFTCxNQUNFLElBQUlnQixPQUFKLENBQWFDLE9BQUQsSUFBYTtBQUN2QixXQUFLUCxNQUFMLENBQVl5QixPQUFaLENBQW9CLFlBQVk7QUFDOUJsQixRQUFBQSxPQUFPO0FBQ1IsT0FGRDtBQUdELEtBSkQsQ0FIRyxDQUFQO0FBU0QsR0FsRzRCLENBb0c3Qjs7O0FBQ0EsUUFBTW1CLFVBQU4sR0FBbUI7QUFDakIsV0FBTyxJQUFJcEIsT0FBSixDQUFZLENBQUNDLE9BQUQsRUFBVW9CLE1BQVYsS0FBcUI7QUFDdEMsV0FBSzNCLE1BQUwsQ0FBWTRCLElBQVosQ0FBaUIsR0FBakIsRUFBc0IsQ0FBQ25CLEdBQUQsRUFBTW1CLElBQU4sS0FBZTtBQUNuQyxZQUFJbkIsR0FBSixFQUFTO0FBQ1BrQixVQUFBQSxNQUFNLENBQUNsQixHQUFELENBQU47QUFDRCxTQUZELE1BRU87QUFDTEYsVUFBQUEsT0FBTyxDQUFDcUIsSUFBRCxDQUFQO0FBQ0Q7QUFDRixPQU5EO0FBT0QsS0FSTSxDQUFQO0FBU0Q7O0FBL0c0Qjs7O2VBa0hoQi9CLGlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcbmltcG9ydCB7IEtleVByb21pc2VRdWV1ZSB9IGZyb20gJy4vS2V5UHJvbWlzZVF1ZXVlJztcblxuY29uc3QgREVGQVVMVF9SRURJU19UVEwgPSAzMCAqIDEwMDA7IC8vIDMwIHNlY29uZHMgaW4gbWlsbGlzZWNvbmRzXG5jb25zdCBGTFVTSF9EQl9LRVkgPSAnX19mbHVzaF9kYl9fJztcblxuZnVuY3Rpb24gZGVidWcoKSB7XG4gIGxvZ2dlci5kZWJ1Zy5hcHBseShsb2dnZXIsIFsnUmVkaXNDYWNoZUFkYXB0ZXInLCAuLi5hcmd1bWVudHNdKTtcbn1cblxuY29uc3QgaXNWYWxpZFRUTCA9ICh0dGwpID0+IHR5cGVvZiB0dGwgPT09ICdudW1iZXInICYmIHR0bCA+IDA7XG5cbmV4cG9ydCBjbGFzcyBSZWRpc0NhY2hlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKHJlZGlzQ3R4LCB0dGwgPSBERUZBVUxUX1JFRElTX1RUTCkge1xuICAgIHRoaXMudHRsID0gaXNWYWxpZFRUTCh0dGwpID8gdHRsIDogREVGQVVMVF9SRURJU19UVEw7XG4gICAgdGhpcy5jbGllbnQgPSByZWRpcy5jcmVhdGVDbGllbnQocmVkaXNDdHgpO1xuICAgIHRoaXMucXVldWUgPSBuZXcgS2V5UHJvbWlzZVF1ZXVlKCk7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy5jbGllbnQucXVpdCgoZXJyKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1JlZGlzQ2FjaGVBZGFwdGVyIGVycm9yIG9uIHNodXRkb3duJywgeyBlcnJvcjogZXJyIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGRlYnVnKCdnZXQnLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoXG4gICAgICBrZXksXG4gICAgICAoKSA9PlxuICAgICAgICBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgIHRoaXMuY2xpZW50LmdldChrZXksIGZ1bmN0aW9uIChlcnIsIHJlcykge1xuICAgICAgICAgICAgZGVidWcoJy0+IGdldCcsIGtleSwgcmVzKTtcbiAgICAgICAgICAgIGlmICghcmVzKSB7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb2x2ZShKU09OLnBhcnNlKHJlcykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwdXQoa2V5LCB2YWx1ZSwgdHRsID0gdGhpcy50dGwpIHtcbiAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICBkZWJ1ZygncHV0Jywga2V5LCB2YWx1ZSwgdHRsKTtcblxuICAgIGlmICh0dGwgPT09IDApIHtcbiAgICAgIC8vIHR0bCBvZiB6ZXJvIGlzIGEgbG9naWNhbCBuby1vcCwgYnV0IHJlZGlzIGNhbm5vdCBzZXQgZXhwaXJlIHRpbWUgb2YgemVyb1xuICAgICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShrZXksICgpID0+IFByb21pc2UucmVzb2x2ZSgpKTtcbiAgICB9XG5cbiAgICBpZiAodHRsID09PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgICAga2V5LFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5zZXQoa2V5LCB2YWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzVmFsaWRUVEwodHRsKSkge1xuICAgICAgdHRsID0gdGhpcy50dGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIGtleSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgdGhpcy5jbGllbnQucHNldGV4KGtleSwgdHRsLCB2YWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgZGVidWcoJ2RlbCcsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIGtleSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgdGhpcy5jbGllbnQuZGVsKGtleSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICBkZWJ1ZygnY2xlYXInKTtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5lbnF1ZXVlKFxuICAgICAgRkxVU0hfREJfS0VZLFxuICAgICAgKCkgPT5cbiAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICB0aGlzLmNsaWVudC5mbHVzaGRiKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gVXNlZCBmb3IgdGVzdGluZ1xuICBhc3luYyBnZXRBbGxLZXlzKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudC5rZXlzKCcqJywgKGVyciwga2V5cykgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShrZXlzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVkaXNDYWNoZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Email/MailAdapter.js b/lib/Adapters/Email/MailAdapter.js new file mode 100644 index 0000000000..217860c759 --- /dev/null +++ b/lib/Adapters/Email/MailAdapter.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.MailAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface MailAdapter + * Mail Adapter prototype + * A MailAdapter should implement at least sendMail() + */ +class MailAdapter { + /** + * A method for sending mail + * @param options would have the parameters + * - to: the recipient + * - text: the raw text of the message + * - subject: the subject of the email + */ + sendMail(options) {} + /* You can implement those methods if you want + * to provide HTML templates etc... + */ + // sendVerificationEmail({ link, appName, user }) {} + // sendPasswordResetEmail({ link, appName, user }) {} + + +} + +exports.MailAdapter = MailAdapter; +var _default = MailAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9FbWFpbC9NYWlsQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJNYWlsQWRhcHRlciIsInNlbmRNYWlsIiwib3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7Ozs7O0FBS08sTUFBTUEsV0FBTixDQUFrQjtBQUN2Qjs7Ozs7OztBQU9BQyxFQUFBQSxRQUFRLENBQUNDLE9BQUQsRUFBVSxDQUFFO0FBRXBCOzs7QUFHQTtBQUNBOzs7QUFkdUI7OztlQWlCVkYsVyIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgTWFpbEFkYXB0ZXJcbiAqIE1haWwgQWRhcHRlciBwcm90b3R5cGVcbiAqIEEgTWFpbEFkYXB0ZXIgc2hvdWxkIGltcGxlbWVudCBhdCBsZWFzdCBzZW5kTWFpbCgpXG4gKi9cbmV4cG9ydCBjbGFzcyBNYWlsQWRhcHRlciB7XG4gIC8qKlxuICAgKiBBIG1ldGhvZCBmb3Igc2VuZGluZyBtYWlsXG4gICAqIEBwYXJhbSBvcHRpb25zIHdvdWxkIGhhdmUgdGhlIHBhcmFtZXRlcnNcbiAgICogLSB0bzogdGhlIHJlY2lwaWVudFxuICAgKiAtIHRleHQ6IHRoZSByYXcgdGV4dCBvZiB0aGUgbWVzc2FnZVxuICAgKiAtIHN1YmplY3Q6IHRoZSBzdWJqZWN0IG9mIHRoZSBlbWFpbFxuICAgKi9cbiAgc2VuZE1haWwob3B0aW9ucykge31cblxuICAvKiBZb3UgY2FuIGltcGxlbWVudCB0aG9zZSBtZXRob2RzIGlmIHlvdSB3YW50XG4gICAqIHRvIHByb3ZpZGUgSFRNTCB0ZW1wbGF0ZXMgZXRjLi4uXG4gICAqL1xuICAvLyBzZW5kVmVyaWZpY2F0aW9uRW1haWwoeyBsaW5rLCBhcHBOYW1lLCB1c2VyIH0pIHt9XG4gIC8vIHNlbmRQYXNzd29yZFJlc2V0RW1haWwoeyBsaW5rLCBhcHBOYW1lLCB1c2VyIH0pIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1haWxBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Files/FilesAdapter.js b/lib/Adapters/Files/FilesAdapter.js new file mode 100644 index 0000000000..e17cb707e7 --- /dev/null +++ b/lib/Adapters/Files/FilesAdapter.js @@ -0,0 +1,136 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.validateFilename = validateFilename; +exports.default = exports.FilesAdapter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint no-unused-vars: "off"*/ +// Files Adapter +// +// Allows you to change the file storage mechanism. +// +// Adapter classes must implement the following functions: +// * createFile(filename, data, contentType) +// * deleteFile(filename) +// * getFileData(filename) +// * getFileLocation(config, filename) +// Adapter classes should implement the following functions: +// * validateFilename(filename) +// * handleFileStream(filename, req, res, contentType) +// +// Default is GridFSBucketAdapter, which requires mongo +// and for the API server to be using the DatabaseController with Mongo +// database adapter. + +/** + * @module Adapters + */ + +/** + * @interface FilesAdapter + */ +class FilesAdapter { + /** Responsible for storing the file in order to be retrieved later by its filename + * + * @param {string} filename - the filename to save + * @param {*} data - the buffer of data from the file + * @param {string} contentType - the supposed contentType + * @discussion the contentType can be undefined if the controller was not able to determine it + * @param {object} options - (Optional) options to be passed to file adapter (S3 File Adapter Only) + * - tags: object containing key value pairs that will be stored with file + * - metadata: object containing key value pairs that will be sotred with file (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/add-object-metadata.html) + * @discussion options are not supported by all file adapters. Check the your adapter's documentation for compatibility + * + * @return {Promise} a promise that should fail if the storage didn't succeed + */ + createFile(filename, data, contentType, options) {} + /** Responsible for deleting the specified file + * + * @param {string} filename - the filename to delete + * + * @return {Promise} a promise that should fail if the deletion didn't succeed + */ + + + deleteFile(filename) {} + /** Responsible for retrieving the data of the specified file + * + * @param {string} filename - the name of file to retrieve + * + * @return {Promise} a promise that should pass with the file data or fail on error + */ + + + getFileData(filename) {} + /** Returns an absolute URL where the file can be accessed + * + * @param {Config} config - server configuration + * @param {string} filename + * + * @return {string} Absolute URL + */ + + + getFileLocation(config, filename) {} + /** Validate a filename for this adapter type + * + * @param {string} filename + * + * @returns {null|Parse.Error} null if there are no errors + */ + // validateFilename(filename: string): ?Parse.Error {} + + /** Handles Byte-Range Requests for Streaming + * + * @param {string} filename + * @param {object} req + * @param {object} res + * @param {string} contentType + * + * @returns {Promise} Data for byte range + */ + // handleFileStream(filename: string, res: any, req: any, contentType: string): Promise + + /** Responsible for retrieving metadata and tags + * + * @param {string} filename - the filename to retrieve metadata + * + * @return {Promise} a promise that should pass with metadata + */ + // getMetadata(filename: string): Promise {} + + +} +/** + * Simple filename validation + * + * @param filename + * @returns {null|Parse.Error} + */ + + +exports.FilesAdapter = FilesAdapter; + +function validateFilename(filename) { + if (filename.length > 128) { + return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); + } + + const regx = /^[_a-zA-Z0-9][a-zA-Z0-9@. ~_-]*$/; + + if (!filename.match(regx)) { + return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); + } + + return null; +} + +var _default = FilesAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9GaWxlc0FkYXB0ZXIuanMiXSwibmFtZXMiOlsiRmlsZXNBZGFwdGVyIiwiY3JlYXRlRmlsZSIsImZpbGVuYW1lIiwiZGF0YSIsImNvbnRlbnRUeXBlIiwib3B0aW9ucyIsImRlbGV0ZUZpbGUiLCJnZXRGaWxlRGF0YSIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsInZhbGlkYXRlRmlsZW5hbWUiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9GSUxFX05BTUUiLCJyZWd4IiwibWF0Y2giXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBbUJBOzs7O0FBbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBSUE7Ozs7QUFHQTs7O0FBR08sTUFBTUEsWUFBTixDQUFtQjtBQUN4Qjs7Ozs7Ozs7Ozs7OztBQWFBQyxFQUFBQSxVQUFVLENBQ1JDLFFBRFEsRUFFUkMsSUFGUSxFQUdSQyxXQUhRLEVBSVJDLE9BSlEsRUFLQyxDQUFFO0FBRWI7Ozs7Ozs7O0FBTUFDLEVBQUFBLFVBQVUsQ0FBQ0osUUFBRCxFQUE0QixDQUFFO0FBRXhDOzs7Ozs7OztBQU1BSyxFQUFBQSxXQUFXLENBQUNMLFFBQUQsRUFBaUMsQ0FBRTtBQUU5Qzs7Ozs7Ozs7O0FBT0FNLEVBQUFBLGVBQWUsQ0FBQ0MsTUFBRCxFQUFpQlAsUUFBakIsRUFBMkMsQ0FBRTtBQUU1RDs7Ozs7O0FBTUE7O0FBRUE7Ozs7Ozs7OztBQVNBOztBQUVBOzs7Ozs7QUFNQTs7O0FBdkV3QjtBQTBFMUI7Ozs7Ozs7Ozs7QUFNTyxTQUFTUSxnQkFBVCxDQUEwQlIsUUFBMUIsRUFBa0Q7QUFDdkQsTUFBSUEsUUFBUSxDQUFDUyxNQUFULEdBQWtCLEdBQXRCLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0Msb0JBQS9DLENBQVA7QUFDRDs7QUFFRCxRQUFNQyxJQUFJLEdBQUcsa0NBQWI7O0FBQ0EsTUFBSSxDQUFDYixRQUFRLENBQUNjLEtBQVQsQ0FBZUQsSUFBZixDQUFMLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUgsY0FBTUMsS0FBVixDQUNMRCxjQUFNQyxLQUFOLENBQVlDLGlCQURQLEVBRUwsdUNBRkssQ0FBUDtBQUlEOztBQUNELFNBQU8sSUFBUDtBQUNEOztlQUVjZCxZIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLy8gRmlsZXMgQWRhcHRlclxuLy9cbi8vIEFsbG93cyB5b3UgdG8gY2hhbmdlIHRoZSBmaWxlIHN0b3JhZ2UgbWVjaGFuaXNtLlxuLy9cbi8vIEFkYXB0ZXIgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogY3JlYXRlRmlsZShmaWxlbmFtZSwgZGF0YSwgY29udGVudFR5cGUpXG4vLyAqIGRlbGV0ZUZpbGUoZmlsZW5hbWUpXG4vLyAqIGdldEZpbGVEYXRhKGZpbGVuYW1lKVxuLy8gKiBnZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSlcbi8vIEFkYXB0ZXIgY2xhc3NlcyBzaG91bGQgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuLy8gKiB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKVxuLy8gKiBoYW5kbGVGaWxlU3RyZWFtKGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpXG4vL1xuLy8gRGVmYXVsdCBpcyBHcmlkRlNCdWNrZXRBZGFwdGVyLCB3aGljaCByZXF1aXJlcyBtb25nb1xuLy8gYW5kIGZvciB0aGUgQVBJIHNlcnZlciB0byBiZSB1c2luZyB0aGUgRGF0YWJhc2VDb250cm9sbGVyIHdpdGggTW9uZ29cbi8vIGRhdGFiYXNlIGFkYXB0ZXIuXG5cbmltcG9ydCB0eXBlIHsgQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29uZmlnJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgRmlsZXNBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWxlc0FkYXB0ZXIge1xuICAvKiogUmVzcG9uc2libGUgZm9yIHN0b3JpbmcgdGhlIGZpbGUgaW4gb3JkZXIgdG8gYmUgcmV0cmlldmVkIGxhdGVyIGJ5IGl0cyBmaWxlbmFtZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSB0aGUgZmlsZW5hbWUgdG8gc2F2ZVxuICAgKiBAcGFyYW0geyp9IGRhdGEgLSB0aGUgYnVmZmVyIG9mIGRhdGEgZnJvbSB0aGUgZmlsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudFR5cGUgLSB0aGUgc3VwcG9zZWQgY29udGVudFR5cGVcbiAgICogQGRpc2N1c3Npb24gdGhlIGNvbnRlbnRUeXBlIGNhbiBiZSB1bmRlZmluZWQgaWYgdGhlIGNvbnRyb2xsZXIgd2FzIG5vdCBhYmxlIHRvIGRldGVybWluZSBpdFxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIChPcHRpb25hbCkgb3B0aW9ucyB0byBiZSBwYXNzZWQgdG8gZmlsZSBhZGFwdGVyIChTMyBGaWxlIEFkYXB0ZXIgT25seSlcbiAgICogLSB0YWdzOiBvYmplY3QgY29udGFpbmluZyBrZXkgdmFsdWUgcGFpcnMgdGhhdCB3aWxsIGJlIHN0b3JlZCB3aXRoIGZpbGVcbiAgICogLSBtZXRhZGF0YTogb2JqZWN0IGNvbnRhaW5pbmcga2V5IHZhbHVlIHBhaXJzIHRoYXQgd2lsbCBiZSBzb3RyZWQgd2l0aCBmaWxlIChodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L3VzZXItZ3VpZGUvYWRkLW9iamVjdC1tZXRhZGF0YS5odG1sKVxuICAgKiBAZGlzY3Vzc2lvbiBvcHRpb25zIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IGFsbCBmaWxlIGFkYXB0ZXJzLiBDaGVjayB0aGUgeW91ciBhZGFwdGVyJ3MgZG9jdW1lbnRhdGlvbiBmb3IgY29tcGF0aWJpbGl0eVxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCBzaG91bGQgZmFpbCBpZiB0aGUgc3RvcmFnZSBkaWRuJ3Qgc3VjY2VlZFxuICAgKi9cbiAgY3JlYXRlRmlsZShcbiAgICBmaWxlbmFtZTogc3RyaW5nLFxuICAgIGRhdGEsXG4gICAgY29udGVudFR5cGU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBPYmplY3RcbiAgKTogUHJvbWlzZSB7fVxuXG4gIC8qKiBSZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgdGhlIHNwZWNpZmllZCBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byBkZWxldGVcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgc2hvdWxkIGZhaWwgaWYgdGhlIGRlbGV0aW9uIGRpZG4ndCBzdWNjZWVkXG4gICAqL1xuICBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpOiBQcm9taXNlIHt9XG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgZmlsZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSB0aGUgbmFtZSBvZiBmaWxlIHRvIHJldHJpZXZlXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSB0aGF0IHNob3VsZCBwYXNzIHdpdGggdGhlIGZpbGUgZGF0YSBvciBmYWlsIG9uIGVycm9yXG4gICAqL1xuICBnZXRGaWxlRGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG5cbiAgLyoqIFJldHVybnMgYW4gYWJzb2x1dGUgVVJMIHdoZXJlIHRoZSBmaWxlIGNhbiBiZSBhY2Nlc3NlZFxuICAgKlxuICAgKiBAcGFyYW0ge0NvbmZpZ30gY29uZmlnIC0gc2VydmVyIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQWJzb2x1dGUgVVJMXG4gICAqL1xuICBnZXRGaWxlTG9jYXRpb24oY29uZmlnOiBDb25maWcsIGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge31cblxuICAvKiogVmFsaWRhdGUgYSBmaWxlbmFtZSBmb3IgdGhpcyBhZGFwdGVyIHR5cGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfSBudWxsIGlmIHRoZXJlIGFyZSBubyBlcnJvcnNcbiAgICovXG4gIC8vIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWU6IHN0cmluZyk6ID9QYXJzZS5FcnJvciB7fVxuXG4gIC8qKiBIYW5kbGVzIEJ5dGUtUmFuZ2UgUmVxdWVzdHMgZm9yIFN0cmVhbWluZ1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWVcbiAgICogQHBhcmFtIHtvYmplY3R9IHJlcVxuICAgKiBAcGFyYW0ge29iamVjdH0gcmVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50VHlwZVxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gRGF0YSBmb3IgYnl0ZSByYW5nZVxuICAgKi9cbiAgLy8gaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZTogc3RyaW5nLCByZXM6IGFueSwgcmVxOiBhbnksIGNvbnRlbnRUeXBlOiBzdHJpbmcpOiBQcm9taXNlXG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIG1ldGFkYXRhIGFuZCB0YWdzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byByZXRyaWV2ZSBtZXRhZGF0YVxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCBzaG91bGQgcGFzcyB3aXRoIG1ldGFkYXRhXG4gICAqL1xuICAvLyBnZXRNZXRhZGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG59XG5cbi8qKlxuICogU2ltcGxlIGZpbGVuYW1lIHZhbGlkYXRpb25cbiAqXG4gKiBAcGFyYW0gZmlsZW5hbWVcbiAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk6ID9QYXJzZS5FcnJvciB7XG4gIGlmIChmaWxlbmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCAnRmlsZW5hbWUgdG9vIGxvbmcuJyk7XG4gIH1cblxuICBjb25zdCByZWd4ID0gL15bX2EtekEtWjAtOV1bYS16QS1aMC05QC4gfl8tXSokLztcbiAgaWYgKCFmaWxlbmFtZS5tYXRjaChyZWd4KSkge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSxcbiAgICAgICdGaWxlbmFtZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJ1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGVzQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Files/GridFSBucketAdapter.js b/lib/Adapters/Files/GridFSBucketAdapter.js new file mode 100644 index 0000000000..e6abe0c03f --- /dev/null +++ b/lib/Adapters/Files/GridFSBucketAdapter.js @@ -0,0 +1,273 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GridFSBucketAdapter = void 0; + +var _mongodb = require("mongodb"); + +var _FilesAdapter = require("./FilesAdapter"); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + GridFSBucketAdapter + Stores files in Mongo using GridStore + Requires the database adapter to be based on mongoclient + + + */ +// -disable-next +const crypto = require('crypto'); + +class GridFSBucketAdapter extends _FilesAdapter.FilesAdapter { + constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}, encryptionKey = undefined) { + super(); + this._databaseURI = mongoDatabaseURI; + this._algorithm = 'aes-256-gcm'; + this._encryptionKey = encryptionKey !== undefined ? crypto.createHash('sha256').update(String(encryptionKey)).digest('base64').substr(0, 32) : null; + const defaultMongoOptions = { + useNewUrlParser: true, + useUnifiedTopology: true + }; + this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); + } + + _connect() { + if (!this._connectionPromise) { + this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { + this._client = client; + return client.db(client.s.options.dbName); + }); + } + + return this._connectionPromise; + } + + _getBucket() { + return this._connect().then(database => new _mongodb.GridFSBucket(database)); + } // For a given config object, filename, and data, store a file + // Returns a promise + + + async createFile(filename, data, contentType, options = {}) { + const bucket = await this._getBucket(); + const stream = await bucket.openUploadStream(filename, { + metadata: options.metadata + }); + + if (this._encryptionKey !== null) { + try { + const iv = crypto.randomBytes(16); + const cipher = crypto.createCipheriv(this._algorithm, this._encryptionKey, iv); + const encryptedResult = Buffer.concat([cipher.update(data), cipher.final(), iv, cipher.getAuthTag()]); + await stream.write(encryptedResult); + } catch (err) { + return new Promise((resolve, reject) => { + return reject(err); + }); + } + } else { + await stream.write(data); + } + + stream.end(); + return new Promise((resolve, reject) => { + stream.on('finish', resolve); + stream.on('error', reject); + }); + } + + async deleteFile(filename) { + const bucket = await this._getBucket(); + const documents = await bucket.find({ + filename + }).toArray(); + + if (documents.length === 0) { + throw new Error('FileNotFound'); + } + + return Promise.all(documents.map(doc => { + return bucket.delete(doc._id); + })); + } + + async getFileData(filename) { + const bucket = await this._getBucket(); + const stream = bucket.openDownloadStreamByName(filename); + stream.read(); + return new Promise((resolve, reject) => { + const chunks = []; + stream.on('data', data => { + chunks.push(data); + }); + stream.on('end', () => { + const data = Buffer.concat(chunks); + + if (this._encryptionKey !== null) { + try { + const authTagLocation = data.length - 16; + const ivLocation = data.length - 32; + const authTag = data.slice(authTagLocation); + const iv = data.slice(ivLocation, authTagLocation); + const encrypted = data.slice(0, ivLocation); + const decipher = crypto.createDecipheriv(this._algorithm, this._encryptionKey, iv); + decipher.setAuthTag(authTag); + const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]); + return resolve(decrypted); + } catch (err) { + return reject(err); + } + } + + resolve(data); + }); + stream.on('error', err => { + reject(err); + }); + }); + } + + async rotateEncryptionKey(options = {}) { + var fileNames = []; + var oldKeyFileAdapter = {}; + const bucket = await this._getBucket(); + + if (options.oldKey !== undefined) { + oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions, options.oldKey); + } else { + oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions); + } + + if (options.fileNames !== undefined) { + fileNames = options.fileNames; + } else { + const fileNamesIterator = await bucket.find().toArray(); + fileNamesIterator.forEach(file => { + fileNames.push(file.filename); + }); + } + + return new Promise(resolve => { + var fileNamesNotRotated = fileNames; + var fileNamesRotated = []; + var fileNameTotal = fileNames.length; + var fileNameIndex = 0; + fileNames.forEach(fileName => { + oldKeyFileAdapter.getFileData(fileName).then(plainTextData => { + //Overwrite file with data encrypted with new key + this.createFile(fileName, plainTextData).then(() => { + fileNamesRotated.push(fileName); + fileNamesNotRotated = fileNamesNotRotated.filter(function (value) { + return value !== fileName; + }); + fileNameIndex += 1; + + if (fileNameIndex == fileNameTotal) { + resolve({ + rotated: fileNamesRotated, + notRotated: fileNamesNotRotated + }); + } + }).catch(() => { + fileNameIndex += 1; + + if (fileNameIndex == fileNameTotal) { + resolve({ + rotated: fileNamesRotated, + notRotated: fileNamesNotRotated + }); + } + }); + }).catch(() => { + fileNameIndex += 1; + + if (fileNameIndex == fileNameTotal) { + resolve({ + rotated: fileNamesRotated, + notRotated: fileNamesNotRotated + }); + } + }); + }); + }); + } + + getFileLocation(config, filename) { + return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); + } + + async getMetadata(filename) { + const bucket = await this._getBucket(); + const files = await bucket.find({ + filename + }).toArray(); + + if (files.length === 0) { + return {}; + } + + const { + metadata + } = files[0]; + return { + metadata + }; + } + + async handleFileStream(filename, req, res, contentType) { + const bucket = await this._getBucket(); + const files = await bucket.find({ + filename + }).toArray(); + + if (files.length === 0) { + throw new Error('FileNotFound'); + } + + const parts = req.get('Range').replace(/bytes=/, '').split('-'); + const partialstart = parts[0]; + const partialend = parts[1]; + const start = parseInt(partialstart, 10); + const end = partialend ? parseInt(partialend, 10) : files[0].length - 1; + res.writeHead(206, { + 'Accept-Ranges': 'bytes', + 'Content-Length': end - start + 1, + 'Content-Range': 'bytes ' + start + '-' + end + '/' + files[0].length, + 'Content-Type': contentType + }); + const stream = bucket.openDownloadStreamByName(filename); + stream.start(start); + stream.on('data', chunk => { + res.write(chunk); + }); + stream.on('error', () => { + res.sendStatus(404); + }); + stream.on('end', () => { + res.end(); + }); + } + + handleShutdown() { + if (!this._client) { + return Promise.resolve(); + } + + return this._client.close(false); + } + + validateFilename(filename) { + return (0, _FilesAdapter.validateFilename)(filename); + } + +} + +exports.GridFSBucketAdapter = GridFSBucketAdapter; +var _default = GridFSBucketAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkRlNCdWNrZXRBZGFwdGVyLmpzIl0sIm5hbWVzIjpbImNyeXB0byIsInJlcXVpcmUiLCJHcmlkRlNCdWNrZXRBZGFwdGVyIiwiRmlsZXNBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJtb25nb0RhdGFiYXNlVVJJIiwiZGVmYXVsdHMiLCJEZWZhdWx0TW9uZ29VUkkiLCJtb25nb09wdGlvbnMiLCJlbmNyeXB0aW9uS2V5IiwidW5kZWZpbmVkIiwiX2RhdGFiYXNlVVJJIiwiX2FsZ29yaXRobSIsIl9lbmNyeXB0aW9uS2V5IiwiY3JlYXRlSGFzaCIsInVwZGF0ZSIsIlN0cmluZyIsImRpZ2VzdCIsInN1YnN0ciIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJfZ2V0QnVja2V0IiwiZGF0YWJhc2UiLCJHcmlkRlNCdWNrZXQiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJidWNrZXQiLCJzdHJlYW0iLCJvcGVuVXBsb2FkU3RyZWFtIiwibWV0YWRhdGEiLCJpdiIsInJhbmRvbUJ5dGVzIiwiY2lwaGVyIiwiY3JlYXRlQ2lwaGVyaXYiLCJlbmNyeXB0ZWRSZXN1bHQiLCJCdWZmZXIiLCJjb25jYXQiLCJmaW5hbCIsImdldEF1dGhUYWciLCJ3cml0ZSIsImVyciIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZW5kIiwib24iLCJkZWxldGVGaWxlIiwiZG9jdW1lbnRzIiwiZmluZCIsInRvQXJyYXkiLCJsZW5ndGgiLCJFcnJvciIsImFsbCIsIm1hcCIsImRvYyIsImRlbGV0ZSIsIl9pZCIsImdldEZpbGVEYXRhIiwib3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lIiwicmVhZCIsImNodW5rcyIsInB1c2giLCJhdXRoVGFnTG9jYXRpb24iLCJpdkxvY2F0aW9uIiwiYXV0aFRhZyIsInNsaWNlIiwiZW5jcnlwdGVkIiwiZGVjaXBoZXIiLCJjcmVhdGVEZWNpcGhlcml2Iiwic2V0QXV0aFRhZyIsImRlY3J5cHRlZCIsInJvdGF0ZUVuY3J5cHRpb25LZXkiLCJmaWxlTmFtZXMiLCJvbGRLZXlGaWxlQWRhcHRlciIsIm9sZEtleSIsImZpbGVOYW1lc0l0ZXJhdG9yIiwiZm9yRWFjaCIsImZpbGUiLCJmaWxlTmFtZXNOb3RSb3RhdGVkIiwiZmlsZU5hbWVzUm90YXRlZCIsImZpbGVOYW1lVG90YWwiLCJmaWxlTmFtZUluZGV4IiwiZmlsZU5hbWUiLCJwbGFpblRleHREYXRhIiwiZmlsdGVyIiwidmFsdWUiLCJyb3RhdGVkIiwibm90Um90YXRlZCIsImNhdGNoIiwiZ2V0RmlsZUxvY2F0aW9uIiwiY29uZmlnIiwibW91bnQiLCJhcHBsaWNhdGlvbklkIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwiZ2V0TWV0YWRhdGEiLCJmaWxlcyIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInBhcnRpYWxzdGFydCIsInBhcnRpYWxlbmQiLCJzdGFydCIsInBhcnNlSW50Iiwid3JpdGVIZWFkIiwiY2h1bmsiLCJzZW5kU3RhdHVzIiwiaGFuZGxlU2h1dGRvd24iLCJjbG9zZSIsInZhbGlkYXRlRmlsZW5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFTQTs7QUFDQTs7QUFDQTs7OztBQVhBOzs7Ozs7O0FBUUE7QUFJQSxNQUFNQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUVPLE1BQU1DLG1CQUFOLFNBQWtDQywwQkFBbEMsQ0FBK0M7QUFNcERDLEVBQUFBLFdBQVcsQ0FDVEMsZ0JB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QUZEO0FBR0FqRixJQUFBQSxNQUFNLENBQUNrQixFQUFQLENBQVUsT0FBVixFQUFtQixNQUFNO0FBQ3ZCcUQsTUFBQUEsR0FBRyxDQUFDVyxVQUFKLENBQWUsR0FBZjtBQUNELEtBRkQ7QUFHQWxGLElBQUFBLE1BQU0sQ0FBQ2tCLEVBQVAsQ0FBVSxLQUFWLEVBQWlCLE1BQU07QUFDckJxRCxNQUFBQSxHQUFHLENBQUN0RCxHQUFKO0FBQ0QsS0FGRDtBQUdEOztBQUVEa0UsRUFBQUEsY0FBYyxHQUFHO0FBQ2YsUUFBSSxDQUFDLEtBQUtoRyxPQUFWLEVBQW1CO0FBQ2pCLGFBQU8yQixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFdBQU8sS0FBSzVCLE9BQUwsQ0FBYWlHLEtBQWIsQ0FBbUIsS0FBbkIsQ0FBUDtBQUNEOztBQUVEQyxFQUFBQSxnQkFBZ0IsQ0FBQ3pGLFFBQUQsRUFBVztBQUN6QixXQUFPLG9DQUFpQkEsUUFBakIsQ0FBUDtBQUNEOztBQWxSbUQ7OztlQXFSdkN0QyxtQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuIEdyaWRGU0J1Y2tldEFkYXB0ZXJcbiBTdG9yZXMgZmlsZXMgaW4gTW9uZ28gdXNpbmcgR3JpZFN0b3JlXG4gUmVxdWlyZXMgdGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gYmUgYmFzZWQgb24gbW9uZ29jbGllbnRcblxuIEBmbG93IHdlYWtcbiAqL1xuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IE1vbmdvQ2xpZW50LCBHcmlkRlNCdWNrZXQsIERiIH0gZnJvbSAnbW9uZ29kYic7XG5pbXBvcnQgeyBGaWxlc0FkYXB0ZXIsIHZhbGlkYXRlRmlsZW5hbWUgfSBmcm9tICcuL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuY29uc3QgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbmV4cG9ydCBjbGFzcyBHcmlkRlNCdWNrZXRBZGFwdGVyIGV4dGVuZHMgRmlsZXNBZGFwdGVyIHtcbiAgX2RhdGFiYXNlVVJJOiBzdHJpbmc7XG4gIF9jb25uZWN0aW9uUHJvbWlzZTogUHJvbWlzZTxEYj47XG4gIF9tb25nb09wdGlvbnM6IE9iamVjdDtcbiAgX2FsZ29yaXRobTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1vbmdvRGF0YWJhc2VVUkkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksXG4gICAgbW9uZ29PcHRpb25zID0ge30sXG4gICAgZW5jcnlwdGlvbktleSA9IHVuZGVmaW5lZFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RhdGFiYXNlVVJJID0gbW9uZ29EYXRhYmFzZVVSSTtcbiAgICB0aGlzLl9hbGdvcml0aG0gPSAnYWVzLTI1Ni1nY20nO1xuICAgIHRoaXMuX2VuY3J5cHRpb25LZXkgPVxuICAgICAgZW5jcnlwdGlvbktleSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gY3J5cHRvXG4gICAgICAgICAgLmNyZWF0ZUhhc2goJ3NoYTI1NicpXG4gICAgICAgICAgLnVwZGF0ZShTdHJpbmcoZW5jcnlwdGlvbktleSkpXG4gICAgICAgICAgLmRpZ2VzdCgnYmFzZTY0JylcbiAgICAgICAgICAuc3Vic3RyKDAsIDMyKVxuICAgICAgICA6IG51bGw7XG4gICAgY29uc3QgZGVmYXVsdE1vbmdvT3B0aW9ucyA9IHtcbiAgICAgIHVzZU5ld1VybFBhcnNlcjogdHJ1ZSxcbiAgICAgIHVzZVVuaWZpZWRUb3BvbG9neTogdHJ1ZSxcbiAgICB9O1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdE1vbmdvT3B0aW9ucywgbW9uZ29PcHRpb25zKTtcbiAgfVxuXG4gIF9jb25uZWN0KCkge1xuICAgIGlmICghdGhpcy5fY29ubmVjdGlvblByb21pc2UpIHtcbiAgICAgIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlID0gTW9uZ29DbGllbnQuY29ubmVjdChcbiAgICAgICAgdGhpcy5fZGF0YWJhc2VVUkksXG4gICAgICAgIHRoaXMuX21vbmdvT3B0aW9uc1xuICAgICAgKS50aGVuKGNsaWVudCA9PiB7XG4gICAgICAgIHRoaXMuX2NsaWVudCA9IGNsaWVudDtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kYihjbGllbnQucy5vcHRpb25zLmRiTmFtZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlO1xuICB9XG5cbiAgX2dldEJ1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpLnRoZW4oZGF0YWJhc2UgPT4gbmV3IEdyaWRGU0J1Y2tldChkYXRhYmFzZSkpO1xuICB9XG5cbiAgLy8gRm9yIGEgZ2l2ZW4gY29uZmlnIG9iamVjdCwgZmlsZW5hbWUsIGFuZCBkYXRhLCBzdG9yZSBhIGZpbGVcbiAgLy8gUmV0dXJucyBhIHByb21pc2VcbiAgYXN5bmMgY3JlYXRlRmlsZShmaWxlbmFtZTogc3RyaW5nLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgYnVja2V0Lm9wZW5VcGxvYWRTdHJlYW0oZmlsZW5hbWUsIHtcbiAgICAgIG1ldGFkYXRhOiBvcHRpb25zLm1ldGFkYXRhLFxuICAgIH0pO1xuICAgIGlmICh0aGlzLl9lbmNyeXB0aW9uS2V5ICE9PSBudWxsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpdiA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXJpdihcbiAgICAgICAgICB0aGlzLl9hbGdvcml0aG0sXG4gICAgICAgICAgdGhpcy5fZW5jcnlwdGlvbktleSxcbiAgICAgICAgICBpdlxuICAgICAgICApO1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRSZXN1bHQgPSBCdWZmZXIuY29uY2F0KFtcbiAgICAgICAgICBjaXBoZXIudXBkYXRlKGRhdGEpLFxuICAgICAgICAgIGNpcGhlci5maW5hbCgpLFxuICAgICAgICAgIGl2LFxuICAgICAgICAgIGNpcGhlci5nZXRBdXRoVGFnKCksXG4gICAgICAgIF0pO1xuICAgICAgICBhd2FpdCBzdHJlYW0ud3JpdGUoZW5jcnlwdGVkUmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHN0cmVhbS53cml0ZShkYXRhKTtcbiAgICB9XG4gICAgc3RyZWFtLmVuZCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBzdHJlYW0ub24oJ2ZpbmlzaCcsIHJlc29sdmUpO1xuICAgICAgc3RyZWFtLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBkb2N1bWVudHMgPSBhd2FpdCBidWNrZXQuZmluZCh7IGZpbGVuYW1lIH0pLnRvQXJyYXkoKTtcbiAgICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGaWxlTm90Rm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgZG9jdW1lbnRzLm1hcChkb2MgPT4ge1xuICAgICAgICByZXR1cm4gYnVja2V0LmRlbGV0ZShkb2MuX2lkKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGdldEZpbGVEYXRhKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBzdHJlYW0gPSBidWNrZXQub3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lKGZpbGVuYW1lKTtcbiAgICBzdHJlYW0ucmVhZCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIHN0cmVhbS5vbignZGF0YScsIGRhdGEgPT4ge1xuICAgICAgICBjaHVua3MucHVzaChkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBCdWZmZXIuY29uY2F0KGNodW5rcyk7XG4gICAgICAgIGlmICh0aGlzLl9lbmNyeXB0aW9uS2V5ICE9PSBudWxsKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGF1dGhUYWdMb2NhdGlvbiA9IGRhdGEubGVuZ3RoIC0gMTY7XG4gICAgICAgICAgICBjb25zdCBpdkxvY2F0aW9uID0gZGF0YS5sZW5ndGggLSAzMjtcbiAgICAgICAgICAgIGNvbnN0IGF1dGhUYWcgPSBkYXRhLnNsaWNlKGF1dGhUYWdMb2NhdGlvbik7XG4gICAgICAgICAgICBjb25zdCBpdiA9IGRhdGEuc2xpY2UoaXZMb2NhdGlvbiwgYXV0aFRhZ0xvY2F0aW9uKTtcbiAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZCA9IGRhdGEuc2xpY2UoMCwgaXZMb2NhdGlvbik7XG4gICAgICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0by5jcmVhdGVEZWNpcGhlcml2KFxuICAgICAgICAgICAgICB0aGlzLl9hbGdvcml0aG0sXG4gICAgICAgICAgICAgIHRoaXMuX2VuY3J5cHRpb25LZXksXG4gICAgICAgICAgICAgIGl2XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZGVjaXBoZXIuc2V0QXV0aFRhZyhhdXRoVGFnKTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IEJ1ZmZlci5jb25jYXQoW1xuICAgICAgICAgICAgICBkZWNpcGhlci51cGRhdGUoZW5jcnlwdGVkKSxcbiAgICAgICAgICAgICAgZGVjaXBoZXIuZmluYWwoKSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGVjcnlwdGVkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdlcnJvcicsIGVyciA9PiB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyByb3RhdGVFbmNyeXB0aW9uS2V5KG9wdGlvbnMgPSB7fSkge1xuICAgIHZhciBmaWxlTmFtZXMgPSBbXTtcbiAgICB2YXIgb2xkS2V5RmlsZUFkYXB0ZXIgPSB7fTtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBpZiAob3B0aW9ucy5vbGRLZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2xkS2V5RmlsZUFkYXB0ZXIgPSBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihcbiAgICAgICAgdGhpcy5fZGF0YWJhc2VVUkksXG4gICAgICAgIHRoaXMuX21vbmdvT3B0aW9ucyxcbiAgICAgICAgb3B0aW9ucy5vbGRLZXlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZEtleUZpbGVBZGFwdGVyID0gbmV3IEdyaWRGU0J1Y2tldEFkYXB0ZXIoXG4gICAgICAgIHRoaXMuX2RhdGFiYXNlVVJJLFxuICAgICAgICB0aGlzLl9tb25nb09wdGlvbnNcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmZpbGVOYW1lcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlTmFtZXMgPSBvcHRpb25zLmZpbGVOYW1lcztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZmlsZU5hbWVzSXRlcmF0b3IgPSBhd2FpdCBidWNrZXQuZmluZCgpLnRvQXJyYXkoKTtcbiAgICAgIGZpbGVOYW1lc0l0ZXJhdG9yLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgIGZpbGVOYW1lcy5wdXNoKGZpbGUuZmlsZW5hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHZhciBmaWxlTmFtZXNOb3RSb3RhdGVkID0gZmlsZU5hbWVzO1xuICAgICAgdmFyIGZpbGVOYW1lc1JvdGF0ZWQgPSBbXTtcbiAgICAgIHZhciBmaWxlTmFtZVRvdGFsID0gZmlsZU5hbWVzLmxlbmd0aDtcbiAgICAgIHZhciBmaWxlTmFtZUluZGV4ID0gMDtcbiAgICAgIGZpbGVOYW1lcy5mb3JFYWNoKGZpbGVOYW1lID0+IHtcbiAgICAgICAgb2xkS2V5RmlsZUFkYXB0ZXJcbiAgICAgICAgICAuZ2V0RmlsZURhdGEoZmlsZU5hbWUpXG4gICAgICAgICAgLnRoZW4ocGxhaW5UZXh0RGF0YSA9PiB7XG4gICAgICAgICAgICAvL092ZXJ3cml0ZSBmaWxlIHdpdGggZGF0YSBlbmNyeXB0ZWQgd2l0aCBuZXcga2V5XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUZpbGUoZmlsZU5hbWUsIHBsYWluVGV4dERhdGEpXG4gICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZXNSb3RhdGVkLnB1c2goZmlsZU5hbWUpO1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lc05vdFJvdGF0ZWQgPSBmaWxlTmFtZXNOb3RSb3RhdGVkLmZpbHRlcihmdW5jdGlvbiAoXG4gICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlICE9PSBmaWxlTmFtZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZUluZGV4ICs9IDE7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lSW5kZXggPT0gZmlsZU5hbWVUb3RhbCkge1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHJvdGF0ZWQ6IGZpbGVOYW1lc1JvdGF0ZWQsXG4gICAgICAgICAgICAgICAgICAgIG5vdFJvdGF0ZWQ6IGZpbGVOYW1lc05vdFJvdGF0ZWQsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgZmlsZU5hbWVJbmRleCArPSAxO1xuICAgICAgICAgICAgICAgIGlmIChmaWxlTmFtZUluZGV4ID09IGZpbGVOYW1lVG90YWwpIHtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICByb3RhdGVkOiBmaWxlTmFtZXNSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgICBub3RSb3RhdGVkOiBmaWxlTmFtZXNOb3RSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICBmaWxlTmFtZUluZGV4ICs9IDE7XG4gICAgICAgICAgICBpZiAoZmlsZU5hbWVJbmRleCA9PSBmaWxlTmFtZVRvdGFsKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgIHJvdGF0ZWQ6IGZpbGVOYW1lc1JvdGF0ZWQsXG4gICAgICAgICAgICAgICAgbm90Um90YXRlZDogZmlsZU5hbWVzTm90Um90YXRlZCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGNvbmZpZy5tb3VudCArXG4gICAgICAnL2ZpbGVzLycgK1xuICAgICAgY29uZmlnLmFwcGxpY2F0aW9uSWQgK1xuICAgICAgJy8nICtcbiAgICAgIGVuY29kZVVSSUNvbXBvbmVudChmaWxlbmFtZSlcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0TWV0YWRhdGEoZmlsZW5hbWUpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IGJ1Y2tldC5maW5kKHsgZmlsZW5hbWUgfSkudG9BcnJheSgpO1xuICAgIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3QgeyBtZXRhZGF0YSB9ID0gZmlsZXNbMF07XG4gICAgcmV0dXJuIHsgbWV0YWRhdGEgfTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUZpbGVTdHJlYW0oZmlsZW5hbWU6IHN0cmluZywgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCBidWNrZXQuZmluZCh7IGZpbGVuYW1lIH0pLnRvQXJyYXkoKTtcbiAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpbGVOb3RGb3VuZCcpO1xuICAgIH1cbiAgICBjb25zdCBwYXJ0cyA9IHJlcVxuICAgICAgLmdldCgnUmFuZ2UnKVxuICAgICAgLnJlcGxhY2UoL2J5dGVzPS8sICcnKVxuICAgICAgLnNwbGl0KCctJyk7XG4gICAgY29uc3QgcGFydGlhbHN0YXJ0ID0gcGFydHNbMF07XG4gICAgY29uc3QgcGFydGlhbGVuZCA9IHBhcnRzWzFdO1xuXG4gICAgY29uc3Qgc3RhcnQgPSBwYXJzZUludChwYXJ0aWFsc3RhcnQsIDEwKTtcbiAgICBjb25zdCBlbmQgPSBwYXJ0aWFsZW5kID8gcGFyc2VJbnQocGFydGlhbGVuZCwgMTApIDogZmlsZXNbMF0ubGVuZ3RoIC0gMTtcblxuICAgIHJlcy53cml0ZUhlYWQoMjA2LCB7XG4gICAgICAnQWNjZXB0LVJhbmdlcyc6ICdieXRlcycsXG4gICAgICAnQ29udGVudC1MZW5ndGgnOiBlbmQgLSBzdGFydCArIDEsXG4gICAgICAnQ29udGVudC1SYW5nZSc6ICdieXRlcyAnICsgc3RhcnQgKyAnLScgKyBlbmQgKyAnLycgKyBmaWxlc1swXS5sZW5ndGgsXG4gICAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gICAgfSk7XG4gICAgY29uc3Qgc3RyZWFtID0gYnVja2V0Lm9wZW5Eb3dubG9hZFN0cmVhbUJ5TmFtZShmaWxlbmFtZSk7XG4gICAgc3RyZWFtLnN0YXJ0KHN0YXJ0KTtcbiAgICBzdHJlYW0ub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICByZXMud3JpdGUoY2h1bmspO1xuICAgIH0pO1xuICAgIHN0cmVhbS5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICByZXMuc2VuZFN0YXR1cyg0MDQpO1xuICAgIH0pO1xuICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgcmVzLmVuZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLl9jbGllbnQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdyaWRGU0J1Y2tldEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Files/GridStoreAdapter.js b/lib/Adapters/Files/GridStoreAdapter.js new file mode 100644 index 0000000000..5ff3c1e0e3 --- /dev/null +++ b/lib/Adapters/Files/GridStoreAdapter.js @@ -0,0 +1,182 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GridStoreAdapter = void 0; + +var _mongodb = require("mongodb"); + +var _FilesAdapter = require("./FilesAdapter"); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + GridStoreAdapter + Stores files in Mongo using GridStore + Requires the database adapter to be based on mongoclient + (GridStore is deprecated, Please use GridFSBucket instead) + + + */ +// -disable-next +class GridStoreAdapter extends _FilesAdapter.FilesAdapter { + constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}) { + super(); + this._databaseURI = mongoDatabaseURI; + const defaultMongoOptions = { + useNewUrlParser: true, + useUnifiedTopology: true + }; + this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); + } + + _connect() { + if (!this._connectionPromise) { + this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { + this._client = client; + return client.db(client.s.options.dbName); + }); + } + + return this._connectionPromise; + } // For a given config object, filename, and data, store a file + // Returns a promise + + + createFile(filename, data) { + return this._connect().then(database => { + const gridStore = new _mongodb.GridStore(database, filename, 'w'); + return gridStore.open(); + }).then(gridStore => { + return gridStore.write(data); + }).then(gridStore => { + return gridStore.close(); + }); + } + + deleteFile(filename) { + return this._connect().then(database => { + const gridStore = new _mongodb.GridStore(database, filename, 'r'); + return gridStore.open(); + }).then(gridStore => { + return gridStore.unlink(); + }).then(gridStore => { + return gridStore.close(); + }); + } + + getFileData(filename) { + return this._connect().then(database => { + return _mongodb.GridStore.exist(database, filename).then(() => { + const gridStore = new _mongodb.GridStore(database, filename, 'r'); + return gridStore.open(); + }); + }).then(gridStore => { + return gridStore.read(); + }); + } + + getFileLocation(config, filename) { + return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); + } + + async handleFileStream(filename, req, res, contentType) { + const stream = await this._connect().then(database => { + return _mongodb.GridStore.exist(database, filename).then(() => { + const gridStore = new _mongodb.GridStore(database, filename, 'r'); + return gridStore.open(); + }); + }); + handleRangeRequest(stream, req, res, contentType); + } + + handleShutdown() { + if (!this._client) { + return Promise.resolve(); + } + + return this._client.close(false); + } + + validateFilename(filename) { + return (0, _FilesAdapter.validateFilename)(filename); + } + +} // handleRangeRequest is licensed under Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). +// Author: LEROIB at weightingformypizza (https://weightingformypizza.wordpress.com/2015/06/24/stream-html5-media-content-like-video-audio-from-mongodb-using-express-and-gridstore/). + + +exports.GridStoreAdapter = GridStoreAdapter; + +function handleRangeRequest(stream, req, res, contentType) { + const buffer_size = 1024 * 1024; //1024Kb + // Range request, partial stream the file + + const parts = req.get('Range').replace(/bytes=/, '').split('-'); + let [start, end] = parts; + const notEnded = !end && end !== 0; + const notStarted = !start && start !== 0; // No end provided, we want all bytes + + if (notEnded) { + end = stream.length - 1; + } // No start provided, we're reading backwards + + + if (notStarted) { + start = stream.length - end; + end = start + end - 1; + } // Data exceeds the buffer_size, cap + + + if (end - start >= buffer_size) { + end = start + buffer_size - 1; + } + + const contentLength = end - start + 1; + res.writeHead(206, { + 'Content-Range': 'bytes ' + start + '-' + end + '/' + stream.length, + 'Accept-Ranges': 'bytes', + 'Content-Length': contentLength, + 'Content-Type': contentType + }); + stream.seek(start, function () { + // Get gridFile stream + const gridFileStream = stream.stream(true); + let bufferAvail = 0; + let remainingBytesToWrite = contentLength; + let totalBytesWritten = 0; // Write to response + + gridFileStream.on('data', function (data) { + bufferAvail += data.length; + + if (bufferAvail > 0) { + // slice returns the same buffer if overflowing + // safe to call in any case + const buffer = data.slice(0, remainingBytesToWrite); // Write the buffer + + res.write(buffer); // Increment total + + totalBytesWritten += buffer.length; // Decrement remaining + + remainingBytesToWrite -= data.length; // Decrement the available buffer + + bufferAvail -= buffer.length; + } // In case of small slices, all values will be good at that point + // we've written enough, end... + + + if (totalBytesWritten >= contentLength) { + stream.close(); + res.end(); + this.destroy(); + } + }); + }); +} + +var _default = GridStoreAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkU3RvcmVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkdyaWRTdG9yZUFkYXB0ZXIiLCJGaWxlc0FkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsIm1vbmdvRGF0YWJhc2VVUkkiLCJkZWZhdWx0cyIsIkRlZmF1bHRNb25nb1VSSSIsIm1vbmdvT3B0aW9ucyIsIl9kYXRhYmFzZVVSSSIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiZGF0YWJhc2UiLCJncmlkU3RvcmUiLCJHcmlkU3RvcmUiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsImRlbGV0ZUZpbGUiLCJ1bmxpbmsiLCJnZXRGaWxlRGF0YSIsImV4aXN0IiwicmVhZCIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsIm1vdW50IiwiYXBwbGljYXRpb25JZCIsImVuY29kZVVSSUNvbXBvbmVudCIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJjb250ZW50VHlwZSIsInN0cmVhbSIsImhhbmRsZVJhbmdlUmVxdWVzdCIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiYnVmZmVyX3NpemUiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInN0YXJ0IiwiZW5kIiwibm90RW5kZWQiLCJub3RTdGFydGVkIiwibGVuZ3RoIiwiY29udGVudExlbmd0aCIsIndyaXRlSGVhZCIsInNlZWsiLCJncmlkRmlsZVN0cmVhbSIsImJ1ZmZlckF2YWlsIiwicmVtYWluaW5nQnl0ZXNUb1dyaXRlIiwidG90YWxCeXRlc1dyaXR0ZW4iLCJvbiIsImJ1ZmZlciIsInNsaWNlIiwiZGVzdHJveSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVVBOztBQUNBOztBQUNBOzs7O0FBWkE7Ozs7Ozs7O0FBU0E7QUFLTyxNQUFNQSxnQkFBTixTQUErQkMsMEJBQS9CLENBQTRDO0FBS2pEQyxFQUFBQSxXQUFXLENBQUNDLGdCQUFnQixHQUFHQyxrQkFBU0MsZUFBN0IsRUFBOENDLFlBQVksR0FBRyxFQUE3RCxFQUFpRTtBQUMxRTtBQUNBLFNBQUtDLFlBQUwsR0FBb0JKLGdCQUFwQjtBQUVBLFVBQU1LLG1CQUFtQixHQUFHO0FBQzFCQyxNQUFBQSxlQUFlLEVBQUUsSUFEUztBQUUxQkMsTUFBQUEsa0JBQWtCLEVBQUU7QUFGTSxLQUE1QjtBQUlBLFNBQUtDLGFBQUwsR0FBcUJDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjTCxtQkFBZCxFQUFtQ0YsWUFBbkMsQ0FBckI7QUFDRDs7QUFFRFEsRUFBQUEsUUFBUSxHQUFHO0FBQ1QsUUFBSSxDQUFDLEtBQUtDLGtCQUFWLEVBQThCO0FBQzVCLFdBQUtBLGtCQUFMLEdBQTBCQyxxQkFBWUMsT0FBWixDQUN4QixLQUFLVixZQURtQixFQUV4QixLQUFLSSxhQUZtQixFQUd4Qk8sSUFId0IsQ0FHbkJDLE1BQU0sSUFBSTtBQUNmLGFBQUtDLE9BQUwsR0FBZUQsTUFBZjtBQUNBLGVBQU9BLE1BQU0sQ0FBQ0UsRUFBUCxDQUFVRixNQUFNLENBQUNHLENBQVAsQ0FBU0MsT0FBVCxDQUFpQkMsTUFBM0IsQ0FBUDtBQUNELE9BTnlCLENBQTFCO0FBT0Q7O0FBQ0QsV0FBTyxLQUFLVCxrQkFBWjtBQUNELEdBM0JnRCxDQTZCakQ7QUFDQTs7O0FBQ0FVLEVBQUFBLFVBQVUsQ0FBQ0MsUUFBRCxFQUFtQkMsSUFBbkIsRUFBeUI7QUFDakMsV0FBTyxLQUFLYixRQUFMLEdBQ0pJLElBREksQ0FDQ1UsUUFBUSxJQUFJO0FBQ2hCLFlBQU1DLFNBQVMsR0FBRyxJQUFJQyxrQkFBSixDQUFjRixRQUFkLEVBQXdCRixRQUF4QixFQUFrQyxHQUFsQyxDQUFsQjtBQUNBLGFBQU9HLFNBQVMsQ0FBQ0UsSUFBVixFQUFQO0FBQ0QsS0FKSSxFQUtKYixJQUxJLENBS0NXLFNBQVMsSUFBSTtBQUNqQixhQUFPQSxTQUFTLENBQUNHLEtBQVYsQ0FBZ0JMLElBQWhCLENBQVA7QUFDRCxLQVBJLEVBUUpULElBUkksQ0FRQ1csU0FBUyxJQUFJO0FBQ2pCLGFBQU9BLFNBQVMsQ0FBQ0ksS0FBVixFQUFQO0FBQ0QsS0FWSSxDQUFQO0FBV0Q7O0FBRURDLEVBQUFBLFVBQVUsQ0FBQ1IsUUFBRCxFQUFtQjtBQUMzQixXQUFPLEtBQUtaLFFBQUwsR0FDSkksSUFESSxDQUNDVSxRQUFRLElBQUk7QUFDaEIsWUFBTUMsU0FBUyxHQUFHLElBQUlDLGtCQUFKLENBQWNGLFFBQWQsRUFBd0JGLFFBQXhCLEVBQWtDLEdBQWxDLENBQWxCO0FBQ0EsYUFBT0csU0FBUyxDQUFDRSxJQUFWLEVBQVA7QUFDRCxLQUpJLEVBS0piLElBTEksQ0FLQ1csU0FBUyxJQUFJO0FBQ2pCLGFBQU9BLFNBQVMsQ0FBQ00sTUFBVixFQUFQO0FBQ0QsS0FQSSxFQVFKakIsSUFSSSxDQVFDVyxTQUFTLElBQUk7QUFDakIsYUFBT0EsU0FBUyxDQUFDSSxLQUFWLEVBQVA7QUFDRCxLQVZJLENBQVA7QUFXRDs7QUFFREcsRUFBQUEsV0FBVyxDQUFDVixRQUFELEVBQW1CO0FBQzVCLFdBQU8sS0FBS1osUUFBTCxHQUNKSSxJQURJLENBQ0NVLFFBQVEsSUFBSTtBQUNoQixhQUFPRSxtQkFBVU8sS0FBVixDQUFnQlQsUUFBaEIsRUFBMEJGLFFBQTFCLEVBQW9DUixJQUFwQyxDQUF5QyxNQUFNO0FBQ3BELGNBQU1XLFNBQVMsR0FBRyxJQUFJQyxrQkFBSixDQUFjRixRQUFkLEVBQXdCRixRQUF4QixFQUFrQyxHQUFsQyxDQUFsQjtBQUNBLGVBQU9HLFNBQVMsQ0FBQ0UsSUFBVixFQUFQO0FBQ0QsT0FITSxDQUFQO0FBSUQsS0FOSSxFQU9KYixJQVBJLENBT0NXLFNBQVMsSUFBSTtBQUNqQixhQUFPQSxTQUFTLENBQUNTLElBQVYsRUFBUDtBQUNELEtBVEksQ0FBUDtBQVVEOztBQUVEQyxFQUFBQSxlQUFlLENBQUNDLE1BQUQsRUFBU2QsUUFBVCxFQUFtQjtBQUNoQyxXQUNFYyxNQUFNLENBQUNDLEtBQVAsR0FDQSxTQURBLEdBRUFELE1BQU0sQ0FBQ0UsYUFGUCxHQUdBLEdBSEEsR0FJQUMsa0JBQWtCLENBQUNqQixRQUFELENBTHBCO0FBT0Q7O0FBRUQsUUFBTWtCLGdCQUFOLENBQXVCbEIsUUFBdkIsRUFBeUNtQixHQUF6QyxFQUE4Q0MsR0FBOUMsRUFBbURDLFdBQW5ELEVBQWdFO0FBQzlELFVBQU1DLE1BQU0sR0FBRyxNQUFNLEtBQUtsQyxRQUFMLEdBQWdCSSxJQUFoQixDQUFxQlUsUUFBUSxJQUFJO0FBQ3BELGFBQU9FLG1CQUFVTyxLQUFWLENBQWdCVCxRQUFoQixFQUEwQkYsUUFBMUIsRUFBb0NSLElBQXBDLENBQXlDLE1BQU07QUFDcEQsY0FBTVcsU0FBUyxHQUFHLElBQUlDLGtCQUFKLENBQWNGLFFBQWQsRUFBd0JGLFFBQXhCLEVBQWtDLEdBQWxDLENBQWxCO0FBQ0EsZUFBT0csU0FBUyxDQUFDRSxJQUFWLEVBQVA7QUFDRCxPQUhNLENBQVA7QUFJRCxLQUxvQixDQUFyQjtBQU1Ba0IsSUFBQUEsa0JBQWtCLENBQUNELE1BQUQsRUFBU0gsR0FBVCxFQUFjQyxHQUFkLEVBQW1CQyxXQUFuQixDQUFsQjtBQUNEOztBQUVERyxFQUFBQSxjQUFjLEdBQUc7QUFDZixRQUFJLENBQUMsS0FBSzlCLE9BQVYsRUFBbUI7QUFDakIsYUFBTytCLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxLQUFLaEMsT0FBTCxDQUFhYSxLQUFiLENBQW1CLEtBQW5CLENBQVA7QUFDRDs7QUFFRG9CLEVBQUFBLGdCQUFnQixDQUFDM0IsUUFBRCxFQUFXO0FBQ3pCLFdBQU8sb0NBQWlCQSxRQUFqQixDQUFQO0FBQ0Q7O0FBckdnRCxDLENBd0duRDtBQUNBOzs7OztBQUNBLFNBQVN1QixrQkFBVCxDQUE0QkQsTUFBNUIsRUFBb0NILEdBQXBDLEVBQXlDQyxHQUF6QyxFQUE4Q0MsV0FBOUMsRUFBMkQ7QUFDekQsUUFBTU8sV0FBVyxHQUFHLE9BQU8sSUFBM0IsQ0FEeUQsQ0FDeEI7QUFDakM7O0FBQ0EsUUFBTUMsS0FBSyxHQUFHVixHQUFHLENBQ2RXLEdBRFcsQ0FDUCxPQURPLEVBRVhDLE9BRlcsQ0FFSCxRQUZHLEVBRU8sRUFGUCxFQUdYQyxLQUhXLENBR0wsR0FISyxDQUFkO0FBSUEsTUFBSSxDQUFDQyxLQUFELEVBQVFDLEdBQVIsSUFBZUwsS0FBbkI7QUFDQSxRQUFNTSxRQUFRLEdBQUcsQ0FBQ0QsR0FBRCxJQUFRQSxHQUFHLEtBQUssQ0FBakM7QUFDQSxRQUFNRSxVQUFVLEdBQUcsQ0FBQ0gsS0FBRCxJQUFVQSxLQUFLLEtBQUssQ0FBdkMsQ0FUeUQsQ0FVekQ7O0FBQ0EsTUFBSUUsUUFBSixFQUFjO0FBQ1pELElBQUFBLEdBQUcsR0FBR1osTUFBTSxDQUFDZSxNQUFQLEdBQWdCLENBQXRCO0FBQ0QsR0Fid0QsQ0FjekQ7OztBQUNBLE1BQUlELFVBQUosRUFBZ0I7QUFDZEgsSUFBQUEsS0FBSyxHQUFHWCxNQUFNLENBQUNlLE1BQVAsR0FBZ0JILEdBQXhCO0FBQ0FBLElBQUFBLEdBQUcsR0FBR0QsS0FBSyxHQUFHQyxHQUFSLEdBQWMsQ0FBcEI7QUFDRCxHQWxCd0QsQ0FvQnpEOzs7QUFDQSxNQUFJQSxHQUFHLEdBQUdELEtBQU4sSUFBZUwsV0FBbkIsRUFBZ0M7QUFDOUJNLElBQUFBLEdBQUcsR0FBR0QsS0FBSyxHQUFHTCxXQUFSLEdBQXNCLENBQTVCO0FBQ0Q7O0FBRUQsUUFBTVUsYUFBYSxHQUFHSixHQUFHLEdBQUdELEtBQU4sR0FBYyxDQUFwQztBQUVBYixFQUFBQSxHQUFHLENBQUNtQixTQUFKLENBQWMsR0FBZCxFQUFtQjtBQUNqQixxQkFBaUIsV0FBV04sS0FBWCxHQUFtQixHQUFuQixHQUF5QkMsR0FBekIsR0FBK0IsR0FBL0IsR0FBcUNaLE1BQU0sQ0FBQ2UsTUFENUM7QUFFakIscUJBQWlCLE9BRkE7QUFHakIsc0JBQWtCQyxhQUhEO0FBSWpCLG9CQUFnQmpCO0FBSkMsR0FBbkI7QUFPQUMsRUFBQUEsTUFBTSxDQUFDa0IsSUFBUCxDQUFZUCxLQUFaLEVBQW1CLFlBQVc7QUFDNUI7QUFDQSxVQUFNUSxjQUFjLEdBQUduQixNQUFNLENBQUNBLE1BQVAsQ0FBYyxJQUFkLENBQXZCO0FBQ0EsUUFBSW9CLFdBQVcsR0FBRyxDQUFsQjtBQUNBLFFBQUlDLHFCQUFxQixHQUFHTCxhQUE1QjtBQUNBLFFBQUlNLGlCQUFpQixHQUFHLENBQXhCLENBTDRCLENBTTVCOztBQUNBSCxJQUFBQSxjQUFjLENBQUNJLEVBQWYsQ0FBa0IsTUFBbEIsRUFBMEIsVUFBUzVDLElBQVQsRUFBZTtBQUN2Q3lDLE1BQUFBLFdBQVcsSUFBSXpDLElBQUksQ0FBQ29DLE1BQXBCOztBQUNBLFVBQUlLLFdBQVcsR0FBRyxDQUFsQixFQUFxQjtBQUNuQjtBQUNBO0FBQ0EsY0FBTUksTUFBTSxHQUFHN0MsSUFBSSxDQUFDOEMsS0FBTCxDQUFXLENBQVgsRUFBY0oscUJBQWQsQ0FBZixDQUhtQixDQUluQjs7QUFDQXZCLFFBQUFBLEdBQUcsQ0FBQ2QsS0FBSixDQUFVd0MsTUFBVixFQUxtQixDQU1uQjs7QUFDQUYsUUFBQUEsaUJBQWlCLElBQUlFLE1BQU0sQ0FBQ1QsTUFBNUIsQ0FQbUIsQ0FRbkI7O0FBQ0FNLFFBQUFBLHFCQUFxQixJQUFJMUMsSUFBSSxDQUFDb0MsTUFBOUIsQ0FUbUIsQ0FVbkI7O0FBQ0FLLFFBQUFBLFdBQVcsSUFBSUksTUFBTSxDQUFDVCxNQUF0QjtBQUNELE9BZHNDLENBZXZDO0FBQ0E7OztBQUNBLFVBQUlPLGlCQUFpQixJQUFJTixhQUF6QixFQUF3QztBQUN0Q2hCLFFBQUFBLE1BQU0sQ0FBQ2YsS0FBUDtBQUNBYSxRQUFBQSxHQUFHLENBQUNjLEdBQUo7QUFDQSxhQUFLYyxPQUFMO0FBQ0Q7QUFDRixLQXRCRDtBQXVCRCxHQTlCRDtBQStCRDs7ZUFFYzFFLGdCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gR3JpZFN0b3JlQWRhcHRlclxuIFN0b3JlcyBmaWxlcyBpbiBNb25nbyB1c2luZyBHcmlkU3RvcmVcbiBSZXF1aXJlcyB0aGUgZGF0YWJhc2UgYWRhcHRlciB0byBiZSBiYXNlZCBvbiBtb25nb2NsaWVudFxuIChHcmlkU3RvcmUgaXMgZGVwcmVjYXRlZCwgUGxlYXNlIHVzZSBHcmlkRlNCdWNrZXQgaW5zdGVhZClcblxuIEBmbG93IHdlYWtcbiAqL1xuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IE1vbmdvQ2xpZW50LCBHcmlkU3RvcmUsIERiIH0gZnJvbSAnbW9uZ29kYic7XG5pbXBvcnQgeyBGaWxlc0FkYXB0ZXIsIHZhbGlkYXRlRmlsZW5hbWUgfSBmcm9tICcuL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuXG5leHBvcnQgY2xhc3MgR3JpZFN0b3JlQWRhcHRlciBleHRlbmRzIEZpbGVzQWRhcHRlciB7XG4gIF9kYXRhYmFzZVVSSTogc3RyaW5nO1xuICBfY29ubmVjdGlvblByb21pc2U6IFByb21pc2U8RGI+O1xuICBfbW9uZ29PcHRpb25zOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IobW9uZ29EYXRhYmFzZVVSSSA9IGRlZmF1bHRzLkRlZmF1bHRNb25nb1VSSSwgbW9uZ29PcHRpb25zID0ge30pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RhdGFiYXNlVVJJID0gbW9uZ29EYXRhYmFzZVVSSTtcblxuICAgIGNvbnN0IGRlZmF1bHRNb25nb09wdGlvbnMgPSB7XG4gICAgICB1c2VOZXdVcmxQYXJzZXI6IHRydWUsXG4gICAgICB1c2VVbmlmaWVkVG9wb2xvZ3k6IHRydWUsXG4gICAgfTtcbiAgICB0aGlzLl9tb25nb09wdGlvbnMgPSBPYmplY3QuYXNzaWduKGRlZmF1bHRNb25nb09wdGlvbnMsIG1vbmdvT3B0aW9ucyk7XG4gIH1cblxuICBfY29ubmVjdCgpIHtcbiAgICBpZiAoIXRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlKSB7XG4gICAgICB0aGlzLl9jb25uZWN0aW9uUHJvbWlzZSA9IE1vbmdvQ2xpZW50LmNvbm5lY3QoXG4gICAgICAgIHRoaXMuX2RhdGFiYXNlVVJJLFxuICAgICAgICB0aGlzLl9tb25nb09wdGlvbnNcbiAgICAgICkudGhlbihjbGllbnQgPT4ge1xuICAgICAgICB0aGlzLl9jbGllbnQgPSBjbGllbnQ7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGIoY2xpZW50LnMub3B0aW9ucy5kYk5hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jb25uZWN0aW9uUHJvbWlzZTtcbiAgfVxuXG4gIC8vIEZvciBhIGdpdmVuIGNvbmZpZyBvYmplY3QsIGZpbGVuYW1lLCBhbmQgZGF0YSwgc3RvcmUgYSBmaWxlXG4gIC8vIFJldHVybnMgYSBwcm9taXNlXG4gIGNyZWF0ZUZpbGUoZmlsZW5hbWU6IHN0cmluZywgZGF0YSkge1xuICAgIHJldHVybiB0aGlzLl9jb25uZWN0KClcbiAgICAgIC50aGVuKGRhdGFiYXNlID0+IHtcbiAgICAgICAgY29uc3QgZ3JpZFN0b3JlID0gbmV3IEdyaWRTdG9yZShkYXRhYmFzZSwgZmlsZW5hbWUsICd3Jyk7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUub3BlbigpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGdyaWRTdG9yZSA9PiB7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUud3JpdGUoZGF0YSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZ3JpZFN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5jbG9zZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpXG4gICAgICAudGhlbihkYXRhYmFzZSA9PiB7XG4gICAgICAgIGNvbnN0IGdyaWRTdG9yZSA9IG5ldyBHcmlkU3RvcmUoZGF0YWJhc2UsIGZpbGVuYW1lLCAncicpO1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLm9wZW4oKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLnVubGluaygpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGdyaWRTdG9yZSA9PiB7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUuY2xvc2UoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0RmlsZURhdGEoZmlsZW5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jb25uZWN0KClcbiAgICAgIC50aGVuKGRhdGFiYXNlID0+IHtcbiAgICAgICAgcmV0dXJuIEdyaWRTdG9yZS5leGlzdChkYXRhYmFzZSwgZmlsZW5hbWUpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGdyaWRTdG9yZSA9IG5ldyBHcmlkU3RvcmUoZGF0YWJhc2UsIGZpbGVuYW1lLCAncicpO1xuICAgICAgICAgIHJldHVybiBncmlkU3RvcmUub3BlbigpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLnJlYWQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgY29uZmlnLm1vdW50ICtcbiAgICAgICcvZmlsZXMvJyArXG4gICAgICBjb25maWcuYXBwbGljYXRpb25JZCArXG4gICAgICAnLycgK1xuICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVGaWxlU3RyZWFtKGZpbGVuYW1lOiBzdHJpbmcsIHJlcSwgcmVzLCBjb250ZW50VHlwZSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHRoaXMuX2Nvbm5lY3QoKS50aGVuKGRhdGFiYXNlID0+IHtcbiAgICAgIHJldHVybiBHcmlkU3RvcmUuZXhpc3QoZGF0YWJhc2UsIGZpbGVuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgY29uc3QgZ3JpZFN0b3JlID0gbmV3IEdyaWRTdG9yZShkYXRhYmFzZSwgZmlsZW5hbWUsICdyJyk7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUub3BlbigpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaGFuZGxlUmFuZ2VSZXF1ZXN0KHN0cmVhbSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKTtcbiAgfVxuXG4gIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGlmICghdGhpcy5fY2xpZW50KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jbGllbnQuY2xvc2UoZmFsc2UpO1xuICB9XG5cbiAgdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSkge1xuICAgIHJldHVybiB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKTtcbiAgfVxufVxuXG4vLyBoYW5kbGVSYW5nZVJlcXVlc3QgaXMgbGljZW5zZWQgdW5kZXIgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbiA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlIChodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnkvNC4wLykuXG4vLyBBdXRob3I6IExFUk9JQiBhdCB3ZWlnaHRpbmdmb3JteXBpenphIChodHRwczovL3dlaWdodGluZ2Zvcm15cGl6emEud29yZHByZXNzLmNvbS8yMDE1LzA2LzI0L3N0cmVhbS1odG1sNS1tZWRpYS1jb250ZW50LWxpa2UtdmlkZW8tYXVkaW8tZnJvbS1tb25nb2RiLXVzaW5nLWV4cHJlc3MtYW5kLWdyaWRzdG9yZS8pLlxuZnVuY3Rpb24gaGFuZGxlUmFuZ2VSZXF1ZXN0KHN0cmVhbSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gIGNvbnN0IGJ1ZmZlcl9zaXplID0gMTAyNCAqIDEwMjQ7IC8vMTAyNEtiXG4gIC8vIFJhbmdlIHJlcXVlc3QsIHBhcnRpYWwgc3RyZWFtIHRoZSBmaWxlXG4gIGNvbnN0IHBhcnRzID0gcmVxXG4gICAgLmdldCgnUmFuZ2UnKVxuICAgIC5yZXBsYWNlKC9ieXRlcz0vLCAnJylcbiAgICAuc3BsaXQoJy0nKTtcbiAgbGV0IFtzdGFydCwgZW5kXSA9IHBhcnRzO1xuICBjb25zdCBub3RFbmRlZCA9ICFlbmQgJiYgZW5kICE9PSAwO1xuICBjb25zdCBub3RTdGFydGVkID0gIXN0YXJ0ICYmIHN0YXJ0ICE9PSAwO1xuICAvLyBObyBlbmQgcHJvdmlkZWQsIHdlIHdhbnQgYWxsIGJ5dGVzXG4gIGlmIChub3RFbmRlZCkge1xuICAgIGVuZCA9IHN0cmVhbS5sZW5ndGggLSAxO1xuICB9XG4gIC8vIE5vIHN0YXJ0IHByb3ZpZGVkLCB3ZSdyZSByZWFkaW5nIGJhY2t3YXJkc1xuICBpZiAobm90U3RhcnRlZCkge1xuICAgIHN0YXJ0ID0gc3RyZWFtLmxlbmd0aCAtIGVuZDtcbiAgICBlbmQgPSBzdGFydCArIGVuZCAtIDE7XG4gIH1cblxuICAvLyBEYXRhIGV4Y2VlZHMgdGhlIGJ1ZmZlcl9zaXplLCBjYXBcbiAgaWYgKGVuZCAtIHN0YXJ0ID49IGJ1ZmZlcl9zaXplKSB7XG4gICAgZW5kID0gc3RhcnQgKyBidWZmZXJfc2l6ZSAtIDE7XG4gIH1cblxuICBjb25zdCBjb250ZW50TGVuZ3RoID0gZW5kIC0gc3RhcnQgKyAxO1xuXG4gIHJlcy53cml0ZUhlYWQoMjA2LCB7XG4gICAgJ0NvbnRlbnQtUmFuZ2UnOiAnYnl0ZXMgJyArIHN0YXJ0ICsgJy0nICsgZW5kICsgJy8nICsgc3RyZWFtLmxlbmd0aCxcbiAgICAnQWNjZXB0LVJhbmdlcyc6ICdieXRlcycsXG4gICAgJ0NvbnRlbnQtTGVuZ3RoJzogY29udGVudExlbmd0aCxcbiAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gIH0pO1xuXG4gIHN0cmVhbS5zZWVrKHN0YXJ0LCBmdW5jdGlvbigpIHtcbiAgICAvLyBHZXQgZ3JpZEZpbGUgc3RyZWFtXG4gICAgY29uc3QgZ3JpZEZpbGVTdHJlYW0gPSBzdHJlYW0uc3RyZWFtKHRydWUpO1xuICAgIGxldCBidWZmZXJBdmFpbCA9IDA7XG4gICAgbGV0IHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSA9IGNvbnRlbnRMZW5ndGg7XG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICAvLyBXcml0ZSB0byByZXNwb25zZVxuICAgIGdyaWRGaWxlU3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSkge1xuICAgICAgYnVmZmVyQXZhaWwgKz0gZGF0YS5sZW5ndGg7XG4gICAgICBpZiAoYnVmZmVyQXZhaWwgPiAwKSB7XG4gICAgICAgIC8vIHNsaWNlIHJldHVybnMgdGhlIHNhbWUgYnVmZmVyIGlmIG92ZXJmbG93aW5nXG4gICAgICAgIC8vIHNhZmUgdG8gY2FsbCBpbiBhbnkgY2FzZVxuICAgICAgICBjb25zdCBidWZmZXIgPSBkYXRhLnNsaWNlKDAsIHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSk7XG4gICAgICAgIC8vIFdyaXRlIHRoZSBidWZmZXJcbiAgICAgICAgcmVzLndyaXRlKGJ1ZmZlcik7XG4gICAgICAgIC8vIEluY3JlbWVudCB0b3RhbFxuICAgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICAvLyBEZWNyZW1lbnQgcmVtYWluaW5nXG4gICAgICAgIHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSAtPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgLy8gRGVjcmVtZW50IHRoZSBhdmFpbGFibGUgYnVmZmVyXG4gICAgICAgIGJ1ZmZlckF2YWlsIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICB9XG4gICAgICAvLyBJbiBjYXNlIG9mIHNtYWxsIHNsaWNlcywgYWxsIHZhbHVlcyB3aWxsIGJlIGdvb2QgYXQgdGhhdCBwb2ludFxuICAgICAgLy8gd2UndmUgd3JpdHRlbiBlbm91Z2gsIGVuZC4uLlxuICAgICAgaWYgKHRvdGFsQnl0ZXNXcml0dGVuID49IGNvbnRlbnRMZW5ndGgpIHtcbiAgICAgICAgc3RyZWFtLmNsb3NlKCk7XG4gICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBHcmlkU3RvcmVBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Logger/LoggerAdapter.js b/lib/Adapters/Logger/LoggerAdapter.js new file mode 100644 index 0000000000..ed88ce5000 --- /dev/null +++ b/lib/Adapters/Logger/LoggerAdapter.js @@ -0,0 +1,39 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LoggerAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface LoggerAdapter + * Logger Adapter + * Allows you to change the logger mechanism + * Default is WinstonLoggerAdapter.js + */ +class LoggerAdapter { + constructor(options) {} + /** + * log + * @param {String} level + * @param {String} message + * @param {Object} metadata + */ + + + log(level, message + /* meta */ + ) {} + +} + +exports.LoggerAdapter = LoggerAdapter; +var _default = LoggerAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibGV2ZWwiLCJtZXNzYWdlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFHQTs7Ozs7O0FBTU8sTUFBTUEsYUFBTixDQUFvQjtBQUN6QkMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVUsQ0FBRTtBQUN2Qjs7Ozs7Ozs7QUFNQUMsRUFBQUEsR0FBRyxDQUFDQyxLQUFELEVBQVFDO0FBQVE7QUFBaEIsSUFBNEIsQ0FBRTs7QUFSUjs7O2VBV1pMLGEiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIExvZ2dlckFkYXB0ZXJcbiAqIExvZ2dlciBBZGFwdGVyXG4gKiBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgbG9nZ2VyIG1lY2hhbmlzbVxuICogRGVmYXVsdCBpcyBXaW5zdG9uTG9nZ2VyQWRhcHRlci5qc1xuICovXG5leHBvcnQgY2xhc3MgTG9nZ2VyQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHt9XG4gIC8qKlxuICAgKiBsb2dcbiAgICogQHBhcmFtIHtTdHJpbmd9IGxldmVsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtZXRhZGF0YVxuICAgKi9cbiAgbG9nKGxldmVsLCBtZXNzYWdlIC8qIG1ldGEgKi8pIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dlckFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLogger.js b/lib/Adapters/Logger/WinstonLogger.js new file mode 100644 index 0000000000..fca457a137 --- /dev/null +++ b/lib/Adapters/Logger/WinstonLogger.js @@ -0,0 +1,137 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.configureLogger = configureLogger; +exports.addTransport = addTransport; +exports.removeTransport = removeTransport; +exports.default = exports.logger = void 0; + +var _winston = _interopRequireWildcard(require("winston")); + +var _fs = _interopRequireDefault(require("fs")); + +var _path = _interopRequireDefault(require("path")); + +var _winstonDailyRotateFile = _interopRequireDefault(require("winston-daily-rotate-file")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const logger = _winston.default.createLogger(); + +exports.logger = logger; + +function configureTransports(options) { + const transports = []; + + if (options) { + const silent = options.silent; + delete options.silent; + + try { + if (!_lodash.default.isNil(options.dirname)) { + const parseServer = new _winstonDailyRotateFile.default(Object.assign({ + filename: 'parse-server.info', + json: true, + format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) + }, options)); + parseServer.name = 'parse-server'; + transports.push(parseServer); + const parseServerError = new _winstonDailyRotateFile.default(Object.assign({ + filename: 'parse-server.err', + json: true, + format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) + }, options, { + level: 'error' + })); + parseServerError.name = 'parse-server-error'; + transports.push(parseServerError); + } + } catch (e) { + /* */ + } + + const consoleFormat = options.json ? _winston.format.json() : _winston.format.simple(); + const consoleOptions = Object.assign({ + colorize: true, + name: 'console', + silent, + format: consoleFormat + }, options); + transports.push(new _winston.default.transports.Console(consoleOptions)); + } + + logger.configure({ + transports + }); +} + +function configureLogger({ + logsFolder = _defaults.default.logsFolder, + jsonLogs = _defaults.default.jsonLogs, + logLevel = _winston.default.level, + verbose = _defaults.default.verbose, + silent = _defaults.default.silent, + maxLogFiles +} = {}) { + if (verbose) { + logLevel = 'verbose'; + } + + _winston.default.level = logLevel; + const options = {}; + + if (logsFolder) { + if (!_path.default.isAbsolute(logsFolder)) { + logsFolder = _path.default.resolve(process.cwd(), logsFolder); + } + + try { + _fs.default.mkdirSync(logsFolder); + } catch (e) { + /* */ + } + } + + options.dirname = logsFolder; + options.level = logLevel; + options.silent = silent; + options.maxFiles = maxLogFiles; + + if (jsonLogs) { + options.json = true; + options.stringify = true; + } + + configureTransports(options); +} + +function addTransport(transport) { + // we will remove the existing transport + // before replacing it with a new one + removeTransport(transport.name); + logger.add(transport); +} + +function removeTransport(transport) { + const matchingTransport = logger.transports.find(t1 => { + return typeof transport === 'string' ? t1.name === transport : t1 === transport; + }); + + if (matchingTransport) { + logger.remove(matchingTransport); + } +} + +var _default = logger; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlci5qcyJdLCJuYW1lcyI6WyJsb2dnZXIiLCJ3aW5zdG9uIiwiY3JlYXRlTG9nZ2VyIiwiY29uZmlndXJlVHJhbnNwb3J0cyIsIm9wdGlvbnMiLCJ0cmFuc3BvcnRzIiwic2lsZW50IiwiXyIsImlzTmlsIiwiZGlybmFtZSIsInBhcnNlU2VydmVyIiwiRGFpbHlSb3RhdGVGaWxlIiwiT2JqZWN0IiwiYXNzaWduIiwiZmlsZW5hbWUiLCJqc29uIiwiZm9ybWF0IiwiY29tYmluZSIsInRpbWVzdGFtcCIsInNwbGF0IiwibmFtZSIsInB1c2giLCJwYXJzZVNlcnZlckVycm9yIiwibGV2ZWwiLCJlIiwiY29uc29sZUZvcm1hdCIsInNpbXBsZSIsImNvbnNvbGVPcHRpb25zIiwiY29sb3JpemUiLCJDb25zb2xlIiwiY29uZmlndXJlIiwiY29uZmlndXJlTG9nZ2VyIiwibG9nc0ZvbGRlciIsImRlZmF1bHRzIiwianNvbkxvZ3MiLCJsb2dMZXZlbCIsInZlcmJvc2UiLCJtYXhMb2dGaWxlcyIsInBhdGgiLCJpc0Fic29sdXRlIiwicmVzb2x2ZSIsInByb2Nlc3MiLCJjd2QiLCJmcyIsIm1rZGlyU3luYyIsIm1heEZpbGVzIiwic3RyaW5naWZ5IiwiYWRkVHJhbnNwb3J0IiwidHJhbnNwb3J0IiwicmVtb3ZlVHJhbnNwb3J0IiwiYWRkIiwibWF0Y2hpbmdUcmFuc3BvcnQiLCJmaW5kIiwidDEiLCJyZW1vdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxNQUFNLEdBQUdDLGlCQUFRQyxZQUFSLEVBQWY7Ozs7QUFFQSxTQUFTQyxtQkFBVCxDQUE2QkMsT0FBN0IsRUFBc0M7QUFDcEMsUUFBTUMsVUFBVSxHQUFHLEVBQW5COztBQUNBLE1BQUlELE9BQUosRUFBYTtBQUNYLFVBQU1FLE1BQU0sR0FBR0Ys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LCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IERhaWx5Um90YXRlRmlsZSBmcm9tICd3aW5zdG9uLWRhaWx5LXJvdGF0ZS1maWxlJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuXG5jb25zdCBsb2dnZXIgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcigpO1xuXG5mdW5jdGlvbiBjb25maWd1cmVUcmFuc3BvcnRzKG9wdGlvbnMpIHtcbiAgY29uc3QgdHJhbnNwb3J0cyA9IFtdO1xuICBpZiAob3B0aW9ucykge1xuICAgIGNvbnN0IHNpbGVudCA9IG9wdGlvbnMuc2lsZW50O1xuICAgIGRlbGV0ZSBvcHRpb25zLnNpbGVudDtcblxuICAgIHRyeSB7XG4gICAgICBpZiAoIV8uaXNOaWwob3B0aW9ucy5kaXJuYW1lKSkge1xuICAgICAgICBjb25zdCBwYXJzZVNlcnZlciA9IG5ldyBEYWlseVJvdGF0ZUZpbGUoXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6ICdwYXJzZS1zZXJ2ZXIuaW5mbycsXG4gICAgICAgICAgICAgIGpzb246IHRydWUsXG4gICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoXG4gICAgICAgICAgICAgICAgZm9ybWF0LnRpbWVzdGFtcCgpLFxuICAgICAgICAgICAgICAgIGZvcm1hdC5zcGxhdCgpLFxuICAgICAgICAgICAgICAgIGZvcm1hdC5qc29uKClcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBwYXJzZVNlcnZlci5uYW1lID0gJ3BhcnNlLXNlcnZlcic7XG4gICAgICAgIHRyYW5zcG9ydHMucHVzaChwYXJzZVNlcnZlcik7XG5cbiAgICAgICAgY29uc3QgcGFyc2VTZXJ2ZXJFcnJvciA9IG5ldyBEYWlseVJvdGF0ZUZpbGUoXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6ICdwYXJzZS1zZXJ2ZXIuZXJyJyxcbiAgICAgICAgICAgICAganNvbjogdHJ1ZSxcbiAgICAgICAgICAgICAgZm9ybWF0OiBmb3JtYXQuY29tYmluZShcbiAgICAgICAgICAgICAgICBmb3JtYXQudGltZXN0YW1wKCksXG4gICAgICAgICAgICAgICAgZm9ybWF0LnNwbGF0KCksXG4gICAgICAgICAgICAgICAgZm9ybWF0Lmpzb24oKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICB7IGxldmVsOiAnZXJyb3InIH1cbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICAgIHBhcnNlU2VydmVyRXJyb3IubmFtZSA9ICdwYXJzZS1zZXJ2ZXItZXJyb3InO1xuICAgICAgICB0cmFuc3BvcnRzLnB1c2gocGFyc2VTZXJ2ZXJFcnJvcik7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogKi9cbiAgICB9XG5cbiAgICBjb25zdCBjb25zb2xlRm9ybWF0ID0gb3B0aW9ucy5qc29uID8gZm9ybWF0Lmpzb24oKSA6IGZvcm1hdC5zaW1wbGUoKTtcbiAgICBjb25zdCBjb25zb2xlT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7XG4gICAgICAgIGNvbG9yaXplOiB0cnVlLFxuICAgICAgICBuYW1lOiAnY29uc29sZScsXG4gICAgICAgIHNpbGVudCxcbiAgICAgICAgZm9ybWF0OiBjb25zb2xlRm9ybWF0LFxuICAgICAgfSxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuXG4gICAgdHJhbnNwb3J0cy5wdXNoKG5ldyB3aW5zdG9uLnRyYW5zcG9ydHMuQ29uc29sZShjb25zb2xlT3B0aW9ucykpO1xuICB9XG5cbiAgbG9nZ2VyLmNvbmZpZ3VyZSh7XG4gICAgdHJhbnNwb3J0cyxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb25maWd1cmVMb2dnZXIoe1xuICBsb2dzRm9sZGVyID0gZGVmYXVsdHMubG9nc0ZvbGRlcixcbiAganNvbkxvZ3MgPSBkZWZhdWx0cy5qc29uTG9ncyxcbiAgbG9nTGV2ZWwgPSB3aW5zdG9uLmxldmVsLFxuICB2ZXJib3NlID0gZGVmYXVsdHMudmVyYm9zZSxcbiAgc2lsZW50ID0gZGVmYXVsdHMuc2lsZW50LFxuICBtYXhMb2dGaWxlcyxcbn0gPSB7fSkge1xuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ0xldmVsID0gJ3ZlcmJvc2UnO1xuICB9XG5cbiAgd2luc3Rvbi5sZXZlbCA9IGxvZ0xldmVsO1xuICBjb25zdCBvcHRpb25zID0ge307XG5cbiAgaWYgKGxvZ3NGb2xkZXIpIHtcbiAgICBpZiAoIXBhdGguaXNBYnNvbHV0ZShsb2dzRm9sZGVyKSkge1xuICAgICAgbG9nc0ZvbGRlciA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBsb2dzRm9sZGVyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGZzLm1rZGlyU3luYyhsb2dzRm9sZGVyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiAqL1xuICAgIH1cbiAgfVxuICBvcHRpb25zLmRpcm5hbWUgPSBsb2dzRm9sZGVyO1xuICBvcHRpb25zLmxldmVsID0gbG9nTGV2ZWw7XG4gIG9wdGlvbnMuc2lsZW50ID0gc2lsZW50O1xuICBvcHRpb25zLm1heEZpbGVzID0gbWF4TG9nRmlsZXM7XG5cbiAgaWYgKGpzb25Mb2dzKSB7XG4gICAgb3B0aW9ucy5qc29uID0gdHJ1ZTtcbiAgICBvcHRpb25zLnN0cmluZ2lmeSA9IHRydWU7XG4gIH1cbiAgY29uZmlndXJlVHJhbnNwb3J0cyhvcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgLy8gd2Ugd2lsbCByZW1vdmUgdGhlIGV4aXN0aW5nIHRyYW5zcG9ydFxuICAvLyBiZWZvcmUgcmVwbGFjaW5nIGl0IHdpdGggYSBuZXcgb25lXG4gIHJlbW92ZVRyYW5zcG9ydCh0cmFuc3BvcnQubmFtZSk7XG5cbiAgbG9nZ2VyLmFkZCh0cmFuc3BvcnQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJhbnNwb3J0KHRyYW5zcG9ydCkge1xuICBjb25zdCBtYXRjaGluZ1RyYW5zcG9ydCA9IGxvZ2dlci50cmFuc3BvcnRzLmZpbmQodDEgPT4ge1xuICAgIHJldHVybiB0eXBlb2YgdHJhbnNwb3J0ID09PSAnc3RyaW5nJ1xuICAgICAgPyB0MS5uYW1lID09PSB0cmFuc3BvcnRcbiAgICAgIDogdDEgPT09IHRyYW5zcG9ydDtcbiAgfSk7XG5cbiAgaWYgKG1hdGNoaW5nVHJhbnNwb3J0KSB7XG4gICAgbG9nZ2VyLnJlbW92ZShtYXRjaGluZ1RyYW5zcG9ydCk7XG4gIH1cbn1cblxuZXhwb3J0IHsgbG9nZ2VyIH07XG5leHBvcnQgZGVmYXVsdCBsb2dnZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLoggerAdapter.js b/lib/Adapters/Logger/WinstonLoggerAdapter.js new file mode 100644 index 0000000000..9731f1816a --- /dev/null +++ b/lib/Adapters/Logger/WinstonLoggerAdapter.js @@ -0,0 +1,75 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.WinstonLoggerAdapter = void 0; + +var _LoggerAdapter = require("./LoggerAdapter"); + +var _WinstonLogger = require("./WinstonLogger"); + +const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; + +class WinstonLoggerAdapter extends _LoggerAdapter.LoggerAdapter { + constructor(options) { + super(); + + if (options) { + (0, _WinstonLogger.configureLogger)(options); + } + } + + log() { + return _WinstonLogger.logger.log.apply(_WinstonLogger.logger, arguments); + } + + addTransport(transport) { + // Note that this is calling addTransport + // from logger. See import - confusing. + // but this is not recursive. + (0, _WinstonLogger.addTransport)(transport); + } // custom query as winston is currently limited + + + query(options, callback = () => {}) { + if (!options) { + options = {}; + } // defaults to 7 days prior + + + const from = options.from || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); + const until = options.until || new Date(); + const limit = options.size || 10; + const order = options.order || 'desc'; + const level = options.level || 'info'; + const queryOptions = { + from, + until, + limit, + order + }; + return new Promise((resolve, reject) => { + _WinstonLogger.logger.query(queryOptions, (err, res) => { + if (err) { + callback(err); + return reject(err); + } + + if (level === 'error') { + callback(res['parse-server-error']); + resolve(res['parse-server-error']); + } else { + callback(res['parse-server']); + resolve(res['parse-server']); + } + }); + }); + } + +} + +exports.WinstonLoggerAdapter = WinstonLoggerAdapter; +var _default = WinstonLoggerAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXIuanMiXSwibmFtZXMiOlsiTUlMTElTRUNPTkRTX0lOX0FfREFZIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJhZGRUcmFuc3BvcnQiLCJ0cmFuc3BvcnQiLCJxdWVyeSIsImNhbGxiYWNrIiwiZnJvbSIsIkRhdGUiLCJub3ciLCJ1bnRpbCIsImxpbWl0Iiwic2l6ZSIsIm9yZGVyIiwibGV2ZWwiLCJxdWVyeU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImVyciIsInJlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLEtBQUssRUFBTCxHQUFVLEVBQVYsR0FBZSxJQUE3Qzs7QUFFTyxNQUFNQyxvQkFBTixTQUFtQ0MsNEJBQW5DLENBQWlEO0FBQ3REQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVTtBQUNuQjs7QUFDQSxRQUFJQSxPQUFKLEVBQWE7QUFDWCwwQ0FBZ0JBLE9BQWhCO0FBQ0Q7QUFDRjs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0Msc0JBQU9ELEdBQVAsQ0FBV0UsS0FBWCxDQUFpQkQscUJBQWpCLEVBQXlCRSxTQUF6QixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLFlBQVksQ0FBQ0MsU0FBRCxFQUFZO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLHFDQUFhQSxTQUFiO0FBQ0QsR0FqQnFELENBbUJ0RDs7O0FBQ0FDLEVBQUFBLEtBQUssQ0FBQ1AsT0FBRCxFQUFVUSxRQUFRLEdBQUcsTUFBTSxDQUFFLENBQTdCLEVBQStCO0FBQ2xDLFFBQUksQ0FBQ1IsT0FBTCxFQUFjO0FBQ1pBLE1BQUFBLE9BQU8sR0FBRyxFQUFWO0FBQ0QsS0FIaUMsQ0FJbEM7OztBQUNBLFVBQU1TLElBQUksR0FDUlQsT0FBTyxDQUFDUyxJQUFSLElBQWdCLElBQUlDLElBQUosQ0FBU0EsSUFBSSxDQUFDQyxHQUFMLEtBQWEsSUFBSWYscUJBQTFCLENBRGxCO0FBRUEsVUFBTWdCLEtBQUssR0FBR1osT0FBTyxDQUFDWSxLQUFSLElBQWlCLElBQUlGLElBQUosRUFBL0I7QUFDQSxVQUFNRyxLQUFLLEdBQUdiLE9BQU8sQ0FBQ2MsSUFBUixJQUFnQixFQUE5QjtBQUNBLFVBQU1DLEtBQUssR0FBR2YsT0FBTyxDQUFDZSxLQUFSLElBQWlCLE1BQS9CO0FBQ0EsVUFBTUMsS0FBSyxHQUFHaEIsT0FBTyxDQUFDZ0IsS0FBUixJQUFpQixNQUEvQjtBQUVBLFVBQU1DLFlBQVksR0FBRztBQUNuQlIsTUFBQUEsSUFEbUI7QUFFbkJHLE1BQUFBLEtBRm1CO0FBR25CQyxNQUFBQSxLQUhtQjtBQUluQkUsTUFBQUE7QUFKbUIsS0FBckI7QUFPQSxXQUFPLElBQUlHLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDdENsQiw0QkFBT0ssS0FBUCxDQUFhVSxZQUFiLEVBQTJCLENBQUNJLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQ3ZDLFlBQUlELEdBQUosRUFBUztBQUNQYixVQUFBQSxRQUFRLENBQUNhLEdBQUQsQ0FBUjtBQUNBLGlCQUFPRCxNQUFNLENBQUNDLEdBQUQsQ0FBYjtBQUNEOztBQUVELFlBQUlMLEtBQUssS0FBSyxPQUFkLEVBQXVCO0FBQ3JCUixVQUFBQSxRQUFRLENBQUNjLEdBQUcsQ0FBQyxvQkFBRCxDQUFKLENBQVI7QUFDQUgsVUFBQUEsT0FBTyxDQUFDRyxHQUFHLENBQUMsb0JBQUQsQ0FBSixDQUFQO0FBQ0QsU0FIRCxNQUdPO0FBQ0xkLFVBQUFBLFFBQVEsQ0FBQ2MsR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFSO0FBQ0FILFVBQUFBLE9BQU8sQ0FBQ0csR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFQO0FBQ0Q7QUFDRixPQWJEO0FBY0QsS0FmTSxDQUFQO0FBZ0JEOztBQXZEcUQ7OztlQTBEekN6QixvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgbG9nZ2VyLCBhZGRUcmFuc3BvcnQsIGNvbmZpZ3VyZUxvZ2dlciB9IGZyb20gJy4vV2luc3RvbkxvZ2dlcic7XG5cbmNvbnN0IE1JTExJU0VDT05EU19JTl9BX0RBWSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBXaW5zdG9uTG9nZ2VyQWRhcHRlciBleHRlbmRzIExvZ2dlckFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgY29uZmlndXJlTG9nZ2VyKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGxvZygpIHtcbiAgICByZXR1cm4gbG9nZ2VyLmxvZy5hcHBseShsb2dnZXIsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KSB7XG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgY2FsbGluZyBhZGRUcmFuc3BvcnRcbiAgICAvLyBmcm9tIGxvZ2dlci4gIFNlZSBpbXBvcnQgLSBjb25mdXNpbmcuXG4gICAgLy8gYnV0IHRoaXMgaXMgbm90IHJlY3Vyc2l2ZS5cbiAgICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfVxuXG4gIC8vIGN1c3RvbSBxdWVyeSBhcyB3aW5zdG9uIGlzIGN1cnJlbnRseSBsaW1pdGVkXG4gIHF1ZXJ5KG9wdGlvbnMsIGNhbGxiYWNrID0gKCkgPT4ge30pIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gNyBkYXlzIHByaW9yXG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBvcHRpb25zLmZyb20gfHwgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gb3B0aW9ucy51bnRpbCB8fCBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGxpbWl0ID0gb3B0aW9ucy5zaXplIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCAnZGVzYyc7XG4gICAgY29uc3QgbGV2ZWwgPSBvcHRpb25zLmxldmVsIHx8ICdpbmZvJztcblxuICAgIGNvbnN0IHF1ZXJ5T3B0aW9ucyA9IHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIGxpbWl0LFxuICAgICAgb3JkZXIsXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsb2dnZXIucXVlcnkocXVlcnlPcHRpb25zLCAoZXJyLCByZXMpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxldmVsID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgY2FsbGJhY2socmVzWydwYXJzZS1zZXJ2ZXItZXJyb3InXSk7XG4gICAgICAgICAgcmVzb2x2ZShyZXNbJ3BhcnNlLXNlcnZlci1lcnJvciddKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYWxsYmFjayhyZXNbJ3BhcnNlLXNlcnZlciddKTtcbiAgICAgICAgICByZXNvbHZlKHJlc1sncGFyc2Utc2VydmVyJ10pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBXaW5zdG9uTG9nZ2VyQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/MessageQueue/EventEmitterMQ.js b/lib/Adapters/MessageQueue/EventEmitterMQ.js new file mode 100644 index 0000000000..ddf372cd6d --- /dev/null +++ b/lib/Adapters/MessageQueue/EventEmitterMQ.js @@ -0,0 +1,73 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.EventEmitterMQ = void 0; + +var _events = _interopRequireDefault(require("events")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const emitter = new _events.default.EventEmitter(); +const subscriptions = new Map(); + +function unsubscribe(channel) { + if (!subscriptions.has(channel)) { + //console.log('No channel to unsub from'); + return; + } //console.log('unsub ', channel); + + + emitter.removeListener(channel, subscriptions.get(channel)); + subscriptions.delete(channel); +} + +class Publisher { + constructor(emitter) { + this.emitter = emitter; + } + + publish(channel, message) { + this.emitter.emit(channel, message); + } + +} + +class Consumer extends _events.default.EventEmitter { + constructor(emitter) { + super(); + this.emitter = emitter; + } + + subscribe(channel) { + unsubscribe(channel); + + const handler = message => { + this.emit('message', channel, message); + }; + + subscriptions.set(channel, handler); + this.emitter.on(channel, handler); + } + + unsubscribe(channel) { + unsubscribe(channel); + } + +} + +function createPublisher() { + return new Publisher(emitter); +} + +function createSubscriber() { + return new Consumer(emitter); +} + +const EventEmitterMQ = { + createPublisher, + createSubscriber +}; +exports.EventEmitterMQ = EventEmitterMQ; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9NZXNzYWdlUXVldWUvRXZlbnRFbWl0dGVyTVEuanMiXSwibmFtZXMiOlsiZW1pdHRlciIsImV2ZW50cyIsIkV2ZW50RW1pdHRlciIsInN1YnNjcmlwdGlvbnMiLCJNYXAiLCJ1bnN1YnNjcmliZSIsImNoYW5uZWwiLCJoYXMiLCJyZW1vdmVMaXN0ZW5lciIsImdldCIsImRlbGV0ZSIsIlB1Ymxpc2hlciIsImNvbnN0cnVjdG9yIiwicHVibGlzaCIsIm1lc3NhZ2UiLCJlbWl0IiwiQ29uc3VtZXIiLCJzdWJzY3JpYmUiLCJoYW5kbGVyIiwic2V0Iiwib24iLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwiRXZlbnRFbWl0dGVyTVEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBLE1BQU1BLE9BQU8sR0FBRyxJQUFJQyxnQkFBT0MsWUFBWCxFQUFoQjtBQUNBLE1BQU1DLGFBQWEsR0FBRyxJQUFJQyxHQUFKLEVBQXRCOztBQUVBLFNBQVNDLFdBQVQsQ0FBcUJDLE9BQXJCLEVBQXNDO0FBQ3BDLE1BQUksQ0FBQ0gsYUFBYSxDQUFDSSxHQUFkLENBQWtCRCxPQUFsQixDQUFMLEVBQWlDO0FBQy9CO0FBQ0E7QUFDRCxHQUptQyxDQUtwQzs7O0FBQ0FOLEVBQUFBLE9BQU8sQ0FBQ1EsY0FBUixDQUF1QkYsT0FBdkIsRUFBZ0NILGFBQWEsQ0FBQ00sR0FBZCxDQUFrQkgsT0FBbEIsQ0FBaEM7QUFDQUgsRUFBQUEsYUFBYSxDQUFDTyxNQUFkLENBQXFCSixPQUFyQjtBQUNEOztBQUVELE1BQU1LLFNBQU4sQ0FBZ0I7QUFHZEMsRUFBQUEsV0FBVyxDQUFDWixPQUFELEVBQWU7QUFDeEIsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRURhLEVBQUFBLE9BQU8sQ0FBQ1AsT0FBRCxFQUFrQlEsT0FBbEIsRUFBeUM7QUFDOUMsU0FBS2QsT0FBTCxDQUFhZSxJQUFiLENBQWtCVCxPQUFsQixFQUEyQlEsT0FBM0I7QUFDRDs7QUFUYTs7QUFZaEIsTUFBTUUsUUFBTixTQUF1QmYsZ0JBQU9DLFlBQTlCLENBQTJDO0FBR3pDVSxFQUFBQSxXQUFXLENBQUNaLE9BQUQsRUFBZTtBQUN4QjtBQUNBLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVEaUIsRUFBQUEsU0FBUyxDQUFDWCxPQUFELEVBQXdCO0FBQy9CRCxJQUFBQSxXQUFXLENBQUNDLE9BQUQsQ0FBWDs7QUFDQSxVQUFNWSxPQUFPLEdBQUdKLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQlQsT0FBckIsRUFBOEJRLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQVgsSUFBQUEsYUFBYSxDQUFDZ0IsR0FBZCxDQUFrQmIsT0FBbEIsRUFBMkJZLE9BQTNCO0FBQ0EsU0FBS2xCLE9BQUwsQ0FBYW9CLEVBQWIsQ0FBZ0JkLE9BQWhCLEVBQXlCWSxPQUF6QjtBQUNEOztBQUVEYixFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBd0I7QUFDakNELElBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxDQUFYO0FBQ0Q7O0FBbkJ3Qzs7QUFzQjNDLFNBQVNlLGVBQVQsR0FBZ0M7QUFDOUIsU0FBTyxJQUFJVixTQUFKLENBQWNYLE9BQWQsQ0FBUDtBQUNEOztBQUVELFNBQVNzQixnQkFBVCxHQUFpQztBQUMvQixTQUFPLElBQUlOLFFBQUosQ0FBYWhCLE9BQWIsQ0FBUDtBQUNEOztBQUVELE1BQU11QixjQUFjLEdBQUc7QUFDckJGLEVBQUFBLGVBRHFCO0FBRXJCQyxFQUFBQTtBQUZxQixDQUF2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuY29uc3QgZW1pdHRlciA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG5jb25zdCBzdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuXG5mdW5jdGlvbiB1bnN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpIHtcbiAgaWYgKCFzdWJzY3JpcHRpb25zLmhhcyhjaGFubmVsKSkge1xuICAgIC8vY29uc29sZS5sb2coJ05vIGNoYW5uZWwgdG8gdW5zdWIgZnJvbScpO1xuICAgIHJldHVybjtcbiAgfVxuICAvL2NvbnNvbGUubG9nKCd1bnN1YiAnLCBjaGFubmVsKTtcbiAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihjaGFubmVsLCBzdWJzY3JpcHRpb25zLmdldChjaGFubmVsKSk7XG4gIHN1YnNjcmlwdGlvbnMuZGVsZXRlKGNoYW5uZWwpO1xufVxuXG5jbGFzcyBQdWJsaXNoZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgfVxuXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtaXR0ZXIuZW1pdChjaGFubmVsLCBtZXNzYWdlKTtcbiAgfVxufVxuXG5jbGFzcyBDb25zdW1lciBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICB9XG5cbiAgc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHVuc3Vic2NyaWJlKGNoYW5uZWwpO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBtZXNzYWdlID0+IHtcbiAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIGNoYW5uZWwsIG1lc3NhZ2UpO1xuICAgIH07XG4gICAgc3Vic2NyaXB0aW9ucy5zZXQoY2hhbm5lbCwgaGFuZGxlcik7XG4gICAgdGhpcy5lbWl0dGVyLm9uKGNoYW5uZWwsIGhhbmRsZXIpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdW5zdWJzY3JpYmUoY2hhbm5lbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgUHVibGlzaGVyKGVtaXR0ZXIpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgQ29uc3VtZXIoZW1pdHRlcik7XG59XG5cbmNvbnN0IEV2ZW50RW1pdHRlck1RID0ge1xuICBjcmVhdGVQdWJsaXNoZXIsXG4gIGNyZWF0ZVN1YnNjcmliZXIsXG59O1xuXG5leHBvcnQgeyBFdmVudEVtaXR0ZXJNUSB9O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/EventEmitterPubSub.js b/lib/Adapters/PubSub/EventEmitterPubSub.js new file mode 100644 index 0000000000..e5f1670d83 --- /dev/null +++ b/lib/Adapters/PubSub/EventEmitterPubSub.js @@ -0,0 +1,65 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.EventEmitterPubSub = void 0; + +var _events = _interopRequireDefault(require("events")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const emitter = new _events.default.EventEmitter(); + +class Publisher { + constructor(emitter) { + this.emitter = emitter; + } + + publish(channel, message) { + this.emitter.emit(channel, message); + } + +} + +class Subscriber extends _events.default.EventEmitter { + constructor(emitter) { + super(); + this.emitter = emitter; + this.subscriptions = new Map(); + } + + subscribe(channel) { + const handler = message => { + this.emit('message', channel, message); + }; + + this.subscriptions.set(channel, handler); + this.emitter.on(channel, handler); + } + + unsubscribe(channel) { + if (!this.subscriptions.has(channel)) { + return; + } + + this.emitter.removeListener(channel, this.subscriptions.get(channel)); + this.subscriptions.delete(channel); + } + +} + +function createPublisher() { + return new Publisher(emitter); +} + +function createSubscriber() { + return new Subscriber(emitter); +} + +const EventEmitterPubSub = { + createPublisher, + createSubscriber +}; +exports.EventEmitterPubSub = EventEmitterPubSub; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvRXZlbnRFbWl0dGVyUHViU3ViLmpzIl0sIm5hbWVzIjpbImVtaXR0ZXIiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsInB1Ymxpc2giLCJjaGFubmVsIiwibWVzc2FnZSIsImVtaXQiLCJTdWJzY3JpYmVyIiwic3Vic2NyaXB0aW9ucyIsIk1hcCIsInN1YnNjcmliZSIsImhhbmRsZXIiLCJzZXQiLCJvbiIsInVuc3Vic2NyaWJlIiwiaGFzIiwicmVtb3ZlTGlzdGVuZXIiLCJnZXQiLCJkZWxldGUiLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwiRXZlbnRFbWl0dGVyUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxNQUFNQSxPQUFPLEdBQUcsSUFBSUMsZ0JBQU9DLFlBQVgsRUFBaEI7O0FBRUEsTUFBTUMsU0FBTixDQUFnQjtBQUdkQyxFQUFBQSxXQUFXLENBQUNKLE9BQUQsRUFBZTtBQUN4QixTQUFLQSxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREssRUFBQUEsT0FBTyxDQUFDQyxPQUFELEVBQWtCQyxPQUFsQixFQUF5QztBQUM5QyxTQUFLUCxPQUFMLENBQWFRLElBQWIsQ0FBa0JGLE9BQWxCLEVBQTJCQyxPQUEzQjtBQUNEOztBQVRhOztBQVloQixNQUFNRSxVQUFOLFNBQXlCUixnQkFBT0MsWUFBaEMsQ0FBNkM7QUFJM0NFLEVBQUFBLFdBQVcsQ0FBQ0osT0FBRCxFQUFlO0FBQ3hCO0FBQ0EsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS1UsYUFBTCxHQUFxQixJQUFJQyxHQUFKLEVBQXJCO0FBQ0Q7O0FBRURDLEVBQUFBLFNBQVMsQ0FBQ04sT0FBRCxFQUF3QjtBQUMvQixVQUFNTyxPQUFPLEdBQUdOLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQkYsT0FBckIsRUFBOEJDLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQSxTQUFLRyxhQUFMLENBQW1CSSxHQUFuQixDQUF1QlIsT0FBdkIsRUFBZ0NPLE9BQWhDO0FBQ0EsU0FBS2IsT0FBTCxDQUFhZSxFQUFiLENBQWdCVCxPQUFoQixFQUF5Qk8sT0FBekI7QUFDRDs7QUFFREcsRUFBQUEsV0FBVyxDQUFDVixPQUFELEVBQXdCO0FBQ2pDLFFBQUksQ0FBQyxLQUFLSSxhQUFMLENBQW1CTyxHQUFuQixDQUF1QlgsT0FBdkIsQ0FBTCxFQUFzQztBQUNwQztBQUNEOztBQUNELFNBQUtOLE9BQUwsQ0FBYWtCLGNBQWIsQ0FBNEJaLE9BQTVCLEVBQXFDLEtBQUtJLGFBQUwsQ0FBbUJTLEdBQW5CLENBQXVCYixPQUF2QixDQUFyQztBQUNBLFNBQUtJLGFBQUwsQ0FBbUJVLE1BQW5CLENBQTBCZCxPQUExQjtBQUNEOztBQXhCMEM7O0FBMkI3QyxTQUFTZSxlQUFULEdBQWdDO0FBQzlCLFNBQU8sSUFBSWxCLFNBQUosQ0FBY0gsT0FBZCxDQUFQO0FBQ0Q7O0FBRUQsU0FBU3NCLGdCQUFULEdBQWlDO0FBQy9CLFNBQU8sSUFBSWIsVUFBSixDQUFlVCxPQUFmLENBQVA7QUFDRDs7QUFFRCxNQUFNdUIsa0JBQWtCLEdBQUc7QUFDekJGLEVBQUFBLGVBRHlCO0FBRXpCQyxFQUFBQTtBQUZ5QixDQUEzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuY29uc3QgZW1pdHRlciA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG5cbmNsYXNzIFB1Ymxpc2hlciB7XG4gIGVtaXR0ZXI6IGFueTtcblxuICBjb25zdHJ1Y3RvcihlbWl0dGVyOiBhbnkpIHtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICB9XG5cbiAgcHVibGlzaChjaGFubmVsOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZW1pdHRlci5lbWl0KGNoYW5uZWwsIG1lc3NhZ2UpO1xuICB9XG59XG5cbmNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgZW1pdHRlcjogYW55O1xuICBzdWJzY3JpcHRpb25zOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIHN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBoYW5kbGVyID0gbWVzc2FnZSA9PiB7XG4gICAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCBjaGFubmVsLCBtZXNzYWdlKTtcbiAgICB9O1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5zZXQoY2hhbm5lbCwgaGFuZGxlcik7XG4gICAgdGhpcy5lbWl0dGVyLm9uKGNoYW5uZWwsIGhhbmRsZXIpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN1YnNjcmlwdGlvbnMuaGFzKGNoYW5uZWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihjaGFubmVsLCB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNoYW5uZWwpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZGVsZXRlKGNoYW5uZWwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVB1Ymxpc2hlcigpOiBhbnkge1xuICByZXR1cm4gbmV3IFB1Ymxpc2hlcihlbWl0dGVyKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlU3Vic2NyaWJlcigpOiBhbnkge1xuICByZXR1cm4gbmV3IFN1YnNjcmliZXIoZW1pdHRlcik7XG59XG5cbmNvbnN0IEV2ZW50RW1pdHRlclB1YlN1YiA9IHtcbiAgY3JlYXRlUHVibGlzaGVyLFxuICBjcmVhdGVTdWJzY3JpYmVyLFxufTtcblxuZXhwb3J0IHsgRXZlbnRFbWl0dGVyUHViU3ViIH07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/PubSub/PubSubAdapter.js b/lib/Adapters/PubSub/PubSubAdapter.js new file mode 100644 index 0000000000..77e50d7e44 --- /dev/null +++ b/lib/Adapters/PubSub/PubSubAdapter.js @@ -0,0 +1,39 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PubSubAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface PubSubAdapter + */ +class PubSubAdapter { + /** + * @returns {PubSubAdapter.Publisher} + */ + static createPublisher() {} + /** + * @returns {PubSubAdapter.Subscriber} + */ + + + static createSubscriber() {} + +} +/** + * @interface Publisher + * @memberof PubSubAdapter + */ + + +exports.PubSubAdapter = PubSubAdapter; +var _default = PubSubAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUHViU3ViQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJQdWJTdWJBZGFwdGVyIiwiY3JlYXRlUHVibGlzaGVyIiwiY3JlYXRlU3Vic2NyaWJlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7OztBQUdPLE1BQU1BLGFBQU4sQ0FBb0I7QUFDekI7OztBQUdBLFNBQU9DLGVBQVAsR0FBeUIsQ0FBRTtBQUMzQjs7Ozs7QUFHQSxTQUFPQyxnQkFBUCxHQUEwQixDQUFFOztBQVJIO0FBVzNCOzs7Ozs7O2VBOEJlRixhIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJzXG4gKi9cbi8qKlxuICogQGludGVyZmFjZSBQdWJTdWJBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJTdWJBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQdWJTdWJBZGFwdGVyLlB1Ymxpc2hlcn1cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVQdWJsaXNoZXIoKSB7fVxuICAvKipcbiAgICogQHJldHVybnMge1B1YlN1YkFkYXB0ZXIuU3Vic2NyaWJlcn1cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVTdWJzY3JpYmVyKCkge31cbn1cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFB1Ymxpc2hlclxuICogQG1lbWJlcm9mIFB1YlN1YkFkYXB0ZXJcbiAqL1xuaW50ZXJmYWNlIFB1Ymxpc2hlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2hhbm5lbCB0aGUgY2hhbm5lbCBpbiB3aGljaCB0byBwdWJsaXNoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIHRoZSBtZXNzYWdlIHRvIHB1Ymxpc2hcbiAgICovXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkO1xufVxuXG4vKipcbiAqIEBpbnRlcmZhY2UgU3Vic2NyaWJlclxuICogQG1lbWJlcm9mIFB1YlN1YkFkYXB0ZXJcbiAqL1xuaW50ZXJmYWNlIFN1YnNjcmliZXIge1xuICAvKipcbiAgICogY2FsbGVkIHdoZW4gYSBuZXcgc3Vic2NyaXB0aW9uIHRoZSBjaGFubmVsIGlzIHJlcXVpcmVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsIHRoZSBjaGFubmVsIHRvIHN1YnNjcmliZVxuICAgKi9cbiAgc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGNhbGxlZCB3aGVuIHRoZSBzdWJzY3JpcHRpb24gZnJvbSB0aGUgY2hhbm5lbCBzaG91bGQgYmUgc3RvcHBlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2hhbm5lbFxuICAgKi9cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUHViU3ViQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/PubSub/RedisPubSub.js b/lib/Adapters/PubSub/RedisPubSub.js new file mode 100644 index 0000000000..cb4a03c10a --- /dev/null +++ b/lib/Adapters/PubSub/RedisPubSub.js @@ -0,0 +1,33 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RedisPubSub = void 0; + +var _redis = _interopRequireDefault(require("redis")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function createPublisher({ + redisURL, + redisOptions = {} +}) { + redisOptions.no_ready_check = true; + return _redis.default.createClient(redisURL, redisOptions); +} + +function createSubscriber({ + redisURL, + redisOptions = {} +}) { + redisOptions.no_ready_check = true; + return _redis.default.createClient(redisURL, redisOptions); +} + +const RedisPubSub = { + createPublisher, + createSubscriber +}; +exports.RedisPubSub = RedisPubSub; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUmVkaXNQdWJTdWIuanMiXSwibmFtZXMiOlsiY3JlYXRlUHVibGlzaGVyIiwicmVkaXNVUkwiLCJyZWRpc09wdGlvbnMiLCJub19yZWFkeV9jaGVjayIsInJlZGlzIiwiY3JlYXRlQ2xpZW50IiwiY3JlYXRlU3Vic2NyaWJlciIsIlJlZGlzUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxTQUFTQSxlQUFULENBQXlCO0FBQUVDLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQXpCLEVBQStEO0FBQzdEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELFNBQVNJLGdCQUFULENBQTBCO0FBQUVMLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQTFCLEVBQWdFO0FBQzlEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELE1BQU1LLFdBQVcsR0FBRztBQUNsQlAsRUFBQUEsZUFEa0I7QUFFbEJNLEVBQUFBO0FBRmtCLENBQXBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5jb25zdCBSZWRpc1B1YlN1YiA9IHtcbiAgY3JlYXRlUHVibGlzaGVyLFxuICBjcmVhdGVTdWJzY3JpYmVyLFxufTtcblxuZXhwb3J0IHsgUmVkaXNQdWJTdWIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Push/PushAdapter.js b/lib/Adapters/Push/PushAdapter.js new file mode 100644 index 0000000000..494c52bc1f --- /dev/null +++ b/lib/Adapters/Push/PushAdapter.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ +// Push Adapter +// +// Allows you to change the push notification mechanism. +// +// Adapter classes must implement the following functions: +// * getValidPushTypes() +// * send(devices, installations, pushStatus) +// +// Default is ParsePushAdapter, which uses GCM for +// android push and APNS for ios push. + +/** + * @module Adapters + */ + +/** + * @interface PushAdapter + */ +class PushAdapter { + /** + * @param {any} body + * @param {Parse.Installation[]} installations + * @param {any} pushStatus + * @returns {Promise} + */ + send(body, installations, pushStatus) {} + /** + * Get an array of valid push types. + * @returns {Array} An array of valid push types + */ + + + getValidPushTypes() { + return []; + } + +} + +exports.PushAdapter = PushAdapter; +var _default = PushAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIlB1c2hBZGFwdGVyIiwic2VuZCIsImJvZHkiLCJpbnN0YWxsYXRpb25zIiwicHVzaFN0YXR1cyIsImdldFZhbGlkUHVzaFR5cGVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7OztBQUdBOzs7QUFHTyxNQUFNQSxXQUFOLENBQWtCO0FBQ3ZCOzs7Ozs7QUFNQUMsRUFBQUEsSUFBSSxDQUFDQyxJQUFELEVBQVlDLGFBQVosRUFBa0NDLFVBQWxDLEVBQWdFLENBQUU7QUFFdEU7Ozs7OztBQUlBQyxFQUFBQSxpQkFBaUIsR0FBYTtBQUM1QixXQUFPLEVBQVA7QUFDRDs7QUFmc0I7OztlQWtCVkwsVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vLyBQdXNoIEFkYXB0ZXJcbi8vXG4vLyBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgcHVzaCBub3RpZmljYXRpb24gbWVjaGFuaXNtLlxuLy9cbi8vIEFkYXB0ZXIgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogZ2V0VmFsaWRQdXNoVHlwZXMoKVxuLy8gKiBzZW5kKGRldmljZXMsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMpXG4vL1xuLy8gRGVmYXVsdCBpcyBQYXJzZVB1c2hBZGFwdGVyLCB3aGljaCB1c2VzIEdDTSBmb3Jcbi8vIGFuZHJvaWQgcHVzaCBhbmQgQVBOUyBmb3IgaW9zIHB1c2guXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgUHVzaEFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFB1c2hBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSBib2R5XG4gICAqIEBwYXJhbSB7UGFyc2UuSW5zdGFsbGF0aW9uW119IGluc3RhbGxhdGlvbnNcbiAgICogQHBhcmFtIHthbnl9IHB1c2hTdGF0dXNcbiAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAqL1xuICBzZW5kKGJvZHk6IGFueSwgaW5zdGFsbGF0aW9uczogYW55W10sIHB1c2hTdGF0dXM6IGFueSk6ID9Qcm9taXNlPCo+IHt9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBhcnJheSBvZiB2YWxpZCBwdXNoIHR5cGVzLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IEFuIGFycmF5IG9mIHZhbGlkIHB1c2ggdHlwZXNcbiAgICovXG4gIGdldFZhbGlkUHVzaFR5cGVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoCollection.js b/lib/Adapters/Storage/Mongo/MongoCollection.js new file mode 100644 index 0000000000..306cb2d098 --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoCollection.js @@ -0,0 +1,229 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const mongodb = require('mongodb'); + +const Collection = mongodb.Collection; + +class MongoCollection { + constructor(mongoCollection) { + this._mongoCollection = mongoCollection; + } // Does a find with "smart indexing". + // Currently this just means, if it needs a geoindex and there is + // none, then build the geoindex. + // This could be improved a lot but it's not clear if that's a good + // idea. Or even if this behavior is a good idea. + + + find(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + } = {}) { + // Support for Full Text Search - $text + if (keys && keys.$score) { + delete keys.$score; + keys.score = { + $meta: 'textScore' + }; + } + + return this._rawFind(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + }).catch(error => { + // Check for "no geoindex" error + if (error.code != 17007 && !error.message.match(/unable to find index for .geoNear/)) { + throw error; + } // Figure out what key needs an index + + + const key = error.message.match(/field=([A-Za-z_0-9]+) /)[1]; + + if (!key) { + throw error; + } + + var index = {}; + index[key] = '2d'; + return this._mongoCollection.createIndex(index) // Retry, but just once. + .then(() => this._rawFind(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + })); + }); + } + /** + * Collation to support case insensitive queries + */ + + + static caseInsensitiveCollation() { + return { + locale: 'en_US', + strength: 2 + }; + } + + _rawFind(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + } = {}) { + let findOperation = this._mongoCollection.find(query, { + skip, + limit, + sort, + readPreference, + hint + }); + + if (keys) { + findOperation = findOperation.project(keys); + } + + if (caseInsensitive) { + findOperation = findOperation.collation(MongoCollection.caseInsensitiveCollation()); + } + + if (maxTimeMS) { + findOperation = findOperation.maxTimeMS(maxTimeMS); + } + + return explain ? findOperation.explain(explain) : findOperation.toArray(); + } + + count(query, { + skip, + limit, + sort, + maxTimeMS, + readPreference, + hint + } = {}) { + // If query is empty, then use estimatedDocumentCount instead. + // This is due to countDocuments performing a scan, + // which greatly increases execution time when being run on large collections. + // See https://github.com/Automattic/mongoose/issues/6713 for more info regarding this problem. + if (typeof query !== 'object' || !Object.keys(query).length) { + return this._mongoCollection.estimatedDocumentCount({ + maxTimeMS + }); + } + + const countOperation = this._mongoCollection.countDocuments(query, { + skip, + limit, + sort, + maxTimeMS, + readPreference, + hint + }); + + return countOperation; + } + + distinct(field, query) { + return this._mongoCollection.distinct(field, query); + } + + aggregate(pipeline, { + maxTimeMS, + readPreference, + hint, + explain + } = {}) { + return this._mongoCollection.aggregate(pipeline, { + maxTimeMS, + readPreference, + hint, + explain + }).toArray(); + } + + insertOne(object, session) { + return this._mongoCollection.insertOne(object, { + session + }); + } // Atomically updates data in the database for a single (first) object that matched the query + // If there is nothing that matches the query - does insert + // Postgres Note: `INSERT ... ON CONFLICT UPDATE` that is available since 9.5. + + + upsertOne(query, update, session) { + return this._mongoCollection.updateOne(query, update, { + upsert: true, + session + }); + } + + updateOne(query, update) { + return this._mongoCollection.updateOne(query, update); + } + + updateMany(query, update, session) { + return this._mongoCollection.updateMany(query, update, { + session + }); + } + + deleteMany(query, session) { + return this._mongoCollection.deleteMany(query, { + session + }); + } + + _ensureSparseUniqueIndexInBackground(indexRequest) { + return new Promise((resolve, reject) => { + this._mongoCollection.createIndex(indexRequest, { + unique: true, + background: true, + sparse: true + }, error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + } + + drop() { + return this._mongoCollection.drop(); + } + +} + +exports.default = MongoCollection; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb2RiIiwicmVxdWlyZSIsIkNvbGxlY3Rpb24iLCJNb25nb0NvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsIm1vbmdvQ29sbGVjdGlvbiIsIl9tb25nb0NvbGxlY3Rpb24iLCJmaW5kIiwicXVlcnkiLCJza2lwIiwibGltaXQiLCJzb3J0Iiwia2V5cyIsIm1heFRpbWVNUyIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCIkc2NvcmUiLCJzY29yZSIsIiRtZXRhIiwiX3Jhd0ZpbmQiLCJjYXRjaCIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJtYXRjaCIsImtleSIsImluZGV4IiwiY3JlYXRlSW5kZXgiLCJ0aGVuIiwiY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uIiwibG9jYWxlIiwic3RyZW5ndGgiLCJmaW5kT3BlcmF0aW9uIiwicHJvamVjdCIsImNvbGxhdGlvbiIsInRvQXJyYXkiLCJjb3VudCIsIk9iamVjdCIsImxlbmd0aCIsImVzdGltYXRlZERvY3VtZW50Q291bnQiLCJjb3VudE9wZXJhdGlvbiIsImNvdW50RG9jdW1lbnRzIiwiZGlzdGluY3QiLCJmaWVsZCIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwiaW5zZXJ0T25lIiwib2JqZWN0Iiwic2Vzc2lvbiIsInVwc2VydE9uZSIsInVwZGF0ZSIsInVwZGF0ZU9uZSIsInVwc2VydCIsInVwZGF0ZU1hbnkiLCJkZWxldGVNYW55IiwiX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kIiwiaW5kZXhSZXF1ZXN0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ1bmlxdWUiLCJiYWNrZ3JvdW5kIiwic3BhcnNlIiwiZHJvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLE9BQU8sR0FBR0Ms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TWtDIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IENvbGxlY3Rpb24gPSBtb25nb2RiLkNvbGxlY3Rpb247XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1vbmdvQ29sbGVjdGlvbiB7XG4gIF9tb25nb0NvbGxlY3Rpb246IENvbGxlY3Rpb247XG5cbiAgY29uc3RydWN0b3IobW9uZ29Db2xsZWN0aW9uOiBDb2xsZWN0aW9uKSB7XG4gICAgdGhpcy5fbW9uZ29Db2xsZWN0aW9uID0gbW9uZ29Db2xsZWN0aW9uO1xuICB9XG5cbiAgLy8gRG9lcyBhIGZpbmQgd2l0aCBcInNtYXJ0IGluZGV4aW5nXCIuXG4gIC8vIEN1cnJlbnRseSB0aGlzIGp1c3QgbWVhbnMsIGlmIGl0IG5lZWRzIGEgZ2VvaW5kZXggYW5kIHRoZXJlIGlzXG4gIC8vIG5vbmUsIHRoZW4gYnVpbGQgdGhlIGdlb2luZGV4LlxuICAvLyBUaGlzIGNvdWxkIGJlIGltcHJvdmVkIGEgbG90IGJ1dCBpdCdzIG5vdCBjbGVhciBpZiB0aGF0J3MgYSBnb29kXG4gIC8vIGlkZWEuIE9yIGV2ZW4gaWYgdGhpcyBiZWhhdmlvciBpcyBhIGdvb2QgaWRlYS5cbiAgZmluZChcbiAgICBxdWVyeSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgfSA9IHt9XG4gICkge1xuICAgIC8vIFN1cHBvcnQgZm9yIEZ1bGwgVGV4dCBTZWFyY2ggLSAkdGV4dFxuICAgIGlmIChrZXlzICYmIGtleXMuJHNjb3JlKSB7XG4gICAgICBkZWxldGUga2V5cy4kc2NvcmU7XG4gICAgICBrZXlzLnNjb3JlID0geyAkbWV0YTogJ3RleHRTY29yZScgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Jhd0ZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICBrZXlzLFxuICAgICAgbWF4VGltZU1TLFxuICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICBoaW50LFxuICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgZXhwbGFpbixcbiAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAvLyBDaGVjayBmb3IgXCJubyBnZW9pbmRleFwiIGVycm9yXG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yLmNvZGUgIT0gMTcwMDcgJiZcbiAgICAgICAgIWVycm9yLm1lc3NhZ2UubWF0Y2goL3VuYWJsZSB0byBmaW5kIGluZGV4IGZvciAuZ2VvTmVhci8pXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBGaWd1cmUgb3V0IHdoYXQga2V5IG5lZWRzIGFuIGluZGV4XG4gICAgICBjb25zdCBrZXkgPSBlcnJvci5tZXNzYWdlLm1hdGNoKC9maWVsZD0oW0EtWmEtel8wLTldKykgLylbMV07XG4gICAgICBpZiAoIWtleSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgdmFyIGluZGV4ID0ge307XG4gICAgICBpbmRleFtrZXldID0gJzJkJztcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvblxuICAgICAgICAgIC5jcmVhdGVJbmRleChpbmRleClcbiAgICAgICAgICAvLyBSZXRyeSwgYnV0IGp1c3Qgb25jZS5cbiAgICAgICAgICAudGhlbigoKSA9PlxuICAgICAgICAgICAgdGhpcy5fcmF3RmluZChxdWVyeSwge1xuICAgICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgICAgbWF4VGltZU1TLFxuICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICAgICAgICBleHBsYWluLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbGxhdGlvbiB0byBzdXBwb3J0IGNhc2UgaW5zZW5zaXRpdmUgcXVlcmllc1xuICAgKi9cbiAgc3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpIHtcbiAgICByZXR1cm4geyBsb2NhbGU6ICdlbl9VUycsIHN0cmVuZ3RoOiAyIH07XG4gIH1cblxuICBfcmF3RmluZChcbiAgICBxdWVyeSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgfSA9IHt9XG4gICkge1xuICAgIGxldCBmaW5kT3BlcmF0aW9uID0gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgIGhpbnQsXG4gICAgfSk7XG5cbiAgICBpZiAoa2V5cykge1xuICAgICAgZmluZE9wZXJhdGlvbiA9IGZpbmRPcGVyYXRpb24ucHJvamVjdChrZXlzKTtcbiAgICB9XG5cbiAgICBpZiAoY2FzZUluc2Vuc2l0aXZlKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5jb2xsYXRpb24oXG4gICAgICAgIE1vbmdvQ29sbGVjdGlvbi5jYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24oKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAobWF4VGltZU1TKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5tYXhUaW1lTVMobWF4VGltZU1TKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwbGFpbiA/IGZpbmRPcGVyYXRpb24uZXhwbGFpbihleHBsYWluKSA6IGZpbmRPcGVyYXRpb24udG9BcnJheSgpO1xuICB9XG5cbiAgY291bnQocXVlcnksIHsgc2tpcCwgbGltaXQsIHNvcnQsIG1heFRpbWVNUywgcmVhZFByZWZlcmVuY2UsIGhpbnQgfSA9IHt9KSB7XG4gICAgLy8gSWYgcXVlcnkgaXMgZW1wdHksIHRoZW4gdXNlIGVzdGltYXRlZERvY3VtZW50Q291bnQgaW5zdGVhZC5cbiAgICAvLyBUaGlzIGlzIGR1ZSB0byBjb3VudERvY3VtZW50cyBwZXJmb3JtaW5nIGEgc2NhbixcbiAgICAvLyB3aGljaCBncmVhdGx5IGluY3JlYXNlcyBleGVjdXRpb24gdGltZSB3aGVuIGJlaW5nIHJ1biBvbiBsYXJnZSBjb2xsZWN0aW9ucy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvbW9uZ29vc2UvaXNzdWVzLzY3MTMgZm9yIG1vcmUgaW5mbyByZWdhcmRpbmcgdGhpcyBwcm9ibGVtLlxuICAgIGlmICh0eXBlb2YgcXVlcnkgIT09ICdvYmplY3QnIHx8ICFPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmVzdGltYXRlZERvY3VtZW50Q291bnQoe1xuICAgICAgICBtYXhUaW1lTVMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudE9wZXJhdGlvbiA9IHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jb3VudERvY3VtZW50cyhxdWVyeSwge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgc29ydCxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICB9KTtcblxuICAgIHJldHVybiBjb3VudE9wZXJhdGlvbjtcbiAgfVxuXG4gIGRpc3RpbmN0KGZpZWxkLCBxdWVyeSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZGlzdGluY3QoZmllbGQsIHF1ZXJ5KTtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZShwaXBlbGluZSwgeyBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBleHBsYWluIH0gPSB7fSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb25cbiAgICAgIC5hZ2dyZWdhdGUocGlwZWxpbmUsIHsgbWF4VGltZU1TLCByZWFkUHJlZmVyZW5jZSwgaGludCwgZXhwbGFpbiB9KVxuICAgICAgLnRvQXJyYXkoKTtcbiAgfVxuXG4gIGluc2VydE9uZShvYmplY3QsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmluc2VydE9uZShvYmplY3QsIHsgc2Vzc2lvbiB9KTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgdXBkYXRlcyBkYXRhIGluIHRoZSBkYXRhYmFzZSBmb3IgYSBzaW5nbGUgKGZpcnN0KSBvYmplY3QgdGhhdCBtYXRjaGVkIHRoZSBxdWVyeVxuICAvLyBJZiB0aGVyZSBpcyBub3RoaW5nIHRoYXQgbWF0Y2hlcyB0aGUgcXVlcnkgLSBkb2VzIGluc2VydFxuICAvLyBQb3N0Z3JlcyBOb3RlOiBgSU5TRVJUIC4uLiBPTiBDT05GTElDVCBVUERBVEVgIHRoYXQgaXMgYXZhaWxhYmxlIHNpbmNlIDkuNS5cbiAgdXBzZXJ0T25lKHF1ZXJ5LCB1cGRhdGUsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlLCB7XG4gICAgICB1cHNlcnQ6IHRydWUsXG4gICAgICBzZXNzaW9uLFxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlT25lKHF1ZXJ5LCB1cGRhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlKTtcbiAgfVxuXG4gIHVwZGF0ZU1hbnkocXVlcnksIHVwZGF0ZSwgc2Vzc2lvbikge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24udXBkYXRlTWFueShxdWVyeSwgdXBkYXRlLCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBkZWxldGVNYW55KHF1ZXJ5LCBzZXNzaW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5kZWxldGVNYW55KHF1ZXJ5LCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhSZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChcbiAgICAgICAgaW5kZXhSZXF1ZXN0LFxuICAgICAgICB7IHVuaXF1ZTogdHJ1ZSwgYmFja2dyb3VuZDogdHJ1ZSwgc3BhcnNlOiB0cnVlIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBkcm9wKCkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZHJvcCgpO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js b/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js new file mode 100644 index 0000000000..88e30fc139 --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js @@ -0,0 +1,365 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function mongoFieldToParseSchemaField(type) { + if (type[0] === '*') { + return { + type: 'Pointer', + targetClass: type.slice(1) + }; + } + + if (type.startsWith('relation<')) { + return { + type: 'Relation', + targetClass: type.slice('relation<'.length, type.length - 1) + }; + } + + switch (type) { + case 'number': + return { + type: 'Number' + }; + + case 'string': + return { + type: 'String' + }; + + case 'boolean': + return { + type: 'Boolean' + }; + + case 'date': + return { + type: 'Date' + }; + + case 'map': + case 'object': + return { + type: 'Object' + }; + + case 'array': + return { + type: 'Array' + }; + + case 'geopoint': + return { + type: 'GeoPoint' + }; + + case 'file': + return { + type: 'File' + }; + + case 'bytes': + return { + type: 'Bytes' + }; + + case 'polygon': + return { + type: 'Polygon' + }; + } +} + +const nonFieldSchemaKeys = ['_id', '_metadata', '_client_permissions']; + +function mongoSchemaFieldsToParseSchemaFields(schema) { + var fieldNames = Object.keys(schema).filter(key => nonFieldSchemaKeys.indexOf(key) === -1); + var response = fieldNames.reduce((obj, fieldName) => { + obj[fieldName] = mongoFieldToParseSchemaField(schema[fieldName]); + + if (schema._metadata && schema._metadata.fields_options && schema._metadata.fields_options[fieldName]) { + obj[fieldName] = Object.assign({}, obj[fieldName], schema._metadata.fields_options[fieldName]); + } + + return obj; + }, {}); + response.ACL = { + type: 'ACL' + }; + response.createdAt = { + type: 'Date' + }; + response.updatedAt = { + type: 'Date' + }; + response.objectId = { + type: 'String' + }; + return response; +} + +const emptyCLPS = Object.freeze({ + find: {}, + count: {}, + get: {}, + create: {}, + update: {}, + delete: {}, + addField: {}, + protectedFields: {} +}); +const defaultCLPS = Object.freeze({ + find: { + '*': true + }, + count: { + '*': true + }, + get: { + '*': true + }, + create: { + '*': true + }, + update: { + '*': true + }, + delete: { + '*': true + }, + addField: { + '*': true + }, + protectedFields: { + '*': [] + } +}); + +function mongoSchemaToParseSchema(mongoSchema) { + let clps = defaultCLPS; + let indexes = {}; + + if (mongoSchema._metadata) { + if (mongoSchema._metadata.class_permissions) { + clps = _objectSpread(_objectSpread({}, emptyCLPS), mongoSchema._metadata.class_permissions); + } + + if (mongoSchema._metadata.indexes) { + indexes = _objectSpread({}, mongoSchema._metadata.indexes); + } + } + + return { + className: mongoSchema._id, + fields: mongoSchemaFieldsToParseSchemaFields(mongoSchema), + classLevelPermissions: clps, + indexes: indexes + }; +} + +function _mongoSchemaQueryFromNameQuery(name, query) { + const object = { + _id: name + }; + + if (query) { + Object.keys(query).forEach(key => { + object[key] = query[key]; + }); + } + + return object; +} // Returns a type suitable for inserting into mongo _SCHEMA collection. +// Does no validation. That is expected to be done in Parse Server. + + +function parseFieldTypeToMongoFieldType({ + type, + targetClass +}) { + switch (type) { + case 'Pointer': + return `*${targetClass}`; + + case 'Relation': + return `relation<${targetClass}>`; + + case 'Number': + return 'number'; + + case 'String': + return 'string'; + + case 'Boolean': + return 'boolean'; + + case 'Date': + return 'date'; + + case 'Object': + return 'object'; + + case 'Array': + return 'array'; + + case 'GeoPoint': + return 'geopoint'; + + case 'File': + return 'file'; + + case 'Bytes': + return 'bytes'; + + case 'Polygon': + return 'polygon'; + } +} + +class MongoSchemaCollection { + constructor(collection) { + this._collection = collection; + } + + _fetchAllSchemasFrom_SCHEMA() { + return this._collection._rawFind({}).then(schemas => schemas.map(mongoSchemaToParseSchema)); + } + + _fetchOneSchemaFrom_SCHEMA(name) { + return this._collection._rawFind(_mongoSchemaQueryFromNameQuery(name), { + limit: 1 + }).then(results => { + if (results.length === 1) { + return mongoSchemaToParseSchema(results[0]); + } else { + throw undefined; + } + }); + } // Atomically find and delete an object based on query. + + + findAndDeleteSchema(name) { + return this._collection._mongoCollection.findOneAndDelete(_mongoSchemaQueryFromNameQuery(name)); + } + + insertSchema(schema) { + return this._collection.insertOne(schema).then(result => mongoSchemaToParseSchema(result.ops[0])).catch(error => { + if (error.code === 11000) { + //Mongo's duplicate key error + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Class already exists.'); + } else { + throw error; + } + }); + } + + updateSchema(name, update) { + return this._collection.updateOne(_mongoSchemaQueryFromNameQuery(name), update); + } + + upsertSchema(name, query, update) { + return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update); + } // Add a field to the schema. If database does not support the field + // type (e.g. mongo doesn't support more than one GeoPoint in a class) reject with an "Incorrect Type" + // Parse error with a desciptive message. If the field already exists, this function must + // not modify the schema, and must reject with DUPLICATE_VALUE error. + // If this is called for a class that doesn't exist, this function must create that class. + // TODO: throw an error if an unsupported field type is passed. Deciding whether a type is supported + // should be the job of the adapter. Some adapters may not support GeoPoint at all. Others may + // Support additional types that Mongo doesn't, like Money, or something. + // TODO: don't spend an extra query on finding the schema if the type we are trying to add isn't a GeoPoint. + + + addFieldIfNotExists(className, fieldName, fieldType) { + return this._fetchOneSchemaFrom_SCHEMA(className).then(schema => { + // If a field with this name already exists, it will be handled elsewhere. + if (schema.fields[fieldName] != undefined) { + return; + } // The schema exists. Check for existing GeoPoints. + + + if (fieldType.type === 'GeoPoint') { + // Make sure there are not other geopoint fields + if (Object.keys(schema.fields).some(existingField => schema.fields[existingField].type === 'GeoPoint')) { + throw new _node.default.Error(_node.default.Error.INCORRECT_TYPE, 'MongoDB only supports one GeoPoint field in a class.'); + } + } + + return; + }, error => { + // If error is undefined, the schema doesn't exist, and we can create the schema with the field. + // If some other error, reject with it. + if (error === undefined) { + return; + } + + throw error; + }).then(() => { + const { + type, + targetClass + } = fieldType, + fieldOptions = _objectWithoutProperties(fieldType, ["type", "targetClass"]); // We use $exists and $set to avoid overwriting the field type if it + // already exists. (it could have added inbetween the last query and the update) + + + if (fieldOptions && Object.keys(fieldOptions).length > 0) { + return this.upsertSchema(className, { + [fieldName]: { + $exists: false + } + }, { + $set: { + [fieldName]: parseFieldTypeToMongoFieldType({ + type, + targetClass + }), + [`_metadata.fields_options.${fieldName}`]: fieldOptions + } + }); + } else { + return this.upsertSchema(className, { + [fieldName]: { + $exists: false + } + }, { + $set: { + [fieldName]: parseFieldTypeToMongoFieldType({ + type, + targetClass + }) + } + }); + } + }); + } + +} // Exported for testing reasons and because we haven't moved all mongo schema format +// related logic into the database adapter yet. + + +MongoSchemaCollection._TESTmongoSchemaToParseSchema = mongoSchemaToParseSchema; +MongoSchemaCollection.parseFieldTypeToMongoFieldType = parseFieldTypeToMongoFieldType; +var _default = MongoSchemaCollection; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU2NoZW1hQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkIiwidHlwZSIsInRhcmdldENsYXNzIiwic2xpY2UiLCJzdGFydHNXaXRoIiwibGVuZ3RoIiwibm9uRmllbGRTY2hlbWFLZXlzIiwibW9uZ29TY2hlbWFGaWVsZHNUb1BhcnNlU2NoZW1hRmllbGRzIiwic2NoZW1hIiwiZmllbGROYW1lcyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJpbmRleE9mIiwicmVzcG9uc2UiLCJyZWR1Y2UiLCJvYmoiLCJmaWVsZE5hbWUiLCJfbWV0YWRhdGEiLCJmaWVsZHNfb3B0aW9ucyIsImFzc2lnbiIsIkFDTCIsImNyZWF0ZWRBdCIsInVwZGF0ZWRBdCIsIm9iamVjdElkIiwiZW1wdHlDTFBTIiwiZnJlZXplIiwiZmluZCIsImNvdW50IiwiZ2V0IiwiY3JlYXRlIiwidXBkYXRlIiwiZGVsZXRlIiwiYWRkRmllbGQiLCJwcm90ZWN0ZWRGaWVsZHMiLCJkZWZhdWx0Q0xQUyIsIm1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSIsIm1vbmdvU2NoZW1hIiwiY2xwcyIsImluZGV4ZXMiLCJjbGFzc19wZXJtaXNzaW9ucyIsImNsYXNzTmFtZSIsIl9pZCIsImZpZWxkcyIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIl9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeSIsIm5hbWUiLCJxdWVyeSIsIm9iamVjdCIsImZvckVhY2giLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsImNvbGxlY3Rpb24iLCJfY29sbGVjdGlvbiIsIl9mZXRjaEFsbFNjaGVtYXNGcm9tX1NDSEVNQSIsIl9yYXdGaW5kIiwidGhlbiIsInNjaGVtYXMiLCJtYXAiLCJfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQSIsImxpbWl0IiwicmVzdWx0cyIsInVuZGVmaW5lZCIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJfbW9uZ29Db2xsZWN0aW9uIiwiZmluZE9uZUFuZERlbGV0ZSIsImluc2VydFNjaGVtYSIsImluc2VydE9uZSIsInJlc3VsdCIsIm9wcyIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiUGFyc2UiLCJFcnJvciIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZVNjaGVtYSIsInVwZGF0ZU9uZSIsInVwc2VydFNjaGVtYSIsInVwc2VydE9uZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJmaWVsZFR5cGUiLCJzb21lIiwiZXhpc3RpbmdGaWVsZCIsIklOQ09SUkVDVF9UWVBFIiwiZmllbGRPcHRpb25zIiwiJGV4aXN0cyIsIiRzZXQiLCJfVEVTVG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLFNBQVNBLDRCQUFULENBQXNDQyxJQUF0QyxFQUE0QztBQUMxQyxNQUFJQSxJQUFJLENBQUMsQ0FBRCxDQUFKLEtBQVksR0FBaEIsRUFBcUI7QUFDbkIsV0FBTztBQUNMQSxNQUFBQSxJQUFJLEVBQUUsU0FERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLENBQVg7QUFGUixLQUFQO0FBSUQ7O0FBQ0QsTUFBSUYsSUFBSSxDQUFDRyxVQUFMLENBQWdCLFdBQWhCLENBQUosRUFBa0M7QUFDaEMsV0FBTztBQUNMSCxNQUFBQSxJQUFJLEVBQUUsVUFERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLFlBQVlFLE1BQXZCLEVBQStCSixJQUFJLENBQUNJLE1BQUwsR0FBYyxDQUE3QztBQUZSLEtBQVA7QUFJRDs7QUFDRCxVQUFRSixJQUFSO0FBQ0UsU0FBSyxRQUFMO0FBQ0UsYUFBTztBQUFFQSxRQUFBQSxJQUFJLEVBQUU7QUFBUixPQUFQ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QUE4QixDQUFDO0FBQzFDbEQsY0FBQUEsSUFEMEM7QUFFMUNDLGNBQUFBO0FBRjBDLGFBQUQ7QUFEdkM7QUFEUixTQUhLLENBQVA7QUFZRDtBQUNGLEtBakVJLENBQVA7QUFrRUQ7O0FBN0l5QixDLENBZ0o1QjtBQUNBOzs7QUFDQWtELHFCQUFxQixDQUFDc0MsNkJBQXRCLEdBQXNEckQsd0JBQXREO0FBQ0FlLHFCQUFxQixDQUFDRCw4QkFBdEIsR0FBdURBLDhCQUF2RDtlQUVlQyxxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNb25nb0NvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5mdW5jdGlvbiBtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkKHR5cGUpIHtcbiAgaWYgKHR5cGVbMF0gPT09ICcqJykge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnUG9pbnRlcicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgxKSxcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3JlbGF0aW9uPCcpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgncmVsYXRpb248Jy5sZW5ndGgsIHR5cGUubGVuZ3RoIC0gMSksXG4gICAgfTtcbiAgfVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ051bWJlcicgfTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB7IHR5cGU6ICdCb29sZWFuJyB9O1xuICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0RhdGUnIH07XG4gICAgY2FzZSAnbWFwJzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICBjYXNlICdhcnJheSc6XG4gICAgICByZXR1cm4geyB0eXBlOiAnQXJyYXknIH07XG4gICAgY2FzZSAnZ2VvcG9pbnQnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0dlb1BvaW50JyB9O1xuICAgIGNhc2UgJ2ZpbGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0ZpbGUnIH07XG4gICAgY2FzZSAnYnl0ZXMnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0J5dGVzJyB9O1xuICAgIGNhc2UgJ3BvbHlnb24nOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1BvbHlnb24nIH07XG4gIH1cbn1cblxuY29uc3Qgbm9uRmllbGRTY2hlbWFLZXlzID0gWydfaWQnLCAnX21ldGFkYXRhJywgJ19jbGllbnRfcGVybWlzc2lvbnMnXTtcbmZ1bmN0aW9uIG1vbmdvU2NoZW1hRmllbGRzVG9QYXJzZVNjaGVtYUZpZWxkcyhzY2hlbWEpIHtcbiAgdmFyIGZpZWxkTmFtZXMgPSBPYmplY3Qua2V5cyhzY2hlbWEpLmZpbHRlcihcbiAgICAoa2V5KSA9PiBub25GaWVsZFNjaGVtYUtleXMuaW5kZXhPZihrZXkpID09PSAtMVxuICApO1xuICB2YXIgcmVzcG9uc2UgPSBmaWVsZE5hbWVzLnJlZHVjZSgob2JqLCBmaWVsZE5hbWUpID0+IHtcbiAgICBvYmpbZmllbGROYW1lXSA9IG1vbmdvRmllbGRUb1BhcnNlU2NoZW1hRmllbGQoc2NoZW1hW2ZpZWxkTmFtZV0pO1xuICAgIGlmIChcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICkge1xuICAgICAgb2JqW2ZpZWxkTmFtZV0gPSBPYmplY3QuYXNzaWduKFxuICAgICAgICB7fSxcbiAgICAgICAgb2JqW2ZpZWxkTmFtZV0sXG4gICAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xuICByZXNwb25zZS5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG4gIHJlc3BvbnNlLmNyZWF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLnVwZGF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLm9iamVjdElkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbmNvbnN0IGVtcHR5Q0xQUyA9IE9iamVjdC5mcmVlemUoe1xuICBmaW5kOiB7fSxcbiAgY291bnQ6IHt9LFxuICBnZXQ6IHt9LFxuICBjcmVhdGU6IHt9LFxuICB1cGRhdGU6IHt9LFxuICBkZWxldGU6IHt9LFxuICBhZGRGaWVsZDoge30sXG4gIHByb3RlY3RlZEZpZWxkczoge30sXG59KTtcblxuY29uc3QgZGVmYXVsdENMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDogeyAnKic6IHRydWUgfSxcbiAgY291bnQ6IHsgJyonOiB0cnVlIH0sXG4gIGdldDogeyAnKic6IHRydWUgfSxcbiAgY3JlYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICB1cGRhdGU6IHsgJyonOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyAnKic6IHRydWUgfSxcbiAgYWRkRmllbGQ6IHsgJyonOiB0cnVlIH0sXG4gIHByb3RlY3RlZEZpZWxkczogeyAnKic6IFtdIH0sXG59KTtcblxuZnVuY3Rpb24gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKG1vbmdvU2NoZW1hKSB7XG4gIGxldCBjbHBzID0gZGVmYXVsdENMUFM7XG4gIGxldCBpbmRleGVzID0ge307XG4gIGlmIChtb25nb1NjaGVtYS5fbWV0YWRhdGEpIHtcbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zKSB7XG4gICAgICBjbHBzID0geyAuLi5lbXB0eUNMUFMsIC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyB9O1xuICAgIH1cbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmluZGV4ZXMpIHtcbiAgICAgIGluZGV4ZXMgPSB7IC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5pbmRleGVzIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgY2xhc3NOYW1lOiBtb25nb1NjaGVtYS5faWQsXG4gICAgZmllbGRzOiBtb25nb1NjaGVtYUZpZWxkc1RvUGFyc2VTY2hlbWFGaWVsZHMobW9uZ29TY2hlbWEpLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogY2xwcyxcbiAgICBpbmRleGVzOiBpbmRleGVzLFxuICB9O1xufVxuXG5mdW5jdGlvbiBfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZTogc3RyaW5nLCBxdWVyeSkge1xuICBjb25zdCBvYmplY3QgPSB7IF9pZDogbmFtZSB9O1xuICBpZiAocXVlcnkpIHtcbiAgICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBvYmplY3Rba2V5XSA9IHF1ZXJ5W2tleV07XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxuLy8gUmV0dXJucyBhIHR5cGUgc3VpdGFibGUgZm9yIGluc2VydGluZyBpbnRvIG1vbmdvIF9TQ0hFTUEgY29sbGVjdGlvbi5cbi8vIERvZXMgbm8gdmFsaWRhdGlvbi4gVGhhdCBpcyBleHBlY3RlZCB0byBiZSBkb25lIGluIFBhcnNlIFNlcnZlci5cbmZ1bmN0aW9uIHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSh7IHR5cGUsIHRhcmdldENsYXNzIH0pIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICByZXR1cm4gYCoke3RhcmdldENsYXNzfWA7XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgcmV0dXJuIGByZWxhdGlvbjwke3RhcmdldENsYXNzfT5gO1xuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICByZXR1cm4gJ251bWJlcic7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiAnYm9vbGVhbic7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgICByZXR1cm4gJ2RhdGUnO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuICdhcnJheSc7XG4gICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgcmV0dXJuICdnZW9wb2ludCc7XG4gICAgY2FzZSAnRmlsZSc6XG4gICAgICByZXR1cm4gJ2ZpbGUnO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiAnYnl0ZXMnO1xuICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgcmV0dXJuICdwb2x5Z29uJztcbiAgfVxufVxuXG5jbGFzcyBNb25nb1NjaGVtYUNvbGxlY3Rpb24ge1xuICBfY29sbGVjdGlvbjogTW9uZ29Db2xsZWN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKGNvbGxlY3Rpb246IE1vbmdvQ29sbGVjdGlvbikge1xuICAgIHRoaXMuX2NvbGxlY3Rpb24gPSBjb2xsZWN0aW9uO1xuICB9XG5cbiAgX2ZldGNoQWxsU2NoZW1hc0Zyb21fU0NIRU1BKCkge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uXG4gICAgICAuX3Jhd0ZpbmQoe30pXG4gICAgICAudGhlbigoc2NoZW1hcykgPT4gc2NoZW1hcy5tYXAobW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKSk7XG4gIH1cblxuICBfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvblxuICAgICAgLl9yYXdGaW5kKF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSwgeyBsaW1pdDogMSB9KVxuICAgICAgLnRoZW4oKHJlc3VsdHMpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgcmV0dXJuIG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYShyZXN1bHRzWzBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gQXRvbWljYWxseSBmaW5kIGFuZCBkZWxldGUgYW4gb2JqZWN0IGJhc2VkIG9uIHF1ZXJ5LlxuICBmaW5kQW5kRGVsZXRlU2NoZW1hKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZmluZE9uZUFuZERlbGV0ZShcbiAgICAgIF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKVxuICAgICk7XG4gIH1cblxuICBpbnNlcnRTY2hlbWEoc2NoZW1hOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvblxuICAgICAgLmluc2VydE9uZShzY2hlbWEpXG4gICAgICAudGhlbigocmVzdWx0KSA9PiBtb25nb1NjaGVtYVRvUGFyc2VTY2hlbWEocmVzdWx0Lm9wc1swXSkpXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIC8vTW9uZ28ncyBkdXBsaWNhdGUga2V5IGVycm9yXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ0NsYXNzIGFscmVhZHkgZXhpc3RzLidcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZVNjaGVtYShuYW1lOiBzdHJpbmcsIHVwZGF0ZSkge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uLnVwZGF0ZU9uZShcbiAgICAgIF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSxcbiAgICAgIHVwZGF0ZVxuICAgICk7XG4gIH1cblxuICB1cHNlcnRTY2hlbWEobmFtZTogc3RyaW5nLCBxdWVyeTogc3RyaW5nLCB1cGRhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvbi51cHNlcnRPbmUoXG4gICAgICBfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZSwgcXVlcnkpLFxuICAgICAgdXBkYXRlXG4gICAgKTtcbiAgfVxuXG4gIC8vIEFkZCBhIGZpZWxkIHRvIHRoZSBzY2hlbWEuIElmIGRhdGFiYXNlIGRvZXMgbm90IHN1cHBvcnQgdGhlIGZpZWxkXG4gIC8vIHR5cGUgKGUuZy4gbW9uZ28gZG9lc24ndCBzdXBwb3J0IG1vcmUgdGhhbiBvbmUgR2VvUG9pbnQgaW4gYSBjbGFzcykgcmVqZWN0IHdpdGggYW4gXCJJbmNvcnJlY3QgVHlwZVwiXG4gIC8vIFBhcnNlIGVycm9yIHdpdGggYSBkZXNjaXB0aXZlIG1lc3NhZ2UuIElmIHRoZSBmaWVsZCBhbHJlYWR5IGV4aXN0cywgdGhpcyBmdW5jdGlvbiBtdXN0XG4gIC8vIG5vdCBtb2RpZnkgdGhlIHNjaGVtYSwgYW5kIG11c3QgcmVqZWN0IHdpdGggRFVQTElDQVRFX1ZBTFVFIGVycm9yLlxuICAvLyBJZiB0aGlzIGlzIGNhbGxlZCBmb3IgYSBjbGFzcyB0aGF0IGRvZXNuJ3QgZXhpc3QsIHRoaXMgZnVuY3Rpb24gbXVzdCBjcmVhdGUgdGhhdCBjbGFzcy5cblxuICAvLyBUT0RPOiB0aHJvdyBhbiBlcnJvciBpZiBhbiB1bnN1cHBvcnRlZCBmaWVsZCB0eXBlIGlzIHBhc3NlZC4gRGVjaWRpbmcgd2hldGhlciBhIHR5cGUgaXMgc3VwcG9ydGVkXG4gIC8vIHNob3VsZCBiZSB0aGUgam9iIG9mIHRoZSBhZGFwdGVyLiBTb21lIGFkYXB0ZXJzIG1heSBub3Qgc3VwcG9ydCBHZW9Qb2ludCBhdCBhbGwuIE90aGVycyBtYXlcbiAgLy8gU3VwcG9ydCBhZGRpdGlvbmFsIHR5cGVzIHRoYXQgTW9uZ28gZG9lc24ndCwgbGlrZSBNb25leSwgb3Igc29tZXRoaW5nLlxuXG4gIC8vIFRPRE86IGRvbid0IHNwZW5kIGFuIGV4dHJhIHF1ZXJ5IG9uIGZpbmRpbmcgdGhlIHNjaGVtYSBpZiB0aGUgdHlwZSB3ZSBhcmUgdHJ5aW5nIHRvIGFkZCBpc24ndCBhIEdlb1BvaW50LlxuICBhZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZywgZmllbGRUeXBlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShjbGFzc05hbWUpXG4gICAgICAudGhlbihcbiAgICAgICAgKHNjaGVtYSkgPT4ge1xuICAgICAgICAgIC8vIElmIGEgZmllbGQgd2l0aCB0aGlzIG5hbWUgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgaGFuZGxlZCBlbHNld2hlcmUuXG4gICAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBleGlzdHMuIENoZWNrIGZvciBleGlzdGluZyBHZW9Qb2ludHMuXG4gICAgICAgICAgaWYgKGZpZWxkVHlwZS50eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIG5vdCBvdGhlciBnZW9wb2ludCBmaWVsZHNcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuc29tZShcbiAgICAgICAgICAgICAgICAoZXhpc3RpbmdGaWVsZCkgPT5cbiAgICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNbZXhpc3RpbmdGaWVsZF0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICAgICdNb25nb0RCIG9ubHkgc3VwcG9ydHMgb25lIEdlb1BvaW50IGZpZWxkIGluIGEgY2xhc3MuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIC8vIElmIGVycm9yIGlzIHVuZGVmaW5lZCwgdGhlIHNjaGVtYSBkb2Vzbid0IGV4aXN0LCBhbmQgd2UgY2FuIGNyZWF0ZSB0aGUgc2NoZW1hIHdpdGggdGhlIGZpZWxkLlxuICAgICAgICAgIC8vIElmIHNvbWUgb3RoZXIgZXJyb3IsIHJlamVjdCB3aXRoIGl0LlxuICAgICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgdGFyZ2V0Q2xhc3MsIC4uLmZpZWxkT3B0aW9ucyB9ID0gZmllbGRUeXBlO1xuICAgICAgICAvLyBXZSB1c2UgJGV4aXN0cyBhbmQgJHNldCB0byBhdm9pZCBvdmVyd3JpdGluZyB0aGUgZmllbGQgdHlwZSBpZiBpdFxuICAgICAgICAvLyBhbHJlYWR5IGV4aXN0cy4gKGl0IGNvdWxkIGhhdmUgYWRkZWQgaW5iZXR3ZWVuIHRoZSBsYXN0IHF1ZXJ5IGFuZCB0aGUgdXBkYXRlKVxuICAgICAgICBpZiAoZmllbGRPcHRpb25zICYmIE9iamVjdC5rZXlzKGZpZWxkT3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVwc2VydFNjaGVtYShcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHsgW2ZpZWxkTmFtZV06IHsgJGV4aXN0czogZmFsc2UgfSB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAkc2V0OiB7XG4gICAgICAgICAgICAgICAgW2ZpZWxkTmFtZV06IHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgW2BfbWV0YWRhdGEuZmllbGRzX29wdGlvbnMuJHtmaWVsZE5hbWV9YF06IGZpZWxkT3B0aW9ucyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVwc2VydFNjaGVtYShcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHsgW2ZpZWxkTmFtZV06IHsgJGV4aXN0czogZmFsc2UgfSB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAkc2V0OiB7XG4gICAgICAgICAgICAgICAgW2ZpZWxkTmFtZV06IHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cblxuLy8gRXhwb3J0ZWQgZm9yIHRlc3RpbmcgcmVhc29ucyBhbmQgYmVjYXVzZSB3ZSBoYXZlbid0IG1vdmVkIGFsbCBtb25nbyBzY2hlbWEgZm9ybWF0XG4vLyByZWxhdGVkIGxvZ2ljIGludG8gdGhlIGRhdGFiYXNlIGFkYXB0ZXIgeWV0LlxuTW9uZ29TY2hlbWFDb2xsZWN0aW9uLl9URVNUbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hID0gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hO1xuTW9uZ29TY2hlbWFDb2xsZWN0aW9uLnBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSA9IHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZTtcblxuZXhwb3J0IGRlZmF1bHQgTW9uZ29TY2hlbWFDb2xsZWN0aW9uO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js b/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js new file mode 100644 index 0000000000..b407a600dc --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -0,0 +1,957 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.MongoStorageAdapter = void 0; + +var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); + +var _MongoSchemaCollection = _interopRequireDefault(require("./MongoSchemaCollection")); + +var _StorageAdapter = require("../StorageAdapter"); + +var _mongodbUrl = require("../../../vendor/mongodbUrl"); + +var _MongoTransform = require("./MongoTransform"); + +var _node = _interopRequireDefault(require("parse/node")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _defaults = _interopRequireDefault(require("../../../defaults")); + +var _logger = _interopRequireDefault(require("../../../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + +// -disable-next +const mongodb = require('mongodb'); + +const MongoClient = mongodb.MongoClient; +const ReadPreference = mongodb.ReadPreference; +const MongoSchemaCollectionName = '_SCHEMA'; + +const storageAdapterAllCollections = mongoAdapter => { + return mongoAdapter.connect().then(() => mongoAdapter.database.collections()).then(collections => { + return collections.filter(collection => { + if (collection.namespace.match(/\.system\./)) { + return false; + } // TODO: If you have one app with a collection prefix that happens to be a prefix of another + // apps prefix, this will go very very badly. We should fix that somehow. + + + return collection.collectionName.indexOf(mongoAdapter._collectionPrefix) == 0; + }); + }); +}; + +const convertParseSchemaToMongoSchema = (_ref) => { + let schema = _extends({}, _ref); + + delete schema.fields._rperm; + delete schema.fields._wperm; + + if (schema.className === '_User') { + // Legacy mongo adapter knows about the difference between password and _hashed_password. + // Future database adapters will only know about _hashed_password. + // Note: Parse Server will bring back password with injectDefaultSchema, so we don't need + // to add _hashed_password back ever. + delete schema.fields._hashed_password; + } + + return schema; +}; // Returns { code, error } if invalid, or { result }, an object +// suitable for inserting into _SCHEMA collection, otherwise. + + +const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPermissions, indexes) => { + const mongoObject = { + _id: className, + objectId: 'string', + updatedAt: 'string', + createdAt: 'string', + _metadata: undefined + }; + + for (const fieldName in fields) { + const _fields$fieldName = fields[fieldName], + { + type, + targetClass + } = _fields$fieldName, + fieldOptions = _objectWithoutProperties(_fields$fieldName, ["type", "targetClass"]); + + mongoObject[fieldName] = _MongoSchemaCollection.default.parseFieldTypeToMongoFieldType({ + type, + targetClass + }); + + if (fieldOptions && Object.keys(fieldOptions).length > 0) { + mongoObject._metadata = mongoObject._metadata || {}; + mongoObject._metadata.fields_options = mongoObject._metadata.fields_options || {}; + mongoObject._metadata.fields_options[fieldName] = fieldOptions; + } + } + + if (typeof classLevelPermissions !== 'undefined') { + mongoObject._metadata = mongoObject._metadata || {}; + + if (!classLevelPermissions) { + delete mongoObject._metadata.class_permissions; + } else { + mongoObject._metadata.class_permissions = classLevelPermissions; + } + } + + if (indexes && typeof indexes === 'object' && Object.keys(indexes).length > 0) { + mongoObject._metadata = mongoObject._metadata || {}; + mongoObject._metadata.indexes = indexes; + } + + if (!mongoObject._metadata) { + // cleanup the unused _metadata + delete mongoObject._metadata; + } + + return mongoObject; +}; + +class MongoStorageAdapter { + // Private + // Public + constructor({ + uri = _defaults.default.DefaultMongoURI, + collectionPrefix = '', + mongoOptions = {} + }) { + this._uri = uri; + this._collectionPrefix = collectionPrefix; + this._mongoOptions = mongoOptions; + this._mongoOptions.useNewUrlParser = true; + this._mongoOptions.useUnifiedTopology = true; // MaxTimeMS is not a global MongoDB client option, it is applied per operation. + + this._maxTimeMS = mongoOptions.maxTimeMS; + this.canSortOnJoinTables = true; + delete mongoOptions.maxTimeMS; + } + + connect() { + if (this.connectionPromise) { + return this.connectionPromise; + } // parsing and re-formatting causes the auth value (if there) to get URI + // encoded + + + const encodedUri = (0, _mongodbUrl.format)((0, _mongodbUrl.parse)(this._uri)); + this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions).then(client => { + // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client + // Fortunately, we can get back the options and use them to select the proper DB. + // https://github.com/mongodb/node-mongodb-native/blob/2c35d76f08574225b8db02d7bef687123e6bb018/lib/mongo_client.js#L885 + const options = client.s.options; + const database = client.db(options.dbName); + + if (!database) { + delete this.connectionPromise; + return; + } + + database.on('error', () => { + delete this.connectionPromise; + }); + database.on('close', () => { + delete this.connectionPromise; + }); + this.client = client; + this.database = database; + }).catch(err => { + delete this.connectionPromise; + return Promise.reject(err); + }); + return this.connectionPromise; + } + + handleError(error) { + if (error && error.code === 13) { + // Unauthorized error + delete this.client; + delete this.database; + delete this.connectionPromise; + + _logger.default.error('Received unauthorized error', { + error: error + }); + } + + throw error; + } + + handleShutdown() { + if (!this.client) { + return Promise.resolve(); + } + + return this.client.close(false); + } + + _adaptiveCollection(name) { + return this.connect().then(() => this.database.collection(this._collectionPrefix + name)).then(rawCollection => new _MongoCollection.default(rawCollection)).catch(err => this.handleError(err)); + } + + _schemaCollection() { + return this.connect().then(() => this._adaptiveCollection(MongoSchemaCollectionName)).then(collection => new _MongoSchemaCollection.default(collection)); + } + + classExists(name) { + return this.connect().then(() => { + return this.database.listCollections({ + name: this._collectionPrefix + name + }).toArray(); + }).then(collections => { + return collections.length > 0; + }).catch(err => this.handleError(err)); + } + + setClassLevelPermissions(className, CLPs) { + return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { + $set: { + '_metadata.class_permissions': CLPs + } + })).catch(err => this.handleError(err)); + } + + setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields) { + if (submittedIndexes === undefined) { + return Promise.resolve(); + } + + if (Object.keys(existingIndexes).length === 0) { + existingIndexes = { + _id_: { + _id: 1 + } + }; + } + + const deletePromises = []; + const insertedIndexes = []; + Object.keys(submittedIndexes).forEach(name => { + const field = submittedIndexes[name]; + + if (existingIndexes[name] && field.__op !== 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); + } + + if (!existingIndexes[name] && field.__op === 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); + } + + if (field.__op === 'Delete') { + const promise = this.dropIndex(className, name); + deletePromises.push(promise); + delete existingIndexes[name]; + } else { + Object.keys(field).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(fields, key.indexOf('_p_') === 0 ? key.replace('_p_', '') : key)) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); + } + }); + existingIndexes[name] = field; + insertedIndexes.push({ + key: field, + name + }); + } + }); + let insertPromise = Promise.resolve(); + + if (insertedIndexes.length > 0) { + insertPromise = this.createIndexes(className, insertedIndexes); + } + + return Promise.all(deletePromises).then(() => insertPromise).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, { + $set: { + '_metadata.indexes': existingIndexes + } + })).catch(err => this.handleError(err)); + } + + setIndexesFromMongo(className) { + return this.getIndexes(className).then(indexes => { + indexes = indexes.reduce((obj, index) => { + if (index.key._fts) { + delete index.key._fts; + delete index.key._ftsx; + + for (const field in index.weights) { + index.key[field] = 'text'; + } + } + + obj[index.name] = index.key; + return obj; + }, {}); + return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { + $set: { + '_metadata.indexes': indexes + } + })); + }).catch(err => this.handleError(err)).catch(() => { + // Ignore if collection not found + return Promise.resolve(); + }); + } + + createClass(className, schema) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions, schema.indexes); + mongoObject._id = className; + return this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.insertSchema(mongoObject)).catch(err => this.handleError(err)); + } + + addFieldIfNotExists(className, fieldName, type) { + return this._schemaCollection().then(schemaCollection => schemaCollection.addFieldIfNotExists(className, fieldName, type)).then(() => this.createIndexesIfNeeded(className, fieldName, type)).catch(err => this.handleError(err)); + } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) + // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. + + + deleteClass(className) { + return this._adaptiveCollection(className).then(collection => collection.drop()).catch(error => { + // 'ns not found' means collection was already gone. Ignore deletion attempt. + if (error.message == 'ns not found') { + return; + } + + throw error; + }) // We've dropped the collection, now remove the _SCHEMA document + .then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.findAndDeleteSchema(className)).catch(err => this.handleError(err)); + } + + deleteAllClasses(fast) { + return storageAdapterAllCollections(this).then(collections => Promise.all(collections.map(collection => fast ? collection.deleteMany({}) : collection.drop()))); + } // Remove the column and all the data. For Relations, the _Join collection is handled + // specially, this function does not delete _Join columns. It should, however, indicate + // that the relation fields does not exist anymore. In mongo, this means removing it from + // the _SCHEMA collection. There should be no actual data in the collection under the same name + // as the relation column, so it's fine to attempt to delete it. If the fields listed to be + // deleted do not exist, this function should return successfully anyways. Checking for + // attempts to delete non-existent fields is the responsibility of Parse Server. + // Pointer field names are passed for legacy reasons: the original mongo + // format stored pointer field names differently in the database, and therefore + // needed to know the type of the field before it could delete it. Future database + // adapters should ignore the pointerFieldNames argument. All the field names are in + // fieldNames, they show up additionally in the pointerFieldNames database for use + // by the mongo adapter, which deals with the legacy mongo format. + // This function is not obligated to delete fields atomically. It is given the field + // names in a list so that databases that are capable of deleting fields atomically + // may do so. + // Returns a Promise. + + + deleteFields(className, schema, fieldNames) { + const mongoFormatNames = fieldNames.map(fieldName => { + if (schema.fields[fieldName].type === 'Pointer') { + return `_p_${fieldName}`; + } else { + return fieldName; + } + }); + const collectionUpdate = { + $unset: {} + }; + mongoFormatNames.forEach(name => { + collectionUpdate['$unset'][name] = null; + }); + const collectionFilter = { + $or: [] + }; + mongoFormatNames.forEach(name => { + collectionFilter['$or'].push({ + [name]: { + $exists: true + } + }); + }); + const schemaUpdate = { + $unset: {} + }; + fieldNames.forEach(name => { + schemaUpdate['$unset'][name] = null; + schemaUpdate['$unset'][`_metadata.fields_options.${name}`] = null; + }); + return this._adaptiveCollection(className).then(collection => collection.updateMany(collectionFilter, collectionUpdate)).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, schemaUpdate)).catch(err => this.handleError(err)); + } // Return a promise for all schemas known to this adapter, in Parse format. In case the + // schemas cannot be retrieved, returns a promise that rejects. Requirements for the + // rejection reason are TBD. + + + getAllClasses() { + return this._schemaCollection().then(schemasCollection => schemasCollection._fetchAllSchemasFrom_SCHEMA()).catch(err => this.handleError(err)); + } // Return a promise for the schema with the given name, in Parse format. If + // this adapter doesn't know about the schema, return a promise that rejects with + // undefined as the reason. + + + getClass(className) { + return this._schemaCollection().then(schemasCollection => schemasCollection._fetchOneSchemaFrom_SCHEMA(className)).catch(err => this.handleError(err)); + } // TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema, + // and should infer from the type. Or maybe does need the schema for validations. Or maybe needs + // the schema only for the legacy mongo format. We'll figure that out later. + + + createObject(className, schema, object, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoObject = (0, _MongoTransform.parseObjectToMongoObjectForCreate)(className, object, schema); + return this._adaptiveCollection(className).then(collection => collection.insertOne(mongoObject, transactionalSession)).catch(error => { + if (error.code === 11000) { + // Duplicate value + const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + err.underlyingError = error; + + if (error.message) { + const matches = error.message.match(/index:[\sa-zA-Z0-9_\-\.]+\$?([a-zA-Z_-]+)_1/); + + if (matches && Array.isArray(matches)) { + err.userInfo = { + duplicated_field: matches[1] + }; + } + } + + throw err; + } + + throw error; + }).catch(err => this.handleError(err)); + } // Remove all objects that match the given Parse Query. + // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. + // If there is some other error, reject with INTERNAL_SERVER_ERROR. + + + deleteObjectsByQuery(className, schema, query, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + return this._adaptiveCollection(className).then(collection => { + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return collection.deleteMany(mongoWhere, transactionalSession); + }).catch(err => this.handleError(err)).then(({ + result + }) => { + if (result.n === 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + return Promise.resolve(); + }, () => { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error'); + }); + } // Apply the update to all objects that match the given Parse Query. + + + updateObjectsByQuery(className, schema, query, update, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return this._adaptiveCollection(className).then(collection => collection.updateMany(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); + } // Atomically finds and updates an object based on query. + // Return value not currently well specified. + + + findOneAndUpdate(className, schema, query, update, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.findOneAndUpdate(mongoWhere, mongoUpdate, { + returnOriginal: false, + session: transactionalSession || undefined + })).then(result => (0, _MongoTransform.mongoObjectToParseObject)(className, result.value, schema)).catch(error => { + if (error.code === 11000) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + } + + throw error; + }).catch(err => this.handleError(err)); + } // Hopefully we can get rid of this. It's only used for config and hooks. + + + upsertOneObject(className, schema, query, update, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return this._adaptiveCollection(className).then(collection => collection.upsertOne(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); + } // Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }. + + + find(className, schema, query, { + skip, + limit, + sort, + keys, + readPreference, + hint, + caseInsensitive, + explain + }) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + + const mongoSort = _lodash.default.mapKeys(sort, (value, fieldName) => (0, _MongoTransform.transformKey)(className, fieldName, schema)); + + const mongoKeys = _lodash.default.reduce(keys, (memo, key) => { + if (key === 'ACL') { + memo['_rperm'] = 1; + memo['_wperm'] = 1; + } else { + memo[(0, _MongoTransform.transformKey)(className, key, schema)] = 1; + } + + return memo; + }, {}); // If we aren't requesting the `_id` field, we need to explicitly opt out + // of it. Doing so in parse-server is unusual, but it can allow us to + // optimize some queries with covering indexes. + + + if (keys && !mongoKeys._id) { + mongoKeys._id = 0; + } + + readPreference = this._parseReadPreference(readPreference); + return this.createTextIndexesIfNeeded(className, query, schema).then(() => this._adaptiveCollection(className)).then(collection => collection.find(mongoWhere, { + skip, + limit, + sort: mongoSort, + keys: mongoKeys, + maxTimeMS: this._maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + })).then(objects => { + if (explain) { + return objects; + } + + return objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema)); + }).catch(err => this.handleError(err)); + } + + ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { + schema = convertParseSchemaToMongoSchema(schema); + const indexCreationRequest = {}; + const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); + mongoFieldNames.forEach(fieldName => { + indexCreationRequest[fieldName] = options.indexType !== undefined ? options.indexType : 1; + }); + const defaultOptions = { + background: true, + sparse: true + }; + const indexNameOptions = indexName ? { + name: indexName + } : {}; + const ttlOptions = options.ttl !== undefined ? { + expireAfterSeconds: options.ttl + } : {}; + const caseInsensitiveOptions = caseInsensitive ? { + collation: _MongoCollection.default.caseInsensitiveCollation() + } : {}; + + const indexOptions = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultOptions), caseInsensitiveOptions), indexNameOptions), ttlOptions); + + return this._adaptiveCollection(className).then(collection => new Promise((resolve, reject) => collection._mongoCollection.createIndex(indexCreationRequest, indexOptions, error => error ? reject(error) : resolve()))).catch(err => this.handleError(err)); + } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't + // currently know which fields are nullable and which aren't, we ignore that criteria. + // As such, we shouldn't expose this function to users of parse until we have an out-of-band + // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, + // which is why we use sparse indexes. + + + ensureUniqueness(className, schema, fieldNames) { + schema = convertParseSchemaToMongoSchema(schema); + const indexCreationRequest = {}; + const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); + mongoFieldNames.forEach(fieldName => { + indexCreationRequest[fieldName] = 1; + }); + return this._adaptiveCollection(className).then(collection => collection._ensureSparseUniqueIndexInBackground(indexCreationRequest)).catch(error => { + if (error.code === 11000) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Tried to ensure field uniqueness for a class that already has duplicates.'); + } + + throw error; + }).catch(err => this.handleError(err)); + } // Used in tests + + + _rawFind(className, query) { + return this._adaptiveCollection(className).then(collection => collection.find(query, { + maxTimeMS: this._maxTimeMS + })).catch(err => this.handleError(err)); + } // Executes a count. + + + count(className, schema, query, readPreference, hint) { + schema = convertParseSchemaToMongoSchema(schema); + readPreference = this._parseReadPreference(readPreference); + return this._adaptiveCollection(className).then(collection => collection.count((0, _MongoTransform.transformWhere)(className, query, schema, true), { + maxTimeMS: this._maxTimeMS, + readPreference, + hint + })).catch(err => this.handleError(err)); + } + + distinct(className, schema, query, fieldName) { + schema = convertParseSchemaToMongoSchema(schema); + const isPointerField = schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; + const transformField = (0, _MongoTransform.transformKey)(className, fieldName, schema); + return this._adaptiveCollection(className).then(collection => collection.distinct(transformField, (0, _MongoTransform.transformWhere)(className, query, schema))).then(objects => { + objects = objects.filter(obj => obj != null); + return objects.map(object => { + if (isPointerField) { + return (0, _MongoTransform.transformPointerString)(schema, fieldName, object); + } + + return (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema); + }); + }).catch(err => this.handleError(err)); + } + + aggregate(className, schema, pipeline, readPreference, hint, explain) { + let isPointerField = false; + pipeline = pipeline.map(stage => { + if (stage.$group) { + stage.$group = this._parseAggregateGroupArgs(schema, stage.$group); + + if (stage.$group._id && typeof stage.$group._id === 'string' && stage.$group._id.indexOf('$_p_') >= 0) { + isPointerField = true; + } + } + + if (stage.$match) { + stage.$match = this._parseAggregateArgs(schema, stage.$match); + } + + if (stage.$project) { + stage.$project = this._parseAggregateProjectArgs(schema, stage.$project); + } + + if (stage.$geoNear && stage.$geoNear.query) { + stage.$geoNear.query = this._parseAggregateArgs(schema, stage.$geoNear.query); + } + + return stage; + }); + readPreference = this._parseReadPreference(readPreference); + return this._adaptiveCollection(className).then(collection => collection.aggregate(pipeline, { + readPreference, + maxTimeMS: this._maxTimeMS, + hint, + explain + })).then(results => { + results.forEach(result => { + if (Object.prototype.hasOwnProperty.call(result, '_id')) { + if (isPointerField && result._id) { + result._id = result._id.split('$')[1]; + } + + if (result._id == null || result._id == undefined || ['object', 'string'].includes(typeof result._id) && _lodash.default.isEmpty(result._id)) { + result._id = null; + } + + result.objectId = result._id; + delete result._id; + } + }); + return results; + }).then(objects => objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema))).catch(err => this.handleError(err)); + } // This function will recursively traverse the pipeline and convert any Pointer or Date columns. + // If we detect a pointer column we will rename the column being queried for to match the column + // in the database. We also modify the value to what we expect the value to be in the database + // as well. + // For dates, the driver expects a Date object, but we have a string coming in. So we'll convert + // the string to a Date so the driver can perform the necessary comparison. + // + // The goal of this method is to look for the "leaves" of the pipeline and determine if it needs + // to be converted. The pipeline can have a few different forms. For more details, see: + // https://docs.mongodb.com/manual/reference/operator/aggregation/ + // + // If the pipeline is an array, it means we are probably parsing an '$and' or '$or' operator. In + // that case we need to loop through all of it's children to find the columns being operated on. + // If the pipeline is an object, then we'll loop through the keys checking to see if the key name + // matches one of the schema columns. If it does match a column and the column is a Pointer or + // a Date, then we'll convert the value as described above. + // + // As much as I hate recursion...this seemed like a good fit for it. We're essentially traversing + // down a tree to find a "leaf node" and checking to see if it needs to be converted. + + + _parseAggregateArgs(schema, pipeline) { + if (pipeline === null) { + return null; + } else if (Array.isArray(pipeline)) { + return pipeline.map(value => this._parseAggregateArgs(schema, value)); + } else if (typeof pipeline === 'object') { + const returnValue = {}; + + for (const field in pipeline) { + if (schema.fields[field] && schema.fields[field].type === 'Pointer') { + if (typeof pipeline[field] === 'object') { + // Pass objects down to MongoDB...this is more than likely an $exists operator. + returnValue[`_p_${field}`] = pipeline[field]; + } else { + returnValue[`_p_${field}`] = `${schema.fields[field].targetClass}$${pipeline[field]}`; + } + } else if (schema.fields[field] && schema.fields[field].type === 'Date') { + returnValue[field] = this._convertToDate(pipeline[field]); + } else { + returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); + } + + if (field === 'objectId') { + returnValue['_id'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'createdAt') { + returnValue['_created_at'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'updatedAt') { + returnValue['_updated_at'] = returnValue[field]; + delete returnValue[field]; + } + } + + return returnValue; + } + + return pipeline; + } // This function is slightly different than the one above. Rather than trying to combine these + // two functions and making the code even harder to understand, I decided to split it up. The + // difference with this function is we are not transforming the values, only the keys of the + // pipeline. + + + _parseAggregateProjectArgs(schema, pipeline) { + const returnValue = {}; + + for (const field in pipeline) { + if (schema.fields[field] && schema.fields[field].type === 'Pointer') { + returnValue[`_p_${field}`] = pipeline[field]; + } else { + returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); + } + + if (field === 'objectId') { + returnValue['_id'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'createdAt') { + returnValue['_created_at'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'updatedAt') { + returnValue['_updated_at'] = returnValue[field]; + delete returnValue[field]; + } + } + + return returnValue; + } // This function is slightly different than the two above. MongoDB $group aggregate looks like: + // { $group: { _id: , : { : }, ... } } + // The could be a column name, prefixed with the '$' character. We'll look for + // these and check to see if it is a 'Pointer' or if it's one of createdAt, + // updatedAt or objectId and change it accordingly. + + + _parseAggregateGroupArgs(schema, pipeline) { + if (Array.isArray(pipeline)) { + return pipeline.map(value => this._parseAggregateGroupArgs(schema, value)); + } else if (typeof pipeline === 'object') { + const returnValue = {}; + + for (const field in pipeline) { + returnValue[field] = this._parseAggregateGroupArgs(schema, pipeline[field]); + } + + return returnValue; + } else if (typeof pipeline === 'string') { + const field = pipeline.substring(1); + + if (schema.fields[field] && schema.fields[field].type === 'Pointer') { + return `$_p_${field}`; + } else if (field == 'createdAt') { + return '$_created_at'; + } else if (field == 'updatedAt') { + return '$_updated_at'; + } + } + + return pipeline; + } // This function will attempt to convert the provided value to a Date object. Since this is part + // of an aggregation pipeline, the value can either be a string or it can be another object with + // an operator in it (like $gt, $lt, etc). Because of this I felt it was easier to make this a + // recursive method to traverse down to the "leaf node" which is going to be the string. + + + _convertToDate(value) { + if (typeof value === 'string') { + return new Date(value); + } + + const returnValue = {}; + + for (const field in value) { + returnValue[field] = this._convertToDate(value[field]); + } + + return returnValue; + } + + _parseReadPreference(readPreference) { + if (readPreference) { + readPreference = readPreference.toUpperCase(); + } + + switch (readPreference) { + case 'PRIMARY': + readPreference = ReadPreference.PRIMARY; + break; + + case 'PRIMARY_PREFERRED': + readPreference = ReadPreference.PRIMARY_PREFERRED; + break; + + case 'SECONDARY': + readPreference = ReadPreference.SECONDARY; + break; + + case 'SECONDARY_PREFERRED': + readPreference = ReadPreference.SECONDARY_PREFERRED; + break; + + case 'NEAREST': + readPreference = ReadPreference.NEAREST; + break; + + case undefined: + case null: + case '': + break; + + default: + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Not supported read preference.'); + } + + return readPreference; + } + + performInitialization() { + return Promise.resolve(); + } + + createIndex(className, index) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndex(index)).catch(err => this.handleError(err)); + } + + createIndexes(className, indexes) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndexes(indexes)).catch(err => this.handleError(err)); + } + + createIndexesIfNeeded(className, fieldName, type) { + if (type && type.type === 'Polygon') { + const index = { + [fieldName]: '2dsphere' + }; + return this.createIndex(className, index); + } + + return Promise.resolve(); + } + + createTextIndexesIfNeeded(className, query, schema) { + for (const fieldName in query) { + if (!query[fieldName] || !query[fieldName].$text) { + continue; + } + + const existingIndexes = schema.indexes; + + for (const key in existingIndexes) { + const index = existingIndexes[key]; + + if (Object.prototype.hasOwnProperty.call(index, fieldName)) { + return Promise.resolve(); + } + } + + const indexName = `${fieldName}_text`; + const textIndex = { + [indexName]: { + [fieldName]: 'text' + } + }; + return this.setIndexesWithSchemaFormat(className, textIndex, existingIndexes, schema.fields).catch(error => { + if (error.code === 85) { + // Index exist with different options + return this.setIndexesFromMongo(className); + } + + throw error; + }); + } + + return Promise.resolve(); + } + + getIndexes(className) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.indexes()).catch(err => this.handleError(err)); + } + + dropIndex(className, index) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndex(index)).catch(err => this.handleError(err)); + } + + dropAllIndexes(className) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndexes()).catch(err => this.handleError(err)); + } + + updateSchemaWithIndexes() { + return this.getAllClasses().then(classes => { + const promises = classes.map(schema => { + return this.setIndexesFromMongo(schema.className); + }); + return Promise.all(promises); + }).catch(err => this.handleError(err)); + } + + createTransactionalSession() { + const transactionalSection = this.client.startSession(); + transactionalSection.startTransaction(); + return Promise.resolve(transactionalSection); + } + + commitTransactionalSession(transactionalSection) { + return transactionalSection.commitTransaction().then(() => { + transactionalSection.endSession(); + }); + } + + abortTransactionalSession(transactionalSection) { + return transactionalSection.abortTransaction().then(() => { + transactionalSection.endSession(); + }); + } + +} + +exports.MongoStorageAdapter = MongoStorageAdapter; +var _default = MongoStorageAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsibW9uZ29kYiIsInJlcXVpcmUiLCJNb25nb0NsaWVudCIsIlJlYWRQcmVmZXJlbmNlIiwiTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSIsInN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnMiLCJtb25nb0FkYXB0ZXIiLCJjb25uZWN0IiwidGhlbiIsImRhdGFiYXNlIiwiY29sbGVjdGlvbnMiLCJmaWx0ZXIiLCJjb2xsZWN0aW9uIiwibmFtZXNwYWNlIiwibWF0Y2giLCJjb2xsZWN0aW9uTmFtZSIsImluZGV4T2YiLCJfY29sbGVjdGlvblByZWZpeCIsImNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEiLCJzY2hlbWEiLCJmaWVsZHMiLCJfcnBlcm0iLCJfd3Blcm0iLCJjbGFzc05hbWUiLCJfaGFzaGVkX3Bhc3N3b3JkIiwibW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lQW5kQ0xQIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsIm1vbmdvT2JqZWN0IiwiX2lkIiwib2JqZWN0SWQiLCJ1cGRhdGVkQXQiLCJjcmVhdGVkQXQiLCJfbWV0YWRhdGEiLCJ1bmRlZmluZWQiLCJmaWVsZE5hbWUiLCJ0eXBlIiwidGFyZ2V0Q2xhc3MiLCJmaWVsZE9wdGlvbnMiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiZmllbGRzX29wdGlvbnMiLCJjbGFzc19wZXJtaXNzaW9ucyIsIk1vbmdvU3RvcmFnZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInVyaSIsImRlZmF1bHRzIiwiRGVmYXVsdE1vbmdvVVJJIiwiY29sbGVjdGlvblByZWZpeCIsIm1vbmdvT3B0aW9ucyIsIl91cmkiLCJfbW9uZ29PcHRpb25zIiwidXNlTmV3VXJsUGFyc2VyIiwidXNlVW5pZmllZFRvcG9sb2d5IiwiX21heFRpbWVNUyIsIm1heFRpbWVNUyIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJjb25uZWN0aW9uUHJvbWlzZSIsImVuY29kZWRVcmkiLCJjbGllbnQiLCJvcHRpb25zIiwicyIsImRiIiwiZGJOYW1lIiwib24iLCJjYXRjaCIsImVyciIsIlByb21pc2UiLCJyZWplY3QiLCJoYW5kbGVFcnJvciIsImVycm9yIiwiY29kZSIsImxvZ2dlciIsImhhbmRsZVNodXRkb3duIiwicmVzb2x2ZSIsImNsb3NlIiwiX2FkYXB0aXZlQ29sbGVjdGlvbiIsIm5hbWUiLCJyYXdDb2xsZWN0aW9uIiwiTW9uZ29Db2xsZWN0aW9uIiwiX3NjaGVtYUNvbGxlY3Rpb24iLCJjbGFzc0V4aXN0cyIsImxpc3RDb2xsZWN0aW9ucyIsInRvQXJyYXkiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2NoZW1hQ29sbGVjdGlvbiIsInVwZGF0ZVNjaGVtYSIsIiRzZXQiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInN1Ym1pdHRlZEluZGV4ZXMiLCJleGlzdGluZ0luZGV4ZXMiLCJfaWRfIiwiZGVsZXRlUHJvbWlzZXMiLCJpbnNlcnRlZEluZGV4ZXMiLCJmb3JFYWNoIiwiZmllbGQiLCJfX29wIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJwcm9taXNlIiwiZHJvcEluZGV4IiwicHVzaCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlcGxhY2UiLCJpbnNlcnRQcm9taXNlIiwiY3JlYXRlSW5kZXhlcyIsImFsbCIsInNldEluZGV4ZXNGcm9tTW9uZ28iLCJnZXRJbmRleGVzIiwicmVkdWNlIiwib2JqIiwiaW5kZXgiLCJfZnRzIiwiX2Z0c3giLCJ3ZWlnaHRzIiwiY3JlYXRlQ2xhc3MiLCJpbnNlcnRTY2hlbWEiLCJhZGRGaWVsZElmTm90RXhpc3RzIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZGVsZXRlQ2xhc3MiLCJkcm9wIiwibWVzc2FnZSIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJkZWxldGVBbGxDbGFzc2VzIiwiZmFzdCIsIm1hcCIsImRlbGV0ZU1hbnkiLCJkZWxldGVGaWVsZHMiLCJmaWVsZE5hbWVzIiwibW9uZ29Gb3JtYXROYW1lcyIsImNvbGxlY3Rpb25VcGRhdGUiLCIkdW5zZXQiLCJjb2xsZWN0aW9uRmlsdGVyIiwiJG9yIiwiJGV4aXN0cyIsInNjaGVtYVVwZGF0ZSIsInVwZGF0ZU1hbnkiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hc0NvbGxlY3Rpb24iLCJfZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEiLCJnZXRDbGFzcyIsIl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BIiwiY3JlYXRlT2JqZWN0Iiwib2JqZWN0IiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJpbnNlcnRPbmUiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1bmRlcmx5aW5nRXJyb3IiLCJtYXRjaGVzIiwiQXJyYXkiLCJpc0FycmF5IiwidXNlckluZm8iLCJkdXBsaWNhdGVkX2ZpZWxkIiwiZGVsZXRlT2JqZWN0c0J5UXVlcnkiLCJxdWVyeSIsIm1vbmdvV2hlcmUiLCJyZXN1bHQiLCJuIiwiT0JKRUNUX05PVF9GT1VORCIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsInVwZGF0ZU9iamVjdHNCeVF1ZXJ5IiwidXBkYXRlIiwibW9uZ29VcGRhdGUiLCJmaW5kT25lQW5kVXBkYXRlIiwiX21vbmdvQ29sbGVjdGlvbiIsInJldHVybk9yaWdpbmFsIiwic2Vzc2lvbiIsInZhbHVlIiwidXBzZXJ0T25lT2JqZWN0IiwidXBzZXJ0T25lIiwiZmluZCIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJyZWFkUHJlZmVyZW5jZSIsImhpbnQiLCJjYXNlSW5zZW5zaXRpdmUiLCJleHBsYWluIiwibW9uZ29Tb3J0IiwiXyIsIm1hcEtleXMiLCJtb25nb0tleXMiLCJtZW1vIiwiX3BhcnNlUmVhZFByZWZlcmVuY2UiLCJjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkIiwib2JqZWN0cyIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwiaW5kZXhDcmVhdGlvblJlcXVlc3QiLCJtb25nb0ZpZWxkTmFtZXMiLCJpbmRleFR5cGUiLCJkZWZhdWx0T3B0aW9ucyIsImJhY2tncm91bmQiLCJzcGFyc2UiLCJpbmRleE5hbWVPcHRpb25zIiwidHRsT3B0aW9ucyIsInR0bCIsImV4cGlyZUFmdGVyU2Vjb25kcyIsImNhc2VJbnNlbnNpdGl2ZU9wdGlvbnMiLCJjb2xsYXRpb24iLCJjYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24iLCJpbmRleE9wdGlvbnMiLCJjcmVhdGVJbmRleCIsImVuc3VyZVVuaXF1ZW5lc3MiLCJfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQiLCJfcmF3RmluZCIsImNvdW50IiwiZGlzdGluY3QiLCJpc1BvaW50ZXJGaWVsZCIsInRyYW5zZm9ybUZpZWxkIiwiYWdncmVnYXRlIiwicGlwZWxpbmUiLCJzdGFnZSIsIiRncm91cCIsIl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyIsIiRtYXRjaCIsIl9wYXJzZUFnZ3JlZ2F0ZUFyZ3MiLCIkcHJvamVjdCIsIl9wYXJzZUFnZ3JlZ2F0ZVByb2plY3RBcmdzIiwiJGdlb05lYXIiLCJyZXN1bHRzIiwic3BsaXQiLCJpbmNsdWRlcyIsImlzRW1wdHkiLCJyZXR1cm5WYWx1ZSIsIl9jb252ZXJ0VG9EYXRlIiwic3Vic3RyaW5nIiwiRGF0ZSIsInRvVXBwZXJDYXNlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCIkdGV4dCIsInRleHRJbmRleCIsImRyb3BBbGxJbmRleGVzIiwiZHJvcEluZGV4ZXMiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsImNsYXNzZXMiLCJwcm9taXNlcyIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwidHJhbnNhY3Rpb25hbFNlY3Rpb24iLCJzdGFydFNlc3Npb24iLCJzdGFydFRyYW5zYWN0aW9uIiwiY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbiIsImVuZFNlc3Npb24iLCJhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOztBQUNBOztBQU9BOztBQUlBOztBQVNBOztBQUVBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7QUFDQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxTQUFELENBQXZCOztBQUNBLE1BQU1DLFdBQVcsR0FBR0YsT0FBTyxDQUFDRSxXQUE1QjtBQUNBLE1BQU1DLGNBQWMsR0FBR0gsT0FBTyxDQUFDRyxjQUEvQjtBQUVBLE1BQU1DLHlCQUF5QixHQUFHLFNBQWxDOztBQUVBLE1BQU1DLDRCQUE0QixHQUFHQyxZQUFZLElBQUk7QUFDbkQsU0FBT0EsWUFBWSxDQUNoQkMsT0FESSxHQUVKQyxJQUZJLENBRUMsTUFBTUYsWUFBWSxDQUFDRyxRQUFiLENBQXNCQyxXQUF0QixFQUZQLEVBR0pGLElBSEksQ0FHQ0UsV0FBVyxJQUFJO0FBQ25CLFdBQU9BLFdBQVcsQ0FBQ0MsTUFBWixDQUFtQkMsVUFBVSxJQUFJO0FBQ3RDLFVBQUlBLFVBQVUsQ0FBQ0MsU0FBWCxDQUFxQkMsS0FBckIsQ0FBMkIsWUFBM0IsQ0FBSixFQUE4QztBQUM1QyxlQUFPLEtBQVA7QUFDRCxPQUhxQyxDQUl0QztBQUNBOzs7QUFDQSxhQUNFRixVQUFVLENBQUNHLGNBQVgsQ0FBMEJDLE9BQTFCLENBQWtDVixZQUFZLENBQUNXLGlCQUEvQyxLQUFxRSxDQUR2RTtBQUdELEtBVE0sQ0FBUDtBQVVELEdBZEksQ0FBUDtBQWVELENBaEJEOztBQWtCQSxNQUFNQywrQkFBK0IsR0FBRyxVQUFtQjtBQUFBLE1BQWJDLE1BQWE7O0FBQ3pELFNBQU9BLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjQyxNQUFyQjtBQUNBLFNBQU9GLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjRSxNQUFyQjs7QUFFQSxNQUFJSCxNQUFNLENBQUNJLFNBQVAsS0FBcUIsT0FBekIsRUFBa0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFPSixNQUFNLENBQUNDLE1BQVAsQ0FBY0ksZ0JBQXJCO0FBQ0Q7O0FBRUQsU0FBT0wsTUFBUDtBQUNELENBYkQsQyxDQWVBO0FBQ0E7OztBQUNBLE1BQU1NLHVDQUF1QyxHQUFHLENBQzlDTCxNQUQ4QyxFQUU5Q0csU0FGOEMsRUFHOUNHLHFCQUg4QyxFQUk5Q0MsT0FKOEMsS0FLM0M7QUFDSCxRQUFNQyxXQUFXLEdBQUc7QUFDbEJDLElBQUFBLEdBQUcsRUFBRU4sU0FEYTtBQUVsQk8sSUFBQUEsUUFBUSxFQUFFLFFBRlE7QUFHbEJDLElBQUFBLFNBQVMsRUFBRSxRQUhPO0FBSWxCQyxJQUFBQSxTQUFTLEVBQUUsUUFKTztBQUtsQkMsSUFBQUEsU0FBUyxFQUFFQztBQUxPLEdBQXBCOztBQVFBLE9BQUssTUFBTUMsU0FBWCxJQUF3QmYsTUFBeEIsRUFBZ0M7QUFDOUIsOEJBQStDQSxNQUFNLENBQUNlLFNBQUQsQ0FBckQ7QUFBQSxVQUFNO0FBQUVDLE1BQUFBLElBQUY7QUFBUUMsTUFBQUE7QUFBUixLQUFOO0FBQUEsVUFBOEJDLFlBQTlCOztBQUNBVixJQUFBQSxXQUFXLENBQ1RPLFNBRFMsQ0FBWCxHQUVJSSwrQkFBc0JDLDhCQUF0QixDQUFxRDtBQUN2REosTUFBQUEsSUFEdUQ7QUFFdkRDLE1BQUFBO0FBRnVELEtBQXJELENBRko7O0FBTUEsUUFBSUMsWUFBWSxJQUFJRyxNQUFNLENBQUNDLElBQVAsQ0FBWUosWUFBWixFQUEwQkssTUFBMUIsR0FBbUMsQ0FBdkQsRUFBMEQ7QUFDeERmLE1BQUFBLFdBQVcsQ0FBQ0ssU0FBWixHQUF3QkwsV0FBVyxDQUFDSyxTQUFaLElBQXlCLEVBQWpEO0FBQ0FMLE1BQUFBLFdBQVcsQ0FBQ0ssU0FBWixDQUFzQlcsY0FBdEIsR0FDRWhCLFdBQVcsQ0FBQ0ssU0FBWixDQUFzQlcsY0FBdEIsSUFBd0MsRUFEMUM7QUFFQWhCLE1BQUFBLFdBQVcsQ0FBQ0ssU0FBWixDQUFzQlcsY0FBdEIsQ0FBcUNULFNBQXJDLElBQWtERyxZQUFsRDtBQUNEO0FBQ0Y7O0FBRUQsTUFBSSxPQUFPWixxQkFBUCxLQUFpQyxXQUFyQyxFQUFrRDtBQUNoREUsSUFBQUEsV0FBVyxDQUFDSyxTQUFaLEdBQXdCTCxXQUFXLENBQUNLLFNBQVosSUFBeUIsRUFBakQ7O0FBQ0EsUUFBSSxDQUFDUCxxQkFBTCxFQUE0QjtBQUMxQixhQUFPRSxXQUFXLENBQUNLLFNBQVosQ0FBc0JZLGlCQUE3QjtBQUNELEtBRkQsTUFFTztBQUNMakIsTUFBQUEsV0FBVyxDQUFDSyxTQUFaLENBQXNCWSxpQkFBdEIsR0FBMENuQixxQkFBMUM7QUFDRDtBQUNGOztBQUVELE1BQ0VDLE9BQU8sSUFDUCxPQUFPQSxPQUFQLEtBQW1CLFFBRG5CLElBRUFjLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZZixPQUFaLEVBQXFCZ0IsTUFBckIsR0FBOEIsQ0FIaEMsRUFJRTtBQUNBZixJQUFBQSxXQUFXLENBQUNLLFNBQVosR0FBd0JMLFdBQVcsQ0FBQ0ssU0FBWixJQUF5QixFQUFqRDtBQUNBTCxJQUFBQSxXQUFXLENBQUNLLFNBQVosQ0FBc0JOLE9BQXRCLEdBQWdDQSxPQUFoQztBQUNEOztBQUVELE1BQUksQ0FBQ0MsV0FBVyxDQUFDSyxTQUFqQixFQUE0QjtBQUMxQjtBQUNBLFdBQU9MLFdBQVcsQ0FBQ0ssU0FBbkI7QUFDRDs7QUFFRCxTQUFPTCxXQUFQO0FBQ0QsQ0F0REQ7O0FBd0RPLE1BQU1rQixtQkFBTixDQUFvRDtBQUN6RDtBQUlBO0FBT0FDLEVBQUFBLFdBQVcsQ0FBQztBQUNWQyxJQUFBQSxHQUFHLEdBQUdDLGtCQUFTQyxlQURMO0FBRVZDLElBQUFBLGdCQUFnQixHQUFHLEVBRlQ7QUFHVkMsSUFBQUEsWUFBWSxHQUFHO0FBSEwsR0FBRCxFQUlIO0FBQ04sU0FBS0MsSUFBTCxHQUFZTCxHQUFaO0FBQ0EsU0FBSy9CLGlCQUFMLEdBQXlCa0MsZ0JBQXpCO0FBQ0EsU0FBS0csYUFBTCxHQUFxQkYsWUFBckI7QUFDQSxTQUFLRSxhQUFMLENBQW1CQyxlQUFuQixHQUFxQyxJQUFyQztBQUNBLFNBQUtELGFBQUwsQ0FBbUJFLGtCQUFuQixHQUF3QyxJQUF4QyxDQUxNLENBT047O0FBQ0EsU0FBS0MsVUFBTCxHQUFrQkwsWUFBWSxDQUFDTSxTQUEvQjtBQUNBLFNBQUtDLG1CQUFMLEdBQTJCLElBQTNCO0FBQ0EsV0FBT1AsWUFBWSxDQUFDTSxTQUFwQjtBQUNEOztBQUVEbkQsRUFBQUEsT0FBTyxHQUFHO0FBQ1IsUUFBSSxLQUFLcUQsaUJBQVQsRUFBNEI7QUFDMUIsYUFBTyxLQUFLQSxpQkFBWjtBQUNELEtBSE8sQ0FLUjtBQUNBOzs7QUFDQSxVQUFNQyxVQUFVLEdBQUcsd0JBQVUsdUJBQVMsS0FBS1IsSUFBZCxDQUFWLENBQW5CO0FBRUEsU0FBS08saUJBQUwsR0FBeUIxRCxXQUFXLENBQUNLLE9BQVosQ0FBb0JzRCxVQUFwQixFQUFnQyxLQUFLUCxhQUFyQyxFQUN0QjlDLElBRHNCLENBQ2pCc0QsTUFBTSxJQUFJO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsWUFBTUMsT0FBTyxHQUFHRCxNQUFNLENBQUNFLENBQVAsQ0FBU0QsT0FBekI7QUFDQSxZQUFNdEQsUUFBUSxHQUFHcUQsTUFBTSxDQUFDRyxFQUFQLENBQVVGLE9BQU8sQ0FBQ0csTUFBbEIsQ0FBakI7O0FBQ0EsVUFBSSxDQUFDekQsUUFBTCxFQUFlO0FBQ2IsZUFBTyxLQUFLbUQsaUJBQVo7QUFDQTtBQUNEOztBQUNEbkQsTUFBQUEsUUFBUSxDQUFDMEQsRUFBVCxDQUFZLE9BQVosRUFBcUIsTUFBTTtBQUN6QixlQUFPLEtBQUtQLGlCQUFaO0FBQ0QsT0FGRDtBQUdBbkQsTUFBQUEsUUFBUSxDQUFDMEQsRUFBVCxDQUFZLE9BQVosRUFBcUIsTUFBTTtBQUN6QixlQUFPLEtBQUtQLGlCQUFaO0FBQ0QsT0FGRDtBQUdBLFdBQUtFLE1BQUwsR0FBY0EsTUFBZDtBQUNBLFdBQUtyRCxRQUFMLEdBQWdCQSxRQUFoQjtBQUNELEtBbkJzQixFQW9CdEIyRCxLQXBCc0IsQ0FvQmhCQyxHQUFHLElBQUk7QUFDWixhQUFPLEtBQUtULGlCQUFaO0FBQ0EsYUFBT1UsT0FBTyxDQUFDQyxNQUFSLENBQWVGLEdBQWYsQ0FBUDtBQUNELEtBdkJzQixDQUF6QjtBQXlCQSxXQUFPLEtBQUtULGlCQUFaO0FBQ0Q7O0FBRURZLEVBQUFBLFdBQVcsQ0FBSUMsS0FBSixFQUErQztBQUN4RCxRQUFJQSxLQUFLLElBQUlBLEtBQUssQ0FBQ0MsSUFBTixLQUFlLEVBQTVCLEVBQWdDO0FBQzlCO0FBQ0EsYUFBTyxLQUFLWixNQUFaO0FBQ0EsYUFBTyxLQUFLckQsUUFBWjtBQUNBLGFBQU8sS0FBS21ELGlCQUFaOztBQUNBZSxzQkFBT0YsS0FBUCxDQUFhLDZCQUFiLEVBQTRDO0FBQUVBLFFBQUFBLEtBQUssRUFBRUE7QUFBVCxPQUE1QztBQUNEOztBQUNELFVBQU1BLEtBQU47QUFDRDs7QUFFREcsRUFBQUEsY0FBYyxHQUFHO0FBQ2YsUUFBSSxDQUFDLEtBQUtkLE1BQVYsRUFBa0I7QUFDaEIsYUFBT1EsT0FBTyxDQUFDTyxPQUFSLEVBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtmLE1BQUwsQ0FBWWdCLEtBQVosQ0FBa0IsS0FBbEIsQ0FBUDtBQUNEOztBQUVEQyxFQUFBQSxtQkFBbUIsQ0FBQ0MsSUFBRCxFQUFlO0FBQ2hDLFdBQU8sS0FBS3pFLE9BQUwsR0FDSkMsSUFESSxDQUNDLE1BQU0sS0FBS0MsUUFBTCxDQUFjRyxVQUFkLENBQXlCLEtBQUtLLGlCQUFMLEdBQXlCK0QsSUFBbEQsQ0FEUCxFQUVKeEUsSUFGSSxDQUVDeUUsYUFBYSxJQUFJLElBQUlDLHdCQUFKLENBQW9CRCxhQUFwQixDQUZsQixFQUdKYixLQUhJLENBR0VDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUhULENBQVA7QUFJRDs7QUFFRGMsRUFBQUEsaUJBQWlCLEdBQW1DO0FBQ2xELFdBQU8sS0FBSzVFLE9BQUwsR0FDSkMsSUFESSxDQUNDLE1BQU0sS0FBS3VFLG1CQUFMLENBQXlCM0UseUJBQXpCLENBRFAsRUFFSkksSUFGSSxDQUVDSSxVQUFVLElBQUksSUFBSTJCLDhCQUFKLENBQTBCM0IsVUFBMUIsQ0FGZixDQUFQO0FBR0Q7O0FBRUR3RSxFQUFBQSxXQUFXLENBQUNKLElBQUQsRUFBZTtBQUN4QixXQUFPLEtBQUt6RSxPQUFMLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBTyxLQUFLQyxRQUFMLENBQ0o0RSxlQURJLENBQ1k7QUFBRUwsUUFBQUEsSUFBSSxFQUFFLEtBQUsvRCxpQkFBTCxHQUF5QitEO0FBQWpDLE9BRFosRUFFSk0sT0FGSSxFQUFQO0FBR0QsS0FMSSxFQU1KOUUsSUFOSSxDQU1DRSxXQUFXLElBQUk7QUFDbkIsYUFBT0EsV0FBVyxDQUFDaUMsTUFBWixHQUFxQixDQUE1QjtBQUNELEtBUkksRUFTSnlCLEtBVEksQ0FTRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBVFQsQ0FBUDtBQVVEOztBQUVEa0IsRUFBQUEsd0JBQXdCLENBQUNoRSxTQUFELEVBQW9CaUUsSUFBcEIsRUFBOEM7QUFDcEUsV0FBTyxLQUFLTCxpQkFBTCxHQUNKM0UsSUFESSxDQUNDaUYsZ0JBQWdCLElBQ3BCQSxnQkFBZ0IsQ0FBQ0MsWUFBakIsQ0FBOEJuRSxTQUE5QixFQUF5QztBQUN2Q29FLE1BQUFBLElBQUksRUFBRTtBQUFFLHVDQUErQkg7QUFBakM7QUFEaUMsS0FBekMsQ0FGRyxFQU1KcEIsS0FOSSxDQU1FQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FOVCxDQUFQO0FBT0Q7O0FBRUR1QixFQUFBQSwwQkFBMEIsQ0FDeEJyRSxTQUR3QixFQUV4QnNFLGdCQUZ3QixFQUd4QkMsZUFBb0IsR0FBRyxFQUhDLEVBSXhCMUUsTUFKd0IsRUFLVDtBQUNmLFFBQUl5RSxnQkFBZ0IsS0FBSzNELFNBQXpCLEVBQW9DO0FBQ2xDLGFBQU9vQyxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNEOztBQUNELFFBQUlwQyxNQUFNLENBQUNDLElBQVAsQ0FBWW9ELGVBQVosRUFBNkJuRCxNQUE3QixLQUF3QyxDQUE1QyxFQUErQztBQUM3Q21ELE1BQUFBLGVBQWUsR0FBRztBQUFFQyxRQUFBQSxJQUFJLEVBQUU7QUFBRWxFLFVBQUFBLEdBQUcsRUFBRTtBQUFQO0FBQVIsT0FBbEI7QUFDRDs7QUFDRCxVQUFNbUUsY0FBYyxHQUFHLEVBQXZCO0FBQ0EsVUFBTUMsZUFBZSxHQUFHLEVBQXhCO0FBQ0F4RCxJQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWW1ELGdCQUFaLEVBQThCSyxPQUE5QixDQUFzQ2xCLElBQUksSUFBSTtBQUM1QyxZQUFNbUIsS0FBSyxHQUFHTixnQkFBZ0IsQ0FBQ2IsSUFBRCxDQUE5Qjs7QUFDQSxVQUFJYyxlQUFlLENBQUNkLElBQUQsQ0FBZixJQUF5Qm1CLEtBQUssQ0FBQ0MsSUFBTixLQUFlLFFBQTVDLEVBQXNEO0FBQ3BELGNBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLGFBRFIsRUFFSCxTQUFRdkIsSUFBSyx5QkFGVixDQUFOO0FBSUQ7O0FBQ0QsVUFBSSxDQUFDYyxlQUFlLENBQUNkLElBQUQsQ0FBaEIsSUFBMEJtQixLQUFLLENBQUNDLElBQU4sS0FBZSxRQUE3QyxFQUF1RDtBQUNyRCxjQUFNLElBQUlDLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZQyxhQURSLEVBRUgsU0FBUXZCLElBQUssaUNBRlYsQ0FBTjtBQUlEOztBQUNELFVBQUltQixLQUFLLENBQUNDLElBQU4sS0FBZSxRQUFuQixFQUE2QjtBQUMzQixjQUFNSSxPQUFPLEdBQUcsS0FBS0MsU0FBTCxDQUFlbEYsU0FBZixFQUEwQnlELElBQTFCLENBQWhCO0FBQ0FnQixRQUFBQSxjQUFjLENBQUNVLElBQWYsQ0FBb0JGLE9BQXBCO0FBQ0EsZUFBT1YsZUFBZSxDQUFDZCxJQUFELENBQXRCO0FBQ0QsT0FKRCxNQUlPO0FBQ0x2QyxRQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWXlELEtBQVosRUFBbUJELE9BQW5CLENBQTJCUyxHQUFHLElBQUk7QUFDaEMsY0FDRSxDQUFDbEUsTUFBTSxDQUFDbUUsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQ0MxRixNQURELEVBRUN1RixHQUFHLENBQUMzRixPQUFKLENBQVksS0FBWixNQUF1QixDQUF2QixHQUEyQjJGLEdBQUcsQ0FBQ0ksT0FBSixDQUFZLEtBQVosRUFBbUIsRUFBbkIsQ0FBM0IsR0FBb0RKLEdBRnJELENBREgsRUFLRTtBQUNBLGtCQUFNLElBQUlOLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZQyxhQURSLEVBRUgsU0FBUUksR0FBSSxvQ0FGVCxDQUFOO0FBSUQ7QUFDRixTQVpEO0FBYUFiLFFBQUFBLGVBQWUsQ0FBQ2QsSUFBRCxDQUFmLEdBQXdCbUIsS0FBeEI7QUFDQUYsUUFBQUEsZUFBZSxDQUFDUyxJQUFoQixDQUFxQjtBQUNuQkMsVUFBQUEsR0FBRyxFQUFFUixLQURjO0FBRW5CbkIsVUFBQUE7QUFGbUIsU0FBckI7QUFJRDtBQUNGLEtBdENEO0FBdUNBLFFBQUlnQyxhQUFhLEdBQUcxQyxPQUFPLENBQUNPLE9BQVIsRUFBcEI7O0FBQ0EsUUFBSW9CLGVBQWUsQ0FBQ3RELE1BQWhCLEdBQXlCLENBQTdCLEVBQWdDO0FBQzlCcUUsTUFBQUEsYUFBYSxHQUFHLEtBQUtDLGFBQUwsQ0FBbUIxRixTQUFuQixFQUE4QjBFLGVBQTlCLENBQWhCO0FBQ0Q7O0FBQ0QsV0FBTzNCLE9BQU8sQ0FBQzRDLEdBQVIsQ0FBWWxCLGNBQVosRUFDSnhGLElBREksQ0FDQyxNQUFNd0csYUFEUCxFQUVKeEcsSUFGSSxDQUVDLE1BQU0sS0FBSzJFLGlCQUFMLEVBRlAsRUFHSjNFLElBSEksQ0FHQ2lGLGdCQUFnQixJQUNwQkEsZ0JBQWdCLENBQUNDLFlBQWpCLENBQThCbkUsU0FBOUIsRUFBeUM7QUFDdkNvRSxNQUFBQSxJQUFJLEVBQUU7QUFBRSw2QkFBcUJHO0FBQXZCO0FBRGlDLEtBQXpDLENBSkcsRUFRSjFCLEtBUkksQ0FRRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBUlQsQ0FBUDtBQVNEOztBQUVEOEMsRUFBQUEsbUJBQW1CLENBQUM1RixTQUFELEVBQW9CO0FBQ3JDLFdBQU8sS0FBSzZGLFVBQUwsQ0FBZ0I3RixTQUFoQixFQUNKZixJQURJLENBQ0NtQixPQUFPLElBQUk7QUFDZkEsTUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUMwRixNQUFSLENBQWUsQ0FBQ0MsR0FBRCxFQUFNQyxLQUFOLEtBQWdCO0FBQ3ZDLFlBQUlBLEtBQUssQ0FBQ1osR0FBTixDQUFVYSxJQUFkLEVBQW9CO0FBQ2xCLGlCQUFPRCxLQUFLLENBQUNaLEdBQU4sQ0FBVWEsSUFBakI7QUFDQSxpQkFBT0QsS0FBSyxDQUFDWixHQUFOLENBQVVjLEtBQWpCOztBQUNBLGVBQUssTUFBTXRCLEtBQVgsSUFBb0JvQixLQUFLLENBQUNHLE9BQTFCLEVBQW1DO0FBQ2pDSCxZQUFBQSxLQUFLLENBQUNaLEdBQU4sQ0FBVVIsS0FBVixJQUFtQixNQUFuQjtBQUNEO0FBQ0Y7O0FBQ0RtQixRQUFBQSxHQUFHLENBQUNDLEtBQUssQ0FBQ3ZDLElBQVAsQ0FBSCxHQUFrQnVDLEtBQUssQ0FBQ1osR0FBeEI7QUFDQSxlQUFPVyxHQUFQO0FBQ0QsT0FWUyxFQVVQLEVBVk8sQ0FBVjtBQVdBLGFBQU8sS0FBS25DLGlCQUFMLEdBQXlCM0UsSUFBekIsQ0FBOEJpRixnQkFBZ0IsSUFDbkRBLGdCQUFnQixDQUFDQyxZQUFqQixDQUE4Qm5FLFNBQTlCLEVBQXlDO0FBQ3ZDb0UsUUFBQUEsSUFBSSxFQUFFO0FBQUUsK0JBQXFCaEU7QUFBdkI7QUFEaUMsT0FBekMsQ0FESyxDQUFQO0FBS0QsS0FsQkksRUFtQkp5QyxLQW5CSSxDQW1CRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBbkJULEVBb0JKRCxLQXBCSSxDQW9CRSxNQUFNO0FBQ1g7QUFDQSxhQUFPRSxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNELEtBdkJJLENBQVA7QUF3QkQ7O0FBRUQ4QyxFQUFBQSxXQUFXLENBQUNwRyxTQUFELEVBQW9CSixNQUFwQixFQUF1RDtBQUNoRUEsSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU1TLFdBQVcsR0FBR0gsdUNBQXVDLENBQ3pETixNQUFNLENBQUNDLE1BRGtELEVBRXpERyxTQUZ5RCxFQUd6REosTUFBTSxDQUFDTyxxQkFIa0QsRUFJekRQLE1BQU0sQ0FBQ1EsT0FKa0QsQ0FBM0Q7QUFNQUMsSUFBQUEsV0FBVyxDQUFDQyxHQUFaLEdBQWtCTixTQUFsQjtBQUNBLFdBQU8sS0FBS3FFLDBCQUFMLENBQ0xyRSxTQURLLEVBRUxKLE1BQU0sQ0FBQ1EsT0FGRixFQUdMLEVBSEssRUFJTFIsTUFBTSxDQUFDQyxNQUpGLEVBTUpaLElBTkksQ0FNQyxNQUFNLEtBQUsyRSxpQkFBTCxFQU5QLEVBT0ozRSxJQVBJLENBT0NpRixnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNtQyxZQUFqQixDQUE4QmhHLFdBQTlCLENBUHJCLEVBUUp3QyxLQVJJLENBUUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQVJULENBQVA7QUFTRDs7QUFFRHdELEVBQUFBLG1CQUFtQixDQUNqQnRHLFNBRGlCLEVBRWpCWSxTQUZpQixFQUdqQkMsSUFIaUIsRUFJRjtBQUNmLFdBQU8sS0FBSytDLGlCQUFMLEdBQ0ozRSxJQURJLENBQ0NpRixnQkFBZ0IsSUFDcEJBLGdCQUFnQixDQUFDb0MsbUJBQWpCLENBQXFDdEcsU0FBckMsRUFBZ0RZLFNBQWhELEVBQTJEQyxJQUEzRCxDQUZHLEVBSUo1QixJQUpJLENBSUMsTUFBTSxLQUFLc0gscUJBQUwsQ0FBMkJ2RyxTQUEzQixFQUFzQ1ksU0FBdEMsRUFBaURDLElBQWpELENBSlAsRUFLSmdDLEtBTEksQ0FLRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBTFQsQ0FBUDtBQU1ELEdBdFB3RCxDQXdQekQ7QUFDQTs7O0FBQ0EwRCxFQUFBQSxXQUFXLENBQUN4RyxTQUFELEVBQW9CO0FBQzdCLFdBQ0UsS0FBS3dELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDR2YsSUFESCxDQUNRSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ29ILElBQVgsRUFEdEIsRUFFRzVELEtBRkgsQ0FFU0ssS0FBSyxJQUFJO0FBQ2Q7QUFDQSxVQUFJQSxLQUFLLENBQUN3RCxPQUFOLElBQWlCLGNBQXJCLEVBQXFDO0FBQ25DO0FBQ0Q7O0FBQ0QsWUFBTXhELEtBQU47QUFDRCxLQVJILEVBU0U7QUFURixLQVVHakUsSUFWSCxDQVVRLE1BQU0sS0FBSzJFLGlCQUFMLEVBVmQsRUFXRzNFLElBWEgsQ0FXUWlGLGdCQUFnQixJQUNwQkEsZ0JBQWdCLENBQUN5QyxtQkFBakIsQ0FBcUMzRyxTQUFyQyxDQVpKLEVBY0c2QyxLQWRILENBY1NDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQWRoQixDQURGO0FBaUJEOztBQUVEOEQsRUFBQUEsZ0JBQWdCLENBQUNDLElBQUQsRUFBZ0I7QUFDOUIsV0FBTy9ILDRCQUE0QixDQUFDLElBQUQsQ0FBNUIsQ0FBbUNHLElBQW5DLENBQXdDRSxXQUFXLElBQ3hENEQsT0FBTyxDQUFDNEMsR0FBUixDQUNFeEcsV0FBVyxDQUFDMkgsR0FBWixDQUFnQnpILFVBQVUsSUFDeEJ3SCxJQUFJLEdBQUd4SCxVQUFVLENBQUMwSCxVQUFYLENBQXNCLEVBQXRCLENBQUgsR0FBK0IxSCxVQUFVLENBQUNvSCxJQUFYLEVBRHJDLENBREYsQ0FESyxDQUFQO0FBT0QsR0F0UndELENBd1J6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7QUFDQU8sRUFBQUEsWUFBWSxDQUFDaEgsU0FBRCxFQUFvQkosTUFBcEIsRUFBd0NxSCxVQUF4QyxFQUE4RDtBQUN4RSxVQUFNQyxnQkFBZ0IsR0FBR0QsVUFBVSxDQUFDSCxHQUFYLENBQWVsRyxTQUFTLElBQUk7QUFDbkQsVUFBSWhCLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjZSxTQUFkLEVBQXlCQyxJQUF6QixLQUFrQyxTQUF0QyxFQUFpRDtBQUMvQyxlQUFRLE1BQUtELFNBQVUsRUFBdkI7QUFDRCxPQUZELE1BRU87QUFDTCxlQUFPQSxTQUFQO0FBQ0Q7QUFDRixLQU53QixDQUF6QjtBQU9BLFVBQU11RyxnQkFBZ0IsR0FBRztBQUFFQyxNQUFBQSxNQUFNLEVBQUU7QUFBVixLQUF6QjtBQUNBRixJQUFBQSxnQkFBZ0IsQ0FBQ3ZDLE9BQWpCLENBQXlCbEIsSUFBSSxJQUFJO0FBQy9CMEQsTUFBQUEsZ0JBQWdCLENBQUMsUUFBRCxDQUFoQixDQUEyQjFELElBQTNCLElBQW1DLElBQW5DO0FBQ0QsS0FGRDtBQUlBLFVBQU00RCxnQkFBZ0IsR0FBRztBQUFFQyxNQUFBQSxHQUFHLEVBQUU7QUFBUCxLQUF6QjtBQUNBSixJQUFBQSxnQkFBZ0IsQ0FBQ3ZDLE9BQWpCLENBQXlCbEIsSUFBSSxJQUFJO0FBQy9CNEQsTUFBQUEsZ0JBQWdCLENBQUMsS0FBRCxDQUFoQixDQUF3QmxDLElBQXhCLENBQTZCO0FBQUUsU0FBQzFCLElBQUQsR0FBUTtBQUFFOEQsVUFBQUEsT0FBTyxFQUFFO0FBQVg7QUFBVixPQUE3QjtBQUNELEtBRkQ7QUFJQSxVQUFNQyxZQUFZLEdBQUc7QUFBRUosTUFBQUEsTUFBTSxFQUFFO0FBQVYsS0FBckI7QUFDQUgsSUFBQUEsVUFBVSxDQUFDdEMsT0FBWCxDQUFtQmxCLElBQUksSUFBSTtBQUN6QitELE1BQUFBLFlBQVksQ0FBQyxRQUFELENBQVosQ0FBdUIvRCxJQUF2QixJQUErQixJQUEvQjtBQUNBK0QsTUFBQUEsWUFBWSxDQUFDLFFBQUQsQ0FBWixDQUF3Qiw0QkFBMkIvRCxJQUFLLEVBQXhELElBQTZELElBQTdEO0FBQ0QsS0FIRDtBQUtBLFdBQU8sS0FBS0QsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDb0ksVUFBWCxDQUFzQkosZ0JBQXRCLEVBQXdDRixnQkFBeEMsQ0FGRyxFQUlKbEksSUFKSSxDQUlDLE1BQU0sS0FBSzJFLGlCQUFMLEVBSlAsRUFLSjNFLElBTEksQ0FLQ2lGLGdCQUFnQixJQUNwQkEsZ0JBQWdCLENBQUNDLFlBQWpCLENBQThCbkUsU0FBOUIsRUFBeUN3SCxZQUF6QyxDQU5HLEVBUUozRSxLQVJJLENBUUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQVJULENBQVA7QUFTRCxHQTdVd0QsQ0ErVXpEO0FBQ0E7QUFDQTs7O0FBQ0E0RSxFQUFBQSxhQUFhLEdBQTRCO0FBQ3ZDLFdBQU8sS0FBSzlELGlCQUFMLEdBQ0ozRSxJQURJLENBQ0MwSSxpQkFBaUIsSUFDckJBLGlCQUFpQixDQUFDQywyQkFBbEIsRUFGRyxFQUlKL0UsS0FKSSxDQUlFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FKVCxDQUFQO0FBS0QsR0F4VndELENBMFZ6RDtBQUNBO0FBQ0E7OztBQUNBK0UsRUFBQUEsUUFBUSxDQUFDN0gsU0FBRCxFQUEyQztBQUNqRCxXQUFPLEtBQUs0RCxpQkFBTCxHQUNKM0UsSUFESSxDQUNDMEksaUJBQWlCLElBQ3JCQSxpQkFBaUIsQ0FBQ0csMEJBQWxCLENBQTZDOUgsU0FBN0MsQ0FGRyxFQUlKNkMsS0FKSSxDQUlFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FKVCxDQUFQO0FBS0QsR0FuV3dELENBcVd6RDtBQUNBO0FBQ0E7OztBQUNBaUYsRUFBQUEsWUFBWSxDQUNWL0gsU0FEVSxFQUVWSixNQUZVLEVBR1ZvSSxNQUhVLEVBSVZDLG9CQUpVLEVBS1Y7QUFDQXJJLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNUyxXQUFXLEdBQUcsdURBQ2xCTCxTQURrQixFQUVsQmdJLE1BRmtCLEVBR2xCcEksTUFIa0IsQ0FBcEI7QUFLQSxXQUFPLEtBQUs0RCxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUNkQSxVQUFVLENBQUM2SSxTQUFYLENBQXFCN0gsV0FBckIsRUFBa0M0SCxvQkFBbEMsQ0FGRyxFQUlKcEYsS0FKSSxDQUlFSyxLQUFLLElBQUk7QUFDZCxVQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZSxLQUFuQixFQUEwQjtBQUN4QjtBQUNBLGNBQU1MLEdBQUcsR0FBRyxJQUFJZ0MsY0FBTUMsS0FBVixDQUNWRCxjQUFNQyxLQUFOLENBQVlvRCxlQURGLEVBRVYsK0RBRlUsQ0FBWjtBQUlBckYsUUFBQUEsR0FBRyxDQUFDc0YsZUFBSixHQUFzQmxGLEtBQXRCOztBQUNBLFlBQUlBLEtBQUssQ0FBQ3dELE9BQVYsRUFBbUI7QUFDakIsZ0JBQU0yQixPQUFPLEdBQUduRixLQUFLLENBQUN3RCxPQUFOLENBQWNuSCxLQUFkLENBQ2QsNkNBRGMsQ0FBaEI7O0FBR0EsY0FBSThJLE9BQU8sSUFBSUMsS0FBSyxDQUFDQyxPQUFOLENBQWNGLE9BQWQsQ0FBZixFQUF1QztBQUNyQ3ZGLFlBQUFBLEdBQUcsQ0FBQzBGLFFBQUosR0FBZTtBQUFFQyxjQUFBQSxnQkFBZ0IsRUFBRUosT0FBTyxDQUFDLENBQUQ7QUFBM0IsYUFBZjtBQUNEO0FBQ0Y7O0FBQ0QsY0FBTXZGLEdBQU47QUFDRDs7QUFDRCxZQUFNSSxLQUFOO0FBQ0QsS0F2QkksRUF3QkpMLEtBeEJJLENBd0JFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0F4QlQsQ0FBUDtBQXlCRCxHQTdZd0QsQ0ErWXpEO0FBQ0E7QUFDQTs7O0FBQ0E0RixFQUFBQSxvQkFBb0IsQ0FDbEIxSSxTQURrQixFQUVsQkosTUFGa0IsRUFHbEIrSSxLQUhrQixFQUlsQlYsb0JBSmtCLEVBS2xCO0FBQ0FySSxJQUFBQSxNQUFNLEdBQUdELCtCQUErQixDQUFDQyxNQUFELENBQXhDO0FBQ0EsV0FBTyxLQUFLNEQsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSTtBQUNsQixZQUFNdUosVUFBVSxHQUFHLG9DQUFlNUksU0FBZixFQUEwQjJJLEtBQTFCLEVBQWlDL0ksTUFBakMsQ0FBbkI7QUFDQSxhQUFPUCxVQUFVLENBQUMwSCxVQUFYLENBQXNCNkIsVUFBdEIsRUFBa0NYLG9CQUFsQyxDQUFQO0FBQ0QsS0FKSSxFQUtKcEYsS0FMSSxDQUtFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FMVCxFQU1KN0QsSUFOSSxDQU9ILENBQUM7QUFBRTRKLE1BQUFBO0FBQUYsS0FBRCxLQUFnQjtBQUNkLFVBQUlBLE1BQU0sQ0FBQ0MsQ0FBUCxLQUFhLENBQWpCLEVBQW9CO0FBQ2xCLGNBQU0sSUFBSWhFLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZZ0UsZ0JBRFIsRUFFSixtQkFGSSxDQUFOO0FBSUQ7O0FBQ0QsYUFBT2hHLE9BQU8sQ0FBQ08sT0FBUixFQUFQO0FBQ0QsS0FmRSxFQWdCSCxNQUFNO0FBQ0osWUFBTSxJQUFJd0IsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlpRSxxQkFEUixFQUVKLHdCQUZJLENBQU47QUFJRCxLQXJCRSxDQUFQO0FBdUJELEdBaGJ3RCxDQWtiekQ7OztBQUNBQyxFQUFBQSxvQkFBb0IsQ0FDbEJqSixTQURrQixFQUVsQkosTUFGa0IsRUFHbEIrSSxLQUhrQixFQUlsQk8sTUFKa0IsRUFLbEJqQixvQkFMa0IsRUFNbEI7QUFDQXJJLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNdUosV0FBVyxHQUFHLHFDQUFnQm5KLFNBQWhCLEVBQTJCa0osTUFBM0IsRUFBbUN0SixNQUFuQyxDQUFwQjtBQUNBLFVBQU1nSixVQUFVLEdBQUcsb0NBQWU1SSxTQUFmLEVBQTBCMkksS0FBMUIsRUFBaUMvSSxNQUFqQyxDQUFuQjtBQUNBLFdBQU8sS0FBSzRELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQ2RBLFVBQVUsQ0FBQ29JLFVBQVgsQ0FBc0JtQixVQUF0QixFQUFrQ08sV0FBbEMsRUFBK0NsQixvQkFBL0MsQ0FGRyxFQUlKcEYsS0FKSSxDQUlFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FKVCxDQUFQO0FBS0QsR0FsY3dELENBb2N6RDtBQUNBOzs7QUFDQXNHLEVBQUFBLGdCQUFnQixDQUNkcEosU0FEYyxFQUVkSixNQUZjLEVBR2QrSSxLQUhjLEVBSWRPLE1BSmMsRUFLZGpCLG9CQUxjLEVBTWQ7QUFDQXJJLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNdUosV0FBVyxHQUFHLHFDQUFnQm5KLFNBQWhCLEVBQTJCa0osTUFBM0IsRUFBbUN0SixNQUFuQyxDQUFwQjtBQUNBLFVBQU1nSixVQUFVLEdBQUcsb0NBQWU1SSxTQUFmLEVBQTBCMkksS0FBMUIsRUFBaUMvSSxNQUFqQyxDQUFuQjtBQUNBLFdBQU8sS0FBSzRELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQ2RBLFVBQVUsQ0FBQ2dLLGdCQUFYLENBQTRCRCxnQkFBNUIsQ0FBNkNSLFVBQTdDLEVBQXlETyxXQUF6RCxFQUFzRTtBQUNwRUcsTUFBQUEsY0FBYyxFQUFFLEtBRG9EO0FBRXBFQyxNQUFBQSxPQUFPLEVBQUV0QixvQkFBb0IsSUFBSXRIO0FBRm1DLEtBQXRFLENBRkcsRUFPSjFCLElBUEksQ0FPQzRKLE1BQU0sSUFBSSw4Q0FBeUI3SSxTQUF6QixFQUFvQzZJLE1BQU0sQ0FBQ1csS0FBM0MsRUFBa0Q1SixNQUFsRCxDQVBYLEVBUUppRCxLQVJJLENBUUVLLEtBQUssSUFBSTtBQUNkLFVBQUlBLEtBQUssQ0FBQ0MsSUFBTixLQUFlLEtBQW5CLEVBQTBCO0FBQ3hCLGNBQU0sSUFBSTJCLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZb0QsZUFEUixFQUVKLCtEQUZJLENBQU47QUFJRDs7QUFDRCxZQUFNakYsS0FBTjtBQUNELEtBaEJJLEVBaUJKTCxLQWpCSSxDQWlCRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBakJULENBQVA7QUFrQkQsR0FsZXdELENBb2V6RDs7O0FBQ0EyRyxFQUFBQSxlQUFlLENBQ2J6SixTQURhLEVBRWJKLE1BRmEsRUFHYitJLEtBSGEsRUFJYk8sTUFKYSxFQUtiakIsb0JBTGEsRUFNYjtBQUNBckksSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU11SixXQUFXLEdBQUcscUNBQWdCbkosU0FBaEIsRUFBMkJrSixNQUEzQixFQUFtQ3RKLE1BQW5DLENBQXBCO0FBQ0EsVUFBTWdKLFVBQVUsR0FBRyxvQ0FBZTVJLFNBQWYsRUFBMEIySSxLQUExQixFQUFpQy9JLE1BQWpDLENBQW5CO0FBQ0EsV0FBTyxLQUFLNEQsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDcUssU0FBWCxDQUFxQmQsVUFBckIsRUFBaUNPLFdBQWpDLEVBQThDbEIsb0JBQTlDLENBRkcsRUFJSnBGLEtBSkksQ0FJRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBSlQsQ0FBUDtBQUtELEdBcGZ3RCxDQXNmekQ7OztBQUNBNkcsRUFBQUEsSUFBSSxDQUNGM0osU0FERSxFQUVGSixNQUZFLEVBR0YrSSxLQUhFLEVBSUY7QUFDRWlCLElBQUFBLElBREY7QUFFRUMsSUFBQUEsS0FGRjtBQUdFQyxJQUFBQSxJQUhGO0FBSUUzSSxJQUFBQSxJQUpGO0FBS0U0SSxJQUFBQSxjQUxGO0FBTUVDLElBQUFBLElBTkY7QUFPRUMsSUFBQUEsZUFQRjtBQVFFQyxJQUFBQTtBQVJGLEdBSkUsRUFjWTtBQUNkdEssSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU1nSixVQUFVLEdBQUcsb0NBQWU1SSxTQUFmLEVBQTBCMkksS0FBMUIsRUFBaUMvSSxNQUFqQyxDQUFuQjs7QUFDQSxVQUFNdUssU0FBUyxHQUFHQyxnQkFBRUMsT0FBRixDQUFVUCxJQUFWLEVBQWdCLENBQUNOLEtBQUQsRUFBUTVJLFNBQVIsS0FDaEMsa0NBQWFaLFNBQWIsRUFBd0JZLFNBQXhCLEVBQW1DaEIsTUFBbkMsQ0FEZ0IsQ0FBbEI7O0FBR0EsVUFBTTBLLFNBQVMsR0FBR0YsZ0JBQUV0RSxNQUFGLENBQ2hCM0UsSUFEZ0IsRUFFaEIsQ0FBQ29KLElBQUQsRUFBT25GLEdBQVAsS0FBZTtBQUNiLFVBQUlBLEdBQUcsS0FBSyxLQUFaLEVBQW1CO0FBQ2pCbUYsUUFBQUEsSUFBSSxDQUFDLFFBQUQsQ0FBSixHQUFpQixDQUFqQjtBQUNBQSxRQUFBQSxJQUFJLENBQUMsUUFBRCxDQUFKLEdBQWlCLENBQWpCO0FBQ0QsT0FIRCxNQUdPO0FBQ0xBLFFBQUFBLElBQUksQ0FBQyxrQ0FBYXZLLFNBQWIsRUFBd0JvRixHQUF4QixFQUE2QnhGLE1BQTdCLENBQUQsQ0FBSixHQUE2QyxDQUE3QztBQUNEOztBQUNELGFBQU8ySyxJQUFQO0FBQ0QsS0FWZSxFQVdoQixFQVhnQixDQUFsQixDQU5jLENBb0JkO0FBQ0E7QUFDQTs7O0FBQ0EsUUFBSXBKLElBQUksSUFBSSxDQUFDbUosU0FBUyxDQUFDaEssR0FBdkIsRUFBNEI7QUFDMUJnSyxNQUFBQSxTQUFTLENBQUNoSyxHQUFWLEdBQWdCLENBQWhCO0FBQ0Q7O0FBRUR5SixJQUFBQSxjQUFjLEdBQUcsS0FBS1Msb0JBQUwsQ0FBMEJULGNBQTFCLENBQWpCO0FBQ0EsV0FBTyxLQUFLVSx5QkFBTCxDQUErQnpLLFNBQS9CLEVBQTBDMkksS0FBMUMsRUFBaUQvSSxNQUFqRCxFQUNKWCxJQURJLENBQ0MsTUFBTSxLQUFLdUUsbUJBQUwsQ0FBeUJ4RCxTQUF6QixDQURQLEVBRUpmLElBRkksQ0FFQ0ksVUFBVSxJQUNkQSxVQUFVLENBQUNzSyxJQUFYLENBQWdCZixVQUFoQixFQUE0QjtBQUMxQmdCLE1BQUFBLElBRDBCO0FBRTFCQyxNQUFBQSxLQUYwQjtBQUcxQkMsTUFBQUEsSUFBSSxFQUFFSyxTQUhvQjtBQUkxQmhKLE1BQUFBLElBQUksRUFBRW1KLFNBSm9CO0FBSzFCbkksTUFBQUEsU0FBUyxFQUFFLEtBQUtELFVBTFU7QUFNMUI2SCxNQUFBQSxjQU4wQjtBQU8xQkMsTUFBQUEsSUFQMEI7QUFRMUJDLE1BQUFBLGVBUjBCO0FBUzFCQyxNQUFBQTtBQVQwQixLQUE1QixDQUhHLEVBZUpqTCxJQWZJLENBZUN5TCxPQUFPLElBQUk7QUFDZixVQUFJUixPQUFKLEVBQWE7QUFDWCxlQUFPUSxPQUFQO0FBQ0Q7O0FBQ0QsYUFBT0EsT0FBTyxDQUFDNUQsR0FBUixDQUFZa0IsTUFBTSxJQUN2Qiw4Q0FBeUJoSSxTQUF6QixFQUFvQ2dJLE1BQXBDLEVBQTRDcEksTUFBNUMsQ0FESyxDQUFQO0FBR0QsS0F0QkksRUF1QkppRCxLQXZCSSxDQXVCRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBdkJULENBQVA7QUF3QkQ7O0FBRUQ2SCxFQUFBQSxXQUFXLENBQ1QzSyxTQURTLEVBRVRKLE1BRlMsRUFHVHFILFVBSFMsRUFJVDJELFNBSlMsRUFLVFgsZUFBd0IsR0FBRyxLQUxsQixFQU1UekgsT0FBZ0IsR0FBRyxFQU5WLEVBT0s7QUFDZDVDLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNaUwsb0JBQW9CLEdBQUcsRUFBN0I7QUFDQSxVQUFNQyxlQUFlLEdBQUc3RCxVQUFVLENBQUNILEdBQVgsQ0FBZWxHLFNBQVMsSUFDOUMsa0NBQWFaLFNBQWIsRUFBd0JZLFNBQXhCLEVBQW1DaEIsTUFBbkMsQ0FEc0IsQ0FBeEI7QUFHQWtMLElBQUFBLGVBQWUsQ0FBQ25HLE9BQWhCLENBQXdCL0QsU0FBUyxJQUFJO0FBQ25DaUssTUFBQUEsb0JBQW9CLENBQUNqSyxTQUFELENBQXBCLEdBQ0U0QixPQUFPLENBQUN1SSxTQUFSLEtBQXNCcEssU0FBdEIsR0FBa0M2QixPQUFPLENBQUN1SSxTQUExQyxHQUFzRCxDQUR4RDtBQUVELEtBSEQ7QUFLQSxVQUFNQyxjQUFzQixHQUFHO0FBQUVDLE1BQUFBLFVBQVUsRUFBRSxJQUFkO0FBQW9CQyxNQUFBQSxNQUFNLEVBQUU7QUFBNUIsS0FBL0I7QUFDQSxVQUFNQyxnQkFBd0IsR0FBR1AsU0FBUyxHQUFHO0FBQUVuSCxNQUFBQSxJQUFJLEVBQUVtSDtBQUFSLEtBQUgsR0FBeUIsRUFBbkU7QUFDQSxVQUFNUSxVQUFrQixHQUN0QjVJLE9BQU8sQ0FBQzZJLEdBQVIsS0FBZ0IxSyxTQUFoQixHQUE0QjtBQUFFMkssTUFBQUEsa0JBQWtCLEVBQUU5SSxPQUFPLENBQUM2STtBQUE5QixLQUE1QixHQUFrRSxFQURwRTtBQUVBLFVBQU1FLHNCQUE4QixHQUFHdEIsZUFBZSxHQUNsRDtBQUFFdUIsTUFBQUEsU0FBUyxFQUFFN0gseUJBQWdCOEgsd0JBQWhCO0FBQWIsS0FEa0QsR0FFbEQsRUFGSjs7QUFHQSxVQUFNQyxZQUFvQiwrREFDckJWLGNBRHFCLEdBRXJCTyxzQkFGcUIsR0FHckJKLGdCQUhxQixHQUlyQkMsVUFKcUIsQ0FBMUI7O0FBT0EsV0FBTyxLQUFLNUgsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBRUhJLFVBQVUsSUFDUixJQUFJMEQsT0FBSixDQUFZLENBQUNPLE9BQUQsRUFBVU4sTUFBVixLQUNWM0QsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEJzQyxXQUE1QixDQUNFZCxvQkFERixFQUVFYSxZQUZGLEVBR0V4SSxLQUFLLElBQUtBLEtBQUssR0FBR0YsTUFBTSxDQUFDRSxLQUFELENBQVQsR0FBbUJJLE9BQU8sRUFIM0MsQ0FERixDQUhDLEVBV0pULEtBWEksQ0FXRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBWFQsQ0FBUDtBQVlELEdBdm1Cd0QsQ0F5bUJ6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQThJLEVBQUFBLGdCQUFnQixDQUNkNUwsU0FEYyxFQUVkSixNQUZjLEVBR2RxSCxVQUhjLEVBSWQ7QUFDQXJILElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNaUwsb0JBQW9CLEdBQUcsRUFBN0I7QUFDQSxVQUFNQyxlQUFlLEdBQUc3RCxVQUFVLENBQUNILEdBQVgsQ0FBZWxHLFNBQVMsSUFDOUMsa0NBQWFaLFNBQWIsRUFBd0JZLFNBQXhCLEVBQW1DaEIsTUFBbkMsQ0FEc0IsQ0FBeEI7QUFHQWtMLElBQUFBLGVBQWUsQ0FBQ25HLE9BQWhCLENBQXdCL0QsU0FBUyxJQUFJO0FBQ25DaUssTUFBQUEsb0JBQW9CLENBQUNqSyxTQUFELENBQXBCLEdBQWtDLENBQWxDO0FBQ0QsS0FGRDtBQUdBLFdBQU8sS0FBSzRDLG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQ2RBLFVBQVUsQ0FBQ3dNLG9DQUFYLENBQWdEaEIsb0JBQWhELENBRkcsRUFJSmhJLEtBSkksQ0FJRUssS0FBSyxJQUFJO0FBQ2QsVUFBSUEsS0FBSyxDQUFDQyxJQUFOLEtBQWUsS0FBbkIsRUFBMEI7QUFDeEIsY0FBTSxJQUFJMkIsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlvRCxlQURSLEVBRUosMkVBRkksQ0FBTjtBQUlEOztBQUNELFlBQU1qRixLQUFOO0FBQ0QsS0FaSSxFQWFKTCxLQWJJLENBYUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQWJULENBQVA7QUFjRCxHQXpvQndELENBMm9CekQ7OztBQUNBZ0osRUFBQUEsUUFBUSxDQUFDOUwsU0FBRCxFQUFvQjJJLEtBQXBCLEVBQXNDO0FBQzVDLFdBQU8sS0FBS25GLG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQ2RBLFVBQVUsQ0FBQ3NLLElBQVgsQ0FBZ0JoQixLQUFoQixFQUF1QjtBQUNyQnhHLE1BQUFBLFNBQVMsRUFBRSxLQUFLRDtBQURLLEtBQXZCLENBRkcsRUFNSlcsS0FOSSxDQU1FQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FOVCxDQUFQO0FBT0QsR0FwcEJ3RCxDQXNwQnpEOzs7QUFDQWlKLEVBQUFBLEtBQUssQ0FDSC9MLFNBREcsRUFFSEosTUFGRyxFQUdIK0ksS0FIRyxFQUlIb0IsY0FKRyxFQUtIQyxJQUxHLEVBTUg7QUFDQXBLLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQW1LLElBQUFBLGNBQWMsR0FBRyxLQUFLUyxvQkFBTCxDQUEwQlQsY0FBMUIsQ0FBakI7QUFDQSxXQUFPLEtBQUt2RyxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUNkQSxVQUFVLENBQUMwTSxLQUFYLENBQWlCLG9DQUFlL0wsU0FBZixFQUEwQjJJLEtBQTFCLEVBQWlDL0ksTUFBakMsRUFBeUMsSUFBekMsQ0FBakIsRUFBaUU7QUFDL0R1QyxNQUFBQSxTQUFTLEVBQUUsS0FBS0QsVUFEK0M7QUFFL0Q2SCxNQUFBQSxjQUYrRDtBQUcvREMsTUFBQUE7QUFIK0QsS0FBakUsQ0FGRyxFQVFKbkgsS0FSSSxDQVFFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FSVCxDQUFQO0FBU0Q7O0FBRURrSixFQUFBQSxRQUFRLENBQ05oTSxTQURNLEVBRU5KLE1BRk0sRUFHTitJLEtBSE0sRUFJTi9ILFNBSk0sRUFLTjtBQUNBaEIsSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU1xTSxjQUFjLEdBQ2xCck0sTUFBTSxDQUFDQyxNQUFQLENBQWNlLFNBQWQsS0FBNEJoQixNQUFNLENBQUNDLE1BQVAsQ0FBY2UsU0FBZCxFQUF5QkMsSUFBekIsS0FBa0MsU0FEaEU7QUFFQSxVQUFNcUwsY0FBYyxHQUFHLGtDQUFhbE0sU0FBYixFQUF3QlksU0FBeEIsRUFBbUNoQixNQUFuQyxDQUF2QjtBQUVBLFdBQU8sS0FBSzRELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQ2RBLFVBQVUsQ0FBQzJNLFFBQVgsQ0FDRUUsY0FERixFQUVFLG9DQUFlbE0sU0FBZixFQUEwQjJJLEtBQTFCLEVBQWlDL0ksTUFBakMsQ0FGRixDQUZHLEVBT0pYLElBUEksQ0FPQ3lMLE9BQU8sSUFBSTtBQUNmQSxNQUFBQSxPQUFPLEdBQUdBLE9BQU8sQ0FBQ3RMLE1BQVIsQ0FBZTJHLEdBQUcsSUFBSUEsR0FBRyxJQUFJLElBQTdCLENBQVY7QUFDQSxhQUFPMkUsT0FBTyxDQUFDNUQsR0FBUixDQUFZa0IsTUFBTSxJQUFJO0FBQzNCLFlBQUlpRSxjQUFKLEVBQW9CO0FBQ2xCLGlCQUFPLDRDQUF1QnJNLE1BQXZCLEVBQStCZ0IsU0FBL0IsRUFBMENvSCxNQUExQyxDQUFQO0FBQ0Q7O0FBQ0QsZUFBTyw4Q0FBeUJoSSxTQUF6QixFQUFvQ2dJLE1BQXBDLEVBQTRDcEksTUFBNUMsQ0FBUDtBQUNELE9BTE0sQ0FBUDtBQU1ELEtBZkksRUFnQkppRCxLQWhCSSxDQWdCRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBaEJULENBQVA7QUFpQkQ7O0FBRURxSixFQUFBQSxTQUFTLENBQ1BuTSxTQURPLEVBRVBKLE1BRk8sRUFHUHdNLFFBSE8sRUFJUHJDLGNBSk8sRUFLUEMsSUFMTyxFQU1QRSxPQU5PLEVBT1A7QUFDQSxRQUFJK0IsY0FBYyxHQUFHLEtBQXJCO0FBQ0FHLElBQUFBLFFBQVEsR0FBR0EsUUFBUSxDQUFDdEYsR0FBVCxDQUFhdUYsS0FBSyxJQUFJO0FBQy9CLFVBQUlBLEtBQUssQ0FBQ0MsTUFBVixFQUFrQjtBQUNoQkQsUUFBQUEsS0FBSyxDQUFDQyxNQUFOLEdBQWUsS0FBS0Msd0JBQUwsQ0FBOEIzTSxNQUE5QixFQUFzQ3lNLEtBQUssQ0FBQ0MsTUFBNUMsQ0FBZjs7QUFDQSxZQUNFRCxLQUFLLENBQUNDLE1BQU4sQ0FBYWhNLEdBQWIsSUFDQSxPQUFPK0wsS0FBSyxDQUFDQyxNQUFOLENBQWFoTSxHQUFwQixLQUE0QixRQUQ1QixJQUVBK0wsS0FBSyxDQUFDQyxNQUFOLENBQWFoTSxHQUFiLENBQWlCYixPQUFqQixDQUF5QixNQUF6QixLQUFvQyxDQUh0QyxFQUlFO0FBQ0F3TSxVQUFBQSxjQUFjLEdBQUcsSUFBakI7QUFDRDtBQUNGOztBQUNELFVBQUlJLEtBQUssQ0FBQ0csTUFBVixFQUFrQjtBQUNoQkgsUUFBQUEsS0FBSyxDQUFDRyxNQUFOLEdBQWUsS0FBS0MsbUJBQUwsQ0FBeUI3TSxNQUF6QixFQUFpQ3lNLEtBQUssQ0FBQ0csTUFBdkMsQ0FBZjtBQUNEOztBQUNELFVBQUlILEtBQUssQ0FBQ0ssUUFBVixFQUFvQjtBQUNsQkwsUUFBQUEsS0FBSyxDQUFDSyxRQUFOLEdBQWlCLEtBQUtDLDBCQUFMLENBQ2YvTSxNQURlLEVBRWZ5TSxLQUFLLENBQUNLLFFBRlMsQ0FBakI7QUFJRDs7QUFDRCxVQUFJTCxLQUFLLENBQUNPLFFBQU4sSUFBa0JQLEtBQUssQ0FBQ08sUUFBTixDQUFlakUsS0FBckMsRUFBNEM7QUFDMUMwRCxRQUFBQSxLQUFLLENBQUNPLFFBQU4sQ0FBZWpFLEtBQWYsR0FBdUIsS0FBSzhELG1CQUFMLENBQ3JCN00sTUFEcUIsRUFFckJ5TSxLQUFLLENBQUNPLFFBQU4sQ0FBZWpFLEtBRk0sQ0FBdkI7QUFJRDs7QUFDRCxhQUFPMEQsS0FBUDtBQUNELEtBM0JVLENBQVg7QUE0QkF0QyxJQUFBQSxjQUFjLEdBQUcsS0FBS1Msb0JBQUwsQ0FBMEJULGNBQTFCLENBQWpCO0FBQ0EsV0FBTyxLQUFLdkcsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDOE0sU0FBWCxDQUFxQkMsUUFBckIsRUFBK0I7QUFDN0JyQyxNQUFBQSxjQUQ2QjtBQUU3QjVILE1BQUFBLFNBQVMsRUFBRSxLQUFLRCxVQUZhO0FBRzdCOEgsTUFBQUEsSUFINkI7QUFJN0JFLE1BQUFBO0FBSjZCLEtBQS9CLENBRkcsRUFTSmpMLElBVEksQ0FTQzROLE9BQU8sSUFBSTtBQUNmQSxNQUFBQSxPQUFPLENBQUNsSSxPQUFSLENBQWdCa0UsTUFBTSxJQUFJO0FBQ3hCLFlBQUkzSCxNQUFNLENBQUNtRSxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNzRCxNQUFyQyxFQUE2QyxLQUE3QyxDQUFKLEVBQXlEO0FBQ3ZELGNBQUlvRCxjQUFjLElBQUlwRCxNQUFNLENBQUN2SSxHQUE3QixFQUFrQztBQUNoQ3VJLFlBQUFBLE1BQU0sQ0FBQ3ZJLEdBQVAsR0FBYXVJLE1BQU0sQ0FBQ3ZJLEdBQVAsQ0FBV3dNLEtBQVgsQ0FBaUIsR0FBakIsRUFBc0IsQ0FBdEIsQ0FBYjtBQUNEOztBQUNELGNBQ0VqRSxNQUFNLENBQUN2SSxHQUFQLElBQWMsSUFBZCxJQUNBdUksTUFBTSxDQUFDdkksR0FBUCxJQUFjSyxTQURkLElBRUMsQ0FBQyxRQUFELEVBQVcsUUFBWCxFQUFxQm9NLFFBQXJCLENBQThCLE9BQU9sRSxNQUFNLENBQUN2SSxHQUE1QyxLQUNDOEosZ0JBQUU0QyxPQUFGLENBQVVuRSxNQUFNLENBQUN2SSxHQUFqQixDQUpKLEVBS0U7QUFDQXVJLFlBQUFBLE1BQU0sQ0FBQ3ZJLEdBQVAsR0FBYSxJQUFiO0FBQ0Q7O0FBQ0R1SSxVQUFBQSxNQUFNLENBQUN0SSxRQUFQLEdBQWtCc0ksTUFBTSxDQUFDdkksR0FBekI7QUFDQSxpQkFBT3VJLE1BQU0sQ0FBQ3ZJLEdBQWQ7QUFDRDtBQUNGLE9BaEJEO0FBaUJBLGFBQU91TSxPQUFQO0FBQ0QsS0E1QkksRUE2Qko1TixJQTdCSSxDQTZCQ3lMLE9BQU8sSUFDWEEsT0FBTyxDQUFDNUQsR0FBUixDQUFZa0IsTUFBTSxJQUNoQiw4Q0FBeUJoSSxTQUF6QixFQUFvQ2dJLE1BQXBDLEVBQTRDcEksTUFBNUMsQ0FERixDQTlCRyxFQWtDSmlELEtBbENJLENBa0NFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FsQ1QsQ0FBUDtBQW1DRCxHQWx4QndELENBb3hCekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBMkosRUFBQUEsbUJBQW1CLENBQUM3TSxNQUFELEVBQWN3TSxRQUFkLEVBQWtDO0FBQ25ELFFBQUlBLFFBQVEsS0FBSyxJQUFqQixFQUF1QjtBQUNyQixhQUFPLElBQVA7QUFDRCxLQUZELE1BRU8sSUFBSTlELEtBQUssQ0FBQ0MsT0FBTixDQUFjNkQsUUFBZCxDQUFKLEVBQTZCO0FBQ2xDLGFBQU9BLFFBQVEsQ0FBQ3RGLEdBQVQsQ0FBYTBDLEtBQUssSUFBSSxLQUFLaUQsbUJBQUwsQ0FBeUI3TSxNQUF6QixFQUFpQzRKLEtBQWpDLENBQXRCLENBQVA7QUFDRCxLQUZNLE1BRUEsSUFBSSxPQUFPNEMsUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUN2QyxZQUFNYSxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsV0FBSyxNQUFNckksS0FBWCxJQUFvQndILFFBQXBCLEVBQThCO0FBQzVCLFlBQUl4TSxNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsS0FBd0JoRixNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsRUFBcUIvRCxJQUFyQixLQUE4QixTQUExRCxFQUFxRTtBQUNuRSxjQUFJLE9BQU91TCxRQUFRLENBQUN4SCxLQUFELENBQWYsS0FBMkIsUUFBL0IsRUFBeUM7QUFDdkM7QUFDQXFJLFlBQUFBLFdBQVcsQ0FBRSxNQUFLckksS0FBTSxFQUFiLENBQVgsR0FBNkJ3SCxRQUFRLENBQUN4SCxLQUFELENBQXJDO0FBQ0QsV0FIRCxNQUdPO0FBQ0xxSSxZQUFBQSxXQUFXLENBQ1IsTUFBS3JJLEtBQU0sRUFESCxDQUFYLEdBRUssR0FBRWhGLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjK0UsS0FBZCxFQUFxQjlELFdBQVksSUFBR3NMLFFBQVEsQ0FBQ3hILEtBQUQsQ0FBUSxFQUYzRDtBQUdEO0FBQ0YsU0FURCxNQVNPLElBQ0xoRixNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsS0FDQWhGLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjK0UsS0FBZCxFQUFxQi9ELElBQXJCLEtBQThCLE1BRnpCLEVBR0w7QUFDQW9NLFVBQUFBLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBWCxHQUFxQixLQUFLc0ksY0FBTCxDQUFvQmQsUUFBUSxDQUFDeEgsS0FBRCxDQUE1QixDQUFyQjtBQUNELFNBTE0sTUFLQTtBQUNMcUksVUFBQUEsV0FBVyxDQUFDckksS0FBRCxDQUFYLEdBQXFCLEtBQUs2SCxtQkFBTCxDQUNuQjdNLE1BRG1CLEVBRW5Cd00sUUFBUSxDQUFDeEgsS0FBRCxDQUZXLENBQXJCO0FBSUQ7O0FBRUQsWUFBSUEsS0FBSyxLQUFLLFVBQWQsRUFBMEI7QUFDeEJxSSxVQUFBQSxXQUFXLENBQUMsS0FBRCxDQUFYLEdBQXFCQSxXQUFXLENBQUNySSxLQUFELENBQWhDO0FBQ0EsaUJBQU9xSSxXQUFXLENBQUNySSxLQUFELENBQWxCO0FBQ0QsU0FIRCxNQUdPLElBQUlBLEtBQUssS0FBSyxXQUFkLEVBQTJCO0FBQ2hDcUksVUFBQUEsV0FBVyxDQUFDLGFBQUQsQ0FBWCxHQUE2QkEsV0FBVyxDQUFDckksS0FBRCxDQUF4QztBQUNBLGlCQUFPcUksV0FBVyxDQUFDckksS0FBRCxDQUFsQjtBQUNELFNBSE0sTUFHQSxJQUFJQSxLQUFLLEtBQUssV0FBZCxFQUEyQjtBQUNoQ3FJLFVBQUFBLFdBQVcsQ0FBQyxhQUFELENBQVgsR0FBNkJBLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBeEM7QUFDQSxpQkFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRDtBQUNGOztBQUNELGFBQU9xSSxXQUFQO0FBQ0Q7O0FBQ0QsV0FBT2IsUUFBUDtBQUNELEdBbDFCd0QsQ0FvMUJ6RDtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0FPLEVBQUFBLDBCQUEwQixDQUFDL00sTUFBRCxFQUFjd00sUUFBZCxFQUFrQztBQUMxRCxVQUFNYSxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsU0FBSyxNQUFNckksS0FBWCxJQUFvQndILFFBQXBCLEVBQThCO0FBQzVCLFVBQUl4TSxNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsS0FBd0JoRixNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsRUFBcUIvRCxJQUFyQixLQUE4QixTQUExRCxFQUFxRTtBQUNuRW9NLFFBQUFBLFdBQVcsQ0FBRSxNQUFLckksS0FBTSxFQUFiLENBQVgsR0FBNkJ3SCxRQUFRLENBQUN4SCxLQUFELENBQXJDO0FBQ0QsT0FGRCxNQUVPO0FBQ0xxSSxRQUFBQSxXQUFXLENBQUNySSxLQUFELENBQVgsR0FBcUIsS0FBSzZILG1CQUFMLENBQXlCN00sTUFBekIsRUFBaUN3TSxRQUFRLENBQUN4SCxLQUFELENBQXpDLENBQXJCO0FBQ0Q7O0FBRUQsVUFBSUEsS0FBSyxLQUFLLFVBQWQsRUFBMEI7QUFDeEJxSSxRQUFBQSxXQUFXLENBQUMsS0FBRCxDQUFYLEdBQXFCQSxXQUFXLENBQUNySSxLQUFELENBQWhDO0FBQ0EsZUFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRCxPQUhELE1BR08sSUFBSUEsS0FBSyxLQUFLLFdBQWQsRUFBMkI7QUFDaENxSSxRQUFBQSxXQUFXLENBQUMsYUFBRCxDQUFYLEdBQTZCQSxXQUFXLENBQUNySSxLQUFELENBQXhDO0FBQ0EsZUFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRCxPQUhNLE1BR0EsSUFBSUEsS0FBSyxLQUFLLFdBQWQsRUFBMkI7QUFDaENxSSxRQUFBQSxXQUFXLENBQUMsYUFBRCxDQUFYLEdBQTZCQSxXQUFXLENBQUNySSxLQUFELENBQXhDO0FBQ0EsZUFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRDtBQUNGOztBQUNELFdBQU9xSSxXQUFQO0FBQ0QsR0E3MkJ3RCxDQSsyQnpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBVixFQUFBQSx3QkFBd0IsQ0FBQzNNLE1BQUQsRUFBY3dNLFFBQWQsRUFBa0M7QUFDeEQsUUFBSTlELEtBQUssQ0FBQ0MsT0FBTixDQUFjNkQsUUFBZCxDQUFKLEVBQTZCO0FBQzNCLGFBQU9BLFFBQVEsQ0FBQ3RGLEdBQVQsQ0FBYTBDLEtBQUssSUFDdkIsS0FBSytDLHdCQUFMLENBQThCM00sTUFBOUIsRUFBc0M0SixLQUF0QyxDQURLLENBQVA7QUFHRCxLQUpELE1BSU8sSUFBSSxPQUFPNEMsUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUN2QyxZQUFNYSxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsV0FBSyxNQUFNckksS0FBWCxJQUFvQndILFFBQXBCLEVBQThCO0FBQzVCYSxRQUFBQSxXQUFXLENBQUNySSxLQUFELENBQVgsR0FBcUIsS0FBSzJILHdCQUFMLENBQ25CM00sTUFEbUIsRUFFbkJ3TSxRQUFRLENBQUN4SCxLQUFELENBRlcsQ0FBckI7QUFJRDs7QUFDRCxhQUFPcUksV0FBUDtBQUNELEtBVE0sTUFTQSxJQUFJLE9BQU9iLFFBQVAsS0FBb0IsUUFBeEIsRUFBa0M7QUFDdkMsWUFBTXhILEtBQUssR0FBR3dILFFBQVEsQ0FBQ2UsU0FBVCxDQUFtQixDQUFuQixDQUFkOztBQUNBLFVBQUl2TixNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsS0FBd0JoRixNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsRUFBcUIvRCxJQUFyQixLQUE4QixTQUExRCxFQUFxRTtBQUNuRSxlQUFRLE9BQU0rRCxLQUFNLEVBQXBCO0FBQ0QsT0FGRCxNQUVPLElBQUlBLEtBQUssSUFBSSxXQUFiLEVBQTBCO0FBQy9CLGVBQU8sY0FBUDtBQUNELE9BRk0sTUFFQSxJQUFJQSxLQUFLLElBQUksV0FBYixFQUEwQjtBQUMvQixlQUFPLGNBQVA7QUFDRDtBQUNGOztBQUNELFdBQU93SCxRQUFQO0FBQ0QsR0E3NEJ3RCxDQSs0QnpEO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQWMsRUFBQUEsY0FBYyxDQUFDMUQsS0FBRCxFQUFrQjtBQUM5QixRQUFJLE9BQU9BLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsYUFBTyxJQUFJNEQsSUFBSixDQUFTNUQsS0FBVCxDQUFQO0FBQ0Q7O0FBRUQsVUFBTXlELFdBQVcsR0FBRyxFQUFwQjs7QUFDQSxTQUFLLE1BQU1ySSxLQUFYLElBQW9CNEUsS0FBcEIsRUFBMkI7QUFDekJ5RCxNQUFBQSxXQUFXLENBQUNySSxLQUFELENBQVgsR0FBcUIsS0FBS3NJLGNBQUwsQ0FBb0IxRCxLQUFLLENBQUM1RSxLQUFELENBQXpCLENBQXJCO0FBQ0Q7O0FBQ0QsV0FBT3FJLFdBQVA7QUFDRDs7QUFFRHpDLEVBQUFBLG9CQUFvQixDQUFDVCxjQUFELEVBQW1DO0FBQ3JELFFBQUlBLGNBQUosRUFBb0I7QUFDbEJBLE1BQUFBLGNBQWMsR0FBR0EsY0FBYyxDQUFDc0QsV0FBZixFQUFqQjtBQUNEOztBQUNELFlBQVF0RCxjQUFSO0FBQ0UsV0FBSyxTQUFMO0FBQ0VBLFFBQUFBLGNBQWMsR0FBR25MLGNBQWMsQ0FBQzBPLE9BQWhDO0FBQ0E7O0FBQ0YsV0FBSyxtQkFBTDtBQUNFdkQsUUFBQUEsY0FBYyxHQUFHbkwsY0FBYyxDQUFDMk8saUJBQWhDO0FBQ0E7O0FBQ0YsV0FBSyxXQUFMO0FBQ0V4RCxRQUFBQSxjQUFjLEdBQUduTCxjQUFjLENBQUM0TyxTQUFoQztBQUNBOztBQUNGLFdBQUsscUJBQUw7QUFDRXpELFFBQUFBLGNBQWMsR0FBR25MLGNBQWMsQ0FBQzZPLG1CQUFoQztBQUNBOztBQUNGLFdBQUssU0FBTDtBQUNFMUQsUUFBQUEsY0FBYyxHQUFHbkwsY0FBYyxDQUFDOE8sT0FBaEM7QUFDQTs7QUFDRixXQUFLL00sU0FBTDtBQUNBLFdBQUssSUFBTDtBQUNBLFdBQUssRUFBTDtBQUNFOztBQUNGO0FBQ0UsY0FBTSxJQUFJbUUsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLGFBRFIsRUFFSixnQ0FGSSxDQUFOO0FBckJKOztBQTBCQSxXQUFPK0UsY0FBUDtBQUNEOztBQUVENEQsRUFBQUEscUJBQXFCLEdBQWtCO0FBQ3JDLFdBQU81SyxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNEOztBQUVEcUksRUFBQUEsV0FBVyxDQUFDM0wsU0FBRCxFQUFvQmdHLEtBQXBCLEVBQWdDO0FBQ3pDLFdBQU8sS0FBS3hDLG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ2dLLGdCQUFYLENBQTRCc0MsV0FBNUIsQ0FBd0MzRixLQUF4QyxDQURmLEVBRUpuRCxLQUZJLENBRUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRDs7QUFFRDRDLEVBQUFBLGFBQWEsQ0FBQzFGLFNBQUQsRUFBb0JJLE9BQXBCLEVBQWtDO0FBQzdDLFdBQU8sS0FBS29ELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ2dLLGdCQUFYLENBQTRCM0QsYUFBNUIsQ0FBMEN0RixPQUExQyxDQURmLEVBRUp5QyxLQUZJLENBRUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRDs7QUFFRHlELEVBQUFBLHFCQUFxQixDQUFDdkcsU0FBRCxFQUFvQlksU0FBcEIsRUFBdUNDLElBQXZDLEVBQWtEO0FBQ3JFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQSxJQUFMLEtBQWMsU0FBMUIsRUFBcUM7QUFDbkMsWUFBTW1GLEtBQUssR0FBRztBQUNaLFNBQUNwRixTQUFELEdBQWE7QUFERCxPQUFkO0FBR0EsYUFBTyxLQUFLK0ssV0FBTCxDQUFpQjNMLFNBQWpCLEVBQTRCZ0csS0FBNUIsQ0FBUDtBQUNEOztBQUNELFdBQU9qRCxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNEOztBQUVEbUgsRUFBQUEseUJBQXlCLENBQ3ZCekssU0FEdUIsRUFFdkIySSxLQUZ1QixFQUd2Qi9JLE1BSHVCLEVBSVI7QUFDZixTQUFLLE1BQU1nQixTQUFYLElBQXdCK0gsS0FBeEIsRUFBK0I7QUFDN0IsVUFBSSxDQUFDQSxLQUFLLENBQUMvSCxTQUFELENBQU4sSUFBcUIsQ0FBQytILEtBQUssQ0FBQy9ILFNBQUQsQ0FBTCxDQUFpQmdOLEtBQTNDLEVBQWtEO0FBQ2hEO0FBQ0Q7O0FBQ0QsWUFBTXJKLGVBQWUsR0FBRzNFLE1BQU0sQ0FBQ1EsT0FBL0I7O0FBQ0EsV0FBSyxNQUFNZ0YsR0FBWCxJQUFrQmIsZUFBbEIsRUFBbUM7QUFDakMsY0FBTXlCLEtBQUssR0FBR3pCLGVBQWUsQ0FBQ2EsR0FBRCxDQUE3Qjs7QUFDQSxZQUFJbEUsTUFBTSxDQUFDbUUsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDUyxLQUFyQyxFQUE0Q3BGLFNBQTVDLENBQUosRUFBNEQ7QUFDMUQsaUJBQU9tQyxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNEO0FBQ0Y7O0FBQ0QsWUFBTXNILFNBQVMsR0FBSSxHQUFFaEssU0FBVSxPQUEvQjtBQUNBLFlBQU1pTixTQUFTLEdBQUc7QUFDaEIsU0FBQ2pELFNBQUQsR0FBYTtBQUFFLFdBQUNoSyxTQUFELEdBQWE7QUFBZjtBQURHLE9BQWxCO0FBR0EsYUFBTyxLQUFLeUQsMEJBQUwsQ0FDTHJFLFNBREssRUFFTDZOLFNBRkssRUFHTHRKLGVBSEssRUFJTDNFLE1BQU0sQ0FBQ0MsTUFKRixFQUtMZ0QsS0FMSyxDQUtDSyxLQUFLLElBQUk7QUFDZixZQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZSxFQUFuQixFQUF1QjtBQUNyQjtBQUNBLGlCQUFPLEtBQUt5QyxtQkFBTCxDQUF5QjVGLFNBQXpCLENBQVA7QUFDRDs7QUFDRCxjQUFNa0QsS0FBTjtBQUNELE9BWE0sQ0FBUDtBQVlEOztBQUNELFdBQU9ILE9BQU8sQ0FBQ08sT0FBUixFQUFQO0FBQ0Q7O0FBRUR1QyxFQUFBQSxVQUFVLENBQUM3RixTQUFELEVBQW9CO0FBQzVCLFdBQU8sS0FBS3dELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ2dLLGdCQUFYLENBQTRCakosT0FBNUIsRUFEZixFQUVKeUMsS0FGSSxDQUVFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FGVCxDQUFQO0FBR0Q7O0FBRURvQyxFQUFBQSxTQUFTLENBQUNsRixTQUFELEVBQW9CZ0csS0FBcEIsRUFBZ0M7QUFDdkMsV0FBTyxLQUFLeEMsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSUEsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEJuRSxTQUE1QixDQUFzQ2MsS0FBdEMsQ0FEZixFQUVKbkQsS0FGSSxDQUVFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FGVCxDQUFQO0FBR0Q7O0FBRURnTCxFQUFBQSxjQUFjLENBQUM5TixTQUFELEVBQW9CO0FBQ2hDLFdBQU8sS0FBS3dELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ2dLLGdCQUFYLENBQTRCMEUsV0FBNUIsRUFEZixFQUVKbEwsS0FGSSxDQUVFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FGVCxDQUFQO0FBR0Q7O0FBRURrTCxFQUFBQSx1QkFBdUIsR0FBaUI7QUFDdEMsV0FBTyxLQUFLdEcsYUFBTCxHQUNKekksSUFESSxDQUNDZ1AsT0FBTyxJQUFJO0FBQ2YsWUFBTUMsUUFBUSxHQUFHRCxPQUFPLENBQUNuSCxHQUFSLENBQVlsSCxNQUFNLElBQUk7QUFDckMsZUFBTyxLQUFLZ0csbUJBQUwsQ0FBeUJoRyxNQUFNLENBQUNJLFNBQWhDLENBQVA7QUFDRCxPQUZnQixDQUFqQjtBQUdBLGFBQU8rQyxPQUFPLENBQUM0QyxHQUFSLENBQVl1SSxRQUFaLENBQVA7QUFDRCxLQU5JLEVBT0pyTCxLQVBJLENBT0VDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQVBULENBQVA7QUFRRDs7QUFFRHFMLEVBQUFBLDBCQUEwQixHQUFpQjtBQUN6QyxVQUFNQyxvQkFBb0IsR0FBRyxLQUFLN0wsTUFBTCxDQUFZOEwsWUFBWixFQUE3QjtBQUNBRCxJQUFBQSxvQkFBb0IsQ0FBQ0UsZ0JBQXJCO0FBQ0EsV0FBT3ZMLE9BQU8sQ0FBQ08sT0FBUixDQUFnQjhLLG9CQUFoQixDQUFQO0FBQ0Q7O0FBRURHLEVBQUFBLDBCQUEwQixDQUFDSCxvQkFBRCxFQUEyQztBQUNuRSxXQUFPQSxvQkFBb0IsQ0FBQ0ksaUJBQXJCLEdBQXlDdlAsSUFBekMsQ0FBOEMsTUFBTTtBQUN6RG1QLE1BQUFBLG9CQUFvQixDQUFDSyxVQUFyQjtBQUNELEtBRk0sQ0FBUDtBQUdEOztBQUVEQyxFQUFBQSx5QkFBeUIsQ0FBQ04sb0JBQUQsRUFBMkM7QUFDbEUsV0FBT0Esb0JBQW9CLENBQUNPLGdCQUFyQixHQUF3QzFQLElBQXhDLENBQTZDLE1BQU07QUFDeERtUCxNQUFBQSxvQkFBb0IsQ0FBQ0ssVUFBckI7QUFDRCxLQUZNLENBQVA7QUFHRDs7QUEzaUN3RDs7O2VBOGlDNUNsTixtQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgTW9uZ29Db2xsZWN0aW9uIGZyb20gJy4vTW9uZ29Db2xsZWN0aW9uJztcbmltcG9ydCBNb25nb1NjaGVtYUNvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb1NjaGVtYUNvbGxlY3Rpb24nO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7XG4gIFNjaGVtYVR5cGUsXG4gIFF1ZXJ5VHlwZSxcbiAgU3RvcmFnZUNsYXNzLFxuICBRdWVyeU9wdGlvbnMsXG59IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB7XG4gIHBhcnNlIGFzIHBhcnNlVXJsLFxuICBmb3JtYXQgYXMgZm9ybWF0VXJsLFxufSBmcm9tICcuLi8uLi8uLi92ZW5kb3IvbW9uZ29kYlVybCc7XG5pbXBvcnQge1xuICBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUsXG4gIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCxcbiAgdHJhbnNmb3JtS2V5LFxuICB0cmFuc2Zvcm1XaGVyZSxcbiAgdHJhbnNmb3JtVXBkYXRlLFxuICB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nLFxufSBmcm9tICcuL01vbmdvVHJhbnNmb3JtJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uLy4uL2RlZmF1bHRzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcblxuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5jb25zdCBtb25nb2RiID0gcmVxdWlyZSgnbW9uZ29kYicpO1xuY29uc3QgTW9uZ29DbGllbnQgPSBtb25nb2RiLk1vbmdvQ2xpZW50O1xuY29uc3QgUmVhZFByZWZlcmVuY2UgPSBtb25nb2RiLlJlYWRQcmVmZXJlbmNlO1xuXG5jb25zdCBNb25nb1NjaGVtYUNvbGxlY3Rpb25OYW1lID0gJ19TQ0hFTUEnO1xuXG5jb25zdCBzdG9yYWdlQWRhcHRlckFsbENvbGxlY3Rpb25zID0gbW9uZ29BZGFwdGVyID0+IHtcbiAgcmV0dXJuIG1vbmdvQWRhcHRlclxuICAgIC5jb25uZWN0KClcbiAgICAudGhlbigoKSA9PiBtb25nb0FkYXB0ZXIuZGF0YWJhc2UuY29sbGVjdGlvbnMoKSlcbiAgICAudGhlbihjb2xsZWN0aW9ucyA9PiB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbnMuZmlsdGVyKGNvbGxlY3Rpb24gPT4ge1xuICAgICAgICBpZiAoY29sbGVjdGlvbi5uYW1lc3BhY2UubWF0Y2goL1xcLnN5c3RlbVxcLi8pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IElmIHlvdSBoYXZlIG9uZSBhcHAgd2l0aCBhIGNvbGxlY3Rpb24gcHJlZml4IHRoYXQgaGFwcGVucyB0byBiZSBhIHByZWZpeCBvZiBhbm90aGVyXG4gICAgICAgIC8vIGFwcHMgcHJlZml4LCB0aGlzIHdpbGwgZ28gdmVyeSB2ZXJ5IGJhZGx5LiBXZSBzaG91bGQgZml4IHRoYXQgc29tZWhvdy5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBjb2xsZWN0aW9uLmNvbGxlY3Rpb25OYW1lLmluZGV4T2YobW9uZ29BZGFwdGVyLl9jb2xsZWN0aW9uUHJlZml4KSA9PSAwXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbn07XG5cbmNvbnN0IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEgPSAoeyAuLi5zY2hlbWEgfSkgPT4ge1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fcnBlcm07XG4gIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl93cGVybTtcblxuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIC8vIExlZ2FjeSBtb25nbyBhZGFwdGVyIGtub3dzIGFib3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gcGFzc3dvcmQgYW5kIF9oYXNoZWRfcGFzc3dvcmQuXG4gICAgLy8gRnV0dXJlIGRhdGFiYXNlIGFkYXB0ZXJzIHdpbGwgb25seSBrbm93IGFib3V0IF9oYXNoZWRfcGFzc3dvcmQuXG4gICAgLy8gTm90ZTogUGFyc2UgU2VydmVyIHdpbGwgYnJpbmcgYmFjayBwYXNzd29yZCB3aXRoIGluamVjdERlZmF1bHRTY2hlbWEsIHNvIHdlIGRvbid0IG5lZWRcbiAgICAvLyB0byBhZGQgX2hhc2hlZF9wYXNzd29yZCBiYWNrIGV2ZXIuXG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG4vLyBSZXR1cm5zIHsgY29kZSwgZXJyb3IgfSBpZiBpbnZhbGlkLCBvciB7IHJlc3VsdCB9LCBhbiBvYmplY3Rcbi8vIHN1aXRhYmxlIGZvciBpbnNlcnRpbmcgaW50byBfU0NIRU1BIGNvbGxlY3Rpb24sIG90aGVyd2lzZS5cbmNvbnN0IG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZUFuZENMUCA9IChcbiAgZmllbGRzLFxuICBjbGFzc05hbWUsXG4gIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgaW5kZXhlc1xuKSA9PiB7XG4gIGNvbnN0IG1vbmdvT2JqZWN0ID0ge1xuICAgIF9pZDogY2xhc3NOYW1lLFxuICAgIG9iamVjdElkOiAnc3RyaW5nJyxcbiAgICB1cGRhdGVkQXQ6ICdzdHJpbmcnLFxuICAgIGNyZWF0ZWRBdDogJ3N0cmluZycsXG4gICAgX21ldGFkYXRhOiB1bmRlZmluZWQsXG4gIH07XG5cbiAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gZmllbGRzKSB7XG4gICAgY29uc3QgeyB0eXBlLCB0YXJnZXRDbGFzcywgLi4uZmllbGRPcHRpb25zIH0gPSBmaWVsZHNbZmllbGROYW1lXTtcbiAgICBtb25nb09iamVjdFtcbiAgICAgIGZpZWxkTmFtZVxuICAgIF0gPSBNb25nb1NjaGVtYUNvbGxlY3Rpb24ucGFyc2VGaWVsZFR5cGVUb01vbmdvRmllbGRUeXBlKHtcbiAgICAgIHR5cGUsXG4gICAgICB0YXJnZXRDbGFzcyxcbiAgICB9KTtcbiAgICBpZiAoZmllbGRPcHRpb25zICYmIE9iamVjdC5rZXlzKGZpZWxkT3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhID0gbW9uZ29PYmplY3QuX21ldGFkYXRhIHx8IHt9O1xuICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhLmZpZWxkc19vcHRpb25zID1cbiAgICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhLmZpZWxkc19vcHRpb25zIHx8IHt9O1xuICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhLmZpZWxkc19vcHRpb25zW2ZpZWxkTmFtZV0gPSBmaWVsZE9wdGlvbnM7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiBjbGFzc0xldmVsUGVybWlzc2lvbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgbW9uZ29PYmplY3QuX21ldGFkYXRhID0gbW9uZ29PYmplY3QuX21ldGFkYXRhIHx8IHt9O1xuICAgIGlmICghY2xhc3NMZXZlbFBlcm1pc3Npb25zKSB7XG4gICAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnMgPSBjbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIGluZGV4ZXMgJiZcbiAgICB0eXBlb2YgaW5kZXhlcyA9PT0gJ29iamVjdCcgJiZcbiAgICBPYmplY3Qua2V5cyhpbmRleGVzKS5sZW5ndGggPiAwXG4gICkge1xuICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSA9IG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSB8fCB7fTtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuaW5kZXhlcyA9IGluZGV4ZXM7XG4gIH1cblxuICBpZiAoIW1vbmdvT2JqZWN0Ll9tZXRhZGF0YSkge1xuICAgIC8vIGNsZWFudXAgdGhlIHVudXNlZCBfbWV0YWRhdGFcbiAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhO1xuICB9XG5cbiAgcmV0dXJuIG1vbmdvT2JqZWN0O1xufTtcblxuZXhwb3J0IGNsYXNzIE1vbmdvU3RvcmFnZUFkYXB0ZXIgaW1wbGVtZW50cyBTdG9yYWdlQWRhcHRlciB7XG4gIC8vIFByaXZhdGVcbiAgX3VyaTogc3RyaW5nO1xuICBfY29sbGVjdGlvblByZWZpeDogc3RyaW5nO1xuICBfbW9uZ29PcHRpb25zOiBPYmplY3Q7XG4gIC8vIFB1YmxpY1xuICBjb25uZWN0aW9uUHJvbWlzZTogP1Byb21pc2U8YW55PjtcbiAgZGF0YWJhc2U6IGFueTtcbiAgY2xpZW50OiBNb25nb0NsaWVudDtcbiAgX21heFRpbWVNUzogP251bWJlcjtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgdXJpID0gZGVmYXVsdHMuRGVmYXVsdE1vbmdvVVJJLFxuICAgIGNvbGxlY3Rpb25QcmVmaXggPSAnJyxcbiAgICBtb25nb09wdGlvbnMgPSB7fSxcbiAgfTogYW55KSB7XG4gICAgdGhpcy5fdXJpID0gdXJpO1xuICAgIHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggPSBjb2xsZWN0aW9uUHJlZml4O1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucyA9IG1vbmdvT3B0aW9ucztcbiAgICB0aGlzLl9tb25nb09wdGlvbnMudXNlTmV3VXJsUGFyc2VyID0gdHJ1ZTtcbiAgICB0aGlzLl9tb25nb09wdGlvbnMudXNlVW5pZmllZFRvcG9sb2d5ID0gdHJ1ZTtcblxuICAgIC8vIE1heFRpbWVNUyBpcyBub3QgYSBnbG9iYWwgTW9uZ29EQiBjbGllbnQgb3B0aW9uLCBpdCBpcyBhcHBsaWVkIHBlciBvcGVyYXRpb24uXG4gICAgdGhpcy5fbWF4VGltZU1TID0gbW9uZ29PcHRpb25zLm1heFRpbWVNUztcbiAgICB0aGlzLmNhblNvcnRPbkpvaW5UYWJsZXMgPSB0cnVlO1xuICAgIGRlbGV0ZSBtb25nb09wdGlvbnMubWF4VGltZU1TO1xuICB9XG5cbiAgY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5jb25uZWN0aW9uUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgfVxuXG4gICAgLy8gcGFyc2luZyBhbmQgcmUtZm9ybWF0dGluZyBjYXVzZXMgdGhlIGF1dGggdmFsdWUgKGlmIHRoZXJlKSB0byBnZXQgVVJJXG4gICAgLy8gZW5jb2RlZFxuICAgIGNvbnN0IGVuY29kZWRVcmkgPSBmb3JtYXRVcmwocGFyc2VVcmwodGhpcy5fdXJpKSk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlID0gTW9uZ29DbGllbnQuY29ubmVjdChlbmNvZGVkVXJpLCB0aGlzLl9tb25nb09wdGlvbnMpXG4gICAgICAudGhlbihjbGllbnQgPT4ge1xuICAgICAgICAvLyBTdGFydGluZyBtb25nb0RCIDMuMCwgdGhlIE1vbmdvQ2xpZW50LmNvbm5lY3QgZG9uJ3QgcmV0dXJuIGEgREIgYW55bW9yZSBidXQgYSBjbGllbnRcbiAgICAgICAgLy8gRm9ydHVuYXRlbHksIHdlIGNhbiBnZXQgYmFjayB0aGUgb3B0aW9ucyBhbmQgdXNlIHRoZW0gdG8gc2VsZWN0IHRoZSBwcm9wZXIgREIuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb25nb2RiL25vZGUtbW9uZ29kYi1uYXRpdmUvYmxvYi8yYzM1ZDc2ZjA4NTc0MjI1YjhkYjAyZDdiZWY2ODcxMjNlNmJiMDE4L2xpYi9tb25nb19jbGllbnQuanMjTDg4NVxuICAgICAgICBjb25zdCBvcHRpb25zID0gY2xpZW50LnMub3B0aW9ucztcbiAgICAgICAgY29uc3QgZGF0YWJhc2UgPSBjbGllbnQuZGIob3B0aW9ucy5kYk5hbWUpO1xuICAgICAgICBpZiAoIWRhdGFiYXNlKSB7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRhdGFiYXNlLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGFiYXNlLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgICAgICB0aGlzLmRhdGFiYXNlID0gZGF0YWJhc2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gIH1cblxuICBoYW5kbGVFcnJvcjxUPihlcnJvcjogPyhFcnJvciB8IFBhcnNlLkVycm9yKSk6IFByb21pc2U8VD4ge1xuICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSAxMykge1xuICAgICAgLy8gVW5hdXRob3JpemVkIGVycm9yXG4gICAgICBkZWxldGUgdGhpcy5jbGllbnQ7XG4gICAgICBkZWxldGUgdGhpcy5kYXRhYmFzZTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgbG9nZ2VyLmVycm9yKCdSZWNlaXZlZCB1bmF1dGhvcml6ZWQgZXJyb3InLCB7IGVycm9yOiBlcnJvciB9KTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICBfYWRhcHRpdmVDb2xsZWN0aW9uKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3QoKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5jb2xsZWN0aW9uKHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggKyBuYW1lKSlcbiAgICAgIC50aGVuKHJhd0NvbGxlY3Rpb24gPT4gbmV3IE1vbmdvQ29sbGVjdGlvbihyYXdDb2xsZWN0aW9uKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIF9zY2hlbWFDb2xsZWN0aW9uKCk6IFByb21pc2U8TW9uZ29TY2hlbWFDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSkpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IG5ldyBNb25nb1NjaGVtYUNvbGxlY3Rpb24oY29sbGVjdGlvbikpO1xuICB9XG5cbiAgY2xhc3NFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFiYXNlXG4gICAgICAgICAgLmxpc3RDb2xsZWN0aW9ucyh7IG5hbWU6IHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggKyBuYW1lIH0pXG4gICAgICAgICAgLnRvQXJyYXkoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihjb2xsZWN0aW9ucyA9PiB7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9ucy5sZW5ndGggPiAwO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHNldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWU6IHN0cmluZywgQ0xQczogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHtcbiAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnMnOiBDTFBzIH0sXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzdWJtaXR0ZWRJbmRleGVzOiBhbnksXG4gICAgZXhpc3RpbmdJbmRleGVzOiBhbnkgPSB7fSxcbiAgICBmaWVsZHM6IGFueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoc3VibWl0dGVkSW5kZXhlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhleGlzdGluZ0luZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdJbmRleGVzID0geyBfaWRfOiB7IF9pZDogMSB9IH07XG4gICAgfVxuICAgIGNvbnN0IGRlbGV0ZVByb21pc2VzID0gW107XG4gICAgY29uc3QgaW5zZXJ0ZWRJbmRleGVzID0gW107XG4gICAgT2JqZWN0LmtleXMoc3VibWl0dGVkSW5kZXhlcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gc3VibWl0dGVkSW5kZXhlc1tuYW1lXTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgIGBJbmRleCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5kcm9wSW5kZXgoY2xhc3NOYW1lLCBuYW1lKTtcbiAgICAgICAgZGVsZXRlUHJvbWlzZXMucHVzaChwcm9taXNlKTtcbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nSW5kZXhlc1tuYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5rZXlzKGZpZWxkKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgICAgZmllbGRzLFxuICAgICAgICAgICAgICBrZXkuaW5kZXhPZignX3BfJykgPT09IDAgPyBrZXkucmVwbGFjZSgnX3BfJywgJycpIDoga2V5XG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgICAgIGBGaWVsZCAke2tleX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBhZGQgaW5kZXguYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBleGlzdGluZ0luZGV4ZXNbbmFtZV0gPSBmaWVsZDtcbiAgICAgICAgaW5zZXJ0ZWRJbmRleGVzLnB1c2goe1xuICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbGV0IGluc2VydFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBpZiAoaW5zZXJ0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGluc2VydFByb21pc2UgPSB0aGlzLmNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lLCBpbnNlcnRlZEluZGV4ZXMpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVsZXRlUHJvbWlzZXMpXG4gICAgICAudGhlbigoKSA9PiBpbnNlcnRQcm9taXNlKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHtcbiAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuaW5kZXhlcyc6IGV4aXN0aW5nSW5kZXhlcyB9LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmdldEluZGV4ZXMoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oaW5kZXhlcyA9PiB7XG4gICAgICAgIGluZGV4ZXMgPSBpbmRleGVzLnJlZHVjZSgob2JqLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGlmIChpbmRleC5rZXkuX2Z0cykge1xuICAgICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzO1xuICAgICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzeDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gaW5kZXgud2VpZ2h0cykge1xuICAgICAgICAgICAgICBpbmRleC5rZXlbZmllbGRdID0gJ3RleHQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBvYmpbaW5kZXgubmFtZV0gPSBpbmRleC5rZXk7XG4gICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSwge30pO1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICAgJHNldDogeyAnX21ldGFkYXRhLmluZGV4ZXMnOiBpbmRleGVzIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIElnbm9yZSBpZiBjb2xsZWN0aW9uIG5vdCBmb3VuZFxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAoXG4gICAgICBzY2hlbWEuZmllbGRzLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgIHNjaGVtYS5pbmRleGVzXG4gICAgKTtcbiAgICBtb25nb09iamVjdC5faWQgPSBjbGFzc05hbWU7XG4gICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBzY2hlbWEuaW5kZXhlcyxcbiAgICAgIHt9LFxuICAgICAgc2NoZW1hLmZpZWxkc1xuICAgIClcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5pbnNlcnRTY2hlbWEobW9uZ29PYmplY3QpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgYWRkRmllbGRJZk5vdEV4aXN0cyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICB0eXBlOiBhbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmNyZWF0ZUluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWUsIGZpZWxkTmFtZSwgdHlwZSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBEcm9wcyBhIGNvbGxlY3Rpb24uIFJlc29sdmVzIHdpdGggdHJ1ZSBpZiBpdCB3YXMgYSBQYXJzZSBTY2hlbWEgKGVnLiBfVXNlciwgQ3VzdG9tLCBldGMuKVxuICAvLyBhbmQgcmVzb2x2ZXMgd2l0aCBmYWxzZSBpZiBpdCB3YXNuJ3QgKGVnLiBhIGpvaW4gdGFibGUpLiBSZWplY3RzIGlmIGRlbGV0aW9uIHdhcyBpbXBvc3NpYmxlLlxuICBkZWxldGVDbGFzcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uZHJvcCgpKVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIC8vICducyBub3QgZm91bmQnIG1lYW5zIGNvbGxlY3Rpb24gd2FzIGFscmVhZHkgZ29uZS4gSWdub3JlIGRlbGV0aW9uIGF0dGVtcHQuXG4gICAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgPT0gJ25zIG5vdCBmb3VuZCcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pXG4gICAgICAgIC8vIFdlJ3ZlIGRyb3BwZWQgdGhlIGNvbGxlY3Rpb24sIG5vdyByZW1vdmUgdGhlIF9TQ0hFTUEgZG9jdW1lbnRcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgICAgc2NoZW1hQ29sbGVjdGlvbi5maW5kQW5kRGVsZXRlU2NoZW1hKGNsYXNzTmFtZSlcbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICApO1xuICB9XG5cbiAgZGVsZXRlQWxsQ2xhc3NlcyhmYXN0OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnModGhpcykudGhlbihjb2xsZWN0aW9ucyA9PlxuICAgICAgUHJvbWlzZS5hbGwoXG4gICAgICAgIGNvbGxlY3Rpb25zLm1hcChjb2xsZWN0aW9uID0+XG4gICAgICAgICAgZmFzdCA/IGNvbGxlY3Rpb24uZGVsZXRlTWFueSh7fSkgOiBjb2xsZWN0aW9uLmRyb3AoKVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlbW92ZSB0aGUgY29sdW1uIGFuZCBhbGwgdGhlIGRhdGEuIEZvciBSZWxhdGlvbnMsIHRoZSBfSm9pbiBjb2xsZWN0aW9uIGlzIGhhbmRsZWRcbiAgLy8gc3BlY2lhbGx5LCB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGRlbGV0ZSBfSm9pbiBjb2x1bW5zLiBJdCBzaG91bGQsIGhvd2V2ZXIsIGluZGljYXRlXG4gIC8vIHRoYXQgdGhlIHJlbGF0aW9uIGZpZWxkcyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLiBJbiBtb25nbywgdGhpcyBtZWFucyByZW1vdmluZyBpdCBmcm9tXG4gIC8vIHRoZSBfU0NIRU1BIGNvbGxlY3Rpb24uICBUaGVyZSBzaG91bGQgYmUgbm8gYWN0dWFsIGRhdGEgaW4gdGhlIGNvbGxlY3Rpb24gdW5kZXIgdGhlIHNhbWUgbmFtZVxuICAvLyBhcyB0aGUgcmVsYXRpb24gY29sdW1uLCBzbyBpdCdzIGZpbmUgdG8gYXR0ZW1wdCB0byBkZWxldGUgaXQuIElmIHRoZSBmaWVsZHMgbGlzdGVkIHRvIGJlXG4gIC8vIGRlbGV0ZWQgZG8gbm90IGV4aXN0LCB0aGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gc3VjY2Vzc2Z1bGx5IGFueXdheXMuIENoZWNraW5nIGZvclxuICAvLyBhdHRlbXB0cyB0byBkZWxldGUgbm9uLWV4aXN0ZW50IGZpZWxkcyBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgUGFyc2UgU2VydmVyLlxuXG4gIC8vIFBvaW50ZXIgZmllbGQgbmFtZXMgYXJlIHBhc3NlZCBmb3IgbGVnYWN5IHJlYXNvbnM6IHRoZSBvcmlnaW5hbCBtb25nb1xuICAvLyBmb3JtYXQgc3RvcmVkIHBvaW50ZXIgZmllbGQgbmFtZXMgZGlmZmVyZW50bHkgaW4gdGhlIGRhdGFiYXNlLCBhbmQgdGhlcmVmb3JlXG4gIC8vIG5lZWRlZCB0byBrbm93IHRoZSB0eXBlIG9mIHRoZSBmaWVsZCBiZWZvcmUgaXQgY291bGQgZGVsZXRlIGl0LiBGdXR1cmUgZGF0YWJhc2VcbiAgLy8gYWRhcHRlcnMgc2hvdWxkIGlnbm9yZSB0aGUgcG9pbnRlckZpZWxkTmFtZXMgYXJndW1lbnQuIEFsbCB0aGUgZmllbGQgbmFtZXMgYXJlIGluXG4gIC8vIGZpZWxkTmFtZXMsIHRoZXkgc2hvdyB1cCBhZGRpdGlvbmFsbHkgaW4gdGhlIHBvaW50ZXJGaWVsZE5hbWVzIGRhdGFiYXNlIGZvciB1c2VcbiAgLy8gYnkgdGhlIG1vbmdvIGFkYXB0ZXIsIHdoaWNoIGRlYWxzIHdpdGggdGhlIGxlZ2FjeSBtb25nbyBmb3JtYXQuXG5cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBub3Qgb2JsaWdhdGVkIHRvIGRlbGV0ZSBmaWVsZHMgYXRvbWljYWxseS4gSXQgaXMgZ2l2ZW4gdGhlIGZpZWxkXG4gIC8vIG5hbWVzIGluIGEgbGlzdCBzbyB0aGF0IGRhdGFiYXNlcyB0aGF0IGFyZSBjYXBhYmxlIG9mIGRlbGV0aW5nIGZpZWxkcyBhdG9taWNhbGx5XG4gIC8vIG1heSBkbyBzby5cblxuICAvLyBSZXR1cm5zIGEgUHJvbWlzZS5cbiAgZGVsZXRlRmllbGRzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIGZpZWxkTmFtZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgbW9uZ29Gb3JtYXROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYF9wXyR7ZmllbGROYW1lfWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmllbGROYW1lO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IGNvbGxlY3Rpb25VcGRhdGUgPSB7ICR1bnNldDoge30gfTtcbiAgICBtb25nb0Zvcm1hdE5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb2xsZWN0aW9uVXBkYXRlWyckdW5zZXQnXVtuYW1lXSA9IG51bGw7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjb2xsZWN0aW9uRmlsdGVyID0geyAkb3I6IFtdIH07XG4gICAgbW9uZ29Gb3JtYXROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29sbGVjdGlvbkZpbHRlclsnJG9yJ10ucHVzaCh7IFtuYW1lXTogeyAkZXhpc3RzOiB0cnVlIH0gfSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBzY2hlbWFVcGRhdGUgPSB7ICR1bnNldDoge30gfTtcbiAgICBmaWVsZE5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBzY2hlbWFVcGRhdGVbJyR1bnNldCddW25hbWVdID0gbnVsbDtcbiAgICAgIHNjaGVtYVVwZGF0ZVsnJHVuc2V0J11bYF9tZXRhZGF0YS5maWVsZHNfb3B0aW9ucy4ke25hbWV9YF0gPSBudWxsO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24udXBkYXRlTWFueShjb2xsZWN0aW9uRmlsdGVyLCBjb2xsZWN0aW9uVXBkYXRlKVxuICAgICAgKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHNjaGVtYVVwZGF0ZSlcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBnZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8U3RvcmFnZUNsYXNzW10+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEoKVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gUmV0dXJuIGEgcHJvbWlzZSBmb3IgdGhlIHNjaGVtYSB3aXRoIHRoZSBnaXZlbiBuYW1lLCBpbiBQYXJzZSBmb3JtYXQuIElmXG4gIC8vIHRoaXMgYWRhcHRlciBkb2Vzbid0IGtub3cgYWJvdXQgdGhlIHNjaGVtYSwgcmV0dXJuIGEgcHJvbWlzZSB0aGF0IHJlamVjdHMgd2l0aFxuICAvLyB1bmRlZmluZWQgYXMgdGhlIHJlYXNvbi5cbiAgZ2V0Q2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFN0b3JhZ2VDbGFzcz4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYXNDb2xsZWN0aW9uID0+XG4gICAgICAgIHNjaGVtYXNDb2xsZWN0aW9uLl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BKGNsYXNzTmFtZSlcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFRPRE86IEFzIHlldCBub3QgcGFydGljdWxhcmx5IHdlbGwgc3BlY2lmaWVkLiBDcmVhdGVzIGFuIG9iamVjdC4gTWF5YmUgc2hvdWxkbid0IGV2ZW4gbmVlZCB0aGUgc2NoZW1hLFxuICAvLyBhbmQgc2hvdWxkIGluZmVyIGZyb20gdGhlIHR5cGUuIE9yIG1heWJlIGRvZXMgbmVlZCB0aGUgc2NoZW1hIGZvciB2YWxpZGF0aW9ucy4gT3IgbWF5YmUgbmVlZHNcbiAgLy8gdGhlIHNjaGVtYSBvbmx5IGZvciB0aGUgbGVnYWN5IG1vbmdvIGZvcm1hdC4gV2UnbGwgZmlndXJlIHRoYXQgb3V0IGxhdGVyLlxuICBjcmVhdGVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIG9iamVjdDogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb09iamVjdCA9IHBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZShcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIG9iamVjdCxcbiAgICAgIHNjaGVtYVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uaW5zZXJ0T25lKG1vbmdvT2JqZWN0LCB0cmFuc2FjdGlvbmFsU2Vzc2lvbilcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIC8vIER1cGxpY2F0ZSB2YWx1ZVxuICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgZXJyLnVuZGVybHlpbmdFcnJvciA9IGVycm9yO1xuICAgICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gZXJyb3IubWVzc2FnZS5tYXRjaChcbiAgICAgICAgICAgICAgL2luZGV4OltcXHNhLXpBLVowLTlfXFwtXFwuXStcXCQ/KFthLXpBLVpfLV0rKV8xL1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzICYmIEFycmF5LmlzQXJyYXkobWF0Y2hlcykpIHtcbiAgICAgICAgICAgICAgZXJyLnVzZXJJbmZvID0geyBkdXBsaWNhdGVkX2ZpZWxkOiBtYXRjaGVzWzFdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBSZW1vdmUgYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIC8vIElmIG5vIG9iamVjdHMgbWF0Y2gsIHJlamVjdCB3aXRoIE9CSkVDVF9OT1RfRk9VTkQuIElmIG9iamVjdHMgYXJlIGZvdW5kIGFuZCBkZWxldGVkLCByZXNvbHZlIHdpdGggdW5kZWZpbmVkLlxuICAvLyBJZiB0aGVyZSBpcyBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBJTlRFUk5BTF9TRVJWRVJfRVJST1IuXG4gIGRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4ge1xuICAgICAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uZGVsZXRlTWFueShtb25nb1doZXJlLCB0cmFuc2FjdGlvbmFsU2Vzc2lvbik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpXG4gICAgICAudGhlbihcbiAgICAgICAgKHsgcmVzdWx0IH0pID0+IHtcbiAgICAgICAgICBpZiAocmVzdWx0Lm4gPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAgICAgJ09iamVjdCBub3QgZm91bmQuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICAgJ0RhdGFiYXNlIGFkYXB0ZXIgZXJyb3InXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgfVxuXG4gIC8vIEFwcGx5IHRoZSB1cGRhdGUgdG8gYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIHVwZGF0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1VwZGF0ZSA9IHRyYW5zZm9ybVVwZGF0ZShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi51cGRhdGVNYW55KG1vbmdvV2hlcmUsIG1vbmdvVXBkYXRlLCB0cmFuc2FjdGlvbmFsU2Vzc2lvbilcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgZmluZHMgYW5kIHVwZGF0ZXMgYW4gb2JqZWN0IGJhc2VkIG9uIHF1ZXJ5LlxuICAvLyBSZXR1cm4gdmFsdWUgbm90IGN1cnJlbnRseSB3ZWxsIHNwZWNpZmllZC5cbiAgZmluZE9uZUFuZFVwZGF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29VcGRhdGUgPSB0cmFuc2Zvcm1VcGRhdGUoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5maW5kT25lQW5kVXBkYXRlKG1vbmdvV2hlcmUsIG1vbmdvVXBkYXRlLCB7XG4gICAgICAgICAgcmV0dXJuT3JpZ2luYWw6IGZhbHNlLFxuICAgICAgICAgIHNlc3Npb246IHRyYW5zYWN0aW9uYWxTZXNzaW9uIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCByZXN1bHQudmFsdWUsIHNjaGVtYSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMTEwMDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIEhvcGVmdWxseSB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGlzLiBJdCdzIG9ubHkgdXNlZCBmb3IgY29uZmlnIGFuZCBob29rcy5cbiAgdXBzZXJ0T25lT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1VwZGF0ZSA9IHRyYW5zZm9ybVVwZGF0ZShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi51cHNlcnRPbmUobW9uZ29XaGVyZSwgbW9uZ29VcGRhdGUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBmaW5kLiBBY2NlcHRzOiBjbGFzc05hbWUsIHF1ZXJ5IGluIFBhcnNlIGZvcm1hdCwgYW5kIHsgc2tpcCwgbGltaXQsIHNvcnQgfS5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgfTogUXVlcnlPcHRpb25zXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvU29ydCA9IF8ubWFwS2V5cyhzb3J0LCAodmFsdWUsIGZpZWxkTmFtZSkgPT5cbiAgICAgIHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKVxuICAgICk7XG4gICAgY29uc3QgbW9uZ29LZXlzID0gXy5yZWR1Y2UoXG4gICAgICBrZXlzLFxuICAgICAgKG1lbW8sIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSAnQUNMJykge1xuICAgICAgICAgIG1lbW9bJ19ycGVybSddID0gMTtcbiAgICAgICAgICBtZW1vWydfd3Blcm0nXSA9IDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWVtb1t0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBrZXksIHNjaGVtYSldID0gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sXG4gICAgICB7fVxuICAgICk7XG5cbiAgICAvLyBJZiB3ZSBhcmVuJ3QgcmVxdWVzdGluZyB0aGUgYF9pZGAgZmllbGQsIHdlIG5lZWQgdG8gZXhwbGljaXRseSBvcHQgb3V0XG4gICAgLy8gb2YgaXQuIERvaW5nIHNvIGluIHBhcnNlLXNlcnZlciBpcyB1bnVzdWFsLCBidXQgaXQgY2FuIGFsbG93IHVzIHRvXG4gICAgLy8gb3B0aW1pemUgc29tZSBxdWVyaWVzIHdpdGggY292ZXJpbmcgaW5kZXhlcy5cbiAgICBpZiAoa2V5cyAmJiAhbW9uZ29LZXlzLl9pZCkge1xuICAgICAgbW9uZ29LZXlzLl9pZCA9IDA7XG4gICAgfVxuXG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmZpbmQobW9uZ29XaGVyZSwge1xuICAgICAgICAgIHNraXAsXG4gICAgICAgICAgbGltaXQsXG4gICAgICAgICAgc29ydDogbW9uZ29Tb3J0LFxuICAgICAgICAgIGtleXM6IG1vbmdvS2V5cyxcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBoaW50LFxuICAgICAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgICAgICBleHBsYWluLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ob2JqZWN0cyA9PiB7XG4gICAgICAgIGlmIChleHBsYWluKSB7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdHMubWFwKG9iamVjdCA9PlxuICAgICAgICAgIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGVuc3VyZUluZGV4KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXSxcbiAgICBpbmRleE5hbWU6ID9zdHJpbmcsXG4gICAgY2FzZUluc2Vuc2l0aXZlOiBib29sZWFuID0gZmFsc2UsXG4gICAgb3B0aW9ucz86IE9iamVjdCA9IHt9XG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGluZGV4Q3JlYXRpb25SZXF1ZXN0ID0ge307XG4gICAgY29uc3QgbW9uZ29GaWVsZE5hbWVzID0gZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+XG4gICAgICB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSlcbiAgICApO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID1cbiAgICAgICAgb3B0aW9ucy5pbmRleFR5cGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuaW5kZXhUeXBlIDogMTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zOiBPYmplY3QgPSB7IGJhY2tncm91bmQ6IHRydWUsIHNwYXJzZTogdHJ1ZSB9O1xuICAgIGNvbnN0IGluZGV4TmFtZU9wdGlvbnM6IE9iamVjdCA9IGluZGV4TmFtZSA/IHsgbmFtZTogaW5kZXhOYW1lIH0gOiB7fTtcbiAgICBjb25zdCB0dGxPcHRpb25zOiBPYmplY3QgPVxuICAgICAgb3B0aW9ucy50dGwgIT09IHVuZGVmaW5lZCA/IHsgZXhwaXJlQWZ0ZXJTZWNvbmRzOiBvcHRpb25zLnR0bCB9IDoge307XG4gICAgY29uc3QgY2FzZUluc2Vuc2l0aXZlT3B0aW9uczogT2JqZWN0ID0gY2FzZUluc2Vuc2l0aXZlXG4gICAgICA/IHsgY29sbGF0aW9uOiBNb25nb0NvbGxlY3Rpb24uY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uKCkgfVxuICAgICAgOiB7fTtcbiAgICBjb25zdCBpbmRleE9wdGlvbnM6IE9iamVjdCA9IHtcbiAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgLi4uY2FzZUluc2Vuc2l0aXZlT3B0aW9ucyxcbiAgICAgIC4uLmluZGV4TmFtZU9wdGlvbnMsXG4gICAgICAuLi50dGxPcHRpb25zLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKFxuICAgICAgICBjb2xsZWN0aW9uID0+XG4gICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT5cbiAgICAgICAgICAgIGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChcbiAgICAgICAgICAgICAgaW5kZXhDcmVhdGlvblJlcXVlc3QsXG4gICAgICAgICAgICAgIGluZGV4T3B0aW9ucyxcbiAgICAgICAgICAgICAgZXJyb3IgPT4gKGVycm9yID8gcmVqZWN0KGVycm9yKSA6IHJlc29sdmUoKSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBDcmVhdGUgYSB1bmlxdWUgaW5kZXguIFVuaXF1ZSBpbmRleGVzIG9uIG51bGxhYmxlIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQuIFNpbmNlIHdlIGRvbid0XG4gIC8vIGN1cnJlbnRseSBrbm93IHdoaWNoIGZpZWxkcyBhcmUgbnVsbGFibGUgYW5kIHdoaWNoIGFyZW4ndCwgd2UgaWdub3JlIHRoYXQgY3JpdGVyaWEuXG4gIC8vIEFzIHN1Y2gsIHdlIHNob3VsZG4ndCBleHBvc2UgdGhpcyBmdW5jdGlvbiB0byB1c2VycyBvZiBwYXJzZSB1bnRpbCB3ZSBoYXZlIGFuIG91dC1vZi1iYW5kXG4gIC8vIFdheSBvZiBkZXRlcm1pbmluZyBpZiBhIGZpZWxkIGlzIG51bGxhYmxlLiBVbmRlZmluZWQgZG9lc24ndCBjb3VudCBhZ2FpbnN0IHVuaXF1ZW5lc3MsXG4gIC8vIHdoaWNoIGlzIHdoeSB3ZSB1c2Ugc3BhcnNlIGluZGV4ZXMuXG4gIGVuc3VyZVVuaXF1ZW5lc3MoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIGZpZWxkTmFtZXM6IHN0cmluZ1tdXG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PlxuICAgICAgdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwgZmllbGROYW1lLCBzY2hlbWEpXG4gICAgKTtcbiAgICBtb25nb0ZpZWxkTmFtZXMuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaW5kZXhDcmVhdGlvblJlcXVlc3RbZmllbGROYW1lXSA9IDE7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kKGluZGV4Q3JlYXRpb25SZXF1ZXN0KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ1RyaWVkIHRvIGVuc3VyZSBmaWVsZCB1bmlxdWVuZXNzIGZvciBhIGNsYXNzIHRoYXQgYWxyZWFkeSBoYXMgZHVwbGljYXRlcy4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBVc2VkIGluIHRlc3RzXG4gIF9yYXdGaW5kKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZmluZChxdWVyeSwge1xuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBjb3VudC5cbiAgY291bnQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgaGludDogP21peGVkXG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmNvdW50KHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSwgdHJ1ZSksIHtcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBoaW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgZGlzdGluY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgZmllbGROYW1lOiBzdHJpbmdcbiAgKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGlzUG9pbnRlckZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInO1xuICAgIGNvbnN0IHRyYW5zZm9ybUZpZWxkID0gdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwgZmllbGROYW1lLCBzY2hlbWEpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZGlzdGluY3QoXG4gICAgICAgICAgdHJhbnNmb3JtRmllbGQsXG4gICAgICAgICAgdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKVxuICAgICAgICApXG4gICAgICApXG4gICAgICAudGhlbihvYmplY3RzID0+IHtcbiAgICAgICAgb2JqZWN0cyA9IG9iamVjdHMuZmlsdGVyKG9iaiA9PiBvYmogIT0gbnVsbCk7XG4gICAgICAgIHJldHVybiBvYmplY3RzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgIGlmIChpc1BvaW50ZXJGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVBvaW50ZXJTdHJpbmcoc2NoZW1hLCBmaWVsZE5hbWUsIG9iamVjdCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IGFueSxcbiAgICBwaXBlbGluZTogYW55LFxuICAgIHJlYWRQcmVmZXJlbmNlOiA/c3RyaW5nLFxuICAgIGhpbnQ6ID9taXhlZCxcbiAgICBleHBsYWluPzogYm9vbGVhblxuICApIHtcbiAgICBsZXQgaXNQb2ludGVyRmllbGQgPSBmYWxzZTtcbiAgICBwaXBlbGluZSA9IHBpcGVsaW5lLm1hcChzdGFnZSA9PiB7XG4gICAgICBpZiAoc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgIHN0YWdlLiRncm91cCA9IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgc3RhZ2UuJGdyb3VwKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHN0YWdlLiRncm91cC5faWQgJiZcbiAgICAgICAgICB0eXBlb2Ygc3RhZ2UuJGdyb3VwLl9pZCA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICBzdGFnZS4kZ3JvdXAuX2lkLmluZGV4T2YoJyRfcF8nKSA+PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIGlzUG9pbnRlckZpZWxkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRtYXRjaCkge1xuICAgICAgICBzdGFnZS4kbWF0Y2ggPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBzdGFnZS4kbWF0Y2gpO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRwcm9qZWN0KSB7XG4gICAgICAgIHN0YWdlLiRwcm9qZWN0ID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVQcm9qZWN0QXJncyhcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgc3RhZ2UuJHByb2plY3RcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kZ2VvTmVhciAmJiBzdGFnZS4kZ2VvTmVhci5xdWVyeSkge1xuICAgICAgICBzdGFnZS4kZ2VvTmVhci5xdWVyeSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgc3RhZ2UuJGdlb05lYXIucXVlcnlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzdGFnZTtcbiAgICB9KTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmFnZ3JlZ2F0ZShwaXBlbGluZSwge1xuICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgJ19pZCcpKSB7XG4gICAgICAgICAgICBpZiAoaXNQb2ludGVyRmllbGQgJiYgcmVzdWx0Ll9pZCkge1xuICAgICAgICAgICAgICByZXN1bHQuX2lkID0gcmVzdWx0Ll9pZC5zcGxpdCgnJCcpWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICByZXN1bHQuX2lkID09IG51bGwgfHxcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgKFsnb2JqZWN0JywgJ3N0cmluZyddLmluY2x1ZGVzKHR5cGVvZiByZXN1bHQuX2lkKSAmJlxuICAgICAgICAgICAgICAgIF8uaXNFbXB0eShyZXN1bHQuX2lkKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXN1bHQuX2lkID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdC5vYmplY3RJZCA9IHJlc3VsdC5faWQ7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0Ll9pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pXG4gICAgICAudGhlbihvYmplY3RzID0+XG4gICAgICAgIG9iamVjdHMubWFwKG9iamVjdCA9PlxuICAgICAgICAgIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVjdXJzaXZlbHkgdHJhdmVyc2UgdGhlIHBpcGVsaW5lIGFuZCBjb252ZXJ0IGFueSBQb2ludGVyIG9yIERhdGUgY29sdW1ucy5cbiAgLy8gSWYgd2UgZGV0ZWN0IGEgcG9pbnRlciBjb2x1bW4gd2Ugd2lsbCByZW5hbWUgdGhlIGNvbHVtbiBiZWluZyBxdWVyaWVkIGZvciB0byBtYXRjaCB0aGUgY29sdW1uXG4gIC8vIGluIHRoZSBkYXRhYmFzZS4gV2UgYWxzbyBtb2RpZnkgdGhlIHZhbHVlIHRvIHdoYXQgd2UgZXhwZWN0IHRoZSB2YWx1ZSB0byBiZSBpbiB0aGUgZGF0YWJhc2VcbiAgLy8gYXMgd2VsbC5cbiAgLy8gRm9yIGRhdGVzLCB0aGUgZHJpdmVyIGV4cGVjdHMgYSBEYXRlIG9iamVjdCwgYnV0IHdlIGhhdmUgYSBzdHJpbmcgY29taW5nIGluLiBTbyB3ZSdsbCBjb252ZXJ0XG4gIC8vIHRoZSBzdHJpbmcgdG8gYSBEYXRlIHNvIHRoZSBkcml2ZXIgY2FuIHBlcmZvcm0gdGhlIG5lY2Vzc2FyeSBjb21wYXJpc29uLlxuICAvL1xuICAvLyBUaGUgZ29hbCBvZiB0aGlzIG1ldGhvZCBpcyB0byBsb29rIGZvciB0aGUgXCJsZWF2ZXNcIiBvZiB0aGUgcGlwZWxpbmUgYW5kIGRldGVybWluZSBpZiBpdCBuZWVkc1xuICAvLyB0byBiZSBjb252ZXJ0ZWQuIFRoZSBwaXBlbGluZSBjYW4gaGF2ZSBhIGZldyBkaWZmZXJlbnQgZm9ybXMuIEZvciBtb3JlIGRldGFpbHMsIHNlZTpcbiAgLy8gICAgIGh0dHBzOi8vZG9jcy5tb25nb2RiLmNvbS9tYW51YWwvcmVmZXJlbmNlL29wZXJhdG9yL2FnZ3JlZ2F0aW9uL1xuICAvL1xuICAvLyBJZiB0aGUgcGlwZWxpbmUgaXMgYW4gYXJyYXksIGl0IG1lYW5zIHdlIGFyZSBwcm9iYWJseSBwYXJzaW5nIGFuICckYW5kJyBvciAnJG9yJyBvcGVyYXRvci4gSW5cbiAgLy8gdGhhdCBjYXNlIHdlIG5lZWQgdG8gbG9vcCB0aHJvdWdoIGFsbCBvZiBpdCdzIGNoaWxkcmVuIHRvIGZpbmQgdGhlIGNvbHVtbnMgYmVpbmcgb3BlcmF0ZWQgb24uXG4gIC8vIElmIHRoZSBwaXBlbGluZSBpcyBhbiBvYmplY3QsIHRoZW4gd2UnbGwgbG9vcCB0aHJvdWdoIHRoZSBrZXlzIGNoZWNraW5nIHRvIHNlZSBpZiB0aGUga2V5IG5hbWVcbiAgLy8gbWF0Y2hlcyBvbmUgb2YgdGhlIHNjaGVtYSBjb2x1bW5zLiBJZiBpdCBkb2VzIG1hdGNoIGEgY29sdW1uIGFuZCB0aGUgY29sdW1uIGlzIGEgUG9pbnRlciBvclxuICAvLyBhIERhdGUsIHRoZW4gd2UnbGwgY29udmVydCB0aGUgdmFsdWUgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAvL1xuICAvLyBBcyBtdWNoIGFzIEkgaGF0ZSByZWN1cnNpb24uLi50aGlzIHNlZW1lZCBsaWtlIGEgZ29vZCBmaXQgZm9yIGl0LiBXZSdyZSBlc3NlbnRpYWxseSB0cmF2ZXJzaW5nXG4gIC8vIGRvd24gYSB0cmVlIHRvIGZpbmQgYSBcImxlYWYgbm9kZVwiIGFuZCBjaGVja2luZyB0byBzZWUgaWYgaXQgbmVlZHMgdG8gYmUgY29udmVydGVkLlxuICBfcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAocGlwZWxpbmUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT4gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgdmFsdWUpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHBpcGVsaW5lW2ZpZWxkXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIFBhc3Mgb2JqZWN0cyBkb3duIHRvIE1vbmdvREIuLi50aGlzIGlzIG1vcmUgdGhhbiBsaWtlbHkgYW4gJGV4aXN0cyBvcGVyYXRvci5cbiAgICAgICAgICAgIHJldHVyblZhbHVlW2BfcF8ke2ZpZWxkfWBdID0gcGlwZWxpbmVbZmllbGRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZVtcbiAgICAgICAgICAgICAgYF9wXyR7ZmllbGR9YFxuICAgICAgICAgICAgXSA9IGAke3NjaGVtYS5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzfSQke3BpcGVsaW5lW2ZpZWxkXX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJlxuICAgICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdEYXRlJ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKFxuICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgcGlwZWxpbmVbZmllbGRdXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfaWQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfY3JlYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbJ191cGRhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcGlwZWxpbmU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSBvbmUgYWJvdmUuIFJhdGhlciB0aGFuIHRyeWluZyB0byBjb21iaW5lIHRoZXNlXG4gIC8vIHR3byBmdW5jdGlvbnMgYW5kIG1ha2luZyB0aGUgY29kZSBldmVuIGhhcmRlciB0byB1bmRlcnN0YW5kLCBJIGRlY2lkZWQgdG8gc3BsaXQgaXQgdXAuIFRoZVxuICAvLyBkaWZmZXJlbmNlIHdpdGggdGhpcyBmdW5jdGlvbiBpcyB3ZSBhcmUgbm90IHRyYW5zZm9ybWluZyB0aGUgdmFsdWVzLCBvbmx5IHRoZSBrZXlzIG9mIHRoZVxuICAvLyBwaXBlbGluZS5cbiAgX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hOiBhbnksIHBpcGVsaW5lOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IHBpcGVsaW5lW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2lkJ10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2NyZWF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgIHJldHVyblZhbHVlWydfdXBkYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSB0d28gYWJvdmUuIE1vbmdvREIgJGdyb3VwIGFnZ3JlZ2F0ZSBsb29rcyBsaWtlOlxuICAvLyAgICAgeyAkZ3JvdXA6IHsgX2lkOiA8ZXhwcmVzc2lvbj4sIDxmaWVsZDE+OiB7IDxhY2N1bXVsYXRvcjE+IDogPGV4cHJlc3Npb24xPiB9LCAuLi4gfSB9XG4gIC8vIFRoZSA8ZXhwcmVzc2lvbj4gY291bGQgYmUgYSBjb2x1bW4gbmFtZSwgcHJlZml4ZWQgd2l0aCB0aGUgJyQnIGNoYXJhY3Rlci4gV2UnbGwgbG9vayBmb3JcbiAgLy8gdGhlc2UgPGV4cHJlc3Npb24+IGFuZCBjaGVjayB0byBzZWUgaWYgaXQgaXMgYSAnUG9pbnRlcicgb3IgaWYgaXQncyBvbmUgb2YgY3JlYXRlZEF0LFxuICAvLyB1cGRhdGVkQXQgb3Igb2JqZWN0SWQgYW5kIGNoYW5nZSBpdCBhY2NvcmRpbmdseS5cbiAgX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT5cbiAgICAgICAgdGhpcy5fcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hLCB2YWx1ZSlcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGlwZWxpbmUgPT09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyhcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgcGlwZWxpbmVbZmllbGRdXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGlwZWxpbmUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IHBpcGVsaW5lLnN1YnN0cmluZygxKTtcbiAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGAkX3BfJHtmaWVsZH1gO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICByZXR1cm4gJyRfY3JlYXRlZF9hdCc7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgIHJldHVybiAnJF91cGRhdGVkX2F0JztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBpcGVsaW5lO1xuICB9XG5cbiAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIGF0dGVtcHQgdG8gY29udmVydCB0aGUgcHJvdmlkZWQgdmFsdWUgdG8gYSBEYXRlIG9iamVjdC4gU2luY2UgdGhpcyBpcyBwYXJ0XG4gIC8vIG9mIGFuIGFnZ3JlZ2F0aW9uIHBpcGVsaW5lLCB0aGUgdmFsdWUgY2FuIGVpdGhlciBiZSBhIHN0cmluZyBvciBpdCBjYW4gYmUgYW5vdGhlciBvYmplY3Qgd2l0aFxuICAvLyBhbiBvcGVyYXRvciBpbiBpdCAobGlrZSAkZ3QsICRsdCwgZXRjKS4gQmVjYXVzZSBvZiB0aGlzIEkgZmVsdCBpdCB3YXMgZWFzaWVyIHRvIG1ha2UgdGhpcyBhXG4gIC8vIHJlY3Vyc2l2ZSBtZXRob2QgdG8gdHJhdmVyc2UgZG93biB0byB0aGUgXCJsZWFmIG5vZGVcIiB3aGljaCBpcyBnb2luZyB0byBiZSB0aGUgc3RyaW5nLlxuICBfY29udmVydFRvRGF0ZSh2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgIGZvciAoY29uc3QgZmllbGQgaW4gdmFsdWUpIHtcbiAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX2NvbnZlcnRUb0RhdGUodmFsdWVbZmllbGRdKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2U6ID9zdHJpbmcpOiA/c3RyaW5nIHtcbiAgICBpZiAocmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2UudG9VcHBlckNhc2UoKTtcbiAgICB9XG4gICAgc3dpdGNoIChyZWFkUHJlZmVyZW5jZSkge1xuICAgICAgY2FzZSAnUFJJTUFSWSc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuUFJJTUFSWTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdQUklNQVJZX1BSRUZFUlJFRCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuUFJJTUFSWV9QUkVGRVJSRUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnU0VDT05EQVJZJzpcbiAgICAgICAgcmVhZFByZWZlcmVuY2UgPSBSZWFkUHJlZmVyZW5jZS5TRUNPTkRBUlk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnU0VDT05EQVJZX1BSRUZFUlJFRCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuU0VDT05EQVJZX1BSRUZFUlJFRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdORUFSRVNUJzpcbiAgICAgICAgcmVhZFByZWZlcmVuY2UgPSBSZWFkUHJlZmVyZW5jZS5ORUFSRVNUO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgY2FzZSBudWxsOlxuICAgICAgY2FzZSAnJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICAnTm90IHN1cHBvcnRlZCByZWFkIHByZWZlcmVuY2UuJ1xuICAgICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBwZXJmb3JtSW5pdGlhbGl6YXRpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgY3JlYXRlSW5kZXgoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4KGluZGV4KSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4ZXM6IGFueSkge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uY3JlYXRlSW5kZXhlcyhpbmRleGVzKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSkge1xuICAgIGlmICh0eXBlICYmIHR5cGUudHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICBjb25zdCBpbmRleCA9IHtcbiAgICAgICAgW2ZpZWxkTmFtZV06ICcyZHNwaGVyZScsXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlSW5kZXgoY2xhc3NOYW1lLCBpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNyZWF0ZVRleHRJbmRleGVzSWZOZWVkZWQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICBzY2hlbWE6IGFueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBxdWVyeSkge1xuICAgICAgaWYgKCFxdWVyeVtmaWVsZE5hbWVdIHx8ICFxdWVyeVtmaWVsZE5hbWVdLiR0ZXh0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhpc3RpbmdJbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBleGlzdGluZ0luZGV4ZXMpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBleGlzdGluZ0luZGV4ZXNba2V5XTtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChpbmRleCwgZmllbGROYW1lKSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXhOYW1lID0gYCR7ZmllbGROYW1lfV90ZXh0YDtcbiAgICAgIGNvbnN0IHRleHRJbmRleCA9IHtcbiAgICAgICAgW2luZGV4TmFtZV06IHsgW2ZpZWxkTmFtZV06ICd0ZXh0JyB9LFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0KFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHRleHRJbmRleCxcbiAgICAgICAgZXhpc3RpbmdJbmRleGVzLFxuICAgICAgICBzY2hlbWEuZmllbGRzXG4gICAgICApLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDg1KSB7XG4gICAgICAgICAgLy8gSW5kZXggZXhpc3Qgd2l0aCBkaWZmZXJlbnQgb3B0aW9uc1xuICAgICAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNGcm9tTW9uZ28oY2xhc3NOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBnZXRJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5pbmRleGVzKCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkcm9wSW5kZXgoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmRyb3BJbmRleChpbmRleCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkcm9wQWxsSW5kZXhlcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZHJvcEluZGV4ZXMoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzKCk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QWxsQ2xhc3NlcygpXG4gICAgICAudGhlbihjbGFzc2VzID0+IHtcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBjbGFzc2VzLm1hcChzY2hlbWEgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNGcm9tTW9uZ28oc2NoZW1hLmNsYXNzTmFtZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25hbFNlY3Rpb24gPSB0aGlzLmNsaWVudC5zdGFydFNlc3Npb24oKTtcbiAgICB0cmFuc2FjdGlvbmFsU2VjdGlvbi5zdGFydFRyYW5zYWN0aW9uKCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0cmFuc2FjdGlvbmFsU2VjdGlvbik7XG4gIH1cblxuICBjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2VjdGlvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmNvbW1pdFRyYW5zYWN0aW9uKCkudGhlbigoKSA9PiB7XG4gICAgICB0cmFuc2FjdGlvbmFsU2VjdGlvbi5lbmRTZXNzaW9uKCk7XG4gICAgfSk7XG4gIH1cblxuICBhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZWN0aW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlY3Rpb24uYWJvcnRUcmFuc2FjdGlvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgdHJhbnNhY3Rpb25hbFNlY3Rpb24uZW5kU2Vzc2lvbigpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1vbmdvU3RvcmFnZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoTransform.js b/lib/Adapters/Storage/Mongo/MongoTransform.js new file mode 100644 index 0000000000..d050f6841c --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoTransform.js @@ -0,0 +1,1795 @@ +"use strict"; + +var _logger = _interopRequireDefault(require("../../../logger")); + +var _lodash = _interopRequireDefault(require("lodash")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var mongodb = require('mongodb'); + +var Parse = require('parse/node').Parse; + +const transformKey = (className, fieldName, schema) => { + // Check if the schema is known since it's a built-in field. + switch (fieldName) { + case 'objectId': + return '_id'; + + case 'createdAt': + return '_created_at'; + + case 'updatedAt': + return '_updated_at'; + + case 'sessionToken': + return '_session_token'; + + case 'lastUsed': + return '_last_used'; + + case 'timesUsed': + return 'times_used'; + } + + if (schema.fields[fieldName] && schema.fields[fieldName].__type == 'Pointer') { + fieldName = '_p_' + fieldName; + } else if (schema.fields[fieldName] && schema.fields[fieldName].type == 'Pointer') { + fieldName = '_p_' + fieldName; + } + + return fieldName; +}; + +const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSchema) => { + // Check if the schema is known since it's a built-in field. + var key = restKey; + var timeField = false; + + switch (key) { + case 'objectId': + case '_id': + if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { + return { + key: key, + value: parseInt(restValue) + }; + } + + key = '_id'; + break; + + case 'createdAt': + case '_created_at': + key = '_created_at'; + timeField = true; + break; + + case 'updatedAt': + case '_updated_at': + key = '_updated_at'; + timeField = true; + break; + + case 'sessionToken': + case '_session_token': + key = '_session_token'; + break; + + case 'expiresAt': + case '_expiresAt': + key = 'expiresAt'; + timeField = true; + break; + + case '_email_verify_token_expires_at': + key = '_email_verify_token_expires_at'; + timeField = true; + break; + + case '_account_lockout_expires_at': + key = '_account_lockout_expires_at'; + timeField = true; + break; + + case '_failed_login_count': + key = '_failed_login_count'; + break; + + case '_perishable_token_expires_at': + key = '_perishable_token_expires_at'; + timeField = true; + break; + + case '_password_changed_at': + key = '_password_changed_at'; + timeField = true; + break; + + case '_rperm': + case '_wperm': + return { + key: key, + value: restValue + }; + + case 'lastUsed': + case '_last_used': + key = '_last_used'; + timeField = true; + break; + + case 'timesUsed': + case 'times_used': + key = 'times_used'; + timeField = true; + break; + } + + if (parseFormatSchema.fields[key] && parseFormatSchema.fields[key].type === 'Pointer' || !parseFormatSchema.fields[key] && restValue && restValue.__type == 'Pointer') { + key = '_p_' + key; + } // Handle atomic values + + + var value = transformTopLevelAtom(restValue); + + if (value !== CannotTransform) { + if (timeField && typeof value === 'string') { + value = new Date(value); + } + + if (restKey.indexOf('.') > 0) { + return { + key, + value: restValue + }; + } + + return { + key, + value + }; + } // Handle arrays + + + if (restValue instanceof Array) { + value = restValue.map(transformInteriorValue); + return { + key, + value + }; + } // Handle update operators + + + if (typeof restValue === 'object' && '__op' in restValue) { + return { + key, + value: transformUpdateOperator(restValue, false) + }; + } // Handle normal objects by recursing + + + value = mapValues(restValue, transformInteriorValue); + return { + key, + value + }; +}; + +const isRegex = value => { + return value && value instanceof RegExp; +}; + +const isStartsWithRegex = value => { + if (!isRegex(value)) { + return false; + } + + const matches = value.toString().match(/\/\^\\Q.*\\E\//); + return !!matches; +}; + +const isAllValuesRegexOrNone = values => { + if (!values || !Array.isArray(values) || values.length === 0) { + return true; + } + + const firstValuesIsRegex = isStartsWithRegex(values[0]); + + if (values.length === 1) { + return firstValuesIsRegex; + } + + for (let i = 1, length = values.length; i < length; ++i) { + if (firstValuesIsRegex !== isStartsWithRegex(values[i])) { + return false; + } + } + + return true; +}; + +const isAnyValueRegex = values => { + return values.some(function (value) { + return isRegex(value); + }); +}; + +const transformInteriorValue = restValue => { + if (restValue !== null && typeof restValue === 'object' && Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { + throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } // Handle atomic values + + + var value = transformInteriorAtom(restValue); + + if (value !== CannotTransform) { + return value; + } // Handle arrays + + + if (restValue instanceof Array) { + return restValue.map(transformInteriorValue); + } // Handle update operators + + + if (typeof restValue === 'object' && '__op' in restValue) { + return transformUpdateOperator(restValue, true); + } // Handle normal objects by recursing + + + return mapValues(restValue, transformInteriorValue); +}; + +const valueAsDate = value => { + if (typeof value === 'string') { + return new Date(value); + } else if (value instanceof Date) { + return value; + } + + return false; +}; + +function transformQueryKeyValue(className, key, value, schema, count = false) { + switch (key) { + case 'createdAt': + if (valueAsDate(value)) { + return { + key: '_created_at', + value: valueAsDate(value) + }; + } + + key = '_created_at'; + break; + + case 'updatedAt': + if (valueAsDate(value)) { + return { + key: '_updated_at', + value: valueAsDate(value) + }; + } + + key = '_updated_at'; + break; + + case 'expiresAt': + if (valueAsDate(value)) { + return { + key: 'expiresAt', + value: valueAsDate(value) + }; + } + + break; + + case '_email_verify_token_expires_at': + if (valueAsDate(value)) { + return { + key: '_email_verify_token_expires_at', + value: valueAsDate(value) + }; + } + + break; + + case 'objectId': + { + if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { + value = parseInt(value); + } + + return { + key: '_id', + value + }; + } + + case '_account_lockout_expires_at': + if (valueAsDate(value)) { + return { + key: '_account_lockout_expires_at', + value: valueAsDate(value) + }; + } + + break; + + case '_failed_login_count': + return { + key, + value + }; + + case 'sessionToken': + return { + key: '_session_token', + value + }; + + case '_perishable_token_expires_at': + if (valueAsDate(value)) { + return { + key: '_perishable_token_expires_at', + value: valueAsDate(value) + }; + } + + break; + + case '_password_changed_at': + if (valueAsDate(value)) { + return { + key: '_password_changed_at', + value: valueAsDate(value) + }; + } + + break; + + case '_rperm': + case '_wperm': + case '_perishable_token': + case '_email_verify_token': + return { + key, + value + }; + + case '$or': + case '$and': + case '$nor': + return { + key: key, + value: value.map(subQuery => transformWhere(className, subQuery, schema, count)) + }; + + case 'lastUsed': + if (valueAsDate(value)) { + return { + key: '_last_used', + value: valueAsDate(value) + }; + } + + key = '_last_used'; + break; + + case 'timesUsed': + return { + key: 'times_used', + value: value + }; + + default: + { + // Other auth data + const authDataMatch = key.match(/^authData\.([a-zA-Z0-9_]+)\.id$/); + + if (authDataMatch) { + const provider = authDataMatch[1]; // Special-case auth data. + + return { + key: `_auth_data_${provider}.id`, + value + }; + } + } + } + + const expectedTypeIsArray = schema && schema.fields[key] && schema.fields[key].type === 'Array'; + const expectedTypeIsPointer = schema && schema.fields[key] && schema.fields[key].type === 'Pointer'; + const field = schema && schema.fields[key]; + + if (expectedTypeIsPointer || !schema && value && value.__type === 'Pointer') { + key = '_p_' + key; + } // Handle query constraints + + + const transformedConstraint = transformConstraint(value, field, count); + + if (transformedConstraint !== CannotTransform) { + if (transformedConstraint.$text) { + return { + key: '$text', + value: transformedConstraint.$text + }; + } + + if (transformedConstraint.$elemMatch) { + return { + key: '$nor', + value: [{ + [key]: transformedConstraint + }] + }; + } + + return { + key, + value: transformedConstraint + }; + } + + if (expectedTypeIsArray && !(value instanceof Array)) { + return { + key, + value: { + $all: [transformInteriorAtom(value)] + } + }; + } // Handle atomic values + + + if (transformTopLevelAtom(value) !== CannotTransform) { + return { + key, + value: transformTopLevelAtom(value) + }; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `You cannot use ${value} as a query parameter.`); + } +} // Main exposed method to help run queries. +// restWhere is the "where" clause in REST API form. +// Returns the mongo form of the query. + + +function transformWhere(className, restWhere, schema, count = false) { + const mongoWhere = {}; + + for (const restKey in restWhere) { + const out = transformQueryKeyValue(className, restKey, restWhere[restKey], schema, count); + mongoWhere[out.key] = out.value; + } + + return mongoWhere; +} + +const parseObjectKeyValueToMongoObjectKeyValue = (restKey, restValue, schema) => { + // Check if the schema is known since it's a built-in field. + let transformedValue; + let coercedToDate; + + switch (restKey) { + case 'objectId': + return { + key: '_id', + value: restValue + }; + + case 'expiresAt': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: 'expiresAt', + value: coercedToDate + }; + + case '_email_verify_token_expires_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_email_verify_token_expires_at', + value: coercedToDate + }; + + case '_account_lockout_expires_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_account_lockout_expires_at', + value: coercedToDate + }; + + case '_perishable_token_expires_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_perishable_token_expires_at', + value: coercedToDate + }; + + case '_password_changed_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_password_changed_at', + value: coercedToDate + }; + + case '_failed_login_count': + case '_rperm': + case '_wperm': + case '_email_verify_token': + case '_hashed_password': + case '_perishable_token': + return { + key: restKey, + value: restValue + }; + + case 'sessionToken': + return { + key: '_session_token', + value: restValue + }; + + default: + // Auth data should have been transformed already + if (restKey.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'can only query on ' + restKey); + } // Trust that the auth data has been transformed and save it directly + + + if (restKey.match(/^_auth_data_[a-zA-Z0-9_]+$/)) { + return { + key: restKey, + value: restValue + }; + } + + } //skip straight to transformTopLevelAtom for Bytes, they don't show up in the schema for some reason + + + if (restValue && restValue.__type !== 'Bytes') { + //Note: We may not know the type of a field here, as the user could be saving (null) to a field + //That never existed before, meaning we can't infer the type. + if (schema.fields[restKey] && schema.fields[restKey].type == 'Pointer' || restValue.__type == 'Pointer') { + restKey = '_p_' + restKey; + } + } // Handle atomic values + + + var value = transformTopLevelAtom(restValue); + + if (value !== CannotTransform) { + return { + key: restKey, + value: value + }; + } // ACLs are handled before this method is called + // If an ACL key still exists here, something is wrong. + + + if (restKey === 'ACL') { + throw 'There was a problem transforming an ACL.'; + } // Handle arrays + + + if (restValue instanceof Array) { + value = restValue.map(transformInteriorValue); + return { + key: restKey, + value: value + }; + } // Handle normal objects by recursing + + + if (Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { + throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } + + value = mapValues(restValue, transformInteriorValue); + return { + key: restKey, + value + }; +}; + +const parseObjectToMongoObjectForCreate = (className, restCreate, schema) => { + restCreate = addLegacyACL(restCreate); + const mongoCreate = {}; + + for (const restKey in restCreate) { + if (restCreate[restKey] && restCreate[restKey].__type === 'Relation') { + continue; + } + + const { + key, + value + } = parseObjectKeyValueToMongoObjectKeyValue(restKey, restCreate[restKey], schema); + + if (value !== undefined) { + mongoCreate[key] = value; + } + } // Use the legacy mongo format for createdAt and updatedAt + + + if (mongoCreate.createdAt) { + mongoCreate._created_at = new Date(mongoCreate.createdAt.iso || mongoCreate.createdAt); + delete mongoCreate.createdAt; + } + + if (mongoCreate.updatedAt) { + mongoCreate._updated_at = new Date(mongoCreate.updatedAt.iso || mongoCreate.updatedAt); + delete mongoCreate.updatedAt; + } + + return mongoCreate; +}; // Main exposed method to help update old objects. + + +const transformUpdate = (className, restUpdate, parseFormatSchema) => { + const mongoUpdate = {}; + const acl = addLegacyACL(restUpdate); + + if (acl._rperm || acl._wperm || acl._acl) { + mongoUpdate.$set = {}; + + if (acl._rperm) { + mongoUpdate.$set._rperm = acl._rperm; + } + + if (acl._wperm) { + mongoUpdate.$set._wperm = acl._wperm; + } + + if (acl._acl) { + mongoUpdate.$set._acl = acl._acl; + } + } + + for (var restKey in restUpdate) { + if (restUpdate[restKey] && restUpdate[restKey].__type === 'Relation') { + continue; + } + + var out = transformKeyValueForUpdate(className, restKey, restUpdate[restKey], parseFormatSchema); // If the output value is an object with any $ keys, it's an + // operator that needs to be lifted onto the top level update + // object. + + if (typeof out.value === 'object' && out.value !== null && out.value.__op) { + mongoUpdate[out.value.__op] = mongoUpdate[out.value.__op] || {}; + mongoUpdate[out.value.__op][out.key] = out.value.arg; + } else { + mongoUpdate['$set'] = mongoUpdate['$set'] || {}; + mongoUpdate['$set'][out.key] = out.value; + } + } + + return mongoUpdate; +}; // Add the legacy _acl format. + + +const addLegacyACL = restObject => { + const restObjectCopy = _objectSpread({}, restObject); + + const _acl = {}; + + if (restObject._wperm) { + restObject._wperm.forEach(entry => { + _acl[entry] = { + w: true + }; + }); + + restObjectCopy._acl = _acl; + } + + if (restObject._rperm) { + restObject._rperm.forEach(entry => { + if (!(entry in _acl)) { + _acl[entry] = { + r: true + }; + } else { + _acl[entry].r = true; + } + }); + + restObjectCopy._acl = _acl; + } + + return restObjectCopy; +}; // A sentinel value that helper transformations return when they +// cannot perform a transformation + + +function CannotTransform() {} + +const transformInteriorAtom = atom => { + // TODO: check validity harder for the __type-defined types + if (typeof atom === 'object' && atom && !(atom instanceof Date) && atom.__type === 'Pointer') { + return { + __type: 'Pointer', + className: atom.className, + objectId: atom.objectId + }; + } else if (typeof atom === 'function' || typeof atom === 'symbol') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); + } else if (DateCoder.isValidJSON(atom)) { + return DateCoder.JSONToDatabase(atom); + } else if (BytesCoder.isValidJSON(atom)) { + return BytesCoder.JSONToDatabase(atom); + } else if (typeof atom === 'object' && atom && atom.$regex !== undefined) { + return new RegExp(atom.$regex); + } else { + return atom; + } +}; // Helper function to transform an atom from REST format to Mongo format. +// An atom is anything that can't contain other expressions. So it +// includes things where objects are used to represent other +// datatypes, like pointers and dates, but it does not include objects +// or arrays with generic stuff inside. +// Raises an error if this cannot possibly be valid REST format. +// Returns CannotTransform if it's just not an atom + + +function transformTopLevelAtom(atom, field) { + switch (typeof atom) { + case 'number': + case 'boolean': + case 'undefined': + return atom; + + case 'string': + if (field && field.type === 'Pointer') { + return `${field.targetClass}$${atom}`; + } + + return atom; + + case 'symbol': + case 'function': + throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); + + case 'object': + if (atom instanceof Date) { + // Technically dates are not rest format, but, it seems pretty + // clear what they should be transformed to, so let's just do it. + return atom; + } + + if (atom === null) { + return atom; + } // TODO: check validity harder for the __type-defined types + + + if (atom.__type == 'Pointer') { + return `${atom.className}$${atom.objectId}`; + } + + if (DateCoder.isValidJSON(atom)) { + return DateCoder.JSONToDatabase(atom); + } + + if (BytesCoder.isValidJSON(atom)) { + return BytesCoder.JSONToDatabase(atom); + } + + if (GeoPointCoder.isValidJSON(atom)) { + return GeoPointCoder.JSONToDatabase(atom); + } + + if (PolygonCoder.isValidJSON(atom)) { + return PolygonCoder.JSONToDatabase(atom); + } + + if (FileCoder.isValidJSON(atom)) { + return FileCoder.JSONToDatabase(atom); + } + + return CannotTransform; + + default: + // I don't think typeof can ever let us get here + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, `really did not expect value: ${atom}`); + } +} + +function relativeTimeToDate(text, now = new Date()) { + text = text.toLowerCase(); + let parts = text.split(' '); // Filter out whitespace + + parts = parts.filter(part => part !== ''); + const future = parts[0] === 'in'; + const past = parts[parts.length - 1] === 'ago'; + + if (!future && !past && text !== 'now') { + return { + status: 'error', + info: "Time should either start with 'in' or end with 'ago'" + }; + } + + if (future && past) { + return { + status: 'error', + info: "Time cannot have both 'in' and 'ago'" + }; + } // strip the 'ago' or 'in' + + + if (future) { + parts = parts.slice(1); + } else { + // past + parts = parts.slice(0, parts.length - 1); + } + + if (parts.length % 2 !== 0 && text !== 'now') { + return { + status: 'error', + info: 'Invalid time string. Dangling unit or number.' + }; + } + + const pairs = []; + + while (parts.length) { + pairs.push([parts.shift(), parts.shift()]); + } + + let seconds = 0; + + for (const [num, interval] of pairs) { + const val = Number(num); + + if (!Number.isInteger(val)) { + return { + status: 'error', + info: `'${num}' is not an integer.` + }; + } + + switch (interval) { + case 'yr': + case 'yrs': + case 'year': + case 'years': + seconds += val * 31536000; // 365 * 24 * 60 * 60 + + break; + + case 'wk': + case 'wks': + case 'week': + case 'weeks': + seconds += val * 604800; // 7 * 24 * 60 * 60 + + break; + + case 'd': + case 'day': + case 'days': + seconds += val * 86400; // 24 * 60 * 60 + + break; + + case 'hr': + case 'hrs': + case 'hour': + case 'hours': + seconds += val * 3600; // 60 * 60 + + break; + + case 'min': + case 'mins': + case 'minute': + case 'minutes': + seconds += val * 60; + break; + + case 'sec': + case 'secs': + case 'second': + case 'seconds': + seconds += val; + break; + + default: + return { + status: 'error', + info: `Invalid interval: '${interval}'` + }; + } + } + + const milliseconds = seconds * 1000; + + if (future) { + return { + status: 'success', + info: 'future', + result: new Date(now.valueOf() + milliseconds) + }; + } else if (past) { + return { + status: 'success', + info: 'past', + result: new Date(now.valueOf() - milliseconds) + }; + } else { + return { + status: 'success', + info: 'present', + result: new Date(now.valueOf()) + }; + } +} // Transforms a query constraint from REST API format to Mongo format. +// A constraint is something with fields like $lt. +// If it is not a valid constraint but it could be a valid something +// else, return CannotTransform. +// inArray is whether this is an array field. + + +function transformConstraint(constraint, field, count = false) { + const inArray = field && field.type && field.type === 'Array'; + + if (typeof constraint !== 'object' || !constraint) { + return CannotTransform; + } + + const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom; + + const transformer = atom => { + const result = transformFunction(atom, field); + + if (result === CannotTransform) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${JSON.stringify(atom)}`); + } + + return result; + }; // keys is the constraints in reverse alphabetical order. + // This is a hack so that: + // $regex is handled before $options + // $nearSphere is handled before $maxDistance + + + var keys = Object.keys(constraint).sort().reverse(); + var answer = {}; + + for (var key of keys) { + switch (key) { + case '$lt': + case '$lte': + case '$gt': + case '$gte': + case '$exists': + case '$ne': + case '$eq': + { + const val = constraint[key]; + + if (val && typeof val === 'object' && val.$relativeTime) { + if (field && field.type !== 'Date') { + throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with Date field'); + } + + switch (key) { + case '$exists': + case '$ne': + case '$eq': + throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'); + } + + const parserResult = relativeTimeToDate(val.$relativeTime); + + if (parserResult.status === 'success') { + answer[key] = parserResult.result; + break; + } + + _logger.default.info('Error while parsing relative date', parserResult); + + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $relativeTime (${key}) value. ${parserResult.info}`); + } + + answer[key] = transformer(val); + break; + } + + case '$in': + case '$nin': + { + const arr = constraint[key]; + + if (!(arr instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); + } + + answer[key] = _lodash.default.flatMap(arr, value => { + return (atom => { + if (Array.isArray(atom)) { + return value.map(transformer); + } else { + return transformer(atom); + } + })(value); + }); + break; + } + + case '$all': + { + const arr = constraint[key]; + + if (!(arr instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); + } + + answer[key] = arr.map(transformInteriorAtom); + const values = answer[key]; + + if (isAnyValueRegex(values) && !isAllValuesRegexOrNone(values)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + values); + } + + break; + } + + case '$regex': + var s = constraint[key]; + + if (typeof s !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad regex: ' + s); + } + + answer[key] = s; + break; + + case '$containedBy': + { + const arr = constraint[key]; + + if (!(arr instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $containedBy: should be an array`); + } + + answer.$elemMatch = { + $nin: arr.map(transformer) + }; + break; + } + + case '$options': + answer[key] = constraint[key]; + break; + + case '$text': + { + const search = constraint[key].$search; + + if (typeof search !== 'object') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $search, should be object`); + } + + if (!search.$term || typeof search.$term !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $term, should be string`); + } else { + answer[key] = { + $search: search.$term + }; + } + + if (search.$language && typeof search.$language !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $language, should be string`); + } else if (search.$language) { + answer[key].$language = search.$language; + } + + if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); + } else if (search.$caseSensitive) { + answer[key].$caseSensitive = search.$caseSensitive; + } + + if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); + } else if (search.$diacriticSensitive) { + answer[key].$diacriticSensitive = search.$diacriticSensitive; + } + + break; + } + + case '$nearSphere': + { + const point = constraint[key]; + + if (count) { + answer.$geoWithin = { + $centerSphere: [[point.longitude, point.latitude], constraint.$maxDistance] + }; + } else { + answer[key] = [point.longitude, point.latitude]; + } + + break; + } + + case '$maxDistance': + { + if (count) { + break; + } + + answer[key] = constraint[key]; + break; + } + // The SDKs don't seem to use these but they are documented in the + // REST API docs. + + case '$maxDistanceInRadians': + answer['$maxDistance'] = constraint[key]; + break; + + case '$maxDistanceInMiles': + answer['$maxDistance'] = constraint[key] / 3959; + break; + + case '$maxDistanceInKilometers': + answer['$maxDistance'] = constraint[key] / 6371; + break; + + case '$select': + case '$dontSelect': + throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, 'the ' + key + ' constraint is not supported yet'); + + case '$within': + var box = constraint[key]['$box']; + + if (!box || box.length != 2) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'malformatted $within arg'); + } + + answer[key] = { + $box: [[box[0].longitude, box[0].latitude], [box[1].longitude, box[1].latitude]] + }; + break; + + case '$geoWithin': + { + const polygon = constraint[key]['$polygon']; + const centerSphere = constraint[key]['$centerSphere']; + + if (polygon !== undefined) { + let points; + + if (typeof polygon === 'object' && polygon.__type === 'Polygon') { + if (!polygon.coordinates || polygon.coordinates.length < 3) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); + } + + points = polygon.coordinates; + } else if (polygon instanceof Array) { + if (polygon.length < 3) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); + } + + points = polygon; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); + } + + points = points.map(point => { + if (point instanceof Array && point.length === 2) { + Parse.GeoPoint._validate(point[1], point[0]); + + return point; + } + + if (!GeoPointCoder.isValidJSON(point)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value'); + } else { + Parse.GeoPoint._validate(point.latitude, point.longitude); + } + + return [point.longitude, point.latitude]; + }); + answer[key] = { + $polygon: points + }; + } else if (centerSphere !== undefined) { + if (!(centerSphere instanceof Array) || centerSphere.length < 2) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); + } // Get point, convert to geo point if necessary and validate + + + let point = centerSphere[0]; + + if (point instanceof Array && point.length === 2) { + point = new Parse.GeoPoint(point[1], point[0]); + } else if (!GeoPointCoder.isValidJSON(point)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); + } + + Parse.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate + + + const distance = centerSphere[1]; + + if (isNaN(distance) || distance < 0) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); + } + + answer[key] = { + $centerSphere: [[point.longitude, point.latitude], distance] + }; + } + + break; + } + + case '$geoIntersects': + { + const point = constraint[key]['$point']; + + if (!GeoPointCoder.isValidJSON(point)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); + } else { + Parse.GeoPoint._validate(point.latitude, point.longitude); + } + + answer[key] = { + $geometry: { + type: 'Point', + coordinates: [point.longitude, point.latitude] + } + }; + break; + } + + default: + if (key.match(/^\$+/)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad constraint: ' + key); + } + + return CannotTransform; + } + } + + return answer; +} // Transforms an update operator from REST format to mongo format. +// To be transformed, the input should have an __op field. +// If flatten is true, this will flatten operators to their static +// data format. For example, an increment of 2 would simply become a +// 2. +// The output for a non-flattened operator is a hash with __op being +// the mongo op, and arg being the argument. +// The output for a flattened operator is just a value. +// Returns undefined if this should be a no-op. + + +function transformUpdateOperator({ + __op, + amount, + objects +}, flatten) { + switch (__op) { + case 'Delete': + if (flatten) { + return undefined; + } else { + return { + __op: '$unset', + arg: '' + }; + } + + case 'Increment': + if (typeof amount !== 'number') { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'incrementing must provide a number'); + } + + if (flatten) { + return amount; + } else { + return { + __op: '$inc', + arg: amount + }; + } + + case 'Add': + case 'AddUnique': + if (!(objects instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + var toAdd = objects.map(transformInteriorAtom); + + if (flatten) { + return toAdd; + } else { + var mongoOp = { + Add: '$push', + AddUnique: '$addToSet' + }[__op]; + return { + __op: mongoOp, + arg: { + $each: toAdd + } + }; + } + + case 'Remove': + if (!(objects instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to remove must be an array'); + } + + var toRemove = objects.map(transformInteriorAtom); + + if (flatten) { + return []; + } else { + return { + __op: '$pullAll', + arg: toRemove + }; + } + + default: + throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, `The ${__op} operator is not supported yet.`); + } +} + +function mapValues(object, iterator) { + const result = {}; + Object.keys(object).forEach(key => { + result[key] = iterator(object[key]); + }); + return result; +} + +const nestedMongoObjectToNestedParseObject = mongoObject => { + switch (typeof mongoObject) { + case 'string': + case 'number': + case 'boolean': + case 'undefined': + return mongoObject; + + case 'symbol': + case 'function': + throw 'bad value in nestedMongoObjectToNestedParseObject'; + + case 'object': + if (mongoObject === null) { + return null; + } + + if (mongoObject instanceof Array) { + return mongoObject.map(nestedMongoObjectToNestedParseObject); + } + + if (mongoObject instanceof Date) { + return Parse._encode(mongoObject); + } + + if (mongoObject instanceof mongodb.Long) { + return mongoObject.toNumber(); + } + + if (mongoObject instanceof mongodb.Double) { + return mongoObject.value; + } + + if (BytesCoder.isValidDatabaseObject(mongoObject)) { + return BytesCoder.databaseToJSON(mongoObject); + } + + if (Object.prototype.hasOwnProperty.call(mongoObject, '__type') && mongoObject.__type == 'Date' && mongoObject.iso instanceof Date) { + mongoObject.iso = mongoObject.iso.toJSON(); + return mongoObject; + } + + return mapValues(mongoObject, nestedMongoObjectToNestedParseObject); + + default: + throw 'unknown js type'; + } +}; + +const transformPointerString = (schema, field, pointerString) => { + const objData = pointerString.split('$'); + + if (objData[0] !== schema.fields[field].targetClass) { + throw 'pointer to incorrect className'; + } + + return { + __type: 'Pointer', + className: objData[0], + objectId: objData[1] + }; +}; // Converts from a mongo-format object to a REST-format object. +// Does not strip out anything based on a lack of authentication. + + +const mongoObjectToParseObject = (className, mongoObject, schema) => { + switch (typeof mongoObject) { + case 'string': + case 'number': + case 'boolean': + case 'undefined': + return mongoObject; + + case 'symbol': + case 'function': + throw 'bad value in mongoObjectToParseObject'; + + case 'object': + { + if (mongoObject === null) { + return null; + } + + if (mongoObject instanceof Array) { + return mongoObject.map(nestedMongoObjectToNestedParseObject); + } + + if (mongoObject instanceof Date) { + return Parse._encode(mongoObject); + } + + if (mongoObject instanceof mongodb.Long) { + return mongoObject.toNumber(); + } + + if (mongoObject instanceof mongodb.Double) { + return mongoObject.value; + } + + if (BytesCoder.isValidDatabaseObject(mongoObject)) { + return BytesCoder.databaseToJSON(mongoObject); + } + + const restObject = {}; + + if (mongoObject._rperm || mongoObject._wperm) { + restObject._rperm = mongoObject._rperm || []; + restObject._wperm = mongoObject._wperm || []; + delete mongoObject._rperm; + delete mongoObject._wperm; + } + + for (var key in mongoObject) { + switch (key) { + case '_id': + restObject['objectId'] = '' + mongoObject[key]; + break; + + case '_hashed_password': + restObject._hashed_password = mongoObject[key]; + break; + + case '_acl': + break; + + case '_email_verify_token': + case '_perishable_token': + case '_perishable_token_expires_at': + case '_password_changed_at': + case '_tombstone': + case '_email_verify_token_expires_at': + case '_account_lockout_expires_at': + case '_failed_login_count': + case '_password_history': + // Those keys will be deleted if needed in the DB Controller + restObject[key] = mongoObject[key]; + break; + + case '_session_token': + restObject['sessionToken'] = mongoObject[key]; + break; + + case 'updatedAt': + case '_updated_at': + restObject['updatedAt'] = Parse._encode(new Date(mongoObject[key])).iso; + break; + + case 'createdAt': + case '_created_at': + restObject['createdAt'] = Parse._encode(new Date(mongoObject[key])).iso; + break; + + case 'expiresAt': + case '_expiresAt': + restObject['expiresAt'] = Parse._encode(new Date(mongoObject[key])); + break; + + case 'lastUsed': + case '_last_used': + restObject['lastUsed'] = Parse._encode(new Date(mongoObject[key])).iso; + break; + + case 'timesUsed': + case 'times_used': + restObject['timesUsed'] = mongoObject[key]; + break; + + case 'authData': + if (className === '_User') { + _logger.default.warn('ignoring authData in _User as this key is reserved to be synthesized of `_auth_data_*` keys'); + } else { + restObject['authData'] = mongoObject[key]; + } + + break; + + default: + // Check other auth data keys + var authDataMatch = key.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch && className === '_User') { + var provider = authDataMatch[1]; + restObject['authData'] = restObject['authData'] || {}; + restObject['authData'][provider] = mongoObject[key]; + break; + } + + if (key.indexOf('_p_') == 0) { + var newKey = key.substring(3); + + if (!schema.fields[newKey]) { + _logger.default.info('transform.js', 'Found a pointer column not in the schema, dropping it.', className, newKey); + + break; + } + + if (schema.fields[newKey].type !== 'Pointer') { + _logger.default.info('transform.js', 'Found a pointer in a non-pointer column, dropping it.', className, key); + + break; + } + + if (mongoObject[key] === null) { + break; + } + + restObject[newKey] = transformPointerString(schema, newKey, mongoObject[key]); + break; + } else if (key[0] == '_' && key != '__type') { + throw 'bad key in untransform: ' + key; + } else { + var value = mongoObject[key]; + + if (schema.fields[key] && schema.fields[key].type === 'File' && FileCoder.isValidDatabaseObject(value)) { + restObject[key] = FileCoder.databaseToJSON(value); + break; + } + + if (schema.fields[key] && schema.fields[key].type === 'GeoPoint' && GeoPointCoder.isValidDatabaseObject(value)) { + restObject[key] = GeoPointCoder.databaseToJSON(value); + break; + } + + if (schema.fields[key] && schema.fields[key].type === 'Polygon' && PolygonCoder.isValidDatabaseObject(value)) { + restObject[key] = PolygonCoder.databaseToJSON(value); + break; + } + + if (schema.fields[key] && schema.fields[key].type === 'Bytes' && BytesCoder.isValidDatabaseObject(value)) { + restObject[key] = BytesCoder.databaseToJSON(value); + break; + } + } + + restObject[key] = nestedMongoObjectToNestedParseObject(mongoObject[key]); + } + } + + const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); + const relationFields = {}; + relationFieldNames.forEach(relationFieldName => { + relationFields[relationFieldName] = { + __type: 'Relation', + className: schema.fields[relationFieldName].targetClass + }; + }); + return _objectSpread(_objectSpread({}, restObject), relationFields); + } + + default: + throw 'unknown js type'; + } +}; + +var DateCoder = { + JSONToDatabase(json) { + return new Date(json.iso); + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'Date'; + } + +}; +var BytesCoder = { + base64Pattern: new RegExp('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'), + + isBase64Value(object) { + if (typeof object !== 'string') { + return false; + } + + return this.base64Pattern.test(object); + }, + + databaseToJSON(object) { + let value; + + if (this.isBase64Value(object)) { + value = object; + } else { + value = object.buffer.toString('base64'); + } + + return { + __type: 'Bytes', + base64: value + }; + }, + + isValidDatabaseObject(object) { + return object instanceof mongodb.Binary || this.isBase64Value(object); + }, + + JSONToDatabase(json) { + return new mongodb.Binary(Buffer.from(json.base64, 'base64')); + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'Bytes'; + } + +}; +var GeoPointCoder = { + databaseToJSON(object) { + return { + __type: 'GeoPoint', + latitude: object[1], + longitude: object[0] + }; + }, + + isValidDatabaseObject(object) { + return object instanceof Array && object.length == 2; + }, + + JSONToDatabase(json) { + return [json.longitude, json.latitude]; + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; + } + +}; +var PolygonCoder = { + databaseToJSON(object) { + // Convert lng/lat -> lat/lng + const coords = object.coordinates[0].map(coord => { + return [coord[1], coord[0]]; + }); + return { + __type: 'Polygon', + coordinates: coords + }; + }, + + isValidDatabaseObject(object) { + const coords = object.coordinates[0]; + + if (object.type !== 'Polygon' || !(coords instanceof Array)) { + return false; + } + + for (let i = 0; i < coords.length; i++) { + const point = coords[i]; + + if (!GeoPointCoder.isValidDatabaseObject(point)) { + return false; + } + + Parse.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); + } + + return true; + }, + + JSONToDatabase(json) { + let coords = json.coordinates; // Add first point to the end to close polygon + + if (coords[0][0] !== coords[coords.length - 1][0] || coords[0][1] !== coords[coords.length - 1][1]) { + coords.push(coords[0]); + } + + const unique = coords.filter((item, index, ar) => { + let foundIndex = -1; + + for (let i = 0; i < ar.length; i += 1) { + const pt = ar[i]; + + if (pt[0] === item[0] && pt[1] === item[1]) { + foundIndex = i; + break; + } + } + + return foundIndex === index; + }); + + if (unique.length < 3) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); + } // Convert lat/long -> long/lat + + + coords = coords.map(coord => { + return [coord[1], coord[0]]; + }); + return { + type: 'Polygon', + coordinates: [coords] + }; + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'Polygon'; + } + +}; +var FileCoder = { + databaseToJSON(object) { + return { + __type: 'File', + name: object + }; + }, + + isValidDatabaseObject(object) { + return typeof object === 'string'; + }, + + JSONToDatabase(json) { + return json.name; + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'File'; + } + +}; +module.exports = { + transformKey, + parseObjectToMongoObjectForCreate, + transformUpdate, + transformWhere, + mongoObjectToParseObject, + relativeTimeToDate, + transformConstraint, + transformPointerString +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvVHJhbnNmb3JtLmpzIl0sIm5hbWVzIjpbIm1vbmdvZGIiLCJyZXF1aXJlIiwiUGFyc2UiLCJ0cmFuc2Zvcm1LZXkiLCJjbGFzc05hbWUiLCJmaWVsZE5hbWUiLCJzY2hlbWEiLCJmaWVsZHMiLCJfX3R5cGUiLCJ0eXBlIiwidHJhbnNmb3JtS2V5VmFsdWVGb3JVcGRhdGUiLCJyZXN0S2V5IiwicmVzdFZhbHVlIiwicGFyc2VGb3JtYXRTY2hlbWEiLCJrZXkiLCJ0aW1lRmllbGQiLCJpbmNsdWRlcyIsInZhbHVlIiwicGFyc2VJbnQiLCJ0cmFuc2Zvcm1Ub3BMZXZlbEF0b20iLCJDYW5ub3RUcmFuc2Zvcm0iLCJEYXRlIiwiaW5kZXhPZiIsIkFycmF5IiwibWFwIiwidHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSIsInRyYW5zZm9ybVVwZGF0ZU9wZXJhdG9yIiwibWFwVmFsdWVzIiwiaXNSZWdleCIsIlJlZ0V4cCIsImlzU3RhcnRzV2l0aFJlZ2V4IiwibWF0Y2hlcyIsInRvU3RyaW5nIiwibWF0Y2giLCJpc0FsbFZhbHVlc1JlZ2V4T3JOb25lIiwidmFsdWVzIiwiaXNBcnJheSIsImxlbmd0aCIsImZpcnN0VmFsdWVzSXNSZWdleCIsImkiLCJpc0FueVZhbHVlUmVnZXgiLCJzb21lIiwiT2JqZWN0Iiwia2V5cyIsIkVycm9yIiwiSU5WQUxJRF9ORVNURURfS0VZIiwidHJhbnNmb3JtSW50ZXJpb3JBdG9tIiwidmFsdWVBc0RhdGUiLCJ0cmFuc2Zvcm1RdWVyeUtleVZhbHVlIiwiY291bnQiLCJzdWJRdWVyeSIsInRyYW5zZm9ybVdoZXJlIiwiYXV0aERhdGFNYXRjaCIsInByb3ZpZGVyIiwiZXhwZWN0ZWRUeXBlSXNBcnJheSIsImV4cGVjdGVkVHlwZUlzUG9pbnRlciIsImZpZWxkIiwidHJhbnNmb3JtZWRDb25zdHJhaW50IiwidHJhbnNmb3JtQ29uc3RyYWludCIsIiR0ZXh0IiwiJGVsZW1NYXRjaCIsIiRhbGwiLCJJTlZBTElEX0pTT04iLCJyZXN0V2hlcmUiLCJtb25nb1doZXJlIiwib3V0IiwicGFyc2VPYmplY3RLZXlWYWx1ZVRvTW9uZ29PYmplY3RLZXlWYWx1ZSIsInRyYW5zZm9ybWVkVmFsdWUiLCJjb2VyY2VkVG9EYXRlIiwiSU5WQUxJRF9LRVlfTkFNRSIsInBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZSIsInJlc3RDcmVhdGUiLCJhZGRMZWdhY3lBQ0wiLCJtb25nb0NyZWF0ZSIsInVuZGVmaW5lZCIsImNyZWF0ZWRBdCIsIl9jcmVhdGVkX2F0IiwiaXNvIiwidXBkYXRlZEF0IiwiX3VwZGF0ZWRfYXQiLCJ0cmFuc2Zvcm1VcGRhdGUiLCJyZXN0VXBkYXRlIiwibW9uZ29VcGRhdGUiLCJhY2wiLCJfcnBlcm0iLCJfd3Blcm0iLCJfYWNsIiwiJHNldCIsIl9fb3AiLCJhcmciLCJyZXN0T2JqZWN0IiwicmVzdE9iamVjdENvcHkiLCJmb3JFYWNoIiwiZW50cnkiLCJ3IiwiciIsImF0b20iLCJvYmplY3RJZCIsIkRhdGVDb2RlciIsImlzVmFsaWRKU09OIiwiSlNPTlRvRGF0YWJhc2UiLCJCeXRlc0NvZGVyIiwiJHJlZ2V4IiwidGFyZ2V0Q2xhc3MiLCJHZW9Qb2ludENvZGVyIiwiUG9seWdvbkNvZGVyIiwiRmlsZUNvZGVyIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwicmVsYXRpdmVUaW1lVG9EYXRlIiwidGV4dCIsIm5vdyIsInRvTG93ZXJDYXNlIiwicGFydHMiLCJzcGxpdCIsImZpbHRlciIsInBhcnQiLCJmdXR1cmUiLCJwYXN0Iiwic3RhdHVzIiwiaW5mbyIsInNsaWNlIiwicGFpcnMiLCJwdXNoIiwic2hpZnQiLCJzZWNvbmRzIiwibnVtIiwiaW50ZXJ2YWwiLCJ2YWwiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJtaWxsaXNlY29uZHMiLCJyZXN1bHQiLCJ2YWx1ZU9mIiwiY29uc3RyYWludCIsImluQXJyYXkiLCJ0cmFuc2Zvcm1GdW5jdGlvbiIsInRyYW5zZm9ybWVyIiwiSlNPTiIsInN0cmluZ2lmeSIsInNvcnQiLCJyZXZlcnNlIiwiYW5zd2VyIiwiJHJlbGF0aXZlVGltZSIsInBhcnNlclJlc3VsdCIsImxvZyIsImFyciIsIl8iLCJmbGF0TWFwIiwicyIsIiRuaW4iLCJzZWFyY2giLCIkc2VhcmNoIiwiJHRlcm0iLCIkbGFuZ3VhZ2UiLCIkY2FzZVNlbnNpdGl2ZSIsIiRkaWFjcml0aWNTZW5zaXRpdmUiLCJwb2ludCIsIiRnZW9XaXRoaW4iLCIkY2VudGVyU3BoZXJlIiwibG9uZ2l0dWRlIiwibGF0aXR1ZGUiLCIkbWF4RGlzdGFuY2UiLCJDT01NQU5EX1VOQVZBSUxBQkxFIiwiYm94IiwiJGJveCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJwb2ludHMiLCJjb29yZGluYXRlcyIsIkdlb1BvaW50IiwiX3ZhbGlkYXRlIiwiJHBvbHlnb24iLCJkaXN0YW5jZSIsImlzTmFOIiwiJGdlb21ldHJ5IiwiYW1vdW50Iiwib2JqZWN0cyIsImZsYXR0ZW4iLCJ0b0FkZCIsIm1vbmdvT3AiLCJBZGQiLCJBZGRVbmlxdWUiLCIkZWFjaCIsInRvUmVtb3ZlIiwib2JqZWN0IiwiaXRlcmF0b3IiLCJuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QiLCJtb25nb09iamVjdCIsIl9lbmNvZGUiLCJMb25nIiwidG9OdW1iZXIiLCJEb3VibGUiLCJpc1ZhbGlkRGF0YWJhc2VPYmplY3QiLCJkYXRhYmFzZVRvSlNPTiIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInRvSlNPTiIsInRyYW5zZm9ybVBvaW50ZXJTdHJpbmciLCJwb2ludGVyU3RyaW5nIiwib2JqRGF0YSIsIm1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJ3YXJuIiwibmV3S2V5Iiwic3Vic3RyaW5nIiwicmVsYXRpb25GaWVsZE5hbWVzIiwicmVsYXRpb25GaWVsZHMiLCJyZWxhdGlvbkZpZWxkTmFtZSIsImpzb24iLCJiYXNlNjRQYXR0ZXJuIiwiaXNCYXNlNjRWYWx1ZSIsInRlc3QiLCJidWZmZXIiLCJiYXNlNjQiLCJCaW5hcnkiLCJCdWZmZXIiLCJmcm9tIiwiY29vcmRzIiwiY29vcmQiLCJwYXJzZUZsb2F0IiwidW5pcXVlIiwiaXRlbSIsImluZGV4IiwiYXIiLCJmb3VuZEluZGV4IiwicHQiLCJuYW1lIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7QUFDQTs7Ozs7Ozs7OztBQUNBLElBQUlBLE9BQU8sR0FBR0MsT0FBTyxDQUFDLFNBQUQsQ0FBckI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQzs7QUFFQSxNQUFNQyxZQUFZLEdBQUcsQ0FBQ0MsU0FBRCxFQUFZQyxTQUFaLEVBQXVCQyxNQUF2QixLQUFrQztBQUNyRDtBQUNBLFVBQVFELFNBQVI7QUFDRSxTQUFLLFVBQUw7QUFDRSxhQUFPLEtBQVA7O0FBQ0YsU0FBSyxXQUFMO0FBQ0UsYUFBTyxhQUFQOztBQUNGLFNBQUssV0FBTDtBQUNFLGFBQU8sYUFBUDs7QUFDRixTQUFLLGNBQUw7QUFDRSxhQUFPLGdCQUFQOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU8sWUFBUDs7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLFlBQVA7QUFaSjs7QUFlQSxNQUNFQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0YsU0FBZCxLQUNBQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0YsU0FBZCxFQUF5QkcsTUFBekIsSUFBbUMsU0FGckMsRUFHRTtBQUNBSCxJQUFBQSxTQUFTLEdBQUcsUUFBUUEsU0FBcEI7QUFDRCxHQUxELE1BS08sSUFDTEMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsS0FDQUMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsRUFBeUJJLElBQXpCLElBQWlDLFNBRjVCLEVBR0w7QUFDQUosSUFBQUEsU0FBUyxHQUFHLFFBQVFBLFNBQXBCO0FBQ0Q7O0FBRUQsU0FBT0EsU0FBUDtBQUNE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QUFLLElBQXZDLElBQStDQSxLQUFLLENBQUNULE1BQU4sS0FBaUIsTUFEbEU7QUFHRDs7QUFwQmEsQ0FBaEI7QUF1QkE0TixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmxPLEVBQUFBLFlBRGU7QUFFZm1FLEVBQUFBLGlDQUZlO0FBR2ZVLEVBQUFBLGVBSGU7QUFJZjdCLEVBQUFBLGNBSmU7QUFLZnNKLEVBQUFBLHdCQUxlO0FBTWY3RixFQUFBQSxrQkFOZTtBQU9mbEQsRUFBQUEsbUJBUGU7QUFRZjRJLEVBQUFBO0FBUmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbG9nIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xudmFyIG1vbmdvZGIgPSByZXF1aXJlKCdtb25nb2RiJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IHRyYW5zZm9ybUtleSA9IChjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKSA9PiB7XG4gIC8vIENoZWNrIGlmIHRoZSBzY2hlbWEgaXMga25vd24gc2luY2UgaXQncyBhIGJ1aWx0LWluIGZpZWxkLlxuICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgIGNhc2UgJ29iamVjdElkJzpcbiAgICAgIHJldHVybiAnX2lkJztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgICAgcmV0dXJuICdfY3JlYXRlZF9hdCc7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgIHJldHVybiAnX3VwZGF0ZWRfYXQnO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4gJ19zZXNzaW9uX3Rva2VuJztcbiAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICByZXR1cm4gJ19sYXN0X3VzZWQnO1xuICAgIGNhc2UgJ3RpbWVzVXNlZCc6XG4gICAgICByZXR1cm4gJ3RpbWVzX3VzZWQnO1xuICB9XG5cbiAgaWYgKFxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5fX3R5cGUgPT0gJ1BvaW50ZXInXG4gICkge1xuICAgIGZpZWxkTmFtZSA9ICdfcF8nICsgZmllbGROYW1lO1xuICB9IGVsc2UgaWYgKFxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09ICdQb2ludGVyJ1xuICApIHtcbiAgICBmaWVsZE5hbWUgPSAnX3BfJyArIGZpZWxkTmFtZTtcbiAgfVxuXG4gIHJldHVybiBmaWVsZE5hbWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1LZXlWYWx1ZUZvclVwZGF0ZSA9IChcbiAgY2xhc3NOYW1lLFxuICByZXN0S2V5LFxuICByZXN0VmFsdWUsXG4gIHBhcnNlRm9ybWF0U2NoZW1hXG4pID0+IHtcbiAgLy8gQ2hlY2sgaWYgdGhlIHNjaGVtYSBpcyBrbm93biBzaW5jZSBpdCdzIGEgYnVpbHQtaW4gZmllbGQuXG4gIHZhciBrZXkgPSByZXN0S2V5O1xuICB2YXIgdGltZUZpZWxkID0gZmFsc2U7XG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnb2JqZWN0SWQnOlxuICAgIGNhc2UgJ19pZCc6XG4gICAgICBpZiAoWydfR2xvYmFsQ29uZmlnJywgJ19HcmFwaFFMQ29uZmlnJ10uaW5jbHVkZXMoY2xhc3NOYW1lKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUludChyZXN0VmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19pZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgIGNhc2UgJ19jcmVhdGVkX2F0JzpcbiAgICAgIGtleSA9ICdfY3JlYXRlZF9hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICBjYXNlICdfdXBkYXRlZF9hdCc6XG4gICAgICBrZXkgPSAnX3VwZGF0ZWRfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgY2FzZSAnX3Nlc3Npb25fdG9rZW4nOlxuICAgICAga2V5ID0gJ19zZXNzaW9uX3Rva2VuJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgY2FzZSAnX2V4cGlyZXNBdCc6XG4gICAgICBrZXkgPSAnZXhwaXJlc0F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAga2V5ID0gJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIGtleSA9ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19mYWlsZWRfbG9naW5fY291bnQnOlxuICAgICAga2V5ID0gJ19mYWlsZWRfbG9naW5fY291bnQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICBrZXkgPSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAga2V5ID0gJ19wYXNzd29yZF9jaGFuZ2VkX2F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfcnBlcm0nOlxuICAgIGNhc2UgJ193cGVybSc6XG4gICAgICByZXR1cm4geyBrZXk6IGtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ2xhc3RVc2VkJzpcbiAgICBjYXNlICdfbGFzdF91c2VkJzpcbiAgICAgIGtleSA9ICdfbGFzdF91c2VkJztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgIGNhc2UgJ3RpbWVzX3VzZWQnOlxuICAgICAga2V5ID0gJ3RpbWVzX3VzZWQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgaWYgKFxuICAgIChwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgcGFyc2VGb3JtYXRTY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ1BvaW50ZXInKSB8fFxuICAgICghcGFyc2VGb3JtYXRTY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgIHJlc3RWYWx1ZSAmJlxuICAgICAgcmVzdFZhbHVlLl9fdHlwZSA9PSAnUG9pbnRlcicpXG4gICkge1xuICAgIGtleSA9ICdfcF8nICsga2V5O1xuICB9XG5cbiAgLy8gSGFuZGxlIGF0b21pYyB2YWx1ZXNcbiAgdmFyIHZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gIGlmICh2YWx1ZSAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgaWYgKHRpbWVGaWVsZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHJlc3RLZXkuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogcmVzdFZhbHVlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXNcbiAgaWYgKHJlc3RWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdmFsdWUgPSByZXN0VmFsdWUubWFwKHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSB1cGRhdGUgb3BlcmF0b3JzXG4gIGlmICh0eXBlb2YgcmVzdFZhbHVlID09PSAnb2JqZWN0JyAmJiAnX19vcCcgaW4gcmVzdFZhbHVlKSB7XG4gICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IocmVzdFZhbHVlLCBmYWxzZSkgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgdmFsdWUgPSBtYXBWYWx1ZXMocmVzdFZhbHVlLCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlKTtcbiAgcmV0dXJuIHsga2V5LCB2YWx1ZSB9O1xufTtcblxuY29uc3QgaXNSZWdleCA9IHZhbHVlID0+IHtcbiAgcmV0dXJuIHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwO1xufTtcblxuY29uc3QgaXNTdGFydHNXaXRoUmVnZXggPSB2YWx1ZSA9PiB7XG4gIGlmICghaXNSZWdleCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBtYXRjaGVzID0gdmFsdWUudG9TdHJpbmcoKS5tYXRjaCgvXFwvXFxeXFxcXFEuKlxcXFxFXFwvLyk7XG4gIHJldHVybiAhIW1hdGNoZXM7XG59O1xuXG5jb25zdCBpc0FsbFZhbHVlc1JlZ2V4T3JOb25lID0gdmFsdWVzID0+IHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0pO1xuICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBmaXJzdFZhbHVlc0lzUmVnZXg7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMSwgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGZpcnN0VmFsdWVzSXNSZWdleCAhPT0gaXNTdGFydHNXaXRoUmVnZXgodmFsdWVzW2ldKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgaXNBbnlWYWx1ZVJlZ2V4ID0gdmFsdWVzID0+IHtcbiAgcmV0dXJuIHZhbHVlcy5zb21lKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGlzUmVnZXgodmFsdWUpO1xuICB9KTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybUludGVyaW9yVmFsdWUgPSByZXN0VmFsdWUgPT4ge1xuICBpZiAoXG4gICAgcmVzdFZhbHVlICE9PSBudWxsICYmXG4gICAgdHlwZW9mIHJlc3RWYWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICBPYmplY3Qua2V5cyhyZXN0VmFsdWUpLnNvbWUoa2V5ID0+IGtleS5pbmNsdWRlcygnJCcpIHx8IGtleS5pbmNsdWRlcygnLicpKVxuICApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX05FU1RFRF9LRVksXG4gICAgICBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCJcbiAgICApO1xuICB9XG4gIC8vIEhhbmRsZSBhdG9taWMgdmFsdWVzXG4gIHZhciB2YWx1ZSA9IHRyYW5zZm9ybUludGVyaW9yQXRvbShyZXN0VmFsdWUpO1xuICBpZiAodmFsdWUgIT09IENhbm5vdFRyYW5zZm9ybSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXNcbiAgaWYgKHJlc3RWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgcmV0dXJuIHJlc3RWYWx1ZS5tYXAodHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG4gIH1cblxuICAvLyBIYW5kbGUgdXBkYXRlIG9wZXJhdG9yc1xuICBpZiAodHlwZW9mIHJlc3RWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ19fb3AnIGluIHJlc3RWYWx1ZSkge1xuICAgIHJldHVybiB0cmFuc2Zvcm1VcGRhdGVPcGVyYXRvcihyZXN0VmFsdWUsIHRydWUpO1xuICB9XG5cbiAgLy8gSGFuZGxlIG5vcm1hbCBvYmplY3RzIGJ5IHJlY3Vyc2luZ1xuICByZXR1cm4gbWFwVmFsdWVzKHJlc3RWYWx1ZSwgdHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG59O1xuXG5jb25zdCB2YWx1ZUFzRGF0ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbmV3IERhdGUodmFsdWUpO1xuICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1RdWVyeUtleVZhbHVlKGNsYXNzTmFtZSwga2V5LCB2YWx1ZSwgc2NoZW1hLCBjb3VudCA9IGZhbHNlKSB7XG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnY3JlYXRlZEF0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnX2NyZWF0ZWRfYXQnLCB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpIH07XG4gICAgICB9XG4gICAgICBrZXkgPSAnX2NyZWF0ZWRfYXQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnX3VwZGF0ZWRfYXQnLCB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpIH07XG4gICAgICB9XG4gICAgICBrZXkgPSAnX3VwZGF0ZWRfYXQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZXhwaXJlc0F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnZXhwaXJlc0F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6ICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdvYmplY3RJZCc6IHtcbiAgICAgIGlmIChbJ19HbG9iYWxDb25maWcnLCAnX0dyYXBoUUxDb25maWcnXS5pbmNsdWRlcyhjbGFzc05hbWUpKSB7XG4gICAgICAgIHZhbHVlID0gcGFyc2VJbnQodmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsga2V5OiAnX2lkJywgdmFsdWUgfTtcbiAgICB9XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfZmFpbGVkX2xvZ2luX2NvdW50JzpcbiAgICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgICBjYXNlICdzZXNzaW9uVG9rZW4nOlxuICAgICAgcmV0dXJuIHsga2V5OiAnX3Nlc3Npb25fdG9rZW4nLCB2YWx1ZSB9O1xuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgaWYgKHZhbHVlQXNEYXRlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleTogJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfcGFzc3dvcmRfY2hhbmdlZF9hdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ19wYXNzd29yZF9jaGFuZ2VkX2F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3JwZXJtJzpcbiAgICBjYXNlICdfd3Blcm0nOlxuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuJzpcbiAgICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgICBjYXNlICckb3InOlxuICAgIGNhc2UgJyRhbmQnOlxuICAgIGNhc2UgJyRub3InOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2V5OiBrZXksXG4gICAgICAgIHZhbHVlOiB2YWx1ZS5tYXAoc3ViUXVlcnkgPT5cbiAgICAgICAgICB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHN1YlF1ZXJ5LCBzY2hlbWEsIGNvdW50KVxuICAgICAgICApLFxuICAgICAgfTtcbiAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ19sYXN0X3VzZWQnLCB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpIH07XG4gICAgICB9XG4gICAgICBrZXkgPSAnX2xhc3RfdXNlZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgICAgcmV0dXJuIHsga2V5OiAndGltZXNfdXNlZCcsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIGRlZmF1bHQ6IHtcbiAgICAgIC8vIE90aGVyIGF1dGggZGF0YVxuICAgICAgY29uc3QgYXV0aERhdGFNYXRjaCA9IGtleS5tYXRjaCgvXmF1dGhEYXRhXFwuKFthLXpBLVowLTlfXSspXFwuaWQkLyk7XG4gICAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IGF1dGhEYXRhTWF0Y2hbMV07XG4gICAgICAgIC8vIFNwZWNpYWwtY2FzZSBhdXRoIGRhdGEuXG4gICAgICAgIHJldHVybiB7IGtleTogYF9hdXRoX2RhdGFfJHtwcm92aWRlcn0uaWRgLCB2YWx1ZSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGV4cGVjdGVkVHlwZUlzQXJyYXkgPVxuICAgIHNjaGVtYSAmJiBzY2hlbWEuZmllbGRzW2tleV0gJiYgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdBcnJheSc7XG5cbiAgY29uc3QgZXhwZWN0ZWRUeXBlSXNQb2ludGVyID1cbiAgICBzY2hlbWEgJiYgc2NoZW1hLmZpZWxkc1trZXldICYmIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnUG9pbnRlcic7XG5cbiAgY29uc3QgZmllbGQgPSBzY2hlbWEgJiYgc2NoZW1hLmZpZWxkc1trZXldO1xuICBpZiAoXG4gICAgZXhwZWN0ZWRUeXBlSXNQb2ludGVyIHx8XG4gICAgKCFzY2hlbWEgJiYgdmFsdWUgJiYgdmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpXG4gICkge1xuICAgIGtleSA9ICdfcF8nICsga2V5O1xuICB9XG5cbiAgLy8gSGFuZGxlIHF1ZXJ5IGNvbnN0cmFpbnRzXG4gIGNvbnN0IHRyYW5zZm9ybWVkQ29uc3RyYWludCA9IHRyYW5zZm9ybUNvbnN0cmFpbnQodmFsdWUsIGZpZWxkLCBjb3VudCk7XG4gIGlmICh0cmFuc2Zvcm1lZENvbnN0cmFpbnQgIT09IENhbm5vdFRyYW5zZm9ybSkge1xuICAgIGlmICh0cmFuc2Zvcm1lZENvbnN0cmFpbnQuJHRleHQpIHtcbiAgICAgIHJldHVybiB7IGtleTogJyR0ZXh0JywgdmFsdWU6IHRyYW5zZm9ybWVkQ29uc3RyYWludC4kdGV4dCB9O1xuICAgIH1cbiAgICBpZiAodHJhbnNmb3JtZWRDb25zdHJhaW50LiRlbGVtTWF0Y2gpIHtcbiAgICAgIHJldHVybiB7IGtleTogJyRub3InLCB2YWx1ZTogW3sgW2tleV06IHRyYW5zZm9ybWVkQ29uc3RyYWludCB9XSB9O1xuICAgIH1cbiAgICByZXR1cm4geyBrZXksIHZhbHVlOiB0cmFuc2Zvcm1lZENvbnN0cmFpbnQgfTtcbiAgfVxuXG4gIGlmIChleHBlY3RlZFR5cGVJc0FycmF5ICYmICEodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICByZXR1cm4geyBrZXksIHZhbHVlOiB7ICRhbGw6IFt0cmFuc2Zvcm1JbnRlcmlvckF0b20odmFsdWUpXSB9IH07XG4gIH1cblxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICBpZiAodHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHZhbHVlKSAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHZhbHVlKSB9O1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgIGBZb3UgY2Fubm90IHVzZSAke3ZhbHVlfSBhcyBhIHF1ZXJ5IHBhcmFtZXRlci5gXG4gICAgKTtcbiAgfVxufVxuXG4vLyBNYWluIGV4cG9zZWQgbWV0aG9kIHRvIGhlbHAgcnVuIHF1ZXJpZXMuXG4vLyByZXN0V2hlcmUgaXMgdGhlIFwid2hlcmVcIiBjbGF1c2UgaW4gUkVTVCBBUEkgZm9ybS5cbi8vIFJldHVybnMgdGhlIG1vbmdvIGZvcm0gb2YgdGhlIHF1ZXJ5LlxuZnVuY3Rpb24gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCByZXN0V2hlcmUsIHNjaGVtYSwgY291bnQgPSBmYWxzZSkge1xuICBjb25zdCBtb25nb1doZXJlID0ge307XG4gIGZvciAoY29uc3QgcmVzdEtleSBpbiByZXN0V2hlcmUpIHtcbiAgICBjb25zdCBvdXQgPSB0cmFuc2Zvcm1RdWVyeUtleVZhbHVlKFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgcmVzdEtleSxcbiAgICAgIHJlc3RXaGVyZVtyZXN0S2V5XSxcbiAgICAgIHNjaGVtYSxcbiAgICAgIGNvdW50XG4gICAgKTtcbiAgICBtb25nb1doZXJlW291dC5rZXldID0gb3V0LnZhbHVlO1xuICB9XG4gIHJldHVybiBtb25nb1doZXJlO1xufVxuXG5jb25zdCBwYXJzZU9iamVjdEtleVZhbHVlVG9Nb25nb09iamVjdEtleVZhbHVlID0gKFxuICByZXN0S2V5LFxuICByZXN0VmFsdWUsXG4gIHNjaGVtYVxuKSA9PiB7XG4gIC8vIENoZWNrIGlmIHRoZSBzY2hlbWEgaXMga25vd24gc2luY2UgaXQncyBhIGJ1aWx0LWluIGZpZWxkLlxuICBsZXQgdHJhbnNmb3JtZWRWYWx1ZTtcbiAgbGV0IGNvZXJjZWRUb0RhdGU7XG4gIHN3aXRjaCAocmVzdEtleSkge1xuICAgIGNhc2UgJ29iamVjdElkJzpcbiAgICAgIHJldHVybiB7IGtleTogJ19pZCcsIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICBjYXNlICdleHBpcmVzQXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gbmV3IERhdGUodHJhbnNmb3JtZWRWYWx1ZSlcbiAgICAgICAgICA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdleHBpcmVzQXQnLCB2YWx1ZTogY29lcmNlZFRvRGF0ZSB9O1xuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICB0cmFuc2Zvcm1lZFZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gICAgICBjb2VyY2VkVG9EYXRlID1cbiAgICAgICAgdHlwZW9mIHRyYW5zZm9ybWVkVmFsdWUgPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyBuZXcgRGF0ZSh0cmFuc2Zvcm1lZFZhbHVlKVxuICAgICAgICAgIDogdHJhbnNmb3JtZWRWYWx1ZTtcbiAgICAgIHJldHVybiB7IGtleTogJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpXG4gICAgICAgICAgOiB0cmFuc2Zvcm1lZFZhbHVlO1xuICAgICAgcmV0dXJuIHsga2V5OiAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JywgdmFsdWU6IGNvZXJjZWRUb0RhdGUgfTtcbiAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpXG4gICAgICAgICAgOiB0cmFuc2Zvcm1lZFZhbHVlO1xuICAgICAgcmV0dXJuIHsga2V5OiAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gbmV3IERhdGUodHJhbnNmb3JtZWRWYWx1ZSlcbiAgICAgICAgICA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgY2FzZSAnX3JwZXJtJzpcbiAgICBjYXNlICdfd3Blcm0nOlxuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW4nOlxuICAgIGNhc2UgJ19oYXNoZWRfcGFzc3dvcmQnOlxuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICAgIHJldHVybiB7IGtleTogcmVzdEtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4geyBrZXk6ICdfc2Vzc2lvbl90b2tlbicsIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gQXV0aCBkYXRhIHNob3VsZCBoYXZlIGJlZW4gdHJhbnNmb3JtZWQgYWxyZWFkeVxuICAgICAgaWYgKHJlc3RLZXkubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICdjYW4gb25seSBxdWVyeSBvbiAnICsgcmVzdEtleVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gVHJ1c3QgdGhhdCB0aGUgYXV0aCBkYXRhIGhhcyBiZWVuIHRyYW5zZm9ybWVkIGFuZCBzYXZlIGl0IGRpcmVjdGx5XG4gICAgICBpZiAocmVzdEtleS5tYXRjaCgvXl9hdXRoX2RhdGFfW2EtekEtWjAtOV9dKyQvKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICAgIH1cbiAgfVxuICAvL3NraXAgc3RyYWlnaHQgdG8gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tIGZvciBCeXRlcywgdGhleSBkb24ndCBzaG93IHVwIGluIHRoZSBzY2hlbWEgZm9yIHNvbWUgcmVhc29uXG4gIGlmIChyZXN0VmFsdWUgJiYgcmVzdFZhbHVlLl9fdHlwZSAhPT0gJ0J5dGVzJykge1xuICAgIC8vTm90ZTogV2UgbWF5IG5vdCBrbm93IHRoZSB0eXBlIG9mIGEgZmllbGQgaGVyZSwgYXMgdGhlIHVzZXIgY291bGQgYmUgc2F2aW5nIChudWxsKSB0byBhIGZpZWxkXG4gICAgLy9UaGF0IG5ldmVyIGV4aXN0ZWQgYmVmb3JlLCBtZWFuaW5nIHdlIGNhbid0IGluZmVyIHRoZSB0eXBlLlxuICAgIGlmIChcbiAgICAgIChzY2hlbWEuZmllbGRzW3Jlc3RLZXldICYmIHNjaGVtYS5maWVsZHNbcmVzdEtleV0udHlwZSA9PSAnUG9pbnRlcicpIHx8XG4gICAgICByZXN0VmFsdWUuX190eXBlID09ICdQb2ludGVyJ1xuICAgICkge1xuICAgICAgcmVzdEtleSA9ICdfcF8nICsgcmVzdEtleTtcbiAgICB9XG4gIH1cblxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICB2YXIgdmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgaWYgKHZhbHVlICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiB2YWx1ZSB9O1xuICB9XG5cbiAgLy8gQUNMcyBhcmUgaGFuZGxlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkXG4gIC8vIElmIGFuIEFDTCBrZXkgc3RpbGwgZXhpc3RzIGhlcmUsIHNvbWV0aGluZyBpcyB3cm9uZy5cbiAgaWYgKHJlc3RLZXkgPT09ICdBQ0wnKSB7XG4gICAgdGhyb3cgJ1RoZXJlIHdhcyBhIHByb2JsZW0gdHJhbnNmb3JtaW5nIGFuIEFDTC4nO1xuICB9XG5cbiAgLy8gSGFuZGxlIGFycmF5c1xuICBpZiAocmVzdFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICB2YWx1ZSA9IHJlc3RWYWx1ZS5tYXAodHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG4gICAgcmV0dXJuIHsga2V5OiByZXN0S2V5LCB2YWx1ZTogdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgaWYgKFxuICAgIE9iamVjdC5rZXlzKHJlc3RWYWx1ZSkuc29tZShrZXkgPT4ga2V5LmluY2x1ZGVzKCckJykgfHwga2V5LmluY2x1ZGVzKCcuJykpXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfTkVTVEVEX0tFWSxcbiAgICAgIFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIlxuICAgICk7XG4gIH1cbiAgdmFsdWUgPSBtYXBWYWx1ZXMocmVzdFZhbHVlLCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlKTtcbiAgcmV0dXJuIHsga2V5OiByZXN0S2V5LCB2YWx1ZSB9O1xufTtcblxuY29uc3QgcGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlID0gKGNsYXNzTmFtZSwgcmVzdENyZWF0ZSwgc2NoZW1hKSA9PiB7XG4gIHJlc3RDcmVhdGUgPSBhZGRMZWdhY3lBQ0wocmVzdENyZWF0ZSk7XG4gIGNvbnN0IG1vbmdvQ3JlYXRlID0ge307XG4gIGZvciAoY29uc3QgcmVzdEtleSBpbiByZXN0Q3JlYXRlKSB7XG4gICAgaWYgKHJlc3RDcmVhdGVbcmVzdEtleV0gJiYgcmVzdENyZWF0ZVtyZXN0S2V5XS5fX3R5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHBhcnNlT2JqZWN0S2V5VmFsdWVUb01vbmdvT2JqZWN0S2V5VmFsdWUoXG4gICAgICByZXN0S2V5LFxuICAgICAgcmVzdENyZWF0ZVtyZXN0S2V5XSxcbiAgICAgIHNjaGVtYVxuICAgICk7XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1vbmdvQ3JlYXRlW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBVc2UgdGhlIGxlZ2FjeSBtb25nbyBmb3JtYXQgZm9yIGNyZWF0ZWRBdCBhbmQgdXBkYXRlZEF0XG4gIGlmIChtb25nb0NyZWF0ZS5jcmVhdGVkQXQpIHtcbiAgICBtb25nb0NyZWF0ZS5fY3JlYXRlZF9hdCA9IG5ldyBEYXRlKFxuICAgICAgbW9uZ29DcmVhdGUuY3JlYXRlZEF0LmlzbyB8fCBtb25nb0NyZWF0ZS5jcmVhdGVkQXRcbiAgICApO1xuICAgIGRlbGV0ZSBtb25nb0NyZWF0ZS5jcmVhdGVkQXQ7XG4gIH1cbiAgaWYgKG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdCkge1xuICAgIG1vbmdvQ3JlYXRlLl91cGRhdGVkX2F0ID0gbmV3IERhdGUoXG4gICAgICBtb25nb0NyZWF0ZS51cGRhdGVkQXQuaXNvIHx8IG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdFxuICAgICk7XG4gICAgZGVsZXRlIG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdDtcbiAgfVxuXG4gIHJldHVybiBtb25nb0NyZWF0ZTtcbn07XG5cbi8vIE1haW4gZXhwb3NlZCBtZXRob2QgdG8gaGVscCB1cGRhdGUgb2xkIG9iamVjdHMuXG5jb25zdCB0cmFuc2Zvcm1VcGRhdGUgPSAoY2xhc3NOYW1lLCByZXN0VXBkYXRlLCBwYXJzZUZvcm1hdFNjaGVtYSkgPT4ge1xuICBjb25zdCBtb25nb1VwZGF0ZSA9IHt9O1xuICBjb25zdCBhY2wgPSBhZGRMZWdhY3lBQ0wocmVzdFVwZGF0ZSk7XG4gIGlmIChhY2wuX3JwZXJtIHx8IGFjbC5fd3Blcm0gfHwgYWNsLl9hY2wpIHtcbiAgICBtb25nb1VwZGF0ZS4kc2V0ID0ge307XG4gICAgaWYgKGFjbC5fcnBlcm0pIHtcbiAgICAgIG1vbmdvVXBkYXRlLiRzZXQuX3JwZXJtID0gYWNsLl9ycGVybTtcbiAgICB9XG4gICAgaWYgKGFjbC5fd3Blcm0pIHtcbiAgICAgIG1vbmdvVXBkYXRlLiRzZXQuX3dwZXJtID0gYWNsLl93cGVybTtcbiAgICB9XG4gICAgaWYgKGFjbC5fYWNsKSB7XG4gICAgICBtb25nb1VwZGF0ZS4kc2V0Ll9hY2wgPSBhY2wuX2FjbDtcbiAgICB9XG4gIH1cbiAgZm9yICh2YXIgcmVzdEtleSBpbiByZXN0VXBkYXRlKSB7XG4gICAgaWYgKHJlc3RVcGRhdGVbcmVzdEtleV0gJiYgcmVzdFVwZGF0ZVtyZXN0S2V5XS5fX3R5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgb3V0ID0gdHJhbnNmb3JtS2V5VmFsdWVGb3JVcGRhdGUoXG4gICAgICBjbGFzc05hbWUsXG4gICAgICByZXN0S2V5LFxuICAgICAgcmVzdFVwZGF0ZVtyZXN0S2V5XSxcbiAgICAgIHBhcnNlRm9ybWF0U2NoZW1hXG4gICAgKTtcblxuICAgIC8vIElmIHRoZSBvdXRwdXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW55ICQga2V5cywgaXQncyBhblxuICAgIC8vIG9wZXJhdG9yIHRoYXQgbmVlZHMgdG8gYmUgbGlmdGVkIG9udG8gdGhlIHRvcCBsZXZlbCB1cGRhdGVcbiAgICAvLyBvYmplY3QuXG4gICAgaWYgKHR5cGVvZiBvdXQudmFsdWUgPT09ICdvYmplY3QnICYmIG91dC52YWx1ZSAhPT0gbnVsbCAmJiBvdXQudmFsdWUuX19vcCkge1xuICAgICAgbW9uZ29VcGRhdGVbb3V0LnZhbHVlLl9fb3BdID0gbW9uZ29VcGRhdGVbb3V0LnZhbHVlLl9fb3BdIHx8IHt9O1xuICAgICAgbW9uZ29VcGRhdGVbb3V0LnZhbHVlLl9fb3BdW291dC5rZXldID0gb3V0LnZhbHVlLmFyZztcbiAgICB9IGVsc2Uge1xuICAgICAgbW9uZ29VcGRhdGVbJyRzZXQnXSA9IG1vbmdvVXBkYXRlWyckc2V0J10gfHwge307XG4gICAgICBtb25nb1VwZGF0ZVsnJHNldCddW291dC5rZXldID0gb3V0LnZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtb25nb1VwZGF0ZTtcbn07XG5cbi8vIEFkZCB0aGUgbGVnYWN5IF9hY2wgZm9ybWF0LlxuY29uc3QgYWRkTGVnYWN5QUNMID0gcmVzdE9iamVjdCA9PiB7XG4gIGNvbnN0IHJlc3RPYmplY3RDb3B5ID0geyAuLi5yZXN0T2JqZWN0IH07XG4gIGNvbnN0IF9hY2wgPSB7fTtcblxuICBpZiAocmVzdE9iamVjdC5fd3Blcm0pIHtcbiAgICByZXN0T2JqZWN0Ll93cGVybS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIF9hY2xbZW50cnldID0geyB3OiB0cnVlIH07XG4gICAgfSk7XG4gICAgcmVzdE9iamVjdENvcHkuX2FjbCA9IF9hY2w7XG4gIH1cblxuICBpZiAocmVzdE9iamVjdC5fcnBlcm0pIHtcbiAgICByZXN0T2JqZWN0Ll9ycGVybS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmICghKGVudHJ5IGluIF9hY2wpKSB7XG4gICAgICAgIF9hY2xbZW50cnldID0geyByOiB0cnVlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfYWNsW2VudHJ5XS5yID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXN0T2JqZWN0Q29weS5fYWNsID0gX2FjbDtcbiAgfVxuXG4gIHJldHVybiByZXN0T2JqZWN0Q29weTtcbn07XG5cbi8vIEEgc2VudGluZWwgdmFsdWUgdGhhdCBoZWxwZXIgdHJhbnNmb3JtYXRpb25zIHJldHVybiB3aGVuIHRoZXlcbi8vIGNhbm5vdCBwZXJmb3JtIGEgdHJhbnNmb3JtYXRpb25cbmZ1bmN0aW9uIENhbm5vdFRyYW5zZm9ybSgpIHt9XG5cbmNvbnN0IHRyYW5zZm9ybUludGVyaW9yQXRvbSA9IGF0b20gPT4ge1xuICAvLyBUT0RPOiBjaGVjayB2YWxpZGl0eSBoYXJkZXIgZm9yIHRoZSBfX3R5cGUtZGVmaW5lZCB0eXBlc1xuICBpZiAoXG4gICAgdHlwZW9mIGF0b20gPT09ICdvYmplY3QnICYmXG4gICAgYXRvbSAmJlxuICAgICEoYXRvbSBpbnN0YW5jZW9mIERhdGUpICYmXG4gICAgYXRvbS5fX3R5cGUgPT09ICdQb2ludGVyJ1xuICApIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICBjbGFzc05hbWU6IGF0b20uY2xhc3NOYW1lLFxuICAgICAgb2JqZWN0SWQ6IGF0b20ub2JqZWN0SWQsXG4gICAgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXRvbSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgYXRvbSA9PT0gJ3N5bWJvbCcpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgY2Fubm90IHRyYW5zZm9ybSB2YWx1ZTogJHthdG9tfWBcbiAgICApO1xuICB9IGVsc2UgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBEYXRlQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gIH0gZWxzZSBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBCeXRlc0NvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhdG9tID09PSAnb2JqZWN0JyAmJiBhdG9tICYmIGF0b20uJHJlZ2V4ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChhdG9tLiRyZWdleCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGF0b207XG4gIH1cbn07XG5cbi8vIEhlbHBlciBmdW5jdGlvbiB0byB0cmFuc2Zvcm0gYW4gYXRvbSBmcm9tIFJFU1QgZm9ybWF0IHRvIE1vbmdvIGZvcm1hdC5cbi8vIEFuIGF0b20gaXMgYW55dGhpbmcgdGhhdCBjYW4ndCBjb250YWluIG90aGVyIGV4cHJlc3Npb25zLiBTbyBpdFxuLy8gaW5jbHVkZXMgdGhpbmdzIHdoZXJlIG9iamVjdHMgYXJlIHVzZWQgdG8gcmVwcmVzZW50IG90aGVyXG4vLyBkYXRhdHlwZXMsIGxpa2UgcG9pbnRlcnMgYW5kIGRhdGVzLCBidXQgaXQgZG9lcyBub3QgaW5jbHVkZSBvYmplY3RzXG4vLyBvciBhcnJheXMgd2l0aCBnZW5lcmljIHN0dWZmIGluc2lkZS5cbi8vIFJhaXNlcyBhbiBlcnJvciBpZiB0aGlzIGNhbm5vdCBwb3NzaWJseSBiZSB2YWxpZCBSRVNUIGZvcm1hdC5cbi8vIFJldHVybnMgQ2Fubm90VHJhbnNmb3JtIGlmIGl0J3MganVzdCBub3QgYW4gYXRvbVxuZnVuY3Rpb24gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKGF0b20sIGZpZWxkKSB7XG4gIHN3aXRjaCAodHlwZW9mIGF0b20pIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gYXRvbTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7ZmllbGQudGFyZ2V0Q2xhc3N9JCR7YXRvbX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0b207XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgYGNhbm5vdCB0cmFuc2Zvcm0gdmFsdWU6ICR7YXRvbX1gXG4gICAgICApO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoYXRvbSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgLy8gVGVjaG5pY2FsbHkgZGF0ZXMgYXJlIG5vdCByZXN0IGZvcm1hdCwgYnV0LCBpdCBzZWVtcyBwcmV0dHlcbiAgICAgICAgLy8gY2xlYXIgd2hhdCB0aGV5IHNob3VsZCBiZSB0cmFuc2Zvcm1lZCB0bywgc28gbGV0J3MganVzdCBkbyBpdC5cbiAgICAgICAgcmV0dXJuIGF0b207XG4gICAgICB9XG5cbiAgICAgIGlmIChhdG9tID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBhdG9tO1xuICAgICAgfVxuXG4gICAgICAvLyBUT0RPOiBjaGVjayB2YWxpZGl0eSBoYXJkZXIgZm9yIHRoZSBfX3R5cGUtZGVmaW5lZCB0eXBlc1xuICAgICAgaWYgKGF0b20uX190eXBlID09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7YXRvbS5jbGFzc05hbWV9JCR7YXRvbS5vYmplY3RJZH1gO1xuICAgICAgfVxuICAgICAgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gRGF0ZUNvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICAgICAgfVxuICAgICAgaWYgKEJ5dGVzQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEJ5dGVzQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gICAgICB9XG4gICAgICBpZiAoR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gR2VvUG9pbnRDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChQb2x5Z29uQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIFBvbHlnb25Db2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChGaWxlQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBDYW5ub3RUcmFuc2Zvcm07XG5cbiAgICBkZWZhdWx0OlxuICAgICAgLy8gSSBkb24ndCB0aGluayB0eXBlb2YgY2FuIGV2ZXIgbGV0IHVzIGdldCBoZXJlXG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgYHJlYWxseSBkaWQgbm90IGV4cGVjdCB2YWx1ZTogJHthdG9tfWBcbiAgICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVsYXRpdmVUaW1lVG9EYXRlKHRleHQsIG5vdyA9IG5ldyBEYXRlKCkpIHtcbiAgdGV4dCA9IHRleHQudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgcGFydHMgPSB0ZXh0LnNwbGl0KCcgJyk7XG5cbiAgLy8gRmlsdGVyIG91dCB3aGl0ZXNwYWNlXG4gIHBhcnRzID0gcGFydHMuZmlsdGVyKHBhcnQgPT4gcGFydCAhPT0gJycpO1xuXG4gIGNvbnN0IGZ1dHVyZSA9IHBhcnRzWzBdID09PSAnaW4nO1xuICBjb25zdCBwYXN0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV0gPT09ICdhZ28nO1xuXG4gIGlmICghZnV0dXJlICYmICFwYXN0ICYmIHRleHQgIT09ICdub3cnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIGluZm86IFwiVGltZSBzaG91bGQgZWl0aGVyIHN0YXJ0IHdpdGggJ2luJyBvciBlbmQgd2l0aCAnYWdvJ1wiLFxuICAgIH07XG4gIH1cblxuICBpZiAoZnV0dXJlICYmIHBhc3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgaW5mbzogXCJUaW1lIGNhbm5vdCBoYXZlIGJvdGggJ2luJyBhbmQgJ2FnbydcIixcbiAgICB9O1xuICB9XG5cbiAgLy8gc3RyaXAgdGhlICdhZ28nIG9yICdpbidcbiAgaWYgKGZ1dHVyZSkge1xuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcGFzdFxuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMCwgcGFydHMubGVuZ3RoIC0gMSk7XG4gIH1cblxuICBpZiAocGFydHMubGVuZ3RoICUgMiAhPT0gMCAmJiB0ZXh0ICE9PSAnbm93Jykge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICBpbmZvOiAnSW52YWxpZCB0aW1lIHN0cmluZy4gRGFuZ2xpbmcgdW5pdCBvciBudW1iZXIuJyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFpcnMgPSBbXTtcbiAgd2hpbGUgKHBhcnRzLmxlbmd0aCkge1xuICAgIHBhaXJzLnB1c2goW3BhcnRzLnNoaWZ0KCksIHBhcnRzLnNoaWZ0KCldKTtcbiAgfVxuXG4gIGxldCBzZWNvbmRzID0gMDtcbiAgZm9yIChjb25zdCBbbnVtLCBpbnRlcnZhbF0gb2YgcGFpcnMpIHtcbiAgICBjb25zdCB2YWwgPSBOdW1iZXIobnVtKTtcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgICBpbmZvOiBgJyR7bnVtfScgaXMgbm90IGFuIGludGVnZXIuYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgY2FzZSAneXInOlxuICAgICAgY2FzZSAneXJzJzpcbiAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgY2FzZSAneWVhcnMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDMxNTM2MDAwOyAvLyAzNjUgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3drJzpcbiAgICAgIGNhc2UgJ3drcyc6XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgIGNhc2UgJ3dlZWtzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiA2MDQ4MDA7IC8vIDcgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2QnOlxuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgIGNhc2UgJ2RheXMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDg2NDAwOyAvLyAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2hyJzpcbiAgICAgIGNhc2UgJ2hycyc6XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgIGNhc2UgJ2hvdXJzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiAzNjAwOyAvLyA2MCAqIDYwXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgY2FzZSAnbWlucyc6XG4gICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgY2FzZSAnbWludXRlcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsICogNjA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzZWMnOlxuICAgICAgY2FzZSAnc2Vjcyc6XG4gICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgY2FzZSAnc2Vjb25kcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICAgICAgaW5mbzogYEludmFsaWQgaW50ZXJ2YWw6ICcke2ludGVydmFsfSdgLFxuICAgICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1pbGxpc2Vjb25kcyA9IHNlY29uZHMgKiAxMDAwO1xuICBpZiAoZnV0dXJlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxuICAgICAgaW5mbzogJ2Z1dHVyZScsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMpLFxuICAgIH07XG4gIH0gZWxzZSBpZiAocGFzdCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcbiAgICAgIGluZm86ICdwYXN0JyxcbiAgICAgIHJlc3VsdDogbmV3IERhdGUobm93LnZhbHVlT2YoKSAtIG1pbGxpc2Vjb25kcyksXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXG4gICAgICBpbmZvOiAncHJlc2VudCcsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkpLFxuICAgIH07XG4gIH1cbn1cblxuLy8gVHJhbnNmb3JtcyBhIHF1ZXJ5IGNvbnN0cmFpbnQgZnJvbSBSRVNUIEFQSSBmb3JtYXQgdG8gTW9uZ28gZm9ybWF0LlxuLy8gQSBjb25zdHJhaW50IGlzIHNvbWV0aGluZyB3aXRoIGZpZWxkcyBsaWtlICRsdC5cbi8vIElmIGl0IGlzIG5vdCBhIHZhbGlkIGNvbnN0cmFpbnQgYnV0IGl0IGNvdWxkIGJlIGEgdmFsaWQgc29tZXRoaW5nXG4vLyBlbHNlLCByZXR1cm4gQ2Fubm90VHJhbnNmb3JtLlxuLy8gaW5BcnJheSBpcyB3aGV0aGVyIHRoaXMgaXMgYW4gYXJyYXkgZmllbGQuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Db25zdHJhaW50KGNvbnN0cmFpbnQsIGZpZWxkLCBjb3VudCA9IGZhbHNlKSB7XG4gIGNvbnN0IGluQXJyYXkgPSBmaWVsZCAmJiBmaWVsZC50eXBlICYmIGZpZWxkLnR5cGUgPT09ICdBcnJheSc7XG4gIGlmICh0eXBlb2YgY29uc3RyYWludCAhPT0gJ29iamVjdCcgfHwgIWNvbnN0cmFpbnQpIHtcbiAgICByZXR1cm4gQ2Fubm90VHJhbnNmb3JtO1xuICB9XG4gIGNvbnN0IHRyYW5zZm9ybUZ1bmN0aW9uID0gaW5BcnJheVxuICAgID8gdHJhbnNmb3JtSW50ZXJpb3JBdG9tXG4gICAgOiB0cmFuc2Zvcm1Ub3BMZXZlbEF0b207XG4gIGNvbnN0IHRyYW5zZm9ybWVyID0gYXRvbSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtRnVuY3Rpb24oYXRvbSwgZmllbGQpO1xuICAgIGlmIChyZXN1bHQgPT09IENhbm5vdFRyYW5zZm9ybSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGBiYWQgYXRvbTogJHtKU09OLnN0cmluZ2lmeShhdG9tKX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAvLyBrZXlzIGlzIHRoZSBjb25zdHJhaW50cyBpbiByZXZlcnNlIGFscGhhYmV0aWNhbCBvcmRlci5cbiAgLy8gVGhpcyBpcyBhIGhhY2sgc28gdGhhdDpcbiAgLy8gICAkcmVnZXggaXMgaGFuZGxlZCBiZWZvcmUgJG9wdGlvbnNcbiAgLy8gICAkbmVhclNwaGVyZSBpcyBoYW5kbGVkIGJlZm9yZSAkbWF4RGlzdGFuY2VcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjb25zdHJhaW50KVxuICAgIC5zb3J0KClcbiAgICAucmV2ZXJzZSgpO1xuICB2YXIgYW5zd2VyID0ge307XG4gIGZvciAodmFyIGtleSBvZiBrZXlzKSB7XG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIGNhc2UgJyRsdCc6XG4gICAgICBjYXNlICckbHRlJzpcbiAgICAgIGNhc2UgJyRndCc6XG4gICAgICBjYXNlICckZ3RlJzpcbiAgICAgIGNhc2UgJyRleGlzdHMnOlxuICAgICAgY2FzZSAnJG5lJzpcbiAgICAgIGNhc2UgJyRlcSc6IHtcbiAgICAgICAgY29uc3QgdmFsID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC4kcmVsYXRpdmVUaW1lKSB7XG4gICAgICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgIT09ICdEYXRlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICckcmVsYXRpdmVUaW1lIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCBEYXRlIGZpZWxkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgY2FzZSAnJGV4aXN0cyc6XG4gICAgICAgICAgICBjYXNlICckbmUnOlxuICAgICAgICAgICAgY2FzZSAnJGVxJzpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnJHJlbGF0aXZlVGltZSBjYW4gb25seSBiZSB1c2VkIHdpdGggdGhlICRsdCwgJGx0ZSwgJGd0LCBhbmQgJGd0ZSBvcGVyYXRvcnMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcGFyc2VyUmVzdWx0ID0gcmVsYXRpdmVUaW1lVG9EYXRlKHZhbC4kcmVsYXRpdmVUaW1lKTtcbiAgICAgICAgICBpZiAocGFyc2VyUmVzdWx0LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSB7XG4gICAgICAgICAgICBhbnN3ZXJba2V5XSA9IHBhcnNlclJlc3VsdC5yZXN1bHQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsb2cuaW5mbygnRXJyb3Igd2hpbGUgcGFyc2luZyByZWxhdGl2ZSBkYXRlJywgcGFyc2VyUmVzdWx0KTtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICRyZWxhdGl2ZVRpbWUgKCR7a2V5fSkgdmFsdWUuICR7cGFyc2VyUmVzdWx0LmluZm99YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBhbnN3ZXJba2V5XSA9IHRyYW5zZm9ybWVyKHZhbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICckaW4nOlxuICAgICAgY2FzZSAnJG5pbic6IHtcbiAgICAgICAgY29uc3QgYXJyID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICcgKyBrZXkgKyAnIHZhbHVlJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSBfLmZsYXRNYXAoYXJyLCB2YWx1ZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIChhdG9tID0+IHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGF0b20pKSB7XG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5tYXAodHJhbnNmb3JtZXIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybWVyKGF0b20pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJGFsbCc6IHtcbiAgICAgICAgY29uc3QgYXJyID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICcgKyBrZXkgKyAnIHZhbHVlJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSBhcnIubWFwKHRyYW5zZm9ybUludGVyaW9yQXRvbSk7XG5cbiAgICAgICAgY29uc3QgdmFsdWVzID0gYW5zd2VyW2tleV07XG4gICAgICAgIGlmIChpc0FueVZhbHVlUmVnZXgodmFsdWVzKSAmJiAhaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSh2YWx1ZXMpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgJ0FsbCAkYWxsIHZhbHVlcyBtdXN0IGJlIG9mIHJlZ2V4IHR5cGUgb3Igbm9uZTogJyArIHZhbHVlc1xuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRyZWdleCc6XG4gICAgICAgIHZhciBzID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIHMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCByZWdleDogJyArIHMpO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0gcztcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyRjb250YWluZWRCeSc6IHtcbiAgICAgICAgY29uc3QgYXJyID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICRjb250YWluZWRCeTogc2hvdWxkIGJlIGFuIGFycmF5YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyLiRlbGVtTWF0Y2ggPSB7XG4gICAgICAgICAgJG5pbjogYXJyLm1hcCh0cmFuc2Zvcm1lciksXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG9wdGlvbnMnOlxuICAgICAgICBhbnN3ZXJba2V5XSA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyR0ZXh0Jzoge1xuICAgICAgICBjb25zdCBzZWFyY2ggPSBjb25zdHJhaW50W2tleV0uJHNlYXJjaDtcbiAgICAgICAgaWYgKHR5cGVvZiBzZWFyY2ggIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJHNlYXJjaCwgc2hvdWxkIGJlIG9iamVjdGBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc2VhcmNoLiR0ZXJtIHx8IHR5cGVvZiBzZWFyY2guJHRlcm0gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJHRlcm0sIHNob3VsZCBiZSBzdHJpbmdgXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhbnN3ZXJba2V5XSA9IHtcbiAgICAgICAgICAgICRzZWFyY2g6IHNlYXJjaC4kdGVybSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWFyY2guJGxhbmd1YWdlICYmIHR5cGVvZiBzZWFyY2guJGxhbmd1YWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGBiYWQgJHRleHQ6ICRsYW5ndWFnZSwgc2hvdWxkIGJlIHN0cmluZ2BcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHNlYXJjaC4kbGFuZ3VhZ2UpIHtcbiAgICAgICAgICBhbnN3ZXJba2V5XS4kbGFuZ3VhZ2UgPSBzZWFyY2guJGxhbmd1YWdlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZWFyY2guJGNhc2VTZW5zaXRpdmUgJiZcbiAgICAgICAgICB0eXBlb2Ygc2VhcmNoLiRjYXNlU2Vuc2l0aXZlICE9PSAnYm9vbGVhbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJGNhc2VTZW5zaXRpdmUsIHNob3VsZCBiZSBib29sZWFuYFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRjYXNlU2Vuc2l0aXZlKSB7XG4gICAgICAgICAgYW5zd2VyW2tleV0uJGNhc2VTZW5zaXRpdmUgPSBzZWFyY2guJGNhc2VTZW5zaXRpdmU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICYmXG4gICAgICAgICAgdHlwZW9mIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICE9PSAnYm9vbGVhbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJGRpYWNyaXRpY1NlbnNpdGl2ZSwgc2hvdWxkIGJlIGJvb2xlYW5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZSkge1xuICAgICAgICAgIGFuc3dlcltrZXldLiRkaWFjcml0aWNTZW5zaXRpdmUgPSBzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRuZWFyU3BoZXJlJzoge1xuICAgICAgICBjb25zdCBwb2ludCA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgYW5zd2VyLiRnZW9XaXRoaW4gPSB7XG4gICAgICAgICAgICAkY2VudGVyU3BoZXJlOiBbXG4gICAgICAgICAgICAgIFtwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXSxcbiAgICAgICAgICAgICAgY29uc3RyYWludC4kbWF4RGlzdGFuY2UsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYW5zd2VyW2tleV0gPSBbcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZV07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckbWF4RGlzdGFuY2UnOiB7XG4gICAgICAgIGlmIChjb3VudCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBTREtzIGRvbid0IHNlZW0gdG8gdXNlIHRoZXNlIGJ1dCB0aGV5IGFyZSBkb2N1bWVudGVkIGluIHRoZVxuICAgICAgLy8gUkVTVCBBUEkgZG9jcy5cbiAgICAgIGNhc2UgJyRtYXhEaXN0YW5jZUluUmFkaWFucyc6XG4gICAgICAgIGFuc3dlclsnJG1heERpc3RhbmNlJ10gPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG1heERpc3RhbmNlSW5NaWxlcyc6XG4gICAgICAgIGFuc3dlclsnJG1heERpc3RhbmNlJ10gPSBjb25zdHJhaW50W2tleV0gLyAzOTU5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRtYXhEaXN0YW5jZUluS2lsb21ldGVycyc6XG4gICAgICAgIGFuc3dlclsnJG1heERpc3RhbmNlJ10gPSBjb25zdHJhaW50W2tleV0gLyA2MzcxO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnJHNlbGVjdCc6XG4gICAgICBjYXNlICckZG9udFNlbGVjdCc6XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5DT01NQU5EX1VOQVZBSUxBQkxFLFxuICAgICAgICAgICd0aGUgJyArIGtleSArICcgY29uc3RyYWludCBpcyBub3Qgc3VwcG9ydGVkIHlldCdcbiAgICAgICAgKTtcblxuICAgICAgY2FzZSAnJHdpdGhpbic6XG4gICAgICAgIHZhciBib3ggPSBjb25zdHJhaW50W2tleV1bJyRib3gnXTtcbiAgICAgICAgaWYgKCFib3ggfHwgYm94Lmxlbmd0aCAhPSAyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgJ21hbGZvcm1hdHRlZCAkd2l0aGluIGFyZydcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICRib3g6IFtcbiAgICAgICAgICAgIFtib3hbMF0ubG9uZ2l0dWRlLCBib3hbMF0ubGF0aXR1ZGVdLFxuICAgICAgICAgICAgW2JveFsxXS5sb25naXR1ZGUsIGJveFsxXS5sYXRpdHVkZV0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyRnZW9XaXRoaW4nOiB7XG4gICAgICAgIGNvbnN0IHBvbHlnb24gPSBjb25zdHJhaW50W2tleV1bJyRwb2x5Z29uJ107XG4gICAgICAgIGNvbnN0IGNlbnRlclNwaGVyZSA9IGNvbnN0cmFpbnRba2V5XVsnJGNlbnRlclNwaGVyZSddO1xuICAgICAgICBpZiAocG9seWdvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbGV0IHBvaW50cztcbiAgICAgICAgICBpZiAodHlwZW9mIHBvbHlnb24gPT09ICdvYmplY3QnICYmIHBvbHlnb24uX190eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgICAgIGlmICghcG9seWdvbi5jb29yZGluYXRlcyB8fCBwb2x5Z29uLmNvb3JkaW5hdGVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7IFBvbHlnb24uY29vcmRpbmF0ZXMgc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBsb24vbGF0IHBhaXJzJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9pbnRzID0gcG9seWdvbi5jb29yZGluYXRlcztcbiAgICAgICAgICB9IGVsc2UgaWYgKHBvbHlnb24gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgaWYgKHBvbHlnb24ubGVuZ3RoIDwgMykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBHZW9Qb2ludHMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb2ludHMgPSBwb2x5Z29uO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgXCJiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGJlIFBvbHlnb24gb2JqZWN0IG9yIEFycmF5IG9mIFBhcnNlLkdlb1BvaW50J3NcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcG9pbnRzID0gcG9pbnRzLm1hcChwb2ludCA9PiB7XG4gICAgICAgICAgICBpZiAocG9pbnQgaW5zdGFuY2VvZiBBcnJheSAmJiBwb2ludC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICAgICAgICAgIHJldHVybiBwb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihwb2ludCkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWUnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBQYXJzZS5HZW9Qb2ludC5fdmFsaWRhdGUocG9pbnQubGF0aXR1ZGUsIHBvaW50LmxvbmdpdHVkZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gW3BvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGVdO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICAgJHBvbHlnb246IHBvaW50cyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGNlbnRlclNwaGVyZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKCEoY2VudGVyU3BoZXJlIGluc3RhbmNlb2YgQXJyYXkpIHx8IGNlbnRlclNwaGVyZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlOyAkY2VudGVyU3BoZXJlIHNob3VsZCBiZSBhbiBhcnJheSBvZiBQYXJzZS5HZW9Qb2ludCBhbmQgZGlzdGFuY2UnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBHZXQgcG9pbnQsIGNvbnZlcnQgdG8gZ2VvIHBvaW50IGlmIG5lY2Vzc2FyeSBhbmQgdmFsaWRhdGVcbiAgICAgICAgICBsZXQgcG9pbnQgPSBjZW50ZXJTcGhlcmVbMF07XG4gICAgICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBwb2ludCA9IG5ldyBQYXJzZS5HZW9Qb2ludChwb2ludFsxXSwgcG9pbnRbMF0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZEpTT04ocG9pbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlOyAkY2VudGVyU3BoZXJlIGdlbyBwb2ludCBpbnZhbGlkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgIC8vIEdldCBkaXN0YW5jZSBhbmQgdmFsaWRhdGVcbiAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGNlbnRlclNwaGVyZVsxXTtcbiAgICAgICAgICBpZiAoaXNOYU4oZGlzdGFuY2UpIHx8IGRpc3RhbmNlIDwgMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBkaXN0YW5jZSBpbnZhbGlkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYW5zd2VyW2tleV0gPSB7XG4gICAgICAgICAgICAkY2VudGVyU3BoZXJlOiBbW3BvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGVdLCBkaXN0YW5jZV0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRnZW9JbnRlcnNlY3RzJzoge1xuICAgICAgICBjb25zdCBwb2ludCA9IGNvbnN0cmFpbnRba2V5XVsnJHBvaW50J107XG4gICAgICAgIGlmICghR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihwb2ludCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9JbnRlcnNlY3QgdmFsdWU7ICRwb2ludCBzaG91bGQgYmUgR2VvUG9pbnQnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBQYXJzZS5HZW9Qb2ludC5fdmFsaWRhdGUocG9pbnQubGF0aXR1ZGUsIHBvaW50LmxvbmdpdHVkZSk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSB7XG4gICAgICAgICAgJGdlb21ldHJ5OiB7XG4gICAgICAgICAgICB0eXBlOiAnUG9pbnQnLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IFtwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChrZXkubWF0Y2goL15cXCQrLykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkIGNvbnN0cmFpbnQ6ICcgKyBrZXlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDYW5ub3RUcmFuc2Zvcm07XG4gICAgfVxuICB9XG4gIHJldHVybiBhbnN3ZXI7XG59XG5cbi8vIFRyYW5zZm9ybXMgYW4gdXBkYXRlIG9wZXJhdG9yIGZyb20gUkVTVCBmb3JtYXQgdG8gbW9uZ28gZm9ybWF0LlxuLy8gVG8gYmUgdHJhbnNmb3JtZWQsIHRoZSBpbnB1dCBzaG91bGQgaGF2ZSBhbiBfX29wIGZpZWxkLlxuLy8gSWYgZmxhdHRlbiBpcyB0cnVlLCB0aGlzIHdpbGwgZmxhdHRlbiBvcGVyYXRvcnMgdG8gdGhlaXIgc3RhdGljXG4vLyBkYXRhIGZvcm1hdC4gRm9yIGV4YW1wbGUsIGFuIGluY3JlbWVudCBvZiAyIHdvdWxkIHNpbXBseSBiZWNvbWUgYVxuLy8gMi5cbi8vIFRoZSBvdXRwdXQgZm9yIGEgbm9uLWZsYXR0ZW5lZCBvcGVyYXRvciBpcyBhIGhhc2ggd2l0aCBfX29wIGJlaW5nXG4vLyB0aGUgbW9uZ28gb3AsIGFuZCBhcmcgYmVpbmcgdGhlIGFyZ3VtZW50LlxuLy8gVGhlIG91dHB1dCBmb3IgYSBmbGF0dGVuZWQgb3BlcmF0b3IgaXMganVzdCBhIHZhbHVlLlxuLy8gUmV0dXJucyB1bmRlZmluZWQgaWYgdGhpcyBzaG91bGQgYmUgYSBuby1vcC5cblxuZnVuY3Rpb24gdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IoeyBfX29wLCBhbW91bnQsIG9iamVjdHMgfSwgZmxhdHRlbikge1xuICBzd2l0Y2ggKF9fb3ApIHtcbiAgICBjYXNlICdEZWxldGUnOlxuICAgICAgaWYgKGZsYXR0ZW4pIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IF9fb3A6ICckdW5zZXQnLCBhcmc6ICcnIH07XG4gICAgICB9XG5cbiAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgaWYgKHR5cGVvZiBhbW91bnQgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ2luY3JlbWVudGluZyBtdXN0IHByb3ZpZGUgYSBudW1iZXInXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmxhdHRlbikge1xuICAgICAgICByZXR1cm4gYW1vdW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgX19vcDogJyRpbmMnLCBhcmc6IGFtb3VudCB9O1xuICAgICAgfVxuXG4gICAgY2FzZSAnQWRkJzpcbiAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgaWYgKCEob2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICdvYmplY3RzIHRvIGFkZCBtdXN0IGJlIGFuIGFycmF5J1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdmFyIHRvQWRkID0gb2JqZWN0cy5tYXAodHJhbnNmb3JtSW50ZXJpb3JBdG9tKTtcbiAgICAgIGlmIChmbGF0dGVuKSB7XG4gICAgICAgIHJldHVybiB0b0FkZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBtb25nb09wID0ge1xuICAgICAgICAgIEFkZDogJyRwdXNoJyxcbiAgICAgICAgICBBZGRVbmlxdWU6ICckYWRkVG9TZXQnLFxuICAgICAgICB9W19fb3BdO1xuICAgICAgICByZXR1cm4geyBfX29wOiBtb25nb09wLCBhcmc6IHsgJGVhY2g6IHRvQWRkIH0gfTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ1JlbW92ZSc6XG4gICAgICBpZiAoIShvYmplY3RzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ29iamVjdHMgdG8gcmVtb3ZlIG11c3QgYmUgYW4gYXJyYXknXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YXIgdG9SZW1vdmUgPSBvYmplY3RzLm1hcCh0cmFuc2Zvcm1JbnRlcmlvckF0b20pO1xuICAgICAgaWYgKGZsYXR0ZW4pIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgX19vcDogJyRwdWxsQWxsJywgYXJnOiB0b1JlbW92ZSB9O1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuQ09NTUFORF9VTkFWQUlMQUJMRSxcbiAgICAgICAgYFRoZSAke19fb3B9IG9wZXJhdG9yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LmBcbiAgICAgICk7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcFZhbHVlcyhvYmplY3QsIGl0ZXJhdG9yKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHt9O1xuICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICByZXN1bHRba2V5XSA9IGl0ZXJhdG9yKG9iamVjdFtrZXldKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmNvbnN0IG5lc3RlZE1vbmdvT2JqZWN0VG9OZXN0ZWRQYXJzZU9iamVjdCA9IG1vbmdvT2JqZWN0ID0+IHtcbiAgc3dpdGNoICh0eXBlb2YgbW9uZ29PYmplY3QpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiBtb25nb09iamVjdDtcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgIHRocm93ICdiYWQgdmFsdWUgaW4gbmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0JztcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgaWYgKG1vbmdvT2JqZWN0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0Lm1hcChuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIHJldHVybiBQYXJzZS5fZW5jb2RlKG1vbmdvT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgbW9uZ29kYi5Mb25nKSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC50b051bWJlcigpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkRvdWJsZSkge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChCeXRlc0NvZGVyLmlzVmFsaWREYXRhYmFzZU9iamVjdChtb25nb09iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIEJ5dGVzQ29kZXIuZGF0YWJhc2VUb0pTT04obW9uZ29PYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb25nb09iamVjdCwgJ19fdHlwZScpICYmXG4gICAgICAgIG1vbmdvT2JqZWN0Ll9fdHlwZSA9PSAnRGF0ZScgJiZcbiAgICAgICAgbW9uZ29PYmplY3QuaXNvIGluc3RhbmNlb2YgRGF0ZVxuICAgICAgKSB7XG4gICAgICAgIG1vbmdvT2JqZWN0LmlzbyA9IG1vbmdvT2JqZWN0Lmlzby50b0pTT04oKTtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbWFwVmFsdWVzKG1vbmdvT2JqZWN0LCBuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyAndW5rbm93biBqcyB0eXBlJztcbiAgfVxufTtcblxuY29uc3QgdHJhbnNmb3JtUG9pbnRlclN0cmluZyA9IChzY2hlbWEsIGZpZWxkLCBwb2ludGVyU3RyaW5nKSA9PiB7XG4gIGNvbnN0IG9iakRhdGEgPSBwb2ludGVyU3RyaW5nLnNwbGl0KCckJyk7XG4gIGlmIChvYmpEYXRhWzBdICE9PSBzY2hlbWEuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzcykge1xuICAgIHRocm93ICdwb2ludGVyIHRvIGluY29ycmVjdCBjbGFzc05hbWUnO1xuICB9XG4gIHJldHVybiB7XG4gICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgY2xhc3NOYW1lOiBvYmpEYXRhWzBdLFxuICAgIG9iamVjdElkOiBvYmpEYXRhWzFdLFxuICB9O1xufTtcblxuLy8gQ29udmVydHMgZnJvbSBhIG1vbmdvLWZvcm1hdCBvYmplY3QgdG8gYSBSRVNULWZvcm1hdCBvYmplY3QuXG4vLyBEb2VzIG5vdCBzdHJpcCBvdXQgYW55dGhpbmcgYmFzZWQgb24gYSBsYWNrIG9mIGF1dGhlbnRpY2F0aW9uLlxuY29uc3QgbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0ID0gKGNsYXNzTmFtZSwgbW9uZ29PYmplY3QsIHNjaGVtYSkgPT4ge1xuICBzd2l0Y2ggKHR5cGVvZiBtb25nb09iamVjdCkge1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0O1xuICAgIGNhc2UgJ3N5bWJvbCc6XG4gICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgdGhyb3cgJ2JhZCB2YWx1ZSBpbiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QnO1xuICAgIGNhc2UgJ29iamVjdCc6IHtcbiAgICAgIGlmIChtb25nb09iamVjdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC5tYXAobmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICByZXR1cm4gUGFyc2UuX2VuY29kZShtb25nb09iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIG1vbmdvZGIuTG9uZykge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QudG9OdW1iZXIoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgbW9uZ29kYi5Eb3VibGUpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0LnZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QobW9uZ29PYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBCeXRlc0NvZGVyLmRhdGFiYXNlVG9KU09OKG1vbmdvT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdE9iamVjdCA9IHt9O1xuICAgICAgaWYgKG1vbmdvT2JqZWN0Ll9ycGVybSB8fCBtb25nb09iamVjdC5fd3Blcm0pIHtcbiAgICAgICAgcmVzdE9iamVjdC5fcnBlcm0gPSBtb25nb09iamVjdC5fcnBlcm0gfHwgW107XG4gICAgICAgIHJlc3RPYmplY3QuX3dwZXJtID0gbW9uZ29PYmplY3QuX3dwZXJtIHx8IFtdO1xuICAgICAgICBkZWxldGUgbW9uZ29PYmplY3QuX3JwZXJtO1xuICAgICAgICBkZWxldGUgbW9uZ29PYmplY3QuX3dwZXJtO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gbW9uZ29PYmplY3QpIHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICBjYXNlICdfaWQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnb2JqZWN0SWQnXSA9ICcnICsgbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19oYXNoZWRfcGFzc3dvcmQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdC5faGFzaGVkX3Bhc3N3b3JkID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19hY2wnOlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbic6XG4gICAgICAgICAgY2FzZSAnX3BlcmlzaGFibGVfdG9rZW4nOlxuICAgICAgICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgICAgIGNhc2UgJ19wYXNzd29yZF9jaGFuZ2VkX2F0JzpcbiAgICAgICAgICBjYXNlICdfdG9tYnN0b25lJzpcbiAgICAgICAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgICAgIGNhc2UgJ19hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCc6XG4gICAgICAgICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgICAgICAgY2FzZSAnX3Bhc3N3b3JkX2hpc3RvcnknOlxuICAgICAgICAgICAgLy8gVGhvc2Uga2V5cyB3aWxsIGJlIGRlbGV0ZWQgaWYgbmVlZGVkIGluIHRoZSBEQiBDb250cm9sbGVyXG4gICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnX3Nlc3Npb25fdG9rZW4nOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnc2Vzc2lvblRva2VuJ10gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgICAgICBjYXNlICdfdXBkYXRlZF9hdCc6XG4gICAgICAgICAgICByZXN0T2JqZWN0Wyd1cGRhdGVkQXQnXSA9IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgICAgICAgIG5ldyBEYXRlKG1vbmdvT2JqZWN0W2tleV0pXG4gICAgICAgICAgICApLmlzbztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2NyZWF0ZWRBdCc6XG4gICAgICAgICAgY2FzZSAnX2NyZWF0ZWRfYXQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnY3JlYXRlZEF0J10gPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICAgICAgICBuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKVxuICAgICAgICAgICAgKS5pc287XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdleHBpcmVzQXQnOlxuICAgICAgICAgIGNhc2UgJ19leHBpcmVzQXQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnZXhwaXJlc0F0J10gPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKG1vbmdvT2JqZWN0W2tleV0pKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2xhc3RVc2VkJzpcbiAgICAgICAgICBjYXNlICdfbGFzdF91c2VkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ2xhc3RVc2VkJ10gPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICAgICAgICBuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKVxuICAgICAgICAgICAgKS5pc287XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgICAgICAgIGNhc2UgJ3RpbWVzX3VzZWQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsndGltZXNVc2VkJ10gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnYXV0aERhdGEnOlxuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgICBsb2cud2FybihcbiAgICAgICAgICAgICAgICAnaWdub3JpbmcgYXV0aERhdGEgaW4gX1VzZXIgYXMgdGhpcyBrZXkgaXMgcmVzZXJ2ZWQgdG8gYmUgc3ludGhlc2l6ZWQgb2YgYF9hdXRoX2RhdGFfKmAga2V5cydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc3RPYmplY3RbJ2F1dGhEYXRhJ10gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIC8vIENoZWNrIG90aGVyIGF1dGggZGF0YSBrZXlzXG4gICAgICAgICAgICB2YXIgYXV0aERhdGFNYXRjaCA9IGtleS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgICAgICAgICAgaWYgKGF1dGhEYXRhTWF0Y2ggJiYgY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgICAgICAgICAgIHZhciBwcm92aWRlciA9IGF1dGhEYXRhTWF0Y2hbMV07XG4gICAgICAgICAgICAgIHJlc3RPYmplY3RbJ2F1dGhEYXRhJ10gPSByZXN0T2JqZWN0WydhdXRoRGF0YSddIHx8IHt9O1xuICAgICAgICAgICAgICByZXN0T2JqZWN0WydhdXRoRGF0YSddW3Byb3ZpZGVyXSA9IG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YoJ19wXycpID09IDApIHtcbiAgICAgICAgICAgICAgdmFyIG5ld0tleSA9IGtleS5zdWJzdHJpbmcoMyk7XG4gICAgICAgICAgICAgIGlmICghc2NoZW1hLmZpZWxkc1tuZXdLZXldKSB7XG4gICAgICAgICAgICAgICAgbG9nLmluZm8oXG4gICAgICAgICAgICAgICAgICAndHJhbnNmb3JtLmpzJyxcbiAgICAgICAgICAgICAgICAgICdGb3VuZCBhIHBvaW50ZXIgY29sdW1uIG5vdCBpbiB0aGUgc2NoZW1hLCBkcm9wcGluZyBpdC4nLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgbmV3S2V5XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoc2NoZW1hLmZpZWxkc1tuZXdLZXldLnR5cGUgIT09ICdQb2ludGVyJykge1xuICAgICAgICAgICAgICAgIGxvZy5pbmZvKFxuICAgICAgICAgICAgICAgICAgJ3RyYW5zZm9ybS5qcycsXG4gICAgICAgICAgICAgICAgICAnRm91bmQgYSBwb2ludGVyIGluIGEgbm9uLXBvaW50ZXIgY29sdW1uLCBkcm9wcGluZyBpdC4nLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobW9uZ29PYmplY3Rba2V5XSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3RPYmplY3RbbmV3S2V5XSA9IHRyYW5zZm9ybVBvaW50ZXJTdHJpbmcoXG4gICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgIG5ld0tleSxcbiAgICAgICAgICAgICAgICBtb25nb09iamVjdFtrZXldXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChrZXlbMF0gPT0gJ18nICYmIGtleSAhPSAnX190eXBlJykge1xuICAgICAgICAgICAgICB0aHJvdyAnYmFkIGtleSBpbiB1bnRyYW5zZm9ybTogJyArIGtleTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhciB2YWx1ZSA9IG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0ZpbGUnICYmXG4gICAgICAgICAgICAgICAgRmlsZUNvZGVyLmlzVmFsaWREYXRhYmFzZU9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gRmlsZUNvZGVyLmRhdGFiYXNlVG9KU09OKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldICYmXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdHZW9Qb2ludCcgJiZcbiAgICAgICAgICAgICAgICBHZW9Qb2ludENvZGVyLmlzVmFsaWREYXRhYmFzZU9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gR2VvUG9pbnRDb2Rlci5kYXRhYmFzZVRvSlNPTih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnUG9seWdvbicgJiZcbiAgICAgICAgICAgICAgICBQb2x5Z29uQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBQb2x5Z29uQ29kZXIuZGF0YWJhc2VUb0pTT04odmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0J5dGVzJyAmJlxuICAgICAgICAgICAgICAgIEJ5dGVzQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBCeXRlc0NvZGVyLmRhdGFiYXNlVG9KU09OKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gbmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KFxuICAgICAgICAgICAgICBtb25nb09iamVjdFtrZXldXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbGF0aW9uRmllbGROYW1lcyA9IE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZpbHRlcihcbiAgICAgICAgZmllbGROYW1lID0+IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nXG4gICAgICApO1xuICAgICAgY29uc3QgcmVsYXRpb25GaWVsZHMgPSB7fTtcbiAgICAgIHJlbGF0aW9uRmllbGROYW1lcy5mb3JFYWNoKHJlbGF0aW9uRmllbGROYW1lID0+IHtcbiAgICAgICAgcmVsYXRpb25GaWVsZHNbcmVsYXRpb25GaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbcmVsYXRpb25GaWVsZE5hbWVdLnRhcmdldENsYXNzLFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7IC4uLnJlc3RPYmplY3QsIC4uLnJlbGF0aW9uRmllbGRzIH07XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyAndW5rbm93biBqcyB0eXBlJztcbiAgfVxufTtcblxudmFyIERhdGVDb2RlciA9IHtcbiAgSlNPTlRvRGF0YWJhc2UoanNvbikge1xuICAgIHJldHVybiBuZXcgRGF0ZShqc29uLmlzbyk7XG4gIH0sXG5cbiAgaXNWYWxpZEpTT04odmFsdWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZS5fX3R5cGUgPT09ICdEYXRlJ1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgQnl0ZXNDb2RlciA9IHtcbiAgYmFzZTY0UGF0dGVybjogbmV3IFJlZ0V4cChcbiAgICAnXig/OltBLVphLXowLTkrL117NH0pKig/OltBLVphLXowLTkrL117Mn09PXxbQS1aYS16MC05Ky9dezN9PSk/JCdcbiAgKSxcbiAgaXNCYXNlNjRWYWx1ZShvYmplY3QpIHtcbiAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYmFzZTY0UGF0dGVybi50ZXN0KG9iamVjdCk7XG4gIH0sXG5cbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGlmICh0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KSkge1xuICAgICAgdmFsdWUgPSBvYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gb2JqZWN0LmJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdCeXRlcycsXG4gICAgICBiYXNlNjQ6IHZhbHVlLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkJpbmFyeSB8fCB0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KTtcbiAgfSxcblxuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgcmV0dXJuIG5ldyBtb25nb2RiLkJpbmFyeShCdWZmZXIuZnJvbShqc29uLmJhc2U2NCwgJ2Jhc2U2NCcpKTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJ1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgR2VvUG9pbnRDb2RlciA9IHtcbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogJ0dlb1BvaW50JyxcbiAgICAgIGxhdGl0dWRlOiBvYmplY3RbMV0sXG4gICAgICBsb25naXR1ZGU6IG9iamVjdFswXSxcbiAgICB9O1xuICB9LFxuXG4gIGlzVmFsaWREYXRhYmFzZU9iamVjdChvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgQXJyYXkgJiYgb2JqZWN0Lmxlbmd0aCA9PSAyO1xuICB9LFxuXG4gIEpTT05Ub0RhdGFiYXNlKGpzb24pIHtcbiAgICByZXR1cm4gW2pzb24ubG9uZ2l0dWRlLCBqc29uLmxhdGl0dWRlXTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgUG9seWdvbkNvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICAvLyBDb252ZXJ0IGxuZy9sYXQgLT4gbGF0L2xuZ1xuICAgIGNvbnN0IGNvb3JkcyA9IG9iamVjdC5jb29yZGluYXRlc1swXS5tYXAoY29vcmQgPT4ge1xuICAgICAgcmV0dXJuIFtjb29yZFsxXSwgY29vcmRbMF1dO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdQb2x5Z29uJyxcbiAgICAgIGNvb3JkaW5hdGVzOiBjb29yZHMsXG4gICAgfTtcbiAgfSxcblxuICBpc1ZhbGlkRGF0YWJhc2VPYmplY3Qob2JqZWN0KSB7XG4gICAgY29uc3QgY29vcmRzID0gb2JqZWN0LmNvb3JkaW5hdGVzWzBdO1xuICAgIGlmIChvYmplY3QudHlwZSAhPT0gJ1BvbHlnb24nIHx8ICEoY29vcmRzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29vcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludCA9IGNvb3Jkc1tpXTtcbiAgICAgIGlmICghR2VvUG9pbnRDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QocG9pbnQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwYXJzZUZsb2F0KHBvaW50WzFdKSwgcGFyc2VGbG9hdChwb2ludFswXSkpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcblxuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgbGV0IGNvb3JkcyA9IGpzb24uY29vcmRpbmF0ZXM7XG4gICAgLy8gQWRkIGZpcnN0IHBvaW50IHRvIHRoZSBlbmQgdG8gY2xvc2UgcG9seWdvblxuICAgIGlmIChcbiAgICAgIGNvb3Jkc1swXVswXSAhPT0gY29vcmRzW2Nvb3Jkcy5sZW5ndGggLSAxXVswXSB8fFxuICAgICAgY29vcmRzWzBdWzFdICE9PSBjb29yZHNbY29vcmRzLmxlbmd0aCAtIDFdWzFdXG4gICAgKSB7XG4gICAgICBjb29yZHMucHVzaChjb29yZHNbMF0pO1xuICAgIH1cbiAgICBjb25zdCB1bmlxdWUgPSBjb29yZHMuZmlsdGVyKChpdGVtLCBpbmRleCwgYXIpID0+IHtcbiAgICAgIGxldCBmb3VuZEluZGV4ID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IHB0ID0gYXJbaV07XG4gICAgICAgIGlmIChwdFswXSA9PT0gaXRlbVswXSAmJiBwdFsxXSA9PT0gaXRlbVsxXSkge1xuICAgICAgICAgIGZvdW5kSW5kZXggPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZm91bmRJbmRleCA9PT0gaW5kZXg7XG4gICAgfSk7XG4gICAgaWYgKHVuaXF1ZS5sZW5ndGggPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgJ0dlb0pTT046IExvb3AgbXVzdCBoYXZlIGF0IGxlYXN0IDMgZGlmZmVyZW50IHZlcnRpY2VzJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ29udmVydCBsYXQvbG9uZyAtPiBsb25nL2xhdFxuICAgIGNvb3JkcyA9IGNvb3Jkcy5tYXAoY29vcmQgPT4ge1xuICAgICAgcmV0dXJuIFtjb29yZFsxXSwgY29vcmRbMF1dO1xuICAgIH0pO1xuICAgIHJldHVybiB7IHR5cGU6ICdQb2x5Z29uJywgY29vcmRpbmF0ZXM6IFtjb29yZHNdIH07XG4gIH0sXG5cbiAgaXNWYWxpZEpTT04odmFsdWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZS5fX3R5cGUgPT09ICdQb2x5Z29uJ1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgRmlsZUNvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICBuYW1lOiBvYmplY3QsXG4gICAgfTtcbiAgfSxcblxuICBpc1ZhbGlkRGF0YWJhc2VPYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnO1xuICB9LFxuXG4gIEpTT05Ub0RhdGFiYXNlKGpzb24pIHtcbiAgICByZXR1cm4ganNvbi5uYW1lO1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnRmlsZSdcbiAgICApO1xuICB9LFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHRyYW5zZm9ybUtleSxcbiAgcGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlLFxuICB0cmFuc2Zvcm1VcGRhdGUsXG4gIHRyYW5zZm9ybVdoZXJlLFxuICBtb25nb09iamVjdFRvUGFyc2VPYmplY3QsXG4gIHJlbGF0aXZlVGltZVRvRGF0ZSxcbiAgdHJhbnNmb3JtQ29uc3RyYWludCxcbiAgdHJhbnNmb3JtUG9pbnRlclN0cmluZyxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresClient.js b/lib/Adapters/Storage/Postgres/PostgresClient.js new file mode 100644 index 0000000000..9c2899b4d5 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/PostgresClient.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createClient = createClient; + +const parser = require('./PostgresConfigParser'); + +function createClient(uri, databaseOptions) { + let dbOptions = {}; + databaseOptions = databaseOptions || {}; + + if (uri) { + dbOptions = parser.getDatabaseOptionsFromURI(uri); + } + + for (const key in databaseOptions) { + dbOptions[key] = databaseOptions[key]; + } + + const initOptions = dbOptions.initOptions || {}; + initOptions.noWarnings = process && process.env.TESTING; + + const pgp = require('pg-promise')(initOptions); + + const client = pgp(dbOptions); + + if (dbOptions.pgOptions) { + for (const key in dbOptions.pgOptions) { + pgp.pg.defaults[key] = dbOptions.pgOptions[key]; + } + } + + return { + client, + pgp + }; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ2xpZW50LmpzIl0sIm5hbWVzIjpbInBhcnNlciIsInJlcXVpcmUiLCJjcmVhdGVDbGllbnQiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJkYk9wdGlvbnMiLCJnZXREYXRhYmFzZU9wdGlvbnNGcm9tVVJJIiwia2V5IiwiaW5pdE9wdGlvbnMiLCJub1dhcm5pbmdzIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJwZ3AiLCJjbGllbnQiLCJwZ09wdGlvbnMiLCJwZyIsImRlZmF1bHRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsd0JBQUQsQ0FBdEI7O0FBRU8sU0FBU0MsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkJDLGVBQTNCLEVBQTRDO0FBQ2pELE1BQUlDLFNBQVMsR0FBRyxFQUFoQjtBQUNBRCxFQUFBQSxlQUFlLEdBQUdBLGVBQWUsSUFBSSxFQUFyQzs7QUFFQSxNQUFJRCxHQUFKLEVBQVM7QUFDUEUsSUFBQUEsU0FBUyxHQUFHTCxNQUFNLENBQUNNLHlCQUFQLENBQWlDSCxHQUFqQyxDQUFaO0FBQ0Q7O0FBRUQsT0FBSyxNQUFNSSxHQUFYLElBQWtCSCxlQUFsQixFQUFtQztBQUNqQ0MsSUFBQUEsU0FBUyxDQUFDRSxHQUFELENBQVQsR0FBaUJILGVBQWUsQ0FBQ0csR0FBRCxDQUFoQztBQUNEOztBQUVELFFBQU1DLFdBQVcsR0FBR0gsU0FBUyxDQUFDRyxXQUFWLElBQXlCLEVBQTdDO0FBQ0FBLEVBQUFBLFdBQVcsQ0FBQ0MsVUFBWixHQUF5QkMsT0FBTyxJQUFJQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBaEQ7O0FBRUEsUUFBTUMsR0FBRyxHQUFHWixPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCTyxXQUF0QixDQUFaOztBQUNBLFFBQU1NLE1BQU0sR0FBR0QsR0FBRyxDQUFDUixTQUFELENBQWxCOztBQUVBLE1BQUlBLFNBQVMsQ0FBQ1UsU0FBZCxFQUF5QjtBQUN2QixTQUFLLE1BQU1SLEdBQVgsSUFBa0JGLFNBQVMsQ0FBQ1UsU0FBNUIsRUFBdUM7QUFDckNGLE1BQUFBLEdBQUcsQ0FBQ0csRUFBSixDQUFPQyxRQUFQLENBQWdCVixHQUFoQixJQUF1QkYsU0FBUyxDQUFDVSxTQUFWLENBQW9CUixHQUFwQixDQUF2QjtBQUNEO0FBQ0Y7O0FBRUQsU0FBTztBQUFFTyxJQUFBQSxNQUFGO0FBQVVELElBQUFBO0FBQVYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgcGFyc2VyID0gcmVxdWlyZSgnLi9Qb3N0Z3Jlc0NvbmZpZ1BhcnNlcicpO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xpZW50KHVyaSwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBkYk9wdGlvbnMgPSB7fTtcbiAgZGF0YWJhc2VPcHRpb25zID0gZGF0YWJhc2VPcHRpb25zIHx8IHt9O1xuXG4gIGlmICh1cmkpIHtcbiAgICBkYk9wdGlvbnMgPSBwYXJzZXIuZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSh1cmkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gZGF0YWJhc2VPcHRpb25zKSB7XG4gICAgZGJPcHRpb25zW2tleV0gPSBkYXRhYmFzZU9wdGlvbnNba2V5XTtcbiAgfVxuXG4gIGNvbnN0IGluaXRPcHRpb25zID0gZGJPcHRpb25zLmluaXRPcHRpb25zIHx8IHt9O1xuICBpbml0T3B0aW9ucy5ub1dhcm5pbmdzID0gcHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HO1xuXG4gIGNvbnN0IHBncCA9IHJlcXVpcmUoJ3BnLXByb21pc2UnKShpbml0T3B0aW9ucyk7XG4gIGNvbnN0IGNsaWVudCA9IHBncChkYk9wdGlvbnMpO1xuXG4gIGlmIChkYk9wdGlvbnMucGdPcHRpb25zKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGJPcHRpb25zLnBnT3B0aW9ucykge1xuICAgICAgcGdwLnBnLmRlZmF1bHRzW2tleV0gPSBkYk9wdGlvbnMucGdPcHRpb25zW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2xpZW50LCBwZ3AgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresConfigParser.js b/lib/Adapters/Storage/Postgres/PostgresConfigParser.js new file mode 100644 index 0000000000..f6bea9303b --- /dev/null +++ b/lib/Adapters/Storage/Postgres/PostgresConfigParser.js @@ -0,0 +1,95 @@ +"use strict"; + +const url = require('url'); + +const fs = require('fs'); + +function getDatabaseOptionsFromURI(uri) { + const databaseOptions = {}; + const parsedURI = url.parse(uri); + const queryParams = parseQueryParams(parsedURI.query); + const authParts = parsedURI.auth ? parsedURI.auth.split(':') : []; + databaseOptions.host = parsedURI.hostname || 'localhost'; + databaseOptions.port = parsedURI.port ? parseInt(parsedURI.port) : 5432; + databaseOptions.database = parsedURI.pathname ? parsedURI.pathname.substr(1) : undefined; + databaseOptions.user = authParts.length > 0 ? authParts[0] : ''; + databaseOptions.password = authParts.length > 1 ? authParts[1] : ''; + + if (queryParams.ssl && queryParams.ssl.toLowerCase() === 'true') { + databaseOptions.ssl = true; + } + + if (queryParams.ca || queryParams.pfx || queryParams.cert || queryParams.key || queryParams.passphrase || queryParams.rejectUnauthorized || queryParams.secureOptions) { + databaseOptions.ssl = {}; + + if (queryParams.ca) { + databaseOptions.ssl.ca = fs.readFileSync(queryParams.ca).toString(); + } + + if (queryParams.pfx) { + databaseOptions.ssl.pfx = fs.readFileSync(queryParams.pfx).toString(); + } + + if (queryParams.cert) { + databaseOptions.ssl.cert = fs.readFileSync(queryParams.cert).toString(); + } + + if (queryParams.key) { + databaseOptions.ssl.key = fs.readFileSync(queryParams.key).toString(); + } + + if (queryParams.passphrase) { + databaseOptions.ssl.passphrase = queryParams.passphrase; + } + + if (queryParams.rejectUnauthorized) { + databaseOptions.ssl.rejectUnauthorized = queryParams.rejectUnauthorized.toLowerCase() === 'true' ? true : false; + } + + if (queryParams.secureOptions) { + databaseOptions.ssl.secureOptions = parseInt(queryParams.secureOptions); + } + } + + databaseOptions.binary = queryParams.binary && queryParams.binary.toLowerCase() === 'true' ? true : false; + databaseOptions.client_encoding = queryParams.client_encoding; + databaseOptions.application_name = queryParams.application_name; + databaseOptions.fallback_application_name = queryParams.fallback_application_name; + + if (queryParams.poolSize) { + databaseOptions.poolSize = parseInt(queryParams.poolSize) || 10; + } + + if (queryParams.max) { + databaseOptions.max = parseInt(queryParams.max) || 10; + } + + if (queryParams.query_timeout) { + databaseOptions.query_timeout = parseInt(queryParams.query_timeout); + } + + if (queryParams.idleTimeoutMillis) { + databaseOptions.idleTimeoutMillis = parseInt(queryParams.idleTimeoutMillis); + } + + if (queryParams.keepAlive) { + databaseOptions.keepAlive = queryParams.keepAlive.toLowerCase() === 'true' ? true : false; + } + + return databaseOptions; +} + +function parseQueryParams(queryString) { + queryString = queryString || ''; + return queryString.split('&').reduce((p, c) => { + const parts = c.split('='); + p[decodeURIComponent(parts[0])] = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : ''; + return p; + }, {}); +} + +module.exports = { + parseQueryParams: parseQueryParams, + getDatabaseOptionsFromURI: getDatabaseOptionsFromURI +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ29uZmlnUGFyc2VyLmpzIl0sIm5hbWVzIjpbInVybCIsInJlcXVpcmUiLCJmcyIsImdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkkiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJwYXJzZWRVUkkiLCJwYXJzZSIsInF1ZXJ5UGFyYW1zIiwicGFyc2VRdWVyeVBhcmFtcyIsInF1ZXJ5IiwiYXV0aFBhcnRzIiwiYXV0aCIsInNwbGl0IiwiaG9zdCIsImhvc3RuYW1lIiwicG9ydCIsInBhcnNlSW50IiwiZGF0YWJhc2UiLCJwYXRobmFtZSIsInN1YnN0ciIsInVuZGVmaW5lZCIsInVzZXIiLCJsZW5ndGgiLCJwYXNzd29yZCIsInNzbCIsInRvTG93ZXJDYXNlIiwiY2EiLCJwZngiLCJjZXJ0Iiwia2V5IiwicGFzc3BocmFzZSIsInJlamVjdFVuYXV0aG9yaXplZCIsInNlY3VyZU9wdGlvbnMiLCJyZWFkRmlsZVN5bmMiLCJ0b1N0cmluZyIsImJpbmFyeSIsImNsaWVudF9lbmNvZGluZyIsImFwcGxpY2F0aW9uX25hbWUiLCJmYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lIiwicG9vbFNpemUiLCJtYXgiLCJxdWVyeV90aW1lb3V0IiwiaWRsZVRpbWVvdXRNaWxsaXMiLCJrZWVwQWxpdmUiLCJxdWVyeVN0cmluZyIsInJlZHVjZSIsInAiLCJjIiwicGFydHMiLCJkZWNvZGVVUklDb21wb25lbnQiLCJzbGljZSIsImpvaW4iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEdBQUcsR0FBR0MsT0FBTyxDQUFDLEtBQUQsQ0FBbkI7O0FBQ0EsTUFBTUMsRUFBRSxHQUFHRCxPQUFPLENBQUMsSUFBRCxDQUFsQjs7QUFDQSxTQUFTRSx5QkFBVCxDQUFtQ0MsR0FBbkMsRUFBd0M7QUFDdEMsUUFBTUMsZUFBZSxHQUFHLEVBQXhCO0FBRUEsUUFBTUMs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QUFGWixDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuZnVuY3Rpb24gZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSh1cmkpIHtcbiAgY29uc3QgZGF0YWJhc2VPcHRpb25zID0ge307XG5cbiAgY29uc3QgcGFyc2VkVVJJID0gdXJsLnBhcnNlKHVyaSk7XG4gIGNvbnN0IHF1ZXJ5UGFyYW1zID0gcGFyc2VRdWVyeVBhcmFtcyhwYXJzZWRVUkkucXVlcnkpO1xuICBjb25zdCBhdXRoUGFydHMgPSBwYXJzZWRVUkkuYXV0aCA/IHBhcnNlZFVSSS5hdXRoLnNwbGl0KCc6JykgOiBbXTtcblxuICBkYXRhYmFzZU9wdGlvbnMuaG9zdCA9IHBhcnNlZFVSSS5ob3N0bmFtZSB8fCAnbG9jYWxob3N0JztcbiAgZGF0YWJhc2VPcHRpb25zLnBvcnQgPSBwYXJzZWRVUkkucG9ydCA/IHBhcnNlSW50KHBhcnNlZFVSSS5wb3J0KSA6IDU0MzI7XG4gIGRhdGFiYXNlT3B0aW9ucy5kYXRhYmFzZSA9IHBhcnNlZFVSSS5wYXRobmFtZVxuICAgID8gcGFyc2VkVVJJLnBhdGhuYW1lLnN1YnN0cigxKVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGRhdGFiYXNlT3B0aW9ucy51c2VyID0gYXV0aFBhcnRzLmxlbmd0aCA+IDAgPyBhdXRoUGFydHNbMF0gOiAnJztcbiAgZGF0YWJhc2VPcHRpb25zLnBhc3N3b3JkID0gYXV0aFBhcnRzLmxlbmd0aCA+IDEgPyBhdXRoUGFydHNbMV0gOiAnJztcblxuICBpZiAocXVlcnlQYXJhbXMuc3NsICYmIHF1ZXJ5UGFyYW1zLnNzbC50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScpIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMuc3NsID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChcbiAgICBxdWVyeVBhcmFtcy5jYSB8fFxuICAgIHF1ZXJ5UGFyYW1zLnBmeCB8fFxuICAgIHF1ZXJ5UGFyYW1zLmNlcnQgfHxcbiAgICBxdWVyeVBhcmFtcy5rZXkgfHxcbiAgICBxdWVyeVBhcmFtcy5wYXNzcGhyYXNlIHx8XG4gICAgcXVlcnlQYXJhbXMucmVqZWN0VW5hdXRob3JpemVkIHx8XG4gICAgcXVlcnlQYXJhbXMuc2VjdXJlT3B0aW9uc1xuICApIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMuc3NsID0ge307XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLmNhKSB7XG4gICAgICBkYXRhYmFzZU9wdGlvbnMuc3NsLmNhID0gZnMucmVhZEZpbGVTeW5jKHF1ZXJ5UGFyYW1zLmNhKS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMucGZ4KSB7XG4gICAgICBkYXRhYmFzZU9wdGlvbnMuc3NsLnBmeCA9IGZzLnJlYWRGaWxlU3luYyhxdWVyeVBhcmFtcy5wZngpLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChxdWVyeVBhcmFtcy5jZXJ0KSB7XG4gICAgICBkYXRhYmFzZU9wdGlvbnMuc3NsLmNlcnQgPSBmcy5yZWFkRmlsZVN5bmMocXVlcnlQYXJhbXMuY2VydCkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLmtleSkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5rZXkgPSBmcy5yZWFkRmlsZVN5bmMocXVlcnlQYXJhbXMua2V5KS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMucGFzc3BocmFzZSkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5wYXNzcGhyYXNlID0gcXVlcnlQYXJhbXMucGFzc3BocmFzZTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnJlamVjdFVuYXV0aG9yaXplZCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5yZWplY3RVbmF1dGhvcml6ZWQgPVxuICAgICAgICBxdWVyeVBhcmFtcy5yZWplY3RVbmF1dGhvcml6ZWQudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnID8gdHJ1ZSA6IGZhbHNlO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMuc2VjdXJlT3B0aW9ucykge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5zZWN1cmVPcHRpb25zID0gcGFyc2VJbnQocXVlcnlQYXJhbXMuc2VjdXJlT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgZGF0YWJhc2VPcHRpb25zLmJpbmFyeSA9XG4gICAgcXVlcnlQYXJhbXMuYmluYXJ5ICYmIHF1ZXJ5UGFyYW1zLmJpbmFyeS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSdcbiAgICAgID8gdHJ1ZVxuICAgICAgOiBmYWxzZTtcblxuICBkYXRhYmFzZU9wdGlvbnMuY2xpZW50X2VuY29kaW5nID0gcXVlcnlQYXJhbXMuY2xpZW50X2VuY29kaW5nO1xuICBkYXRhYmFzZU9wdGlvbnMuYXBwbGljYXRpb25fbmFtZSA9IHF1ZXJ5UGFyYW1zLmFwcGxpY2F0aW9uX25hbWU7XG4gIGRhdGFiYXNlT3B0aW9ucy5mYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lID1cbiAgICBxdWVyeVBhcmFtcy5mYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lO1xuXG4gIGlmIChxdWVyeVBhcmFtcy5wb29sU2l6ZSkge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5wb29sU2l6ZSA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnBvb2xTaXplKSB8fCAxMDtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMubWF4KSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLm1heCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLm1heCkgfHwgMTA7XG4gIH1cbiAgaWYgKHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMucXVlcnlfdGltZW91dCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpO1xuICB9XG4gIGlmIChxdWVyeVBhcmFtcy5pZGxlVGltZW91dE1pbGxpcykge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5pZGxlVGltZW91dE1pbGxpcyA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLmlkbGVUaW1lb3V0TWlsbGlzKTtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMua2VlcEFsaXZlKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLmtlZXBBbGl2ZSA9XG4gICAgICBxdWVyeVBhcmFtcy5rZWVwQWxpdmUudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnID8gdHJ1ZSA6IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGRhdGFiYXNlT3B0aW9ucztcbn1cblxuZnVuY3Rpb24gcGFyc2VRdWVyeVBhcmFtcyhxdWVyeVN0cmluZykge1xuICBxdWVyeVN0cmluZyA9IHF1ZXJ5U3RyaW5nIHx8ICcnO1xuXG4gIHJldHVybiBxdWVyeVN0cmluZy5zcGxpdCgnJicpLnJlZHVjZSgocCwgYykgPT4ge1xuICAgIGNvbnN0IHBhcnRzID0gYy5zcGxpdCgnPScpO1xuICAgIHBbZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzBdKV0gPVxuICAgICAgcGFydHMubGVuZ3RoID4gMSA/IGRlY29kZVVSSUNvbXBvbmVudChwYXJ0cy5zbGljZSgxKS5qb2luKCc9JykpIDogJyc7XG4gICAgcmV0dXJuIHA7XG4gIH0sIHt9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUXVlcnlQYXJhbXM6IHBhcnNlUXVlcnlQYXJhbXMsXG4gIGdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkk6IGdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkksXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js new file mode 100644 index 0000000000..dc2a10f816 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -0,0 +1,2496 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PostgresStorageAdapter = void 0; + +var _PostgresClient = require("./PostgresClient"); + +var _node = _interopRequireDefault(require("parse/node")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _sql = _interopRequireDefault(require("./sql")); + +var _StorageAdapter = require("../StorageAdapter"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const PostgresRelationDoesNotExistError = '42P01'; +const PostgresDuplicateRelationError = '42P07'; +const PostgresDuplicateColumnError = '42701'; +const PostgresMissingColumnError = '42703'; +const PostgresDuplicateObjectError = '42710'; +const PostgresUniqueIndexViolationError = '23505'; +const PostgresTransactionAbortedError = '25P02'; + +const logger = require('../../../logger'); + +const debug = function (...args) { + args = ['PG: ' + arguments[0]].concat(args.slice(1, args.length)); + const log = logger.getLogger(); + log.debug.apply(log, args); +}; + +const parseTypeToPostgresType = type => { + switch (type.type) { + case 'String': + return 'text'; + + case 'Date': + return 'timestamp with time zone'; + + case 'Object': + return 'jsonb'; + + case 'File': + return 'text'; + + case 'Boolean': + return 'boolean'; + + case 'Pointer': + return 'text'; + + case 'Number': + return 'double precision'; + + case 'GeoPoint': + return 'point'; + + case 'Bytes': + return 'jsonb'; + + case 'Polygon': + return 'polygon'; + + case 'Array': + if (type.contents && type.contents.type === 'String') { + return 'text[]'; + } else { + return 'jsonb'; + } + + default: + throw `no type for ${JSON.stringify(type)} yet`; + } +}; + +const ParseToPosgresComparator = { + $gt: '>', + $lt: '<', + $gte: '>=', + $lte: '<=' +}; +const mongoAggregateToPostgres = { + $dayOfMonth: 'DAY', + $dayOfWeek: 'DOW', + $dayOfYear: 'DOY', + $isoDayOfWeek: 'ISODOW', + $isoWeekYear: 'ISOYEAR', + $hour: 'HOUR', + $minute: 'MINUTE', + $second: 'SECOND', + $millisecond: 'MILLISECONDS', + $month: 'MONTH', + $week: 'WEEK', + $year: 'YEAR' +}; + +const toPostgresValue = value => { + if (typeof value === 'object') { + if (value.__type === 'Date') { + return value.iso; + } + + if (value.__type === 'File') { + return value.name; + } + } + + return value; +}; + +const transformValue = value => { + if (typeof value === 'object' && value.__type === 'Pointer') { + return value.objectId; + } + + return value; +}; // Duplicate from then mongo adapter... + + +const emptyCLPS = Object.freeze({ + find: {}, + get: {}, + count: {}, + create: {}, + update: {}, + delete: {}, + addField: {}, + protectedFields: {} +}); +const defaultCLPS = Object.freeze({ + find: { + '*': true + }, + get: { + '*': true + }, + count: { + '*': true + }, + create: { + '*': true + }, + update: { + '*': true + }, + delete: { + '*': true + }, + addField: { + '*': true + }, + protectedFields: { + '*': [] + } +}); + +const toParseSchema = schema => { + if (schema.className === '_User') { + delete schema.fields._hashed_password; + } + + if (schema.fields) { + delete schema.fields._wperm; + delete schema.fields._rperm; + } + + let clps = defaultCLPS; + + if (schema.classLevelPermissions) { + clps = _objectSpread(_objectSpread({}, emptyCLPS), schema.classLevelPermissions); + } + + let indexes = {}; + + if (schema.indexes) { + indexes = _objectSpread({}, schema.indexes); + } + + return { + className: schema.className, + fields: schema.fields, + classLevelPermissions: clps, + indexes + }; +}; + +const toPostgresSchema = schema => { + if (!schema) { + return schema; + } + + schema.fields = schema.fields || {}; + schema.fields._wperm = { + type: 'Array', + contents: { + type: 'String' + } + }; + schema.fields._rperm = { + type: 'Array', + contents: { + type: 'String' + } + }; + + if (schema.className === '_User') { + schema.fields._hashed_password = { + type: 'String' + }; + schema.fields._password_history = { + type: 'Array' + }; + } + + return schema; +}; + +const handleDotFields = object => { + Object.keys(object).forEach(fieldName => { + if (fieldName.indexOf('.') > -1) { + const components = fieldName.split('.'); + const first = components.shift(); + object[first] = object[first] || {}; + let currentObj = object[first]; + let next; + let value = object[fieldName]; + + if (value && value.__op === 'Delete') { + value = undefined; + } + /* eslint-disable no-cond-assign */ + + + while (next = components.shift()) { + /* eslint-enable no-cond-assign */ + currentObj[next] = currentObj[next] || {}; + + if (components.length === 0) { + currentObj[next] = value; + } + + currentObj = currentObj[next]; + } + + delete object[fieldName]; + } + }); + return object; +}; + +const transformDotFieldToComponents = fieldName => { + return fieldName.split('.').map((cmpt, index) => { + if (index === 0) { + return `"${cmpt}"`; + } + + return `'${cmpt}'`; + }); +}; + +const transformDotField = fieldName => { + if (fieldName.indexOf('.') === -1) { + return `"${fieldName}"`; + } + + const components = transformDotFieldToComponents(fieldName); + let name = components.slice(0, components.length - 1).join('->'); + name += '->>' + components[components.length - 1]; + return name; +}; + +const transformAggregateField = fieldName => { + if (typeof fieldName !== 'string') { + return fieldName; + } + + if (fieldName === '$_created_at') { + return 'createdAt'; + } + + if (fieldName === '$_updated_at') { + return 'updatedAt'; + } + + return fieldName.substr(1); +}; + +const validateKeys = object => { + if (typeof object == 'object') { + for (const key in object) { + if (typeof object[key] == 'object') { + validateKeys(object[key]); + } + + if (key.includes('$') || key.includes('.')) { + throw new _node.default.Error(_node.default.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } + } + } +}; // Returns the list of join tables on a schema + + +const joinTablesForSchema = schema => { + const list = []; + + if (schema) { + Object.keys(schema.fields).forEach(field => { + if (schema.fields[field].type === 'Relation') { + list.push(`_Join:${field}:${schema.className}`); + } + }); + } + + return list; +}; + +const buildWhereClause = ({ + schema, + query, + index, + caseInsensitive +}) => { + const patterns = []; + let values = []; + const sorts = []; + schema = toPostgresSchema(schema); + + for (const fieldName in query) { + const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; + const initialPatternsLength = patterns.length; + const fieldValue = query[fieldName]; // nothing in the schema, it's gonna blow up + + if (!schema.fields[fieldName]) { + // as it won't exist + if (fieldValue && fieldValue.$exists === false) { + continue; + } + } + + const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch) { + // TODO: Handle querying by _auth_data_provider, authData is stored in authData field + continue; + } else if (caseInsensitive && (fieldName === 'username' || fieldName === 'email')) { + patterns.push(`LOWER($${index}:name) = LOWER($${index + 1})`); + values.push(fieldName, fieldValue); + index += 2; + } else if (fieldName.indexOf('.') >= 0) { + let name = transformDotField(fieldName); + + if (fieldValue === null) { + patterns.push(`$${index}:raw IS NULL`); + values.push(name); + index += 1; + continue; + } else { + if (fieldValue.$in) { + name = transformDotFieldToComponents(fieldName).join('->'); + patterns.push(`($${index}:raw)::jsonb @> $${index + 1}::jsonb`); + values.push(name, JSON.stringify(fieldValue.$in)); + index += 2; + } else if (fieldValue.$regex) {// Handle later + } else if (typeof fieldValue !== 'object') { + patterns.push(`$${index}:raw = $${index + 1}::text`); + values.push(name, fieldValue); + index += 2; + } + } + } else if (fieldValue === null || fieldValue === undefined) { + patterns.push(`$${index}:name IS NULL`); + values.push(fieldName); + index += 1; + continue; + } else if (typeof fieldValue === 'string') { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'boolean') { + patterns.push(`$${index}:name = $${index + 1}`); // Can't cast boolean to double precision + + if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Number') { + // Should always return zero results + const MAX_INT_PLUS_ONE = 9223372036854775808; + values.push(fieldName, MAX_INT_PLUS_ONE); + } else { + values.push(fieldName, fieldValue); + } + + index += 2; + } else if (typeof fieldValue === 'number') { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (['$or', '$nor', '$and'].includes(fieldName)) { + const clauses = []; + const clauseValues = []; + fieldValue.forEach(subQuery => { + const clause = buildWhereClause({ + schema, + query: subQuery, + index, + caseInsensitive + }); + + if (clause.pattern.length > 0) { + clauses.push(clause.pattern); + clauseValues.push(...clause.values); + index += clause.values.length; + } + }); + const orOrAnd = fieldName === '$and' ? ' AND ' : ' OR '; + const not = fieldName === '$nor' ? ' NOT ' : ''; + patterns.push(`${not}(${clauses.join(orOrAnd)})`); + values.push(...clauseValues); + } + + if (fieldValue.$ne !== undefined) { + if (isArrayField) { + fieldValue.$ne = JSON.stringify([fieldValue.$ne]); + patterns.push(`NOT array_contains($${index}:name, $${index + 1})`); + } else { + if (fieldValue.$ne === null) { + patterns.push(`$${index}:name IS NOT NULL`); + values.push(fieldName); + index += 1; + continue; + } else { + // if not null, we need to manually exclude null + if (fieldValue.$ne.__type === 'GeoPoint') { + patterns.push(`($${index}:name <> POINT($${index + 1}, $${index + 2}) OR $${index}:name IS NULL)`); + } else { + if (fieldName.indexOf('.') >= 0) { + const constraintFieldName = transformDotField(fieldName); + patterns.push(`(${constraintFieldName} <> $${index} OR ${constraintFieldName} IS NULL)`); + } else { + patterns.push(`($${index}:name <> $${index + 1} OR $${index}:name IS NULL)`); + } + } + } + } + + if (fieldValue.$ne.__type === 'GeoPoint') { + const point = fieldValue.$ne; + values.push(fieldName, point.longitude, point.latitude); + index += 3; + } else { + // TODO: support arrays + values.push(fieldName, fieldValue.$ne); + index += 2; + } + } + + if (fieldValue.$eq !== undefined) { + if (fieldValue.$eq === null) { + patterns.push(`$${index}:name IS NULL`); + values.push(fieldName); + index += 1; + } else { + if (fieldName.indexOf('.') >= 0) { + values.push(fieldValue.$eq); + patterns.push(`${transformDotField(fieldName)} = $${index++}`); + } else { + values.push(fieldName, fieldValue.$eq); + patterns.push(`$${index}:name = $${index + 1}`); + index += 2; + } + } + } + + const isInOrNin = Array.isArray(fieldValue.$in) || Array.isArray(fieldValue.$nin); + + if (Array.isArray(fieldValue.$in) && isArrayField && schema.fields[fieldName].contents && schema.fields[fieldName].contents.type === 'String') { + const inPatterns = []; + let allowNull = false; + values.push(fieldName); + fieldValue.$in.forEach((listElem, listIndex) => { + if (listElem === null) { + allowNull = true; + } else { + values.push(listElem); + inPatterns.push(`$${index + 1 + listIndex - (allowNull ? 1 : 0)}`); + } + }); + + if (allowNull) { + patterns.push(`($${index}:name IS NULL OR $${index}:name && ARRAY[${inPatterns.join()}])`); + } else { + patterns.push(`$${index}:name && ARRAY[${inPatterns.join()}]`); + } + + index = index + 1 + inPatterns.length; + } else if (isInOrNin) { + var createConstraint = (baseArray, notIn) => { + const not = notIn ? ' NOT ' : ''; + + if (baseArray.length > 0) { + if (isArrayField) { + patterns.push(`${not} array_contains($${index}:name, $${index + 1})`); + values.push(fieldName, JSON.stringify(baseArray)); + index += 2; + } else { + // Handle Nested Dot Notation Above + if (fieldName.indexOf('.') >= 0) { + return; + } + + const inPatterns = []; + values.push(fieldName); + baseArray.forEach((listElem, listIndex) => { + if (listElem != null) { + values.push(listElem); + inPatterns.push(`$${index + 1 + listIndex}`); + } + }); + patterns.push(`$${index}:name ${not} IN (${inPatterns.join()})`); + index = index + 1 + inPatterns.length; + } + } else if (!notIn) { + values.push(fieldName); + patterns.push(`$${index}:name IS NULL`); + index = index + 1; + } else { + // Handle empty array + if (notIn) { + patterns.push('1 = 1'); // Return all values + } else { + patterns.push('1 = 2'); // Return no values + } + } + }; + + if (fieldValue.$in) { + createConstraint(_lodash.default.flatMap(fieldValue.$in, elt => elt), false); + } + + if (fieldValue.$nin) { + createConstraint(_lodash.default.flatMap(fieldValue.$nin, elt => elt), true); + } + } else if (typeof fieldValue.$in !== 'undefined') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $in value'); + } else if (typeof fieldValue.$nin !== 'undefined') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $nin value'); + } + + if (Array.isArray(fieldValue.$all) && isArrayField) { + if (isAnyValueRegexStartsWith(fieldValue.$all)) { + if (!isAllValuesRegexOrNone(fieldValue.$all)) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + fieldValue.$all); + } + + for (let i = 0; i < fieldValue.$all.length; i += 1) { + const value = processRegexPattern(fieldValue.$all[i].$regex); + fieldValue.$all[i] = value.substring(1) + '%'; + } + + patterns.push(`array_contains_all_regex($${index}:name, $${index + 1}::jsonb)`); + } else { + patterns.push(`array_contains_all($${index}:name, $${index + 1}::jsonb)`); + } + + values.push(fieldName, JSON.stringify(fieldValue.$all)); + index += 2; + } else if (Array.isArray(fieldValue.$all)) { + if (fieldValue.$all.length === 1) { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.$all[0].objectId); + index += 2; + } + } + + if (typeof fieldValue.$exists !== 'undefined') { + if (fieldValue.$exists) { + patterns.push(`$${index}:name IS NOT NULL`); + } else { + patterns.push(`$${index}:name IS NULL`); + } + + values.push(fieldName); + index += 1; + } + + if (fieldValue.$containedBy) { + const arr = fieldValue.$containedBy; + + if (!(arr instanceof Array)) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $containedBy: should be an array`); + } + + patterns.push(`$${index}:name <@ $${index + 1}::jsonb`); + values.push(fieldName, JSON.stringify(arr)); + index += 2; + } + + if (fieldValue.$text) { + const search = fieldValue.$text.$search; + let language = 'english'; + + if (typeof search !== 'object') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $search, should be object`); + } + + if (!search.$term || typeof search.$term !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $term, should be string`); + } + + if (search.$language && typeof search.$language !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $language, should be string`); + } else if (search.$language) { + language = search.$language; + } + + if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); + } else if (search.$caseSensitive) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive not supported, please use $regex or create a separate lower case column.`); + } + + if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); + } else if (search.$diacriticSensitive === false) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive - false not supported, install Postgres Unaccent Extension`); + } + + patterns.push(`to_tsvector($${index}, $${index + 1}:name) @@ to_tsquery($${index + 2}, $${index + 3})`); + values.push(language, fieldName, language, search.$term); + index += 4; + } + + if (fieldValue.$nearSphere) { + const point = fieldValue.$nearSphere; + const distance = fieldValue.$maxDistance; + const distanceInKM = distance * 6371 * 1000; + patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); + sorts.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) ASC`); + values.push(fieldName, point.longitude, point.latitude, distanceInKM); + index += 4; + } + + if (fieldValue.$within && fieldValue.$within.$box) { + const box = fieldValue.$within.$box; + const left = box[0].longitude; + const bottom = box[0].latitude; + const right = box[1].longitude; + const top = box[1].latitude; + patterns.push(`$${index}:name::point <@ $${index + 1}::box`); + values.push(fieldName, `((${left}, ${bottom}), (${right}, ${top}))`); + index += 2; + } + + if (fieldValue.$geoWithin && fieldValue.$geoWithin.$centerSphere) { + const centerSphere = fieldValue.$geoWithin.$centerSphere; + + if (!(centerSphere instanceof Array) || centerSphere.length < 2) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); + } // Get point, convert to geo point if necessary and validate + + + let point = centerSphere[0]; + + if (point instanceof Array && point.length === 2) { + point = new _node.default.GeoPoint(point[1], point[0]); + } else if (!GeoPointCoder.isValidJSON(point)) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); + } + + _node.default.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate + + + const distance = centerSphere[1]; + + if (isNaN(distance) || distance < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); + } + + const distanceInKM = distance * 6371 * 1000; + patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); + values.push(fieldName, point.longitude, point.latitude, distanceInKM); + index += 4; + } + + if (fieldValue.$geoWithin && fieldValue.$geoWithin.$polygon) { + const polygon = fieldValue.$geoWithin.$polygon; + let points; + + if (typeof polygon === 'object' && polygon.__type === 'Polygon') { + if (!polygon.coordinates || polygon.coordinates.length < 3) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); + } + + points = polygon.coordinates; + } else if (polygon instanceof Array) { + if (polygon.length < 3) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); + } + + points = polygon; + } else { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); + } + + points = points.map(point => { + if (point instanceof Array && point.length === 2) { + _node.default.GeoPoint._validate(point[1], point[0]); + + return `(${point[0]}, ${point[1]})`; + } + + if (typeof point !== 'object' || point.__type !== 'GeoPoint') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value'); + } else { + _node.default.GeoPoint._validate(point.latitude, point.longitude); + } + + return `(${point.longitude}, ${point.latitude})`; + }).join(', '); + patterns.push(`$${index}:name::point <@ $${index + 1}::polygon`); + values.push(fieldName, `(${points})`); + index += 2; + } + + if (fieldValue.$geoIntersects && fieldValue.$geoIntersects.$point) { + const point = fieldValue.$geoIntersects.$point; + + if (typeof point !== 'object' || point.__type !== 'GeoPoint') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); + } else { + _node.default.GeoPoint._validate(point.latitude, point.longitude); + } + + patterns.push(`$${index}:name::polygon @> $${index + 1}::point`); + values.push(fieldName, `(${point.longitude}, ${point.latitude})`); + index += 2; + } + + if (fieldValue.$regex) { + let regex = fieldValue.$regex; + let operator = '~'; + const opts = fieldValue.$options; + + if (opts) { + if (opts.indexOf('i') >= 0) { + operator = '~*'; + } + + if (opts.indexOf('x') >= 0) { + regex = removeWhiteSpace(regex); + } + } + + const name = transformDotField(fieldName); + regex = processRegexPattern(regex); + patterns.push(`$${index}:raw ${operator} '$${index + 1}:raw'`); + values.push(name, regex); + index += 2; + } + + if (fieldValue.__type === 'Pointer') { + if (isArrayField) { + patterns.push(`array_contains($${index}:name, $${index + 1})`); + values.push(fieldName, JSON.stringify([fieldValue])); + index += 2; + } else { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.objectId); + index += 2; + } + } + + if (fieldValue.__type === 'Date') { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.iso); + index += 2; + } + + if (fieldValue.__type === 'GeoPoint') { + patterns.push(`$${index}:name ~= POINT($${index + 1}, $${index + 2})`); + values.push(fieldName, fieldValue.longitude, fieldValue.latitude); + index += 3; + } + + if (fieldValue.__type === 'Polygon') { + const value = convertPolygonToSQL(fieldValue.coordinates); + patterns.push(`$${index}:name ~= $${index + 1}::polygon`); + values.push(fieldName, value); + index += 2; + } + + Object.keys(ParseToPosgresComparator).forEach(cmp => { + if (fieldValue[cmp] || fieldValue[cmp] === 0) { + const pgComparator = ParseToPosgresComparator[cmp]; + const postgresValue = toPostgresValue(fieldValue[cmp]); + let constraintFieldName; + + if (fieldName.indexOf('.') >= 0) { + let castType; + + switch (typeof postgresValue) { + case 'number': + castType = 'double precision'; + break; + + case 'boolean': + castType = 'boolean'; + break; + + default: + castType = undefined; + } + + constraintFieldName = castType ? `CAST ((${transformDotField(fieldName)}) AS ${castType})` : transformDotField(fieldName); + } else { + constraintFieldName = `$${index++}:name`; + values.push(fieldName); + } + + values.push(postgresValue); + patterns.push(`${constraintFieldName} ${pgComparator} $${index++}`); + } + }); + + if (initialPatternsLength === patterns.length) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support this query type yet ${JSON.stringify(fieldValue)}`); + } + } + + values = values.map(transformValue); + return { + pattern: patterns.join(' AND '), + values, + sorts + }; +}; + +class PostgresStorageAdapter { + // Private + constructor({ + uri, + collectionPrefix = '', + databaseOptions + }) { + this._collectionPrefix = collectionPrefix; + const { + client, + pgp + } = (0, _PostgresClient.createClient)(uri, databaseOptions); + this._client = client; + this._pgp = pgp; + this.canSortOnJoinTables = false; + } //Note that analyze=true will run the query, executing INSERTS, DELETES, etc. + + + createExplainableQuery(query, analyze = false) { + if (analyze) { + return 'EXPLAIN (ANALYZE, FORMAT JSON) ' + query; + } else { + return 'EXPLAIN (FORMAT JSON) ' + query; + } + } + + handleShutdown() { + if (!this._client) { + return; + } + + this._client.$pool.end(); + } + + async _ensureSchemaCollectionExists(conn) { + conn = conn || this._client; + await conn.none('CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )').catch(error => { + if (error.code === PostgresDuplicateRelationError || error.code === PostgresUniqueIndexViolationError || error.code === PostgresDuplicateObjectError) {// Table already exists, must have been created by a different request. Ignore error. + } else { + throw error; + } + }); + } + + async classExists(name) { + return this._client.one('SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)', [name], a => a.exists); + } + + async setClassLevelPermissions(className, CLPs) { + const self = this; + await this._client.task('set-class-level-permissions', async t => { + await self._ensureSchemaCollectionExists(t); + const values = [className, 'schema', 'classLevelPermissions', JSON.stringify(CLPs)]; + await t.none(`UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1`, values); + }); + } + + async setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields, conn) { + conn = conn || this._client; + const self = this; + + if (submittedIndexes === undefined) { + return Promise.resolve(); + } + + if (Object.keys(existingIndexes).length === 0) { + existingIndexes = { + _id_: { + _id: 1 + } + }; + } + + const deletedIndexes = []; + const insertedIndexes = []; + Object.keys(submittedIndexes).forEach(name => { + const field = submittedIndexes[name]; + + if (existingIndexes[name] && field.__op !== 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); + } + + if (!existingIndexes[name] && field.__op === 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); + } + + if (field.__op === 'Delete') { + deletedIndexes.push(name); + delete existingIndexes[name]; + } else { + Object.keys(field).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(fields, key)) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); + } + }); + existingIndexes[name] = field; + insertedIndexes.push({ + key: field, + name + }); + } + }); + await conn.tx('set-indexes-with-schema-format', async t => { + if (insertedIndexes.length > 0) { + await self.createIndexes(className, insertedIndexes, t); + } + + if (deletedIndexes.length > 0) { + await self.dropIndexes(className, deletedIndexes, t); + } + + await self._ensureSchemaCollectionExists(t); + await t.none('UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1', [className, 'schema', 'indexes', JSON.stringify(existingIndexes)]); + }); + } + + async createClass(className, schema, conn) { + conn = conn || this._client; + return conn.tx('create-class', async t => { + const q1 = this.createTable(className, schema, t); + const q2 = t.none('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($, $, true)', { + className, + schema + }); + const q3 = this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields, t); // TODO: The test should not verify the returned value, and then + // the method can be simplified, to avoid returning useless stuff. + + return t.batch([q1, q2, q3]); + }).then(() => { + return toParseSchema(schema); + }).catch(err => { + if (err.data[0].result.code === PostgresTransactionAbortedError) { + err = err.data[1].result; + } + + if (err.code === PostgresUniqueIndexViolationError && err.detail.includes(className)) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, `Class ${className} already exists.`); + } + + throw err; + }); + } // Just create a table, do not insert in schema + + + async createTable(className, schema, conn) { + conn = conn || this._client; + const self = this; + debug('createTable', className, schema); + const valuesArray = []; + const patternsArray = []; + const fields = Object.assign({}, schema.fields); + + if (className === '_User') { + fields._email_verify_token_expires_at = { + type: 'Date' + }; + fields._email_verify_token = { + type: 'String' + }; + fields._account_lockout_expires_at = { + type: 'Date' + }; + fields._failed_login_count = { + type: 'Number' + }; + fields._perishable_token = { + type: 'String' + }; + fields._perishable_token_expires_at = { + type: 'Date' + }; + fields._password_changed_at = { + type: 'Date' + }; + fields._password_history = { + type: 'Array' + }; + } + + let index = 2; + const relations = []; + Object.keys(fields).forEach(fieldName => { + const parseType = fields[fieldName]; // Skip when it's a relation + // We'll create the tables later + + if (parseType.type === 'Relation') { + relations.push(fieldName); + return; + } + + if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { + parseType.contents = { + type: 'String' + }; + } + + valuesArray.push(fieldName); + valuesArray.push(parseTypeToPostgresType(parseType)); + patternsArray.push(`$${index}:name $${index + 1}:raw`); + + if (fieldName === 'objectId') { + patternsArray.push(`PRIMARY KEY ($${index}:name)`); + } + + index = index + 2; + }); + const qs = `CREATE TABLE IF NOT EXISTS $1:name (${patternsArray.join()})`; + const values = [className, ...valuesArray]; + debug(qs, values); + return conn.task('create-table', async t => { + try { + await self._ensureSchemaCollectionExists(t); + await t.none(qs, values); + } catch (error) { + if (error.code !== PostgresDuplicateRelationError) { + throw error; + } // ELSE: Table already exists, must have been created by a different request. Ignore the error. + + } + + await t.tx('create-table-tx', tx => { + return tx.batch(relations.map(fieldName => { + return tx.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { + joinTable: `_Join:${fieldName}:${className}` + }); + })); + }); + }); + } + + async schemaUpgrade(className, schema, conn) { + debug('schemaUpgrade', { + className, + schema + }); + conn = conn || this._client; + const self = this; + await conn.tx('schema-upgrade', async t => { + const columns = await t.map('SELECT column_name FROM information_schema.columns WHERE table_name = $', { + className + }, a => a.column_name); + const newColumns = Object.keys(schema.fields).filter(item => columns.indexOf(item) === -1).map(fieldName => self.addFieldIfNotExists(className, fieldName, schema.fields[fieldName], t)); + await t.batch(newColumns); + }); + } + + async addFieldIfNotExists(className, fieldName, type, conn) { + // TODO: Must be revised for invalid logic... + debug('addFieldIfNotExists', { + className, + fieldName, + type + }); + conn = conn || this._client; + const self = this; + await conn.tx('add-field-if-not-exists', async t => { + if (type.type !== 'Relation') { + try { + await t.none('ALTER TABLE $ ADD COLUMN IF NOT EXISTS $ $', { + className, + fieldName, + postgresType: parseTypeToPostgresType(type) + }); + } catch (error) { + if (error.code === PostgresRelationDoesNotExistError) { + return self.createClass(className, { + fields: { + [fieldName]: type + } + }, t); + } + + if (error.code !== PostgresDuplicateColumnError) { + throw error; + } // Column already exists, created by other request. Carry on to see if it's the right type. + + } + } else { + await t.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { + joinTable: `_Join:${fieldName}:${className}` + }); + } + + const result = await t.any('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $ and ("schema"::json->\'fields\'->$) is not null', { + className, + fieldName + }); + + if (result[0]) { + throw 'Attempted to add a field that already exists'; + } else { + const path = `{fields,${fieldName}}`; + await t.none('UPDATE "_SCHEMA" SET "schema"=jsonb_set("schema", $, $) WHERE "className"=$', { + path, + type, + className + }); + } + }); + } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) + // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. + + + async deleteClass(className) { + const operations = [{ + query: `DROP TABLE IF EXISTS $1:name`, + values: [className] + }, { + query: `DELETE FROM "_SCHEMA" WHERE "className" = $1`, + values: [className] + }]; + return this._client.tx(t => t.none(this._pgp.helpers.concat(operations))).then(() => className.indexOf('_Join:') != 0); // resolves with false when _Join table + } // Delete all data known to this adapter. Used for testing. + + + async deleteAllClasses() { + const now = new Date().getTime(); + const helpers = this._pgp.helpers; + debug('deleteAllClasses'); + await this._client.task('delete-all-classes', async t => { + try { + const results = await t.any('SELECT * FROM "_SCHEMA"'); + const joins = results.reduce((list, schema) => { + return list.concat(joinTablesForSchema(schema.schema)); + }, []); + const classes = ['_SCHEMA', '_PushStatus', '_JobStatus', '_JobSchedule', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_Audience', '_Idempotency', ...results.map(result => result.className), ...joins]; + const queries = classes.map(className => ({ + query: 'DROP TABLE IF EXISTS $', + values: { + className + } + })); + await t.tx(tx => tx.none(helpers.concat(queries))); + } catch (error) { + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } // No _SCHEMA collection. Don't delete anything. + + } + }).then(() => { + debug(`deleteAllClasses done in ${new Date().getTime() - now}`); + }); + } // Remove the column and all the data. For Relations, the _Join collection is handled + // specially, this function does not delete _Join columns. It should, however, indicate + // that the relation fields does not exist anymore. In mongo, this means removing it from + // the _SCHEMA collection. There should be no actual data in the collection under the same name + // as the relation column, so it's fine to attempt to delete it. If the fields listed to be + // deleted do not exist, this function should return successfully anyways. Checking for + // attempts to delete non-existent fields is the responsibility of Parse Server. + // This function is not obligated to delete fields atomically. It is given the field + // names in a list so that databases that are capable of deleting fields atomically + // may do so. + // Returns a Promise. + + + async deleteFields(className, schema, fieldNames) { + debug('deleteFields', className, fieldNames); + fieldNames = fieldNames.reduce((list, fieldName) => { + const field = schema.fields[fieldName]; + + if (field.type !== 'Relation') { + list.push(fieldName); + } + + delete schema.fields[fieldName]; + return list; + }, []); + const values = [className, ...fieldNames]; + const columns = fieldNames.map((name, idx) => { + return `$${idx + 2}:name`; + }).join(', DROP COLUMN'); + await this._client.tx('delete-fields', async t => { + await t.none('UPDATE "_SCHEMA" SET "schema" = $ WHERE "className" = $', { + schema, + className + }); + + if (values.length > 1) { + await t.none(`ALTER TABLE $1:name DROP COLUMN IF EXISTS ${columns}`, values); + } + }); + } // Return a promise for all schemas known to this adapter, in Parse format. In case the + // schemas cannot be retrieved, returns a promise that rejects. Requirements for the + // rejection reason are TBD. + + + async getAllClasses() { + const self = this; + return this._client.task('get-all-classes', async t => { + await self._ensureSchemaCollectionExists(t); + return await t.map('SELECT * FROM "_SCHEMA"', null, row => toParseSchema(_objectSpread({ + className: row.className + }, row.schema))); + }); + } // Return a promise for the schema with the given name, in Parse format. If + // this adapter doesn't know about the schema, return a promise that rejects with + // undefined as the reason. + + + async getClass(className) { + debug('getClass', className); + return this._client.any('SELECT * FROM "_SCHEMA" WHERE "className" = $', { + className + }).then(result => { + if (result.length !== 1) { + throw undefined; + } + + return result[0].schema; + }).then(toParseSchema); + } // TODO: remove the mongo format dependency in the return value + + + async createObject(className, schema, object, transactionalSession) { + debug('createObject', className, object); + let columnsArray = []; + const valuesArray = []; + schema = toPostgresSchema(schema); + const geoPoints = {}; + object = handleDotFields(object); + validateKeys(object); + Object.keys(object).forEach(fieldName => { + if (object[fieldName] === null) { + return; + } + + var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch) { + var provider = authDataMatch[1]; + object['authData'] = object['authData'] || {}; + object['authData'][provider] = object[fieldName]; + delete object[fieldName]; + fieldName = 'authData'; + } + + columnsArray.push(fieldName); + + if (!schema.fields[fieldName] && className === '_User') { + if (fieldName === '_email_verify_token' || fieldName === '_failed_login_count' || fieldName === '_perishable_token' || fieldName === '_password_history') { + valuesArray.push(object[fieldName]); + } + + if (fieldName === '_email_verify_token_expires_at') { + if (object[fieldName]) { + valuesArray.push(object[fieldName].iso); + } else { + valuesArray.push(null); + } + } + + if (fieldName === '_account_lockout_expires_at' || fieldName === '_perishable_token_expires_at' || fieldName === '_password_changed_at') { + if (object[fieldName]) { + valuesArray.push(object[fieldName].iso); + } else { + valuesArray.push(null); + } + } + + return; + } + + switch (schema.fields[fieldName].type) { + case 'Date': + if (object[fieldName]) { + valuesArray.push(object[fieldName].iso); + } else { + valuesArray.push(null); + } + + break; + + case 'Pointer': + valuesArray.push(object[fieldName].objectId); + break; + + case 'Array': + if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { + valuesArray.push(object[fieldName]); + } else { + valuesArray.push(JSON.stringify(object[fieldName])); + } + + break; + + case 'Object': + case 'Bytes': + case 'String': + case 'Number': + case 'Boolean': + valuesArray.push(object[fieldName]); + break; + + case 'File': + valuesArray.push(object[fieldName].name); + break; + + case 'Polygon': + { + const value = convertPolygonToSQL(object[fieldName].coordinates); + valuesArray.push(value); + break; + } + + case 'GeoPoint': + // pop the point and process later + geoPoints[fieldName] = object[fieldName]; + columnsArray.pop(); + break; + + default: + throw `Type ${schema.fields[fieldName].type} not supported yet`; + } + }); + columnsArray = columnsArray.concat(Object.keys(geoPoints)); + const initialValues = valuesArray.map((val, index) => { + let termination = ''; + const fieldName = columnsArray[index]; + + if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { + termination = '::text[]'; + } else if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { + termination = '::jsonb'; + } + + return `$${index + 2 + columnsArray.length}${termination}`; + }); + const geoPointsInjects = Object.keys(geoPoints).map(key => { + const value = geoPoints[key]; + valuesArray.push(value.longitude, value.latitude); + const l = valuesArray.length + columnsArray.length; + return `POINT($${l}, $${l + 1})`; + }); + const columnsPattern = columnsArray.map((col, index) => `$${index + 2}:name`).join(); + const valuesPattern = initialValues.concat(geoPointsInjects).join(); + const qs = `INSERT INTO $1:name (${columnsPattern}) VALUES (${valuesPattern})`; + const values = [className, ...columnsArray, ...valuesArray]; + debug(qs, values); + const promise = (transactionalSession ? transactionalSession.t : this._client).none(qs, values).then(() => ({ + ops: [object] + })).catch(error => { + if (error.code === PostgresUniqueIndexViolationError) { + const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + err.underlyingError = error; + + if (error.constraint) { + const matches = error.constraint.match(/unique_([a-zA-Z]+)/); + + if (matches && Array.isArray(matches)) { + err.userInfo = { + duplicated_field: matches[1] + }; + } + } + + error = err; + } + + throw error; + }); + + if (transactionalSession) { + transactionalSession.batch.push(promise); + } + + return promise; + } // Remove all objects that match the given Parse Query. + // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. + // If there is some other error, reject with INTERNAL_SERVER_ERROR. + + + async deleteObjectsByQuery(className, schema, query, transactionalSession) { + debug('deleteObjectsByQuery', className, query); + const values = [className]; + const index = 2; + const where = buildWhereClause({ + schema, + index, + query, + caseInsensitive: false + }); + values.push(...where.values); + + if (Object.keys(query).length === 0) { + where.pattern = 'TRUE'; + } + + const qs = `WITH deleted AS (DELETE FROM $1:name WHERE ${where.pattern} RETURNING *) SELECT count(*) FROM deleted`; + debug(qs, values); + const promise = (transactionalSession ? transactionalSession.t : this._client).one(qs, values, a => +a.count).then(count => { + if (count === 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } else { + return count; + } + }).catch(error => { + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } // ELSE: Don't delete anything if doesn't exist + + }); + + if (transactionalSession) { + transactionalSession.batch.push(promise); + } + + return promise; + } // Return value not currently well specified. + + + async findOneAndUpdate(className, schema, query, update, transactionalSession) { + debug('findOneAndUpdate', className, query, update); + return this.updateObjectsByQuery(className, schema, query, update, transactionalSession).then(val => val[0]); + } // Apply the update to all objects that match the given Parse Query. + + + async updateObjectsByQuery(className, schema, query, update, transactionalSession) { + debug('updateObjectsByQuery', className, query, update); + const updatePatterns = []; + const values = [className]; + let index = 2; + schema = toPostgresSchema(schema); + + const originalUpdate = _objectSpread({}, update); // Set flag for dot notation fields + + + const dotNotationOptions = {}; + Object.keys(update).forEach(fieldName => { + if (fieldName.indexOf('.') > -1) { + const components = fieldName.split('.'); + const first = components.shift(); + dotNotationOptions[first] = true; + } else { + dotNotationOptions[fieldName] = false; + } + }); + update = handleDotFields(update); // Resolve authData first, + // So we don't end up with multiple key updates + + for (const fieldName in update) { + const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch) { + var provider = authDataMatch[1]; + const value = update[fieldName]; + delete update[fieldName]; + update['authData'] = update['authData'] || {}; + update['authData'][provider] = value; + } + } + + for (const fieldName in update) { + const fieldValue = update[fieldName]; // Drop any undefined values. + + if (typeof fieldValue === 'undefined') { + delete update[fieldName]; + } else if (fieldValue === null) { + updatePatterns.push(`$${index}:name = NULL`); + values.push(fieldName); + index += 1; + } else if (fieldName == 'authData') { + // This recursively sets the json_object + // Only 1 level deep + const generate = (jsonb, key, value) => { + return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`; + }; + + const lastKey = `$${index}:name`; + const fieldNameIndex = index; + index += 1; + values.push(fieldName); + const update = Object.keys(fieldValue).reduce((lastKey, key) => { + const str = generate(lastKey, `$${index}::text`, `$${index + 1}::jsonb`); + index += 2; + let value = fieldValue[key]; + + if (value) { + if (value.__op === 'Delete') { + value = null; + } else { + value = JSON.stringify(value); + } + } + + values.push(key, value); + return str; + }, lastKey); + updatePatterns.push(`$${fieldNameIndex}:name = ${update}`); + } else if (fieldValue.__op === 'Increment') { + updatePatterns.push(`$${index}:name = COALESCE($${index}:name, 0) + $${index + 1}`); + values.push(fieldName, fieldValue.amount); + index += 2; + } else if (fieldValue.__op === 'Add') { + updatePatterns.push(`$${index}:name = array_add(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); + values.push(fieldName, JSON.stringify(fieldValue.objects)); + index += 2; + } else if (fieldValue.__op === 'Delete') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, null); + index += 2; + } else if (fieldValue.__op === 'Remove') { + updatePatterns.push(`$${index}:name = array_remove(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); + values.push(fieldName, JSON.stringify(fieldValue.objects)); + index += 2; + } else if (fieldValue.__op === 'AddUnique') { + updatePatterns.push(`$${index}:name = array_add_unique(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); + values.push(fieldName, JSON.stringify(fieldValue.objects)); + index += 2; + } else if (fieldName === 'updatedAt') { + //TODO: stop special casing this. It should check for __type === 'Date' and use .iso + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'string') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'boolean') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (fieldValue.__type === 'Pointer') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.objectId); + index += 2; + } else if (fieldValue.__type === 'Date') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, toPostgresValue(fieldValue)); + index += 2; + } else if (fieldValue instanceof Date) { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (fieldValue.__type === 'File') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, toPostgresValue(fieldValue)); + index += 2; + } else if (fieldValue.__type === 'GeoPoint') { + updatePatterns.push(`$${index}:name = POINT($${index + 1}, $${index + 2})`); + values.push(fieldName, fieldValue.longitude, fieldValue.latitude); + index += 3; + } else if (fieldValue.__type === 'Polygon') { + const value = convertPolygonToSQL(fieldValue.coordinates); + updatePatterns.push(`$${index}:name = $${index + 1}::polygon`); + values.push(fieldName, value); + index += 2; + } else if (fieldValue.__type === 'Relation') {// noop + } else if (typeof fieldValue === 'number') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'object' && schema.fields[fieldName] && schema.fields[fieldName].type === 'Object') { + // Gather keys to increment + const keysToIncrement = Object.keys(originalUpdate).filter(k => { + // choose top level fields that have a delete operation set + // Note that Object.keys is iterating over the **original** update object + // and that some of the keys of the original update could be null or undefined: + // (See the above check `if (fieldValue === null || typeof fieldValue == "undefined")`) + const value = originalUpdate[k]; + return value && value.__op === 'Increment' && k.split('.').length === 2 && k.split('.')[0] === fieldName; + }).map(k => k.split('.')[1]); + let incrementPatterns = ''; + + if (keysToIncrement.length > 0) { + incrementPatterns = ' || ' + keysToIncrement.map(c => { + const amount = fieldValue[c].amount; + return `CONCAT('{"${c}":', COALESCE($${index}:name->>'${c}','0')::int + ${amount}, '}')::jsonb`; + }).join(' || '); // Strip the keys + + keysToIncrement.forEach(key => { + delete fieldValue[key]; + }); + } + + const keysToDelete = Object.keys(originalUpdate).filter(k => { + // choose top level fields that have a delete operation set. + const value = originalUpdate[k]; + return value && value.__op === 'Delete' && k.split('.').length === 2 && k.split('.')[0] === fieldName; + }).map(k => k.split('.')[1]); + const deletePatterns = keysToDelete.reduce((p, c, i) => { + return p + ` - '$${index + 1 + i}:value'`; + }, ''); // Override Object + + let updateObject = "'{}'::jsonb"; + + if (dotNotationOptions[fieldName]) { + // Merge Object + updateObject = `COALESCE($${index}:name, '{}'::jsonb)`; + } + + updatePatterns.push(`$${index}:name = (${updateObject} ${deletePatterns} ${incrementPatterns} || $${index + 1 + keysToDelete.length}::jsonb )`); + values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue)); + index += 2 + keysToDelete.length; + } else if (Array.isArray(fieldValue) && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { + const expectedType = parseTypeToPostgresType(schema.fields[fieldName]); + + if (expectedType === 'text[]') { + updatePatterns.push(`$${index}:name = $${index + 1}::text[]`); + values.push(fieldName, fieldValue); + index += 2; + } else { + updatePatterns.push(`$${index}:name = $${index + 1}::jsonb`); + values.push(fieldName, JSON.stringify(fieldValue)); + index += 2; + } + } else { + debug('Not supported update', fieldName, fieldValue); + return Promise.reject(new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support update ${JSON.stringify(fieldValue)} yet`)); + } + } + + const where = buildWhereClause({ + schema, + index, + query, + caseInsensitive: false + }); + values.push(...where.values); + const whereClause = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + const qs = `UPDATE $1:name SET ${updatePatterns.join()} ${whereClause} RETURNING *`; + debug('update: ', qs, values); + const promise = (transactionalSession ? transactionalSession.t : this._client).any(qs, values); + + if (transactionalSession) { + transactionalSession.batch.push(promise); + } + + return promise; + } // Hopefully, we can get rid of this. It's only used for config and hooks. + + + upsertOneObject(className, schema, query, update, transactionalSession) { + debug('upsertOneObject', { + className, + query, + update + }); + const createValue = Object.assign({}, query, update); + return this.createObject(className, schema, createValue, transactionalSession).catch(error => { + // ignore duplicate value errors as it's upsert + if (error.code !== _node.default.Error.DUPLICATE_VALUE) { + throw error; + } + + return this.findOneAndUpdate(className, schema, query, update, transactionalSession); + }); + } + + find(className, schema, query, { + skip, + limit, + sort, + keys, + caseInsensitive, + explain + }) { + debug('find', className, query, { + skip, + limit, + sort, + keys, + caseInsensitive, + explain + }); + const hasLimit = limit !== undefined; + const hasSkip = skip !== undefined; + let values = [className]; + const where = buildWhereClause({ + schema, + query, + index: 2, + caseInsensitive + }); + values.push(...where.values); + const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + const limitPattern = hasLimit ? `LIMIT $${values.length + 1}` : ''; + + if (hasLimit) { + values.push(limit); + } + + const skipPattern = hasSkip ? `OFFSET $${values.length + 1}` : ''; + + if (hasSkip) { + values.push(skip); + } + + let sortPattern = ''; + + if (sort) { + const sortCopy = sort; + const sorting = Object.keys(sort).map(key => { + const transformKey = transformDotFieldToComponents(key).join('->'); // Using $idx pattern gives: non-integer constant in ORDER BY + + if (sortCopy[key] === 1) { + return `${transformKey} ASC`; + } + + return `${transformKey} DESC`; + }).join(); + sortPattern = sort !== undefined && Object.keys(sort).length > 0 ? `ORDER BY ${sorting}` : ''; + } + + if (where.sorts && Object.keys(where.sorts).length > 0) { + sortPattern = `ORDER BY ${where.sorts.join()}`; + } + + let columns = '*'; + + if (keys) { + // Exclude empty keys + // Replace ACL by it's keys + keys = keys.reduce((memo, key) => { + if (key === 'ACL') { + memo.push('_rperm'); + memo.push('_wperm'); + } else if (key.length > 0) { + memo.push(key); + } + + return memo; + }, []); + columns = keys.map((key, index) => { + if (key === '$score') { + return `ts_rank_cd(to_tsvector($${2}, $${3}:name), to_tsquery($${4}, $${5}), 32) as score`; + } + + return `$${index + values.length + 1}:name`; + }).join(); + values = values.concat(keys); + } + + const originalQuery = `SELECT ${columns} FROM $1:name ${wherePattern} ${sortPattern} ${limitPattern} ${skipPattern}`; + const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; + debug(qs, values); + return this._client.any(qs, values).catch(error => { + // Query on non existing table, don't crash + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } + + return []; + }).then(results => { + if (explain) { + return results; + } + + return results.map(object => this.postgresObjectToParseObject(className, object, schema)); + }); + } // Converts from a postgres-format object to a REST-format object. + // Does not strip out anything based on a lack of authentication. + + + postgresObjectToParseObject(className, object, schema) { + Object.keys(schema.fields).forEach(fieldName => { + if (schema.fields[fieldName].type === 'Pointer' && object[fieldName]) { + object[fieldName] = { + objectId: object[fieldName], + __type: 'Pointer', + className: schema.fields[fieldName].targetClass + }; + } + + if (schema.fields[fieldName].type === 'Relation') { + object[fieldName] = { + __type: 'Relation', + className: schema.fields[fieldName].targetClass + }; + } + + if (object[fieldName] && schema.fields[fieldName].type === 'GeoPoint') { + object[fieldName] = { + __type: 'GeoPoint', + latitude: object[fieldName].y, + longitude: object[fieldName].x + }; + } + + if (object[fieldName] && schema.fields[fieldName].type === 'Polygon') { + let coords = object[fieldName]; + coords = coords.substr(2, coords.length - 4).split('),('); + coords = coords.map(point => { + return [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]; + }); + object[fieldName] = { + __type: 'Polygon', + coordinates: coords + }; + } + + if (object[fieldName] && schema.fields[fieldName].type === 'File') { + object[fieldName] = { + __type: 'File', + name: object[fieldName] + }; + } + }); //TODO: remove this reliance on the mongo format. DB adapter shouldn't know there is a difference between created at and any other date field. + + if (object.createdAt) { + object.createdAt = object.createdAt.toISOString(); + } + + if (object.updatedAt) { + object.updatedAt = object.updatedAt.toISOString(); + } + + if (object.expiresAt) { + object.expiresAt = { + __type: 'Date', + iso: object.expiresAt.toISOString() + }; + } + + if (object._email_verify_token_expires_at) { + object._email_verify_token_expires_at = { + __type: 'Date', + iso: object._email_verify_token_expires_at.toISOString() + }; + } + + if (object._account_lockout_expires_at) { + object._account_lockout_expires_at = { + __type: 'Date', + iso: object._account_lockout_expires_at.toISOString() + }; + } + + if (object._perishable_token_expires_at) { + object._perishable_token_expires_at = { + __type: 'Date', + iso: object._perishable_token_expires_at.toISOString() + }; + } + + if (object._password_changed_at) { + object._password_changed_at = { + __type: 'Date', + iso: object._password_changed_at.toISOString() + }; + } + + for (const fieldName in object) { + if (object[fieldName] === null) { + delete object[fieldName]; + } + + if (object[fieldName] instanceof Date) { + object[fieldName] = { + __type: 'Date', + iso: object[fieldName].toISOString() + }; + } + } + + return object; + } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't + // currently know which fields are nullable and which aren't, we ignore that criteria. + // As such, we shouldn't expose this function to users of parse until we have an out-of-band + // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, + // which is why we use sparse indexes. + + + async ensureUniqueness(className, schema, fieldNames) { + const constraintName = `${className}_unique_${fieldNames.sort().join('_')}`; + const constraintPatterns = fieldNames.map((fieldName, index) => `$${index + 3}:name`); + const qs = `CREATE UNIQUE INDEX IF NOT EXISTS $2:name ON $1:name(${constraintPatterns.join()})`; + return this._client.none(qs, [className, constraintName, ...fieldNames]).catch(error => { + if (error.code === PostgresDuplicateRelationError && error.message.includes(constraintName)) {// Index already exists. Ignore error. + } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(constraintName)) { + // Cast the error into the proper parse error + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + } else { + throw error; + } + }); + } // Executes a count. + + + async count(className, schema, query, readPreference, estimate = true) { + debug('count', className, query, readPreference, estimate); + const values = [className]; + const where = buildWhereClause({ + schema, + query, + index: 2, + caseInsensitive: false + }); + values.push(...where.values); + const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + let qs = ''; + + if (where.pattern.length > 0 || !estimate) { + qs = `SELECT count(*) FROM $1:name ${wherePattern}`; + } else { + qs = 'SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = $1'; + } + + return this._client.one(qs, values, a => { + if (a.approximate_row_count != null) { + return +a.approximate_row_count; + } else { + return +a.count; + } + }).catch(error => { + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } + + return 0; + }); + } + + async distinct(className, schema, query, fieldName) { + debug('distinct', className, query); + let field = fieldName; + let column = fieldName; + const isNested = fieldName.indexOf('.') >= 0; + + if (isNested) { + field = transformDotFieldToComponents(fieldName).join('->'); + column = fieldName.split('.')[0]; + } + + const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; + const isPointerField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; + const values = [field, column, className]; + const where = buildWhereClause({ + schema, + query, + index: 4, + caseInsensitive: false + }); + values.push(...where.values); + const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + const transformer = isArrayField ? 'jsonb_array_elements' : 'ON'; + let qs = `SELECT DISTINCT ${transformer}($1:name) $2:name FROM $3:name ${wherePattern}`; + + if (isNested) { + qs = `SELECT DISTINCT ${transformer}($1:raw) $2:raw FROM $3:name ${wherePattern}`; + } + + debug(qs, values); + return this._client.any(qs, values).catch(error => { + if (error.code === PostgresMissingColumnError) { + return []; + } + + throw error; + }).then(results => { + if (!isNested) { + results = results.filter(object => object[field] !== null); + return results.map(object => { + if (!isPointerField) { + return object[field]; + } + + return { + __type: 'Pointer', + className: schema.fields[fieldName].targetClass, + objectId: object[field] + }; + }); + } + + const child = fieldName.split('.')[1]; + return results.map(object => object[column][child]); + }).then(results => results.map(object => this.postgresObjectToParseObject(className, object, schema))); + } + + async aggregate(className, schema, pipeline, readPreference, hint, explain) { + debug('aggregate', className, pipeline, readPreference, hint, explain); + const values = [className]; + let index = 2; + let columns = []; + let countField = null; + let groupValues = null; + let wherePattern = ''; + let limitPattern = ''; + let skipPattern = ''; + let sortPattern = ''; + let groupPattern = ''; + + for (let i = 0; i < pipeline.length; i += 1) { + const stage = pipeline[i]; + + if (stage.$group) { + for (const field in stage.$group) { + const value = stage.$group[field]; + + if (value === null || value === undefined) { + continue; + } + + if (field === '_id' && typeof value === 'string' && value !== '') { + columns.push(`$${index}:name AS "objectId"`); + groupPattern = `GROUP BY $${index}:name`; + values.push(transformAggregateField(value)); + index += 1; + continue; + } + + if (field === '_id' && typeof value === 'object' && Object.keys(value).length !== 0) { + groupValues = value; + const groupByFields = []; + + for (const alias in value) { + if (typeof value[alias] === 'string' && value[alias]) { + const source = transformAggregateField(value[alias]); + + if (!groupByFields.includes(`"${source}"`)) { + groupByFields.push(`"${source}"`); + } + + values.push(source, alias); + columns.push(`$${index}:name AS $${index + 1}:name`); + index += 2; + } else { + const operation = Object.keys(value[alias])[0]; + const source = transformAggregateField(value[alias][operation]); + + if (mongoAggregateToPostgres[operation]) { + if (!groupByFields.includes(`"${source}"`)) { + groupByFields.push(`"${source}"`); + } + + columns.push(`EXTRACT(${mongoAggregateToPostgres[operation]} FROM $${index}:name AT TIME ZONE 'UTC') AS $${index + 1}:name`); + values.push(source, alias); + index += 2; + } + } + } + + groupPattern = `GROUP BY $${index}:raw`; + values.push(groupByFields.join()); + index += 1; + continue; + } + + if (typeof value === 'object') { + if (value.$sum) { + if (typeof value.$sum === 'string') { + columns.push(`SUM($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$sum), field); + index += 2; + } else { + countField = field; + columns.push(`COUNT(*) AS $${index}:name`); + values.push(field); + index += 1; + } + } + + if (value.$max) { + columns.push(`MAX($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$max), field); + index += 2; + } + + if (value.$min) { + columns.push(`MIN($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$min), field); + index += 2; + } + + if (value.$avg) { + columns.push(`AVG($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$avg), field); + index += 2; + } + } + } + } else { + columns.push('*'); + } + + if (stage.$project) { + if (columns.includes('*')) { + columns = []; + } + + for (const field in stage.$project) { + const value = stage.$project[field]; + + if (value === 1 || value === true) { + columns.push(`$${index}:name`); + values.push(field); + index += 1; + } + } + } + + if (stage.$match) { + const patterns = []; + const orOrAnd = Object.prototype.hasOwnProperty.call(stage.$match, '$or') ? ' OR ' : ' AND '; + + if (stage.$match.$or) { + const collapse = {}; + stage.$match.$or.forEach(element => { + for (const key in element) { + collapse[key] = element[key]; + } + }); + stage.$match = collapse; + } + + for (const field in stage.$match) { + const value = stage.$match[field]; + const matchPatterns = []; + Object.keys(ParseToPosgresComparator).forEach(cmp => { + if (value[cmp]) { + const pgComparator = ParseToPosgresComparator[cmp]; + matchPatterns.push(`$${index}:name ${pgComparator} $${index + 1}`); + values.push(field, toPostgresValue(value[cmp])); + index += 2; + } + }); + + if (matchPatterns.length > 0) { + patterns.push(`(${matchPatterns.join(' AND ')})`); + } + + if (schema.fields[field] && schema.fields[field].type && matchPatterns.length === 0) { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(field, value); + index += 2; + } + } + + wherePattern = patterns.length > 0 ? `WHERE ${patterns.join(` ${orOrAnd} `)}` : ''; + } + + if (stage.$limit) { + limitPattern = `LIMIT $${index}`; + values.push(stage.$limit); + index += 1; + } + + if (stage.$skip) { + skipPattern = `OFFSET $${index}`; + values.push(stage.$skip); + index += 1; + } + + if (stage.$sort) { + const sort = stage.$sort; + const keys = Object.keys(sort); + const sorting = keys.map(key => { + const transformer = sort[key] === 1 ? 'ASC' : 'DESC'; + const order = `$${index}:name ${transformer}`; + index += 1; + return order; + }).join(); + values.push(...keys); + sortPattern = sort !== undefined && sorting.length > 0 ? `ORDER BY ${sorting}` : ''; + } + } + + if (groupPattern) { + columns.forEach((e, i, a) => { + if (e && e.trim() === '*') { + a[i] = ''; + } + }); + } + + const originalQuery = `SELECT ${columns.filter(Boolean).join()} FROM $1:name ${wherePattern} ${skipPattern} ${groupPattern} ${sortPattern} ${limitPattern}`; + const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; + debug(qs, values); + return this._client.any(qs, values).then(a => { + if (explain) { + return a; + } + + const results = a.map(object => this.postgresObjectToParseObject(className, object, schema)); + results.forEach(result => { + if (!Object.prototype.hasOwnProperty.call(result, 'objectId')) { + result.objectId = null; + } + + if (groupValues) { + result.objectId = {}; + + for (const key in groupValues) { + result.objectId[key] = result[key]; + delete result[key]; + } + } + + if (countField) { + result[countField] = parseInt(result[countField], 10); + } + }); + return results; + }); + } + + async performInitialization({ + VolatileClassesSchemas + }) { + // TODO: This method needs to be rewritten to make proper use of connections (@vitaly-t) + debug('performInitialization'); + const promises = VolatileClassesSchemas.map(schema => { + return this.createTable(schema.className, schema).catch(err => { + if (err.code === PostgresDuplicateRelationError || err.code === _node.default.Error.INVALID_CLASS_NAME) { + return Promise.resolve(); + } + + throw err; + }).then(() => this.schemaUpgrade(schema.className, schema)); + }); + return Promise.all(promises).then(() => { + return this._client.tx('perform-initialization', t => { + return t.batch([t.none(_sql.default.misc.jsonObjectSetKeys), t.none(_sql.default.array.add), t.none(_sql.default.array.addUnique), t.none(_sql.default.array.remove), t.none(_sql.default.array.containsAll), t.none(_sql.default.array.containsAllRegex), t.none(_sql.default.array.contains)]); + }); + }).then(data => { + debug(`initializationDone in ${data.duration}`); + }).catch(error => { + /* eslint-disable no-console */ + console.error(error); + }); + } + + async createIndexes(className, indexes, conn) { + return (conn || this._client).tx(t => t.batch(indexes.map(i => { + return t.none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [i.name, className, i.key]); + }))); + } + + async createIndexesIfNeeded(className, fieldName, type, conn) { + await (conn || this._client).none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [fieldName, className, type]); + } + + async dropIndexes(className, indexes, conn) { + const queries = indexes.map(i => ({ + query: 'DROP INDEX $1:name', + values: i + })); + await (conn || this._client).tx(t => t.none(this._pgp.helpers.concat(queries))); + } + + async getIndexes(className) { + const qs = 'SELECT * FROM pg_indexes WHERE tablename = ${className}'; + return this._client.any(qs, { + className + }); + } + + async updateSchemaWithIndexes() { + return Promise.resolve(); + } // Used for testing purposes + + + async updateEstimatedCount(className) { + return this._client.none('ANALYZE $1:name', [className]); + } + + async createTransactionalSession() { + return new Promise(resolve => { + const transactionalSession = {}; + transactionalSession.result = this._client.tx(t => { + transactionalSession.t = t; + transactionalSession.promise = new Promise(resolve => { + transactionalSession.resolve = resolve; + }); + transactionalSession.batch = []; + resolve(transactionalSession); + return transactionalSession.promise; + }); + }); + } + + commitTransactionalSession(transactionalSession) { + transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); + return transactionalSession.result; + } + + abortTransactionalSession(transactionalSession) { + const result = transactionalSession.result.catch(); + transactionalSession.batch.push(Promise.reject()); + transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); + return result; + } + + async ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { + const conn = options.conn !== undefined ? options.conn : this._client; + const defaultIndexName = `parse_default_${fieldNames.sort().join('_')}`; + const indexNameOptions = indexName != null ? { + name: indexName + } : { + name: defaultIndexName + }; + const constraintPatterns = caseInsensitive ? fieldNames.map((fieldName, index) => `lower($${index + 3}:name) varchar_pattern_ops`) : fieldNames.map((fieldName, index) => `$${index + 3}:name`); + const qs = `CREATE INDEX IF NOT EXISTS $1:name ON $2:name (${constraintPatterns.join()})`; + await conn.none(qs, [indexNameOptions.name, className, ...fieldNames]).catch(error => { + if (error.code === PostgresDuplicateRelationError && error.message.includes(indexNameOptions.name)) {// Index already exists. Ignore error. + } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(indexNameOptions.name)) { + // Cast the error into the proper parse error + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + } else { + throw error; + } + }); + } + +} + +exports.PostgresStorageAdapter = PostgresStorageAdapter; + +function convertPolygonToSQL(polygon) { + if (polygon.length < 3) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `Polygon must have at least 3 values`); + } + + if (polygon[0][0] !== polygon[polygon.length - 1][0] || polygon[0][1] !== polygon[polygon.length - 1][1]) { + polygon.push(polygon[0]); + } + + const unique = polygon.filter((item, index, ar) => { + let foundIndex = -1; + + for (let i = 0; i < ar.length; i += 1) { + const pt = ar[i]; + + if (pt[0] === item[0] && pt[1] === item[1]) { + foundIndex = i; + break; + } + } + + return foundIndex === index; + }); + + if (unique.length < 3) { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); + } + + const points = polygon.map(point => { + _node.default.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); + + return `(${point[1]}, ${point[0]})`; + }).join(', '); + return `(${points})`; +} + +function removeWhiteSpace(regex) { + if (!regex.endsWith('\n')) { + regex += '\n'; + } // remove non escaped comments + + + return regex.replace(/([^\\])#.*\n/gim, '$1') // remove lines starting with a comment + .replace(/^#.*\n/gim, '') // remove non escaped whitespace + .replace(/([^\\])\s+/gim, '$1') // remove whitespace at the beginning of a line + .replace(/^\s+/, '').trim(); +} + +function processRegexPattern(s) { + if (s && s.startsWith('^')) { + // regex for startsWith + return '^' + literalizeRegexPart(s.slice(1)); + } else if (s && s.endsWith('$')) { + // regex for endsWith + return literalizeRegexPart(s.slice(0, s.length - 1)) + '$'; + } // regex for contains + + + return literalizeRegexPart(s); +} + +function isStartsWithRegex(value) { + if (!value || typeof value !== 'string' || !value.startsWith('^')) { + return false; + } + + const matches = value.match(/\^\\Q.*\\E/); + return !!matches; +} + +function isAllValuesRegexOrNone(values) { + if (!values || !Array.isArray(values) || values.length === 0) { + return true; + } + + const firstValuesIsRegex = isStartsWithRegex(values[0].$regex); + + if (values.length === 1) { + return firstValuesIsRegex; + } + + for (let i = 1, length = values.length; i < length; ++i) { + if (firstValuesIsRegex !== isStartsWithRegex(values[i].$regex)) { + return false; + } + } + + return true; +} + +function isAnyValueRegexStartsWith(values) { + return values.some(function (value) { + return isStartsWithRegex(value.$regex); + }); +} + +function createLiteralRegex(remaining) { + return remaining.split('').map(c => { + const regex = RegExp('[0-9 ]|\\p{L}', 'u'); // Support all unicode letter chars + + if (c.match(regex) !== null) { + // don't escape alphanumeric characters + return c; + } // escape everything else (single quotes with single quotes, everything else with a backslash) + + + return c === `'` ? `''` : `\\${c}`; + }).join(''); +} + +function literalizeRegexPart(s) { + const matcher1 = /\\Q((?!\\E).*)\\E$/; + const result1 = s.match(matcher1); + + if (result1 && result1.length > 1 && result1.index > -1) { + // process regex that has a beginning and an end specified for the literal text + const prefix = s.substr(0, result1.index); + const remaining = result1[1]; + return literalizeRegexPart(prefix) + createLiteralRegex(remaining); + } // process regex that has a beginning specified for the literal text + + + const matcher2 = /\\Q((?!\\E).*)$/; + const result2 = s.match(matcher2); + + if (result2 && result2.length > 1 && result2.index > -1) { + const prefix = s.substr(0, result2.index); + const remaining = result2[1]; + return literalizeRegexPart(prefix) + createLiteralRegex(remaining); + } // remove all instances of \Q and \E from the remaining text & escape single quotes + + + return s.replace(/([^\\])(\\E)/, '$1').replace(/([^\\])(\\Q)/, '$1').replace(/^\\E/, '').replace(/^\\Q/, '').replace(/([^'])'/, `$1''`).replace(/^'([^'])/, `''$1`); +} + +var GeoPointCoder = { + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; + } + +}; +var _default = PostgresStorageAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvciIsIlBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVPYmplY3RFcnJvciIsIlBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciIsIlBvc3RncmVzVHJhbnNhY3Rpb25BYm9ydGVkRXJyb3IiLCJsb2dnZXIiLCJyZXF1aXJlIiwiZGVidWciLCJhcmdzIiwiYXJndW1lbnRzIiwiY29uY2F0Iiwic2xpY2UiLCJsZW5ndGgiLCJsb2ciLCJnZXRMb2dnZXIiLCJhcHBseSIsInBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlIiwidHlwZSIsImNvbnRlbnRzIiwiSlNPTiIsInN0cmluZ2lmeSIsIlBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvciIsIiRndCIsIiRsdCIsIiRndGUiLCIkbHRlIiwibW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzIiwiJGRheU9mTW9udGgiLCIkZGF5T2ZXZWVrIiwiJGRheU9mWWVhciIsIiRpc29EYXlPZldlZWsiLCIkaXNvV2Vla1llYXIiLCIkaG91ciIsIiRtaW51dGUiLCIkc2Vjb25kIiwiJG1pbGxpc2Vjb25kIiwiJG1vbnRoIiwiJHdlZWsiLCIkeWVhciIsInRvUG9zdGdyZXNWYWx1ZSIsInZhbHVlIiwiX190eXBlIiwiaXNvIiwibmFtZSIsInRyYW5zZm9ybVZhbHVlIiwib2JqZWN0SWQiLCJlbXB0eUNMUFMiLCJPYmplY3QiLCJmcmVlemUiLCJmaW5kIiwiZ2V0IiwiY291bnQiLCJjcmVhdGUiLCJ1cGRhdGUiLCJkZWxldGUiLCJhZGRGaWVsZCIsInByb3RlY3RlZEZpZWxkcyIsImRlZmF1bHRDTFBTIiwidG9QYXJzZVNjaGVtYSIsInNjaGVtYSIsImNsYXNzTmFtZSIsImZpZWxkcyIsIl9oYXNoZWRfcGFzc3dvcmQiLCJfd3Blcm0iLCJfcnBlcm0iLCJjbHBzIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsInRvUG9zdGdyZXNTY2hlbWEiLCJfcGFzc3dvcmRfaGlzdG9yeSIsImhhbmRsZURvdEZpZWxkcyIsIm9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwiZmllbGROYW1lIiwiaW5kZXhPZiIsImNvbXBvbmVudHMiLCJzcGxpdCIsImZpcnN0Iiwic2hpZnQiLCJjdXJyZW50T2JqIiwibmV4dCIsIl9fb3AiLCJ1bmRlZmluZWQiLCJ0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyIsIm1hcCIsImNtcHQiLCJpbmRleCIsInRyYW5zZm9ybURvdEZpZWxkIiwiam9pbiIsInRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkIiwic3Vic3RyIiwidmFsaWRhdGVLZXlzIiwia2V5IiwiaW5jbHVkZXMiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9ORVNURURfS0VZIiwiam9pblRhYmxlc0ZvclNjaGVtYSIsImxpc3QiLCJmaWVsZCIsInB1c2giLCJidWlsZFdoZXJlQ2xhdXNlIiwicXVlcnkiLCJjYXNlSW5zZW5zaXRpdmUiLCJwYXR0ZXJucyIsInZhbHVlcyIsInNvcnRzIiwiaXNBcnJheUZpZWxkIiwiaW5pdGlhbFBhdHRlcm5zTGVuZ3RoIiwiZmllbGRWYWx1ZSIsIiRleGlzdHMiLCJhdXRoRGF0YU1hdGNoIiwibWF0Y2giLCIkaW4iLCIkcmVnZXgiLCJNQVhfSU5UX1BMVVNfT05FIiwiY2xhdXNlcyIsImNsYXVzZVZhbHVlcyIsInN1YlF1ZXJ5IiwiY2xhdXNlIiwicGF0dGVybiIsIm9yT3JBbmQiLCJub3QiLCIkbmUiLCJjb25zdHJhaW50RmllbGROYW1lIiwicG9pbnQiLCJsb25naXR1ZGUiLCJsYXRpdHVkZSIsIiRlcSIsImlzSW5Pck5pbiIsIkFycmF5IiwiaXNBcnJheSIsIiRuaW4iLCJpblBhdHRlcm5zIiwiYWxsb3dOdWxsIiwibGlzdEVsZW0iLCJsaXN0SW5kZXgiLCJjcmVhdGVDb25zdHJhaW50IiwiYmFzZUFycmF5Iiwibm90SW4iLCJfIiwiZmxhdE1hcCIsImVsdCIsIklOVkFMSURfSlNPTiIsIiRhbGwiLCJpc0FueVZhbHVlUmVnZXhTdGFydHNXaXRoIiwiaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSIsImkiLCJwcm9jZXNzUmVnZXhQYXR0ZXJuIiwic3Vic3RyaW5nIiwiJGNvbnRhaW5lZEJ5IiwiYXJyIiwiJHRleHQiLCJzZWFyY2giLCIkc2VhcmNoIiwibGFuZ3VhZ2UiLCIkdGVybSIsIiRsYW5ndWFnZSIsIiRjYXNlU2Vuc2l0aXZlIiwiJGRpYWNyaXRpY1NlbnNpdGl2ZSIsIiRuZWFyU3BoZXJlIiwiZGlzdGFuY2UiLCIkbWF4RGlzdGFuY2UiLCJkaXN0YW5jZUluS00iLCIkd2l0aGluIiwiJGJveCIsImJveCIsImxlZnQiLCJib3R0b20iLCJyaWdodCIsInRvcCIsIiRnZW9XaXRoaW4iLCIkY2VudGVyU3BoZXJlIiwiY2VudGVyU3BoZXJlIiwiR2VvUG9pbnQiLCJHZW9Qb2ludENvZGVyIiwiaXNWYWxpZEpTT04iLCJfdmFsaWRhdGUiLCJpc05hTiIsIiRwb2x5Z29uIiwicG9seWdvbiIsInBvaW50cyIsImNvb3JkaW5hdGVzIiwiJGdlb0ludGVyc2VjdHMiLCIkcG9pbnQiLCJyZWdleCIsIm9wZXJhdG9yIiwib3B0cyIsIiRvcHRpb25zIiwicmVtb3ZlV2hpdGVTcGFjZSIsImNvbnZlcnRQb2x5Z29uVG9TUUwiLCJjbXAiLCJwZ0NvbXBhcmF0b3IiLCJwb3N0Z3Jlc1ZhbHVlIiwiY2FzdFR5cGUiLCJPUEVSQVRJT05fRk9SQklEREVOIiwiUG9zdGdyZXNTdG9yYWdlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwidXJpIiwiY29sbGVjdGlvblByZWZpeCIsImRhdGFiYXNlT3B0aW9ucyIsIl9jb2xsZWN0aW9uUHJlZml4IiwiY2xpZW50IiwicGdwIiwiX2NsaWVudCIsIl9wZ3AiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiY3JlYXRlRXhwbGFpbmFibGVRdWVyeSIsImFuYWx5emUiLCJoYW5kbGVTaHV0ZG93biIsIiRwb29sIiwiZW5kIiwiX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHMiLCJjb25uIiwibm9uZSIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiY2xhc3NFeGlzdHMiLCJvbmUiLCJhIiwiZXhpc3RzIiwic2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiQ0xQcyIsInNlbGYiLCJ0YXNrIiwidCIsInNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0Iiwic3VibWl0dGVkSW5kZXhlcyIsImV4aXN0aW5nSW5kZXhlcyIsIlByb21pc2UiLCJyZXNvbHZlIiwiX2lkXyIsIl9pZCIsImRlbGV0ZWRJbmRleGVzIiwiaW5zZXJ0ZWRJbmRleGVzIiwiSU5WQUxJRF9RVUVSWSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR4IiwiY3JlYXRlSW5kZXhlcyIsImRyb3BJbmRleGVzIiwiY3JlYXRlQ2xhc3MiLCJxMSIsImNyZWF0ZVRhYmxlIiwicTIiLCJxMyIsImJhdGNoIiwidGhlbiIsImVyciIsImRhdGEiLCJyZXN1bHQiLCJkZXRhaWwiLCJEVVBMSUNBVEVfVkFMVUUiLCJ2YWx1ZXNBcnJheSIsInBhdHRlcm5zQXJyYXkiLCJhc3NpZ24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJfZW1haWxfdmVyaWZ5X3Rva2VuIiwiX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0IiwiX2ZhaWxlZF9sb2dpbl9jb3VudCIsIl9wZXJpc2hhYmxlX3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCIsIl9wYXNzd29yZF9jaGFuZ2VkX2F0IiwicmVsYXRpb25zIiwicGFyc2VUeXBlIiwicXMiLCJqb2luVGFibGUiLCJzY2hlbWFVcGdyYWRlIiwiY29sdW1ucyIsImNvbHVtbl9uYW1lIiwibmV3Q29sdW1ucyIsImZpbHRlciIsIml0ZW0iLCJhZGRGaWVsZElmTm90RXhpc3RzIiwicG9zdGdyZXNUeXBlIiwiYW55IiwicGF0aCIsImRlbGV0ZUNsYXNzIiwib3BlcmF0aW9ucyIsImhlbHBlcnMiLCJkZWxldGVBbGxDbGFzc2VzIiwibm93IiwiRGF0ZSIsImdldFRpbWUiLCJyZXN1bHRzIiwiam9pbnMiLCJyZWR1Y2UiLCJjbGFzc2VzIiwicXVlcmllcyIsImRlbGV0ZUZpZWxkcyIsImZpZWxkTmFtZXMiLCJpZHgiLCJnZXRBbGxDbGFzc2VzIiwicm93IiwiZ2V0Q2xhc3MiLCJjcmVhdGVPYmplY3QiLCJ0cmFuc2FjdGlvbmFsU2Vzc2lvbiIsImNvbHVtbnNBcnJheSIsImdlb1BvaW50cyIsInByb3ZpZGVyIiwicG9wIiwiaW5pdGlhbFZhbHVlcyIsInZhbCIsInRlcm1pbmF0aW9uIiwiZ2VvUG9pbnRzSW5qZWN0cyIsImwiLCJjb2x1bW5zUGF0dGVybiIsImNvbCIsInZhbHVlc1BhdHRlcm4iLCJwcm9taXNlIiwib3BzIiwidW5kZXJseWluZ0Vycm9yIiwiY29uc3RyYWludCIsIm1hdGNoZXMiLCJ1c2VySW5mbyIsImR1cGxpY2F0ZWRfZmllbGQiLCJkZWxldGVPYmplY3RzQnlRdWVyeSIsIndoZXJlIiwiT0JKRUNUX05PVF9GT1VORCIsImZpbmRPbmVBbmRVcGRhdGUiLCJ1cGRhdGVPYmplY3RzQnlRdWVyeSIsInVwZGF0ZVBhdHRlcm5zIiwib3JpZ2luYWxVcGRhdGUiLCJkb3ROb3RhdGlvbk9wdGlvbnMiLCJnZW5lcmF0ZSIsImpzb25iIiwibGFzdEtleSIsImZpZWxkTmFtZUluZGV4Iiwic3RyIiwiYW1vdW50Iiwib2JqZWN0cyIsImtleXNUb0luY3JlbWVudCIsImsiLCJpbmNyZW1lbnRQYXR0ZXJucyIsImMiLCJrZXlzVG9EZWxldGUiLCJkZWxldGVQYXR0ZXJucyIsInAiLCJ1cGRhdGVPYmplY3QiLCJleHBlY3RlZFR5cGUiLCJyZWplY3QiLCJ3aGVyZUNsYXVzZSIsInVwc2VydE9uZU9iamVjdCIsImNyZWF0ZVZhbHVlIiwic2tpcCIsImxpbWl0Iiwic29ydCIsImV4cGxhaW4iLCJoYXNMaW1pdCIsImhhc1NraXAiLCJ3aGVyZVBhdHRlcm4iLCJsaW1pdFBhdHRlcm4iLCJza2lwUGF0dGVybiIsInNvcnRQYXR0ZXJuIiwic29ydENvcHkiLCJzb3J0aW5nIiwidHJhbnNmb3JtS2V5IiwibWVtbyIsIm9yaWdpbmFsUXVlcnkiLCJwb3N0Z3Jlc09iamVjdFRvUGFyc2VPYmplY3QiLCJ0YXJnZXRDbGFzcyIsInkiLCJ4IiwiY29vcmRzIiwicGFyc2VGbG9hdCIsImNyZWF0ZWRBdCIsInRvSVNPU3RyaW5nIiwidXBkYXRlZEF0IiwiZXhwaXJlc0F0IiwiZW5zdXJlVW5pcXVlbmVzcyIsImNvbnN0cmFpbnROYW1lIiwiY29uc3RyYWludFBhdHRlcm5zIiwibWVzc2FnZSIsInJlYWRQcmVmZXJlbmNlIiwiZXN0aW1hdGUiLCJhcHByb3hpbWF0ZV9yb3dfY291bnQiLCJkaXN0aW5jdCIsImNvbHVtbiIsImlzTmVzdGVkIiwiaXNQb2ludGVyRmllbGQiLCJ0cmFuc2Zvcm1lciIsImNoaWxkIiwiYWdncmVnYXRlIiwicGlwZWxpbmUiLCJoaW50IiwiY291bnRGaWVsZCIsImdyb3VwVmFsdWVzIiwiZ3JvdXBQYXR0ZXJuIiwic3RhZ2UiLCIkZ3JvdXAiLCJncm91cEJ5RmllbGRzIiwiYWxpYXMiLCJzb3VyY2UiLCJvcGVyYXRpb24iLCIkc3VtIiwiJG1heCIsIiRtaW4iLCIkYXZnIiwiJHByb2plY3QiLCIkbWF0Y2giLCIkb3IiLCJjb2xsYXBzZSIsImVsZW1lbnQiLCJtYXRjaFBhdHRlcm5zIiwiJGxpbWl0IiwiJHNraXAiLCIkc29ydCIsIm9yZGVyIiwiZSIsInRyaW0iLCJCb29sZWFuIiwicGFyc2VJbnQiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCJWb2xhdGlsZUNsYXNzZXNTY2hlbWFzIiwicHJvbWlzZXMiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJhbGwiLCJzcWwiLCJtaXNjIiwianNvbk9iamVjdFNldEtleXMiLCJhcnJheSIsImFkZCIsImFkZFVuaXF1ZSIsInJlbW92ZSIsImNvbnRhaW5zQWxsIiwiY29udGFpbnNBbGxSZWdleCIsImNvbnRhaW5zIiwiZHVyYXRpb24iLCJjb25zb2xlIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZ2V0SW5kZXhlcyIsInVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzIiwidXBkYXRlRXN0aW1hdGVkQ291bnQiLCJjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwib3B0aW9ucyIsImRlZmF1bHRJbmRleE5hbWUiLCJpbmRleE5hbWVPcHRpb25zIiwidW5pcXVlIiwiYXIiLCJmb3VuZEluZGV4IiwicHQiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJlbmRzV2l0aCIsInJlcGxhY2UiLCJzIiwic3RhcnRzV2l0aCIsImxpdGVyYWxpemVSZWdleFBhcnQiLCJpc1N0YXJ0c1dpdGhSZWdleCIsImZpcnN0VmFsdWVzSXNSZWdleCIsInNvbWUiLCJjcmVhdGVMaXRlcmFsUmVnZXgiLCJyZW1haW5pbmciLCJSZWdFeHAiLCJtYXRjaGVyMSIsInJlc3VsdDEiLCJwcmVmaXgiLCJtYXRjaGVyMiIsInJlc3VsdDIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFFQTs7QUFFQTs7QUFDQTs7QUFpQkE7Ozs7Ozs7Ozs7QUFmQSxNQUFNQSxpQ0FBaUMsR0FBRyxPQUExQztBQUNBLE1BQU1DLDhCQUE4QixHQUFHLE9BQXZDO0FBQ0EsTUFBTUMsNEJBQTRCLEdBQUcsT0FBckM7QUFDQSxNQUFNQywwQkFBMEIsR0FBRyxPQUFuQztBQUNBLE1BQU1DLDRCQUE0QixHQUFHLE9BQXJDO0FBQ0EsTUFBTUMsaUNBQWlDLEdBQUcsT0FBMUM7QUFDQSxNQUFNQywrQkFBK0IsR0FBRyxPQUF4Qzs7QUFDQSxNQUFNQyxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxp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R1gsQ0FBQyxDQUFDeFcsTUFBRixDQUFTLENBQVQsRUFBWXFYLE9BQU8sQ0FBQ3pYLEtBQXBCLENBQWY7QUFDQSxVQUFNbVgsU0FBUyxHQUFHTSxPQUFPLENBQUMsQ0FBRCxDQUF6QjtBQUVBLFdBQU9YLG1CQUFtQixDQUFDUyxNQUFELENBQW5CLEdBQThCTCxrQkFBa0IsQ0FBQ0MsU0FBRCxDQUF2RDtBQUNELEdBbkJxQyxDQXFCdEM7OztBQUNBLFNBQU9QLENBQUMsQ0FDTEQsT0FESSxDQUNJLGNBREosRUFDb0IsSUFEcEIsRUFFSkEsT0FGSSxDQUVJLGNBRkosRUFFb0IsSUFGcEIsRUFHSkEsT0FISSxDQUdJLE1BSEosRUFHWSxFQUhaLEVBSUpBLE9BSkksQ0FJSSxNQUpKLEVBSVksRUFKWixFQUtKQSxPQUxJLENBS0ksU0FMSixFQUtnQixNQUxoQixFQU1KQSxPQU5JLENBTUksVUFOSixFQU1pQixNQU5qQixDQUFQO0FBT0Q7O0FBRUQsSUFBSWxSLGFBQWEsR0FBRztBQUNsQkMsRUFBQUEsV0FBVyxDQUFDekksS0FBRCxFQUFRO0FBQ2pCLFdBQ0UsT0FBT0EsS0FBUCxLQUFpQixRQUFqQixJQUE2QkEsS0FBSyxLQUFLLElBQXZDLElBQStDQSxLQUFLLENBQUNDLE1BQU4sS0FBaUIsVUFEbEU7QUFHRDs7QUFMaUIsQ0FBcEI7ZUFRZTRKLHNCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IGNyZWF0ZUNsaWVudCB9IGZyb20gJy4vUG9zdGdyZXNDbGllbnQnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgc3FsIGZyb20gJy4vc3FsJztcblxuY29uc3QgUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yID0gJzQyUDAxJztcbmNvbnN0IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciA9ICc0MlAwNyc7XG5jb25zdCBQb3N0Z3Jlc0R1cGxpY2F0ZUNvbHVtbkVycm9yID0gJzQyNzAxJztcbmNvbnN0IFBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yID0gJzQyNzAzJztcbmNvbnN0IFBvc3RncmVzRHVwbGljYXRlT2JqZWN0RXJyb3IgPSAnNDI3MTAnO1xuY29uc3QgUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yID0gJzIzNTA1JztcbmNvbnN0IFBvc3RncmVzVHJhbnNhY3Rpb25BYm9ydGVkRXJyb3IgPSAnMjVQMDInO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vLi4vbG9nZ2VyJyk7XG5cbmNvbnN0IGRlYnVnID0gZnVuY3Rpb24gKC4uLmFyZ3M6IGFueSkge1xuICBhcmdzID0gWydQRzogJyArIGFyZ3VtZW50c1swXV0uY29uY2F0KGFyZ3Muc2xpY2UoMSwgYXJncy5sZW5ndGgpKTtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmdldExvZ2dlcigpO1xuICBsb2cuZGVidWcuYXBwbHkobG9nLCBhcmdzKTtcbn07XG5cbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gZnJvbSAnLi4vU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHR5cGUgeyBTY2hlbWFUeXBlLCBRdWVyeVR5cGUsIFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcblxuY29uc3QgcGFyc2VUeXBlVG9Qb3N0Z3Jlc1R5cGUgPSB0eXBlID0+IHtcbiAgc3dpdGNoICh0eXBlLnR5cGUpIHtcbiAgICBjYXNlICdTdHJpbmcnOlxuICAgICAgcmV0dXJuICd0ZXh0JztcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiAndGltZXN0YW1wIHdpdGggdGltZSB6b25lJztcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuICdqc29uYic7XG4gICAgY2FzZSAnRmlsZSc6XG4gICAgICByZXR1cm4gJ3RleHQnO1xuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgIHJldHVybiAndGV4dCc7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiAnZG91YmxlIHByZWNpc2lvbic7XG4gICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgcmV0dXJuICdwb2ludCc7XG4gICAgY2FzZSAnQnl0ZXMnOlxuICAgICAgcmV0dXJuICdqc29uYic7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gJ3BvbHlnb24nO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIGlmICh0eXBlLmNvbnRlbnRzICYmIHR5cGUuY29udGVudHMudHlwZSA9PT0gJ1N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuICd0ZXh0W10nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICdqc29uYic7XG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IGBubyB0eXBlIGZvciAke0pTT04uc3RyaW5naWZ5KHR5cGUpfSB5ZXRgO1xuICB9XG59O1xuXG5jb25zdCBQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3IgPSB7XG4gICRndDogJz4nLFxuICAkbHQ6ICc8JyxcbiAgJGd0ZTogJz49JyxcbiAgJGx0ZTogJzw9Jyxcbn07XG5cbmNvbnN0IG1vbmdvQWdncmVnYXRlVG9Qb3N0Z3JlcyA9IHtcbiAgJGRheU9mTW9udGg6ICdEQVknLFxuICAkZGF5T2ZXZWVrOiAnRE9XJyxcbiAgJGRheU9mWWVhcjogJ0RPWScsXG4gICRpc29EYXlPZldlZWs6ICdJU09ET1cnLFxuICAkaXNvV2Vla1llYXI6ICdJU09ZRUFSJyxcbiAgJGhvdXI6ICdIT1VSJyxcbiAgJG1pbnV0ZTogJ01JTlVURScsXG4gICRzZWNvbmQ6ICdTRUNPTkQnLFxuICAkbWlsbGlzZWNvbmQ6ICdNSUxMSVNFQ09ORFMnLFxuICAkbW9udGg6ICdNT05USCcsXG4gICR3ZWVrOiAnV0VFSycsXG4gICR5ZWFyOiAnWUVBUicsXG59O1xuXG5jb25zdCB0b1Bvc3RncmVzVmFsdWUgPSB2YWx1ZSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnKSB7XG4gICAgICByZXR1cm4gdmFsdWUuaXNvO1xuICAgIH1cbiAgICBpZiAodmFsdWUuX190eXBlID09PSAnRmlsZScpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5uYW1lO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1WYWx1ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICByZXR1cm4gdmFsdWUub2JqZWN0SWQ7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuLy8gRHVwbGljYXRlIGZyb20gdGhlbiBtb25nbyBhZGFwdGVyLi4uXG5jb25zdCBlbXB0eUNMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDoge30sXG4gIGdldDoge30sXG4gIGNvdW50OiB7fSxcbiAgY3JlYXRlOiB7fSxcbiAgdXBkYXRlOiB7fSxcbiAgZGVsZXRlOiB7fSxcbiAgYWRkRmllbGQ6IHt9LFxuICBwcm90ZWN0ZWRGaWVsZHM6IHt9LFxufSk7XG5cbmNvbnN0IGRlZmF1bHRDTFBTID0gT2JqZWN0LmZyZWV6ZSh7XG4gIGZpbmQ6IHsgJyonOiB0cnVlIH0sXG4gIGdldDogeyAnKic6IHRydWUgfSxcbiAgY291bnQ6IHsgJyonOiB0cnVlIH0sXG4gIGNyZWF0ZTogeyAnKic6IHRydWUgfSxcbiAgdXBkYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICBkZWxldGU6IHsgJyonOiB0cnVlIH0sXG4gIGFkZEZpZWxkOiB7ICcqJzogdHJ1ZSB9LFxuICBwcm90ZWN0ZWRGaWVsZHM6IHsgJyonOiBbXSB9LFxufSk7XG5cbmNvbnN0IHRvUGFyc2VTY2hlbWEgPSBzY2hlbWEgPT4ge1xuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQ7XG4gIH1cbiAgaWYgKHNjaGVtYS5maWVsZHMpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICB9XG4gIGxldCBjbHBzID0gZGVmYXVsdENMUFM7XG4gIGlmIChzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zKSB7XG4gICAgY2xwcyA9IHsgLi4uZW1wdHlDTFBTLCAuLi5zY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zIH07XG4gIH1cbiAgbGV0IGluZGV4ZXMgPSB7fTtcbiAgaWYgKHNjaGVtYS5pbmRleGVzKSB7XG4gICAgaW5kZXhlcyA9IHsgLi4uc2NoZW1hLmluZGV4ZXMgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNsYXNzTmFtZTogc2NoZW1hLmNsYXNzTmFtZSxcbiAgICBmaWVsZHM6IHNjaGVtYS5maWVsZHMsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBjbHBzLFxuICAgIGluZGV4ZXMsXG4gIH07XG59O1xuXG5jb25zdCB0b1Bvc3RncmVzU2NoZW1hID0gc2NoZW1hID0+IHtcbiAgaWYgKCFzY2hlbWEpIHtcbiAgICByZXR1cm4gc2NoZW1hO1xuICB9XG4gIHNjaGVtYS5maWVsZHMgPSBzY2hlbWEuZmllbGRzIHx8IHt9O1xuICBzY2hlbWEuZmllbGRzLl93cGVybSA9IHsgdHlwZTogJ0FycmF5JywgY29udGVudHM6IHsgdHlwZTogJ1N0cmluZycgfSB9O1xuICBzY2hlbWEuZmllbGRzLl9ycGVybSA9IHsgdHlwZTogJ0FycmF5JywgY29udGVudHM6IHsgdHlwZTogJ1N0cmluZycgfSB9O1xuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZCA9IHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICBzY2hlbWEuZmllbGRzLl9wYXNzd29yZF9oaXN0b3J5ID0geyB0eXBlOiAnQXJyYXknIH07XG4gIH1cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbmNvbnN0IGhhbmRsZURvdEZpZWxkcyA9IG9iamVjdCA9PiB7XG4gIE9iamVjdC5rZXlzKG9iamVjdCkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID4gLTEpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBmaWVsZE5hbWUuc3BsaXQoJy4nKTtcbiAgICAgIGNvbnN0IGZpcnN0ID0gY29tcG9uZW50cy5zaGlmdCgpO1xuICAgICAgb2JqZWN0W2ZpcnN0XSA9IG9iamVjdFtmaXJzdF0gfHwge307XG4gICAgICBsZXQgY3VycmVudE9iaiA9IG9iamVjdFtmaXJzdF07XG4gICAgICBsZXQgbmV4dDtcbiAgICAgIGxldCB2YWx1ZSA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgICAgIHdoaWxlICgobmV4dCA9IGNvbXBvbmVudHMuc2hpZnQoKSkpIHtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgICAgICBjdXJyZW50T2JqW25leHRdID0gY3VycmVudE9ialtuZXh0XSB8fCB7fTtcbiAgICAgICAgaWYgKGNvbXBvbmVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgY3VycmVudE9ialtuZXh0XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRPYmogPSBjdXJyZW50T2JqW25leHRdO1xuICAgICAgfVxuICAgICAgZGVsZXRlIG9iamVjdFtmaWVsZE5hbWVdO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyA9IGZpZWxkTmFtZSA9PiB7XG4gIHJldHVybiBmaWVsZE5hbWUuc3BsaXQoJy4nKS5tYXAoKGNtcHQsIGluZGV4KSA9PiB7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gYFwiJHtjbXB0fVwiYDtcbiAgICB9XG4gICAgcmV0dXJuIGAnJHtjbXB0fSdgO1xuICB9KTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybURvdEZpZWxkID0gZmllbGROYW1lID0+IHtcbiAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPT09IC0xKSB7XG4gICAgcmV0dXJuIGBcIiR7ZmllbGROYW1lfVwiYDtcbiAgfVxuICBjb25zdCBjb21wb25lbnRzID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoZmllbGROYW1lKTtcbiAgbGV0IG5hbWUgPSBjb21wb25lbnRzLnNsaWNlKDAsIGNvbXBvbmVudHMubGVuZ3RoIC0gMSkuam9pbignLT4nKTtcbiAgbmFtZSArPSAnLT4+JyArIGNvbXBvbmVudHNbY29tcG9uZW50cy5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIG5hbWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1BZ2dyZWdhdGVGaWVsZCA9IGZpZWxkTmFtZSA9PiB7XG4gIGlmICh0eXBlb2YgZmllbGROYW1lICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmaWVsZE5hbWU7XG4gIH1cbiAgaWYgKGZpZWxkTmFtZSA9PT0gJyRfY3JlYXRlZF9hdCcpIHtcbiAgICByZXR1cm4gJ2NyZWF0ZWRBdCc7XG4gIH1cbiAgaWYgKGZpZWxkTmFtZSA9PT0gJyRfdXBkYXRlZF9hdCcpIHtcbiAgICByZXR1cm4gJ3VwZGF0ZWRBdCc7XG4gIH1cbiAgcmV0dXJuIGZpZWxkTmFtZS5zdWJzdHIoMSk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUtleXMgPSBvYmplY3QgPT4ge1xuICBpZiAodHlwZW9mIG9iamVjdCA9PSAnb2JqZWN0Jykge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKHR5cGVvZiBvYmplY3Rba2V5XSA9PSAnb2JqZWN0Jykge1xuICAgICAgICB2YWxpZGF0ZUtleXMob2JqZWN0W2tleV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LmluY2x1ZGVzKCckJykgfHwga2V5LmluY2x1ZGVzKCcuJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfTkVTVEVEX0tFWSxcbiAgICAgICAgICBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbi8vIFJldHVybnMgdGhlIGxpc3Qgb2Ygam9pbiB0YWJsZXMgb24gYSBzY2hlbWFcbmNvbnN0IGpvaW5UYWJsZXNGb3JTY2hlbWEgPSBzY2hlbWEgPT4ge1xuICBjb25zdCBsaXN0ID0gW107XG4gIGlmIChzY2hlbWEpIHtcbiAgICBPYmplY3Qua2V5cyhzY2hlbWEuZmllbGRzKS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGxpc3QucHVzaChgX0pvaW46JHtmaWVsZH06JHtzY2hlbWEuY2xhc3NOYW1lfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBsaXN0O1xufTtcblxuaW50ZXJmYWNlIFdoZXJlQ2xhdXNlIHtcbiAgcGF0dGVybjogc3RyaW5nO1xuICB2YWx1ZXM6IEFycmF5PGFueT47XG4gIHNvcnRzOiBBcnJheTxhbnk+O1xufVxuXG5jb25zdCBidWlsZFdoZXJlQ2xhdXNlID0gKHtcbiAgc2NoZW1hLFxuICBxdWVyeSxcbiAgaW5kZXgsXG4gIGNhc2VJbnNlbnNpdGl2ZSxcbn0pOiBXaGVyZUNsYXVzZSA9PiB7XG4gIGNvbnN0IHBhdHRlcm5zID0gW107XG4gIGxldCB2YWx1ZXMgPSBbXTtcbiAgY29uc3Qgc29ydHMgPSBbXTtcblxuICBzY2hlbWEgPSB0b1Bvc3RncmVzU2NoZW1hKHNjaGVtYSk7XG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgY29uc3QgaXNBcnJheUZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHMgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheSc7XG4gICAgY29uc3QgaW5pdGlhbFBhdHRlcm5zTGVuZ3RoID0gcGF0dGVybnMubGVuZ3RoO1xuICAgIGNvbnN0IGZpZWxkVmFsdWUgPSBxdWVyeVtmaWVsZE5hbWVdO1xuXG4gICAgLy8gbm90aGluZyBpbiB0aGUgc2NoZW1hLCBpdCdzIGdvbm5hIGJsb3cgdXBcbiAgICBpZiAoIXNjaGVtYS5maWVsZHNbZmllbGROYW1lXSkge1xuICAgICAgLy8gYXMgaXQgd29uJ3QgZXhpc3RcbiAgICAgIGlmIChmaWVsZFZhbHVlICYmIGZpZWxkVmFsdWUuJGV4aXN0cyA9PT0gZmFsc2UpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYXV0aERhdGFNYXRjaCA9IGZpZWxkTmFtZS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgIGlmIChhdXRoRGF0YU1hdGNoKSB7XG4gICAgICAvLyBUT0RPOiBIYW5kbGUgcXVlcnlpbmcgYnkgX2F1dGhfZGF0YV9wcm92aWRlciwgYXV0aERhdGEgaXMgc3RvcmVkIGluIGF1dGhEYXRhIGZpZWxkXG4gICAgICBjb250aW51ZTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgY2FzZUluc2Vuc2l0aXZlICYmXG4gICAgICAoZmllbGROYW1lID09PSAndXNlcm5hbWUnIHx8IGZpZWxkTmFtZSA9PT0gJ2VtYWlsJylcbiAgICApIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYExPV0VSKCQke2luZGV4fTpuYW1lKSA9IExPV0VSKCQke2luZGV4ICsgMX0pYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgbGV0IG5hbWUgPSB0cmFuc2Zvcm1Eb3RGaWVsZChmaWVsZE5hbWUpO1xuICAgICAgaWYgKGZpZWxkVmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9OnJhdyBJUyBOVUxMYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKG5hbWUpO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWVsZFZhbHVlLiRpbikge1xuICAgICAgICAgIG5hbWUgPSB0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyhmaWVsZE5hbWUpLmpvaW4oJy0+Jyk7XG4gICAgICAgICAgcGF0dGVybnMucHVzaChgKCQke2luZGV4fTpyYXcpOjpqc29uYiBAPiAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUuJGluKSk7XG4gICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLiRyZWdleCkge1xuICAgICAgICAgIC8vIEhhbmRsZSBsYXRlclxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpyYXcgPSAkJHtpbmRleCArIDF9Ojp0ZXh0YCk7XG4gICAgICAgICAgdmFsdWVzLnB1c2gobmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZSA9PT0gbnVsbCB8fCBmaWVsZFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgIC8vIENhbid0IGNhc3QgYm9vbGVhbiB0byBkb3VibGUgcHJlY2lzaW9uXG4gICAgICBpZiAoXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ051bWJlcidcbiAgICAgICkge1xuICAgICAgICAvLyBTaG91bGQgYWx3YXlzIHJldHVybiB6ZXJvIHJlc3VsdHNcbiAgICAgICAgY29uc3QgTUFYX0lOVF9QTFVTX09ORSA9IDkyMjMzNzIwMzY4NTQ3NzU4MDg7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgTUFYX0lOVF9QTFVTX09ORSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgfVxuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKFsnJG9yJywgJyRub3InLCAnJGFuZCddLmluY2x1ZGVzKGZpZWxkTmFtZSkpIHtcbiAgICAgIGNvbnN0IGNsYXVzZXMgPSBbXTtcbiAgICAgIGNvbnN0IGNsYXVzZVZhbHVlcyA9IFtdO1xuICAgICAgZmllbGRWYWx1ZS5mb3JFYWNoKHN1YlF1ZXJ5ID0+IHtcbiAgICAgICAgY29uc3QgY2xhdXNlID0gYnVpbGRXaGVyZUNsYXVzZSh7XG4gICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgIHF1ZXJ5OiBzdWJRdWVyeSxcbiAgICAgICAgICBpbmRleCxcbiAgICAgICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2xhdXNlLnBhdHRlcm4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNsYXVzZXMucHVzaChjbGF1c2UucGF0dGVybik7XG4gICAgICAgICAgY2xhdXNlVmFsdWVzLnB1c2goLi4uY2xhdXNlLnZhbHVlcyk7XG4gICAgICAgICAgaW5kZXggKz0gY2xhdXNlLnZhbHVlcy5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBvck9yQW5kID0gZmllbGROYW1lID09PSAnJGFuZCcgPyAnIEFORCAnIDogJyBPUiAnO1xuICAgICAgY29uc3Qgbm90ID0gZmllbGROYW1lID09PSAnJG5vcicgPyAnIE5PVCAnIDogJyc7XG5cbiAgICAgIHBhdHRlcm5zLnB1c2goYCR7bm90fSgke2NsYXVzZXMuam9pbihvck9yQW5kKX0pYCk7XG4gICAgICB2YWx1ZXMucHVzaCguLi5jbGF1c2VWYWx1ZXMpO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLiRuZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoaXNBcnJheUZpZWxkKSB7XG4gICAgICAgIGZpZWxkVmFsdWUuJG5lID0gSlNPTi5zdHJpbmdpZnkoW2ZpZWxkVmFsdWUuJG5lXSk7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYE5PVCBhcnJheV9jb250YWlucygkJHtpbmRleH06bmFtZSwgJCR7aW5kZXggKyAxfSlgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWVsZFZhbHVlLiRuZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5PVCBOVUxMYCk7XG4gICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGlmIG5vdCBudWxsLCB3ZSBuZWVkIHRvIG1hbnVhbGx5IGV4Y2x1ZGUgbnVsbFxuICAgICAgICAgIGlmIChmaWVsZFZhbHVlLiRuZS5fX3R5cGUgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgICAgIGAoJCR7aW5kZXh9Om5hbWUgPD4gUE9JTlQoJCR7aW5kZXggKyAxfSwgJCR7XG4gICAgICAgICAgICAgICAgaW5kZXggKyAyXG4gICAgICAgICAgICAgIH0pIE9SICQke2luZGV4fTpuYW1lIElTIE5VTEwpYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50RmllbGROYW1lID0gdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgICAgICAgICBgKCR7Y29uc3RyYWludEZpZWxkTmFtZX0gPD4gJCR7aW5kZXh9IE9SICR7Y29uc3RyYWludEZpZWxkTmFtZX0gSVMgTlVMTClgXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgICAgICAgIGAoJCR7aW5kZXh9Om5hbWUgPD4gJCR7aW5kZXggKyAxfSBPUiAkJHtpbmRleH06bmFtZSBJUyBOVUxMKWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmaWVsZFZhbHVlLiRuZS5fX3R5cGUgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBmaWVsZFZhbHVlLiRuZTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlKTtcbiAgICAgICAgaW5kZXggKz0gMztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IHN1cHBvcnQgYXJyYXlzXG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS4kbmUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZmllbGRWYWx1ZS4kZXEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGZpZWxkVmFsdWUuJGVxID09PSBudWxsKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZFZhbHVlLiRlcSk7XG4gICAgICAgICAgcGF0dGVybnMucHVzaChgJHt0cmFuc2Zvcm1Eb3RGaWVsZChmaWVsZE5hbWUpfSA9ICQke2luZGV4Kyt9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLiRlcSk7XG4gICAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBpc0luT3JOaW4gPVxuICAgICAgQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRpbikgfHwgQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRuaW4pO1xuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kaW4pICYmXG4gICAgICBpc0FycmF5RmllbGQgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5jb250ZW50cyAmJlxuICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLmNvbnRlbnRzLnR5cGUgPT09ICdTdHJpbmcnXG4gICAgKSB7XG4gICAgICBjb25zdCBpblBhdHRlcm5zID0gW107XG4gICAgICBsZXQgYWxsb3dOdWxsID0gZmFsc2U7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgZmllbGRWYWx1ZS4kaW4uZm9yRWFjaCgobGlzdEVsZW0sIGxpc3RJbmRleCkgPT4ge1xuICAgICAgICBpZiAobGlzdEVsZW0gPT09IG51bGwpIHtcbiAgICAgICAgICBhbGxvd051bGwgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGxpc3RFbGVtKTtcbiAgICAgICAgICBpblBhdHRlcm5zLnB1c2goYCQke2luZGV4ICsgMSArIGxpc3RJbmRleCAtIChhbGxvd051bGwgPyAxIDogMCl9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGFsbG93TnVsbCkge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAoJCR7aW5kZXh9Om5hbWUgSVMgTlVMTCBPUiAkJHtpbmRleH06bmFtZSAmJiBBUlJBWVske2luUGF0dGVybnMuam9pbigpfV0pYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgJiYgQVJSQVlbJHtpblBhdHRlcm5zLmpvaW4oKX1dYCk7XG4gICAgICB9XG4gICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgIH0gZWxzZSBpZiAoaXNJbk9yTmluKSB7XG4gICAgICB2YXIgY3JlYXRlQ29uc3RyYWludCA9IChiYXNlQXJyYXksIG5vdEluKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdCA9IG5vdEluID8gJyBOT1QgJyA6ICcnO1xuICAgICAgICBpZiAoYmFzZUFycmF5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpZiAoaXNBcnJheUZpZWxkKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgICAgICBgJHtub3R9IGFycmF5X2NvbnRhaW5zKCQke2luZGV4fTpuYW1lLCAkJHtpbmRleCArIDF9KWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGJhc2VBcnJheSkpO1xuICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSGFuZGxlIE5lc3RlZCBEb3QgTm90YXRpb24gQWJvdmVcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW5QYXR0ZXJucyA9IFtdO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICAgIGJhc2VBcnJheS5mb3JFYWNoKChsaXN0RWxlbSwgbGlzdEluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGlmIChsaXN0RWxlbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2gobGlzdEVsZW0pO1xuICAgICAgICAgICAgICAgIGluUGF0dGVybnMucHVzaChgJCR7aW5kZXggKyAxICsgbGlzdEluZGV4fWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lICR7bm90fSBJTiAoJHtpblBhdHRlcm5zLmpvaW4oKX0pYCk7XG4gICAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghbm90SW4pIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBIYW5kbGUgZW1wdHkgYXJyYXlcbiAgICAgICAgICBpZiAobm90SW4pIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAxJyk7IC8vIFJldHVybiBhbGwgdmFsdWVzXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAyJyk7IC8vIFJldHVybiBubyB2YWx1ZXNcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kaW4pIHtcbiAgICAgICAgY3JlYXRlQ29uc3RyYWludChcbiAgICAgICAgICBfLmZsYXRNYXAoZmllbGRWYWx1ZS4kaW4sIGVsdCA9PiBlbHQpLFxuICAgICAgICAgIGZhbHNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kbmluKSB7XG4gICAgICAgIGNyZWF0ZUNvbnN0cmFpbnQoXG4gICAgICAgICAgXy5mbGF0TWFwKGZpZWxkVmFsdWUuJG5pbiwgZWx0ID0+IGVsdCksXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUuJGluICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCAkaW4gdmFsdWUnKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlLiRuaW4gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkICRuaW4gdmFsdWUnKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRhbGwpICYmIGlzQXJyYXlGaWVsZCkge1xuICAgICAgaWYgKGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICBpZiAoIWlzQWxsVmFsdWVzUmVnZXhPck5vbmUoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICdBbGwgJGFsbCB2YWx1ZXMgbXVzdCBiZSBvZiByZWdleCB0eXBlIG9yIG5vbmU6ICcgKyBmaWVsZFZhbHVlLiRhbGxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZFZhbHVlLiRhbGwubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3NSZWdleFBhdHRlcm4oZmllbGRWYWx1ZS4kYWxsW2ldLiRyZWdleCk7XG4gICAgICAgICAgZmllbGRWYWx1ZS4kYWxsW2ldID0gdmFsdWUuc3Vic3RyaW5nKDEpICsgJyUnO1xuICAgICAgICB9XG4gICAgICAgIHBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgYGFycmF5X2NvbnRhaW5zX2FsbF9yZWdleCgkJHtpbmRleH06bmFtZSwgJCR7aW5kZXggKyAxfTo6anNvbmIpYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgICBgYXJyYXlfY29udGFpbnNfYWxsKCQke2luZGV4fTpuYW1lLCAkJHtpbmRleCArIDF9Ojpqc29uYilgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUuJGFsbCkpO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgaWYgKGZpZWxkVmFsdWUuJGFsbC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS4kYWxsWzBdLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGZpZWxkVmFsdWUuJGV4aXN0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChmaWVsZFZhbHVlLiRleGlzdHMpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgSVMgTk9UIE5VTExgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLiRjb250YWluZWRCeSkge1xuICAgICAgY29uc3QgYXJyID0gZmllbGRWYWx1ZS4kY29udGFpbmVkQnk7XG4gICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICBgYmFkICRjb250YWluZWRCeTogc2hvdWxkIGJlIGFuIGFycmF5YFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA8QCAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShhcnIpKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJHRleHQpIHtcbiAgICAgIGNvbnN0IHNlYXJjaCA9IGZpZWxkVmFsdWUuJHRleHQuJHNlYXJjaDtcbiAgICAgIGxldCBsYW5ndWFnZSA9ICdlbmdsaXNoJztcbiAgICAgIGlmICh0eXBlb2Ygc2VhcmNoICE9PSAnb2JqZWN0Jykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICRzZWFyY2gsIHNob3VsZCBiZSBvYmplY3RgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIXNlYXJjaC4kdGVybSB8fCB0eXBlb2Ygc2VhcmNoLiR0ZXJtICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICR0ZXJtLCBzaG91bGQgYmUgc3RyaW5nYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHNlYXJjaC4kbGFuZ3VhZ2UgJiYgdHlwZW9mIHNlYXJjaC4kbGFuZ3VhZ2UgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGxhbmd1YWdlLCBzaG91bGQgYmUgc3RyaW5nYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGxhbmd1YWdlKSB7XG4gICAgICAgIGxhbmd1YWdlID0gc2VhcmNoLiRsYW5ndWFnZTtcbiAgICAgIH1cbiAgICAgIGlmIChzZWFyY2guJGNhc2VTZW5zaXRpdmUgJiYgdHlwZW9mIHNlYXJjaC4kY2FzZVNlbnNpdGl2ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGNhc2VTZW5zaXRpdmUsIHNob3VsZCBiZSBib29sZWFuYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGNhc2VTZW5zaXRpdmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICBgYmFkICR0ZXh0OiAkY2FzZVNlbnNpdGl2ZSBub3Qgc3VwcG9ydGVkLCBwbGVhc2UgdXNlICRyZWdleCBvciBjcmVhdGUgYSBzZXBhcmF0ZSBsb3dlciBjYXNlIGNvbHVtbi5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICYmXG4gICAgICAgIHR5cGVvZiBzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZSAhPT0gJ2Jvb2xlYW4nXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICBgYmFkICR0ZXh0OiAkZGlhY3JpdGljU2Vuc2l0aXZlLCBzaG91bGQgYmUgYm9vbGVhbmBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRkaWFjcml0aWNTZW5zaXRpdmUgPT09IGZhbHNlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGRpYWNyaXRpY1NlbnNpdGl2ZSAtIGZhbHNlIG5vdCBzdXBwb3J0ZWQsIGluc3RhbGwgUG9zdGdyZXMgVW5hY2NlbnQgRXh0ZW5zaW9uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgYHRvX3RzdmVjdG9yKCQke2luZGV4fSwgJCR7aW5kZXggKyAxfTpuYW1lKSBAQCB0b190c3F1ZXJ5KCQke1xuICAgICAgICAgIGluZGV4ICsgMlxuICAgICAgICB9LCAkJHtpbmRleCArIDN9KWBcbiAgICAgICk7XG4gICAgICB2YWx1ZXMucHVzaChsYW5ndWFnZSwgZmllbGROYW1lLCBsYW5ndWFnZSwgc2VhcmNoLiR0ZXJtKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJG5lYXJTcGhlcmUpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gZmllbGRWYWx1ZS4kbmVhclNwaGVyZTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZmllbGRWYWx1ZS4kbWF4RGlzdGFuY2U7XG4gICAgICBjb25zdCBkaXN0YW5jZUluS00gPSBkaXN0YW5jZSAqIDYzNzEgKiAxMDAwO1xuICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgYFNUX0Rpc3RhbmNlU3BoZXJlKCQke2luZGV4fTpuYW1lOjpnZW9tZXRyeSwgUE9JTlQoJCR7aW5kZXggKyAxfSwgJCR7XG4gICAgICAgICAgaW5kZXggKyAyXG4gICAgICAgIH0pOjpnZW9tZXRyeSkgPD0gJCR7aW5kZXggKyAzfWBcbiAgICAgICk7XG4gICAgICBzb3J0cy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSBBU0NgXG4gICAgICApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlLCBkaXN0YW5jZUluS00pO1xuICAgICAgaW5kZXggKz0gNDtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kd2l0aGluICYmIGZpZWxkVmFsdWUuJHdpdGhpbi4kYm94KSB7XG4gICAgICBjb25zdCBib3ggPSBmaWVsZFZhbHVlLiR3aXRoaW4uJGJveDtcbiAgICAgIGNvbnN0IGxlZnQgPSBib3hbMF0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgYm90dG9tID0gYm94WzBdLmxhdGl0dWRlO1xuICAgICAgY29uc3QgcmlnaHQgPSBib3hbMV0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgdG9wID0gYm94WzFdLmxhdGl0dWRlO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6Ym94YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGAoKCR7bGVmdH0sICR7Ym90dG9tfSksICgke3JpZ2h0fSwgJHt0b3B9KSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJGNlbnRlclNwaGVyZSkge1xuICAgICAgY29uc3QgY2VudGVyU3BoZXJlID0gZmllbGRWYWx1ZS4kZ2VvV2l0aGluLiRjZW50ZXJTcGhlcmU7XG4gICAgICBpZiAoIShjZW50ZXJTcGhlcmUgaW5zdGFuY2VvZiBBcnJheSkgfHwgY2VudGVyU3BoZXJlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgc2hvdWxkIGJlIGFuIGFycmF5IG9mIFBhcnNlLkdlb1BvaW50IGFuZCBkaXN0YW5jZSdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEdldCBwb2ludCwgY29udmVydCB0byBnZW8gcG9pbnQgaWYgbmVjZXNzYXJ5IGFuZCB2YWxpZGF0ZVxuICAgICAgbGV0IHBvaW50ID0gY2VudGVyU3BoZXJlWzBdO1xuICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIHBvaW50ID0gbmV3IFBhcnNlLkdlb1BvaW50KHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICB9IGVsc2UgaWYgKCFHZW9Qb2ludENvZGVyLmlzVmFsaWRKU09OKHBvaW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBnZW8gcG9pbnQgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludC5sYXRpdHVkZSwgcG9pbnQubG9uZ2l0dWRlKTtcbiAgICAgIC8vIEdldCBkaXN0YW5jZSBhbmQgdmFsaWRhdGVcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gY2VudGVyU3BoZXJlWzFdO1xuICAgICAgaWYgKGlzTmFOKGRpc3RhbmNlKSB8fCBkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgZGlzdGFuY2UgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRpc3RhbmNlSW5LTSA9IGRpc3RhbmNlICogNjM3MSAqIDEwMDA7XG4gICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSA8PSAkJHtpbmRleCArIDN9YFxuICAgICAgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZSwgZGlzdGFuY2VJbktNKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb24pIHtcbiAgICAgIGNvbnN0IHBvbHlnb24gPSBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb247XG4gICAgICBsZXQgcG9pbnRzO1xuICAgICAgaWYgKHR5cGVvZiBwb2x5Z29uID09PSAnb2JqZWN0JyAmJiBwb2x5Z29uLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGlmICghcG9seWdvbi5jb29yZGluYXRlcyB8fCBwb2x5Z29uLmNvb3JkaW5hdGVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7IFBvbHlnb24uY29vcmRpbmF0ZXMgc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBsb24vbGF0IHBhaXJzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbi5jb29yZGluYXRlcztcbiAgICAgIH0gZWxzZSBpZiAocG9seWdvbiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgR2VvUG9pbnRzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgXCJiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGJlIFBvbHlnb24gb2JqZWN0IG9yIEFycmF5IG9mIFBhcnNlLkdlb1BvaW50J3NcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcG9pbnRzID0gcG9pbnRzXG4gICAgICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEFycmF5ICYmIHBvaW50Lmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICAgICAgICByZXR1cm4gYCgke3BvaW50WzBdfSwgJHtwb2ludFsxXX0pYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWA7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCcsICcpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6cG9seWdvbmApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBgKCR7cG9pbnRzfSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuICAgIGlmIChmaWVsZFZhbHVlLiRnZW9JbnRlcnNlY3RzICYmIGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50KSB7XG4gICAgICBjb25zdCBwb2ludCA9IGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50O1xuICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ2JhZCAkZ2VvSW50ZXJzZWN0IHZhbHVlOyAkcG9pbnQgc2hvdWxkIGJlIEdlb1BvaW50J1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgfVxuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWU6OnBvbHlnb24gQD4gJCR7aW5kZXggKyAxfTo6cG9pbnRgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWApO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kcmVnZXgpIHtcbiAgICAgIGxldCByZWdleCA9IGZpZWxkVmFsdWUuJHJlZ2V4O1xuICAgICAgbGV0IG9wZXJhdG9yID0gJ34nO1xuICAgICAgY29uc3Qgb3B0cyA9IGZpZWxkVmFsdWUuJG9wdGlvbnM7XG4gICAgICBpZiAob3B0cykge1xuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCdpJykgPj0gMCkge1xuICAgICAgICAgIG9wZXJhdG9yID0gJ34qJztcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCd4JykgPj0gMCkge1xuICAgICAgICAgIHJlZ2V4ID0gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbmFtZSA9IHRyYW5zZm9ybURvdEZpZWxkKGZpZWxkTmFtZSk7XG4gICAgICByZWdleCA9IHByb2Nlc3NSZWdleFBhdHRlcm4ocmVnZXgpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06cmF3ICR7b3BlcmF0b3J9ICckJHtpbmRleCArIDF9OnJhdydgKTtcbiAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIHJlZ2V4KTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIGlmIChpc0FycmF5RmllbGQpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoW2ZpZWxkVmFsdWVdKSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuaXNvKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtpbmRleCArIDJ9KWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmxvbmdpdHVkZSwgZmllbGRWYWx1ZS5sYXRpdHVkZSk7XG4gICAgICBpbmRleCArPSAzO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnZlcnRQb2x5Z29uVG9TUUwoZmllbGRWYWx1ZS5jb29yZGluYXRlcyk7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSAkJHtpbmRleCArIDF9Ojpwb2x5Z29uYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIHZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoUGFyc2VUb1Bvc2dyZXNDb21wYXJhdG9yKS5mb3JFYWNoKGNtcCA9PiB7XG4gICAgICBpZiAoZmllbGRWYWx1ZVtjbXBdIHx8IGZpZWxkVmFsdWVbY21wXSA9PT0gMCkge1xuICAgICAgICBjb25zdCBwZ0NvbXBhcmF0b3IgPSBQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3JbY21wXTtcbiAgICAgICAgY29uc3QgcG9zdGdyZXNWYWx1ZSA9IHRvUG9zdGdyZXNWYWx1ZShmaWVsZFZhbHVlW2NtcF0pO1xuICAgICAgICBsZXQgY29uc3RyYWludEZpZWxkTmFtZTtcbiAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgIGxldCBjYXN0VHlwZTtcbiAgICAgICAgICBzd2l0Y2ggKHR5cGVvZiBwb3N0Z3Jlc1ZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICAgICAgICBjYXN0VHlwZSA9ICdkb3VibGUgcHJlY2lzaW9uJztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSAnYm9vbGVhbic7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0cmFpbnRGaWVsZE5hbWUgPSBjYXN0VHlwZVxuICAgICAgICAgICAgPyBgQ0FTVCAoKCR7dHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKX0pIEFTICR7Y2FzdFR5cGV9KWBcbiAgICAgICAgICAgIDogdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdHJhaW50RmllbGROYW1lID0gYCQke2luZGV4Kyt9Om5hbWVgO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWVzLnB1c2gocG9zdGdyZXNWYWx1ZSk7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCR7Y29uc3RyYWludEZpZWxkTmFtZX0gJHtwZ0NvbXBhcmF0b3J9ICQke2luZGV4Kyt9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoaW5pdGlhbFBhdHRlcm5zTGVuZ3RoID09PSBwYXR0ZXJucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHF1ZXJ5IHR5cGUgeWV0ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgZmllbGRWYWx1ZVxuICAgICAgICApfWBcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHZhbHVlcyA9IHZhbHVlcy5tYXAodHJhbnNmb3JtVmFsdWUpO1xuICByZXR1cm4geyBwYXR0ZXJuOiBwYXR0ZXJucy5qb2luKCcgQU5EICcpLCB2YWx1ZXMsIHNvcnRzIH07XG59O1xuXG5leHBvcnQgY2xhc3MgUG9zdGdyZXNTdG9yYWdlQWRhcHRlciBpbXBsZW1lbnRzIFN0b3JhZ2VBZGFwdGVyIHtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcblxuICAvLyBQcml2YXRlXG4gIF9jb2xsZWN0aW9uUHJlZml4OiBzdHJpbmc7XG4gIF9jbGllbnQ6IGFueTtcbiAgX3BncDogYW55O1xuXG4gIGNvbnN0cnVjdG9yKHsgdXJpLCBjb2xsZWN0aW9uUHJlZml4ID0gJycsIGRhdGFiYXNlT3B0aW9ucyB9OiBhbnkpIHtcbiAgICB0aGlzLl9jb2xsZWN0aW9uUHJlZml4ID0gY29sbGVjdGlvblByZWZpeDtcbiAgICBjb25zdCB7IGNsaWVudCwgcGdwIH0gPSBjcmVhdGVDbGllbnQodXJpLCBkYXRhYmFzZU9wdGlvbnMpO1xuICAgIHRoaXMuX2NsaWVudCA9IGNsaWVudDtcbiAgICB0aGlzLl9wZ3AgPSBwZ3A7XG4gICAgdGhpcy5jYW5Tb3J0T25Kb2luVGFibGVzID0gZmFsc2U7XG4gIH1cblxuICAvL05vdGUgdGhhdCBhbmFseXplPXRydWUgd2lsbCBydW4gdGhlIHF1ZXJ5LCBleGVjdXRpbmcgSU5TRVJUUywgREVMRVRFUywgZXRjLlxuICBjcmVhdGVFeHBsYWluYWJsZVF1ZXJ5KHF1ZXJ5OiBzdHJpbmcsIGFuYWx5emU6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGlmIChhbmFseXplKSB7XG4gICAgICByZXR1cm4gJ0VYUExBSU4gKEFOQUxZWkUsIEZPUk1BVCBKU09OKSAnICsgcXVlcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnRVhQTEFJTiAoRk9STUFUIEpTT04pICcgKyBxdWVyeTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuX2NsaWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9jbGllbnQuJHBvb2wuZW5kKCk7XG4gIH1cblxuICBhc3luYyBfZW5zdXJlU2NoZW1hQ29sbGVjdGlvbkV4aXN0cyhjb25uOiBhbnkpIHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgYXdhaXQgY29ublxuICAgICAgLm5vbmUoXG4gICAgICAgICdDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyBcIl9TQ0hFTUFcIiAoIFwiY2xhc3NOYW1lXCIgdmFyQ2hhcigxMjApLCBcInNjaGVtYVwiIGpzb25iLCBcImlzUGFyc2VDbGFzc1wiIGJvb2wsIFBSSU1BUlkgS0VZIChcImNsYXNzTmFtZVwiKSApJ1xuICAgICAgKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciB8fFxuICAgICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciB8fFxuICAgICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlT2JqZWN0RXJyb3JcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gVGFibGUgYWxyZWFkeSBleGlzdHMsIG11c3QgaGF2ZSBiZWVuIGNyZWF0ZWQgYnkgYSBkaWZmZXJlbnQgcmVxdWVzdC4gSWdub3JlIGVycm9yLlxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNsYXNzRXhpc3RzKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQub25lKFxuICAgICAgJ1NFTEVDVCBFWElTVFMgKFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9uYW1lID0gJDEpJyxcbiAgICAgIFtuYW1lXSxcbiAgICAgIGEgPT4gYS5leGlzdHNcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgc2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nLCBDTFBzOiBhbnkpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBhd2FpdCB0aGlzLl9jbGllbnQudGFzaygnc2V0LWNsYXNzLWxldmVsLXBlcm1pc3Npb25zJywgYXN5bmMgdCA9PiB7XG4gICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgY29uc3QgdmFsdWVzID0gW1xuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICdzY2hlbWEnLFxuICAgICAgICAnY2xhc3NMZXZlbFBlcm1pc3Npb25zJyxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoQ0xQcyksXG4gICAgICBdO1xuICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICBgVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCAkMjpuYW1lID0ganNvbl9vYmplY3Rfc2V0X2tleSgkMjpuYW1lLCAkMzo6dGV4dCwgJDQ6Ompzb25iKSBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDFgLFxuICAgICAgICB2YWx1ZXNcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzdWJtaXR0ZWRJbmRleGVzOiBhbnksXG4gICAgZXhpc3RpbmdJbmRleGVzOiBhbnkgPSB7fSxcbiAgICBmaWVsZHM6IGFueSxcbiAgICBjb25uOiA/YW55XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBpZiAoc3VibWl0dGVkSW5kZXhlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhleGlzdGluZ0luZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdJbmRleGVzID0geyBfaWRfOiB7IF9pZDogMSB9IH07XG4gICAgfVxuICAgIGNvbnN0IGRlbGV0ZWRJbmRleGVzID0gW107XG4gICAgY29uc3QgaW5zZXJ0ZWRJbmRleGVzID0gW107XG4gICAgT2JqZWN0LmtleXMoc3VibWl0dGVkSW5kZXhlcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gc3VibWl0dGVkSW5kZXhlc1tuYW1lXTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgIGBJbmRleCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICBkZWxldGVkSW5kZXhlcy5wdXNoKG5hbWUpO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdJbmRleGVzW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmtleXMoZmllbGQpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmaWVsZHMsIGtleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICAgICAgYEZpZWxkICR7a2V5fSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGFkZCBpbmRleC5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGV4aXN0aW5nSW5kZXhlc1tuYW1lXSA9IGZpZWxkO1xuICAgICAgICBpbnNlcnRlZEluZGV4ZXMucHVzaCh7XG4gICAgICAgICAga2V5OiBmaWVsZCxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBhd2FpdCBjb25uLnR4KCdzZXQtaW5kZXhlcy13aXRoLXNjaGVtYS1mb3JtYXQnLCBhc3luYyB0ID0+IHtcbiAgICAgIGlmIChpbnNlcnRlZEluZGV4ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCBzZWxmLmNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lLCBpbnNlcnRlZEluZGV4ZXMsIHQpO1xuICAgICAgfVxuICAgICAgaWYgKGRlbGV0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgc2VsZi5kcm9wSW5kZXhlcyhjbGFzc05hbWUsIGRlbGV0ZWRJbmRleGVzLCB0KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNlbGYuX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHModCk7XG4gICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICdVUERBVEUgXCJfU0NIRU1BXCIgU0VUICQyOm5hbWUgPSBqc29uX29iamVjdF9zZXRfa2V5KCQyOm5hbWUsICQzOjp0ZXh0LCAkNDo6anNvbmIpIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkMScsXG4gICAgICAgIFtjbGFzc05hbWUsICdzY2hlbWEnLCAnaW5kZXhlcycsIEpTT04uc3RyaW5naWZ5KGV4aXN0aW5nSW5kZXhlcyldXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgY29ubjogP2FueSkge1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICByZXR1cm4gY29ublxuICAgICAgLnR4KCdjcmVhdGUtY2xhc3MnLCBhc3luYyB0ID0+IHtcbiAgICAgICAgY29uc3QgcTEgPSB0aGlzLmNyZWF0ZVRhYmxlKGNsYXNzTmFtZSwgc2NoZW1hLCB0KTtcbiAgICAgICAgY29uc3QgcTIgPSB0Lm5vbmUoXG4gICAgICAgICAgJ0lOU0VSVCBJTlRPIFwiX1NDSEVNQVwiIChcImNsYXNzTmFtZVwiLCBcInNjaGVtYVwiLCBcImlzUGFyc2VDbGFzc1wiKSBWQUxVRVMgKCQ8Y2xhc3NOYW1lPiwgJDxzY2hlbWE+LCB0cnVlKScsXG4gICAgICAgICAgeyBjbGFzc05hbWUsIHNjaGVtYSB9XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHEzID0gdGhpcy5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgc2NoZW1hLmluZGV4ZXMsXG4gICAgICAgICAge30sXG4gICAgICAgICAgc2NoZW1hLmZpZWxkcyxcbiAgICAgICAgICB0XG4gICAgICAgICk7XG4gICAgICAgIC8vIFRPRE86IFRoZSB0ZXN0IHNob3VsZCBub3QgdmVyaWZ5IHRoZSByZXR1cm5lZCB2YWx1ZSwgYW5kIHRoZW5cbiAgICAgICAgLy8gIHRoZSBtZXRob2QgY2FuIGJlIHNpbXBsaWZpZWQsIHRvIGF2b2lkIHJldHVybmluZyB1c2VsZXNzIHN0dWZmLlxuICAgICAgICByZXR1cm4gdC5iYXRjaChbcTEsIHEyLCBxM10pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRvUGFyc2VTY2hlbWEoc2NoZW1hKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgaWYgKGVyci5kYXRhWzBdLnJlc3VsdC5jb2RlID09PSBQb3N0Z3Jlc1RyYW5zYWN0aW9uQWJvcnRlZEVycm9yKSB7XG4gICAgICAgICAgZXJyID0gZXJyLmRhdGFbMV0ucmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlcnIuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yICYmXG4gICAgICAgICAgZXJyLmRldGFpbC5pbmNsdWRlcyhjbGFzc05hbWUpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgIGBDbGFzcyAke2NsYXNzTmFtZX0gYWxyZWFkeSBleGlzdHMuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBKdXN0IGNyZWF0ZSBhIHRhYmxlLCBkbyBub3QgaW5zZXJ0IGluIHNjaGVtYVxuICBhc3luYyBjcmVhdGVUYWJsZShjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBjb25uOiBhbnkpIHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgZGVidWcoJ2NyZWF0ZVRhYmxlJywgY2xhc3NOYW1lLCBzY2hlbWEpO1xuICAgIGNvbnN0IHZhbHVlc0FycmF5ID0gW107XG4gICAgY29uc3QgcGF0dGVybnNBcnJheSA9IFtdO1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5hc3NpZ24oe30sIHNjaGVtYS5maWVsZHMpO1xuICAgIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgIGZpZWxkcy5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSB7IHR5cGU6ICdEYXRlJyB9O1xuICAgICAgZmllbGRzLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gICAgICBmaWVsZHMuX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fZmFpbGVkX2xvZ2luX2NvdW50ID0geyB0eXBlOiAnTnVtYmVyJyB9O1xuICAgICAgZmllbGRzLl9wZXJpc2hhYmxlX3Rva2VuID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgICAgZmllbGRzLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSB7IHR5cGU6ICdEYXRlJyB9O1xuICAgICAgZmllbGRzLl9wYXNzd29yZF9jaGFuZ2VkX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fcGFzc3dvcmRfaGlzdG9yeSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuICAgIH1cbiAgICBsZXQgaW5kZXggPSAyO1xuICAgIGNvbnN0IHJlbGF0aW9ucyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKGZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgY29uc3QgcGFyc2VUeXBlID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAvLyBTa2lwIHdoZW4gaXQncyBhIHJlbGF0aW9uXG4gICAgICAvLyBXZSdsbCBjcmVhdGUgdGhlIHRhYmxlcyBsYXRlclxuICAgICAgaWYgKHBhcnNlVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIHJlbGF0aW9ucy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChbJ19ycGVybScsICdfd3Blcm0nXS5pbmRleE9mKGZpZWxkTmFtZSkgPj0gMCkge1xuICAgICAgICBwYXJzZVR5cGUuY29udGVudHMgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gICAgICB9XG4gICAgICB2YWx1ZXNBcnJheS5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICB2YWx1ZXNBcnJheS5wdXNoKHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHBhcnNlVHlwZSkpO1xuICAgICAgcGF0dGVybnNBcnJheS5wdXNoKGAkJHtpbmRleH06bmFtZSAkJHtpbmRleCArIDF9OnJhd2ApO1xuICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ29iamVjdElkJykge1xuICAgICAgICBwYXR0ZXJuc0FycmF5LnB1c2goYFBSSU1BUlkgS0VZICgkJHtpbmRleH06bmFtZSlgKTtcbiAgICAgIH1cbiAgICAgIGluZGV4ID0gaW5kZXggKyAyO1xuICAgIH0pO1xuICAgIGNvbnN0IHFzID0gYENSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICQxOm5hbWUgKCR7cGF0dGVybnNBcnJheS5qb2luKCl9KWA7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4udmFsdWVzQXJyYXldO1xuXG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgcmV0dXJuIGNvbm4udGFzaygnY3JlYXRlLXRhYmxlJywgYXN5bmMgdCA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgICBhd2FpdCB0Lm5vbmUocXMsIHZhbHVlcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRUxTRTogVGFibGUgYWxyZWFkeSBleGlzdHMsIG11c3QgaGF2ZSBiZWVuIGNyZWF0ZWQgYnkgYSBkaWZmZXJlbnQgcmVxdWVzdC4gSWdub3JlIHRoZSBlcnJvci5cbiAgICAgIH1cbiAgICAgIGF3YWl0IHQudHgoJ2NyZWF0ZS10YWJsZS10eCcsIHR4ID0+IHtcbiAgICAgICAgcmV0dXJuIHR4LmJhdGNoKFxuICAgICAgICAgIHJlbGF0aW9ucy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0eC5ub25lKFxuICAgICAgICAgICAgICAnQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgJDxqb2luVGFibGU6bmFtZT4gKFwicmVsYXRlZElkXCIgdmFyQ2hhcigxMjApLCBcIm93bmluZ0lkXCIgdmFyQ2hhcigxMjApLCBQUklNQVJZIEtFWShcInJlbGF0ZWRJZFwiLCBcIm93bmluZ0lkXCIpICknLFxuICAgICAgICAgICAgICB7IGpvaW5UYWJsZTogYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2NoZW1hVXBncmFkZShjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBjb25uOiBhbnkpIHtcbiAgICBkZWJ1Zygnc2NoZW1hVXBncmFkZScsIHsgY2xhc3NOYW1lLCBzY2hlbWEgfSk7XG4gICAgY29ubiA9IGNvbm4gfHwgdGhpcy5fY2xpZW50O1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgYXdhaXQgY29ubi50eCgnc2NoZW1hLXVwZ3JhZGUnLCBhc3luYyB0ID0+IHtcbiAgICAgIGNvbnN0IGNvbHVtbnMgPSBhd2FpdCB0Lm1hcChcbiAgICAgICAgJ1NFTEVDVCBjb2x1bW5fbmFtZSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIFdIRVJFIHRhYmxlX25hbWUgPSAkPGNsYXNzTmFtZT4nLFxuICAgICAgICB7IGNsYXNzTmFtZSB9LFxuICAgICAgICBhID0+IGEuY29sdW1uX25hbWVcbiAgICAgICk7XG4gICAgICBjb25zdCBuZXdDb2x1bW5zID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcylcbiAgICAgICAgLmZpbHRlcihpdGVtID0+IGNvbHVtbnMuaW5kZXhPZihpdGVtKSA9PT0gLTEpXG4gICAgICAgIC5tYXAoZmllbGROYW1lID0+XG4gICAgICAgICAgc2VsZi5hZGRGaWVsZElmTm90RXhpc3RzKFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLFxuICAgICAgICAgICAgdFxuICAgICAgICAgIClcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgdC5iYXRjaChuZXdDb2x1bW5zKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGFkZEZpZWxkSWZOb3RFeGlzdHMoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgdHlwZTogYW55LFxuICAgIGNvbm46IGFueVxuICApIHtcbiAgICAvLyBUT0RPOiBNdXN0IGJlIHJldmlzZWQgZm9yIGludmFsaWQgbG9naWMuLi5cbiAgICBkZWJ1ZygnYWRkRmllbGRJZk5vdEV4aXN0cycsIHsgY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUgfSk7XG4gICAgY29ubiA9IGNvbm4gfHwgdGhpcy5fY2xpZW50O1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGF3YWl0IGNvbm4udHgoJ2FkZC1maWVsZC1pZi1ub3QtZXhpc3RzJywgYXN5bmMgdCA9PiB7XG4gICAgICBpZiAodHlwZS50eXBlICE9PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAgICAgJ0FMVEVSIFRBQkxFICQ8Y2xhc3NOYW1lOm5hbWU+IEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyAkPGZpZWxkTmFtZTpuYW1lPiAkPHBvc3RncmVzVHlwZTpyYXc+JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBmaWVsZE5hbWUsXG4gICAgICAgICAgICAgIHBvc3RncmVzVHlwZTogcGFyc2VUeXBlVG9Qb3N0Z3Jlc1R5cGUodHlwZSksXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5jcmVhdGVDbGFzcyhcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICB7IGZpZWxkczogeyBbZmllbGROYW1lXTogdHlwZSB9IH0sXG4gICAgICAgICAgICAgIHRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlcnJvci5jb2RlICE9PSBQb3N0Z3Jlc0R1cGxpY2F0ZUNvbHVtbkVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29sdW1uIGFscmVhZHkgZXhpc3RzLCBjcmVhdGVkIGJ5IG90aGVyIHJlcXVlc3QuIENhcnJ5IG9uIHRvIHNlZSBpZiBpdCdzIHRoZSByaWdodCB0eXBlLlxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICAgJ0NSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICQ8am9pblRhYmxlOm5hbWU+IChcInJlbGF0ZWRJZFwiIHZhckNoYXIoMTIwKSwgXCJvd25pbmdJZFwiIHZhckNoYXIoMTIwKSwgUFJJTUFSWSBLRVkoXCJyZWxhdGVkSWRcIiwgXCJvd25pbmdJZFwiKSApJyxcbiAgICAgICAgICB7IGpvaW5UYWJsZTogYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdC5hbnkoXG4gICAgICAgICdTRUxFQ1QgXCJzY2hlbWFcIiBGUk9NIFwiX1NDSEVNQVwiIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkPGNsYXNzTmFtZT4gYW5kIChcInNjaGVtYVwiOjpqc29uLT5cXCdmaWVsZHNcXCctPiQ8ZmllbGROYW1lPikgaXMgbm90IG51bGwnLFxuICAgICAgICB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH1cbiAgICAgICk7XG5cbiAgICAgIGlmIChyZXN1bHRbMF0pIHtcbiAgICAgICAgdGhyb3cgJ0F0dGVtcHRlZCB0byBhZGQgYSBmaWVsZCB0aGF0IGFscmVhZHkgZXhpc3RzJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBge2ZpZWxkcywke2ZpZWxkTmFtZX19YDtcbiAgICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAgICdVUERBVEUgXCJfU0NIRU1BXCIgU0VUIFwic2NoZW1hXCI9anNvbmJfc2V0KFwic2NoZW1hXCIsICQ8cGF0aD4sICQ8dHlwZT4pICBXSEVSRSBcImNsYXNzTmFtZVwiPSQ8Y2xhc3NOYW1lPicsXG4gICAgICAgICAgeyBwYXRoLCB0eXBlLCBjbGFzc05hbWUgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gRHJvcHMgYSBjb2xsZWN0aW9uLiBSZXNvbHZlcyB3aXRoIHRydWUgaWYgaXQgd2FzIGEgUGFyc2UgU2NoZW1hIChlZy4gX1VzZXIsIEN1c3RvbSwgZXRjLilcbiAgLy8gYW5kIHJlc29sdmVzIHdpdGggZmFsc2UgaWYgaXQgd2Fzbid0IChlZy4gYSBqb2luIHRhYmxlKS4gUmVqZWN0cyBpZiBkZWxldGlvbiB3YXMgaW1wb3NzaWJsZS5cbiAgYXN5bmMgZGVsZXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBvcGVyYXRpb25zID0gW1xuICAgICAgeyBxdWVyeTogYERST1AgVEFCTEUgSUYgRVhJU1RTICQxOm5hbWVgLCB2YWx1ZXM6IFtjbGFzc05hbWVdIH0sXG4gICAgICB7XG4gICAgICAgIHF1ZXJ5OiBgREVMRVRFIEZST00gXCJfU0NIRU1BXCIgV0hFUkUgXCJjbGFzc05hbWVcIiA9ICQxYCxcbiAgICAgICAgdmFsdWVzOiBbY2xhc3NOYW1lXSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAudHgodCA9PiB0Lm5vbmUodGhpcy5fcGdwLmhlbHBlcnMuY29uY2F0KG9wZXJhdGlvbnMpKSlcbiAgICAgIC50aGVuKCgpID0+IGNsYXNzTmFtZS5pbmRleE9mKCdfSm9pbjonKSAhPSAwKTsgLy8gcmVzb2x2ZXMgd2l0aCBmYWxzZSB3aGVuIF9Kb2luIHRhYmxlXG4gIH1cblxuICAvLyBEZWxldGUgYWxsIGRhdGEga25vd24gdG8gdGhpcyBhZGFwdGVyLiBVc2VkIGZvciB0ZXN0aW5nLlxuICBhc3luYyBkZWxldGVBbGxDbGFzc2VzKCkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGhlbHBlcnMgPSB0aGlzLl9wZ3AuaGVscGVycztcbiAgICBkZWJ1ZygnZGVsZXRlQWxsQ2xhc3NlcycpO1xuXG4gICAgYXdhaXQgdGhpcy5fY2xpZW50XG4gICAgICAudGFzaygnZGVsZXRlLWFsbC1jbGFzc2VzJywgYXN5bmMgdCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHQuYW55KCdTRUxFQ1QgKiBGUk9NIFwiX1NDSEVNQVwiJyk7XG4gICAgICAgICAgY29uc3Qgam9pbnMgPSByZXN1bHRzLnJlZHVjZSgobGlzdDogQXJyYXk8c3RyaW5nPiwgc2NoZW1hOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0LmNvbmNhdChqb2luVGFibGVzRm9yU2NoZW1hKHNjaGVtYS5zY2hlbWEpKTtcbiAgICAgICAgICB9LCBbXSk7XG4gICAgICAgICAgY29uc3QgY2xhc3NlcyA9IFtcbiAgICAgICAgICAgICdfU0NIRU1BJyxcbiAgICAgICAgICAgICdfUHVzaFN0YXR1cycsXG4gICAgICAgICAgICAnX0pvYlN0YXR1cycsXG4gICAgICAgICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgICAgICAgICdfSG9va3MnLFxuICAgICAgICAgICAgJ19HbG9iYWxDb25maWcnLFxuICAgICAgICAgICAgJ19HcmFwaFFMQ29uZmlnJyxcbiAgICAgICAgICAgICdfQXVkaWVuY2UnLFxuICAgICAgICAgICAgJ19JZGVtcG90ZW5jeScsXG4gICAgICAgICAgICAuLi5yZXN1bHRzLm1hcChyZXN1bHQgPT4gcmVzdWx0LmNsYXNzTmFtZSksXG4gICAgICAgICAgICAuLi5qb2lucyxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0IHF1ZXJpZXMgPSBjbGFzc2VzLm1hcChjbGFzc05hbWUgPT4gKHtcbiAgICAgICAgICAgIHF1ZXJ5OiAnRFJPUCBUQUJMRSBJRiBFWElTVFMgJDxjbGFzc05hbWU6bmFtZT4nLFxuICAgICAgICAgICAgdmFsdWVzOiB7IGNsYXNzTmFtZSB9LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgICBhd2FpdCB0LnR4KHR4ID0+IHR4Lm5vbmUoaGVscGVycy5jb25jYXQocXVlcmllcykpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gTm8gX1NDSEVNQSBjb2xsZWN0aW9uLiBEb24ndCBkZWxldGUgYW55dGhpbmcuXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGRlYnVnKGBkZWxldGVBbGxDbGFzc2VzIGRvbmUgaW4gJHtuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIG5vd31gKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmVtb3ZlIHRoZSBjb2x1bW4gYW5kIGFsbCB0aGUgZGF0YS4gRm9yIFJlbGF0aW9ucywgdGhlIF9Kb2luIGNvbGxlY3Rpb24gaXMgaGFuZGxlZFxuICAvLyBzcGVjaWFsbHksIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgZGVsZXRlIF9Kb2luIGNvbHVtbnMuIEl0IHNob3VsZCwgaG93ZXZlciwgaW5kaWNhdGVcbiAgLy8gdGhhdCB0aGUgcmVsYXRpb24gZmllbGRzIGRvZXMgbm90IGV4aXN0IGFueW1vcmUuIEluIG1vbmdvLCB0aGlzIG1lYW5zIHJlbW92aW5nIGl0IGZyb21cbiAgLy8gdGhlIF9TQ0hFTUEgY29sbGVjdGlvbi4gIFRoZXJlIHNob3VsZCBiZSBubyBhY3R1YWwgZGF0YSBpbiB0aGUgY29sbGVjdGlvbiB1bmRlciB0aGUgc2FtZSBuYW1lXG4gIC8vIGFzIHRoZSByZWxhdGlvbiBjb2x1bW4sIHNvIGl0J3MgZmluZSB0byBhdHRlbXB0IHRvIGRlbGV0ZSBpdC4gSWYgdGhlIGZpZWxkcyBsaXN0ZWQgdG8gYmVcbiAgLy8gZGVsZXRlZCBkbyBub3QgZXhpc3QsIHRoaXMgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBzdWNjZXNzZnVsbHkgYW55d2F5cy4gQ2hlY2tpbmcgZm9yXG4gIC8vIGF0dGVtcHRzIHRvIGRlbGV0ZSBub24tZXhpc3RlbnQgZmllbGRzIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiBQYXJzZSBTZXJ2ZXIuXG5cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBub3Qgb2JsaWdhdGVkIHRvIGRlbGV0ZSBmaWVsZHMgYXRvbWljYWxseS4gSXQgaXMgZ2l2ZW4gdGhlIGZpZWxkXG4gIC8vIG5hbWVzIGluIGEgbGlzdCBzbyB0aGF0IGRhdGFiYXNlcyB0aGF0IGFyZSBjYXBhYmxlIG9mIGRlbGV0aW5nIGZpZWxkcyBhdG9taWNhbGx5XG4gIC8vIG1heSBkbyBzby5cblxuICAvLyBSZXR1cm5zIGEgUHJvbWlzZS5cbiAgYXN5bmMgZGVsZXRlRmllbGRzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBkZWJ1ZygnZGVsZXRlRmllbGRzJywgY2xhc3NOYW1lLCBmaWVsZE5hbWVzKTtcbiAgICBmaWVsZE5hbWVzID0gZmllbGROYW1lcy5yZWR1Y2UoKGxpc3Q6IEFycmF5PHN0cmluZz4sIGZpZWxkTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgIGlmIChmaWVsZC50eXBlICE9PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGxpc3QucHVzaChmaWVsZE5hbWUpO1xuICAgICAgfVxuICAgICAgZGVsZXRlIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IFtjbGFzc05hbWUsIC4uLmZpZWxkTmFtZXNdO1xuICAgIGNvbnN0IGNvbHVtbnMgPSBmaWVsZE5hbWVzXG4gICAgICAubWFwKChuYW1lLCBpZHgpID0+IHtcbiAgICAgICAgcmV0dXJuIGAkJHtpZHggKyAyfTpuYW1lYDtcbiAgICAgIH0pXG4gICAgICAuam9pbignLCBEUk9QIENPTFVNTicpO1xuXG4gICAgYXdhaXQgdGhpcy5fY2xpZW50LnR4KCdkZWxldGUtZmllbGRzJywgYXN5bmMgdCA9PiB7XG4gICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICdVUERBVEUgXCJfU0NIRU1BXCIgU0VUIFwic2NoZW1hXCIgPSAkPHNjaGVtYT4gV0hFUkUgXCJjbGFzc05hbWVcIiA9ICQ8Y2xhc3NOYW1lPicsXG4gICAgICAgIHsgc2NoZW1hLCBjbGFzc05hbWUgfVxuICAgICAgKTtcbiAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICAgYEFMVEVSIFRBQkxFICQxOm5hbWUgRFJPUCBDT0xVTU4gSUYgRVhJU1RTICR7Y29sdW1uc31gLFxuICAgICAgICAgIHZhbHVlc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJuIGEgcHJvbWlzZSBmb3IgYWxsIHNjaGVtYXMga25vd24gdG8gdGhpcyBhZGFwdGVyLCBpbiBQYXJzZSBmb3JtYXQuIEluIGNhc2UgdGhlXG4gIC8vIHNjaGVtYXMgY2Fubm90IGJlIHJldHJpZXZlZCwgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZWplY3RzLiBSZXF1aXJlbWVudHMgZm9yIHRoZVxuICAvLyByZWplY3Rpb24gcmVhc29uIGFyZSBUQkQuXG4gIGFzeW5jIGdldEFsbENsYXNzZXMoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC50YXNrKCdnZXQtYWxsLWNsYXNzZXMnLCBhc3luYyB0ID0+IHtcbiAgICAgIGF3YWl0IHNlbGYuX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHModCk7XG4gICAgICByZXR1cm4gYXdhaXQgdC5tYXAoJ1NFTEVDVCAqIEZST00gXCJfU0NIRU1BXCInLCBudWxsLCByb3cgPT5cbiAgICAgICAgdG9QYXJzZVNjaGVtYSh7IGNsYXNzTmFtZTogcm93LmNsYXNzTmFtZSwgLi4ucm93LnNjaGVtYSB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIHRoZSBzY2hlbWEgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgaW4gUGFyc2UgZm9ybWF0LiBJZlxuICAvLyB0aGlzIGFkYXB0ZXIgZG9lc24ndCBrbm93IGFib3V0IHRoZSBzY2hlbWEsIHJldHVybiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGhcbiAgLy8gdW5kZWZpbmVkIGFzIHRoZSByZWFzb24uXG4gIGFzeW5jIGdldENsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgZGVidWcoJ2dldENsYXNzJywgY2xhc3NOYW1lKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAuYW55KCdTRUxFQ1QgKiBGUk9NIFwiX1NDSEVNQVwiIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkPGNsYXNzTmFtZT4nLCB7XG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0WzBdLnNjaGVtYTtcbiAgICAgIH0pXG4gICAgICAudGhlbih0b1BhcnNlU2NoZW1hKTtcbiAgfVxuXG4gIC8vIFRPRE86IHJlbW92ZSB0aGUgbW9uZ28gZm9ybWF0IGRlcGVuZGVuY3kgaW4gdGhlIHJldHVybiB2YWx1ZVxuICBhc3luYyBjcmVhdGVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIG9iamVjdDogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCdjcmVhdGVPYmplY3QnLCBjbGFzc05hbWUsIG9iamVjdCk7XG4gICAgbGV0IGNvbHVtbnNBcnJheSA9IFtdO1xuICAgIGNvbnN0IHZhbHVlc0FycmF5ID0gW107XG4gICAgc2NoZW1hID0gdG9Qb3N0Z3Jlc1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGdlb1BvaW50cyA9IHt9O1xuXG4gICAgb2JqZWN0ID0gaGFuZGxlRG90RmllbGRzKG9iamVjdCk7XG5cbiAgICB2YWxpZGF0ZUtleXMob2JqZWN0KTtcblxuICAgIE9iamVjdC5rZXlzKG9iamVjdCkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBhdXRoRGF0YU1hdGNoID0gZmllbGROYW1lLm1hdGNoKC9eX2F1dGhfZGF0YV8oW2EtekEtWjAtOV9dKykkLyk7XG4gICAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgICB2YXIgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICBvYmplY3RbJ2F1dGhEYXRhJ10gPSBvYmplY3RbJ2F1dGhEYXRhJ10gfHwge307XG4gICAgICAgIG9iamVjdFsnYXV0aERhdGEnXVtwcm92aWRlcl0gPSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgICAgZGVsZXRlIG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICBmaWVsZE5hbWUgPSAnYXV0aERhdGEnO1xuICAgICAgfVxuXG4gICAgICBjb2x1bW5zQXJyYXkucHVzaChmaWVsZE5hbWUpO1xuICAgICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBmaWVsZE5hbWUgPT09ICdfZW1haWxfdmVyaWZ5X3Rva2VuJyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19mYWlsZWRfbG9naW5fY291bnQnIHx8XG4gICAgICAgICAgZmllbGROYW1lID09PSAnX3BlcmlzaGFibGVfdG9rZW4nIHx8XG4gICAgICAgICAgZmllbGROYW1lID09PSAnX3Bhc3N3b3JkX2hpc3RvcnknXG4gICAgICAgICkge1xuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCcpIHtcbiAgICAgICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0uaXNvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZmllbGROYW1lID09PSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnIHx8XG4gICAgICAgICAgZmllbGROYW1lID09PSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSkge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5pc28pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG51bGwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSkge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5pc28pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG51bGwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5vYmplY3RJZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgICAgICBpZiAoWydfcnBlcm0nLCAnX3dwZXJtJ10uaW5kZXhPZihmaWVsZE5hbWUpID49IDApIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKEpTT04uc3RyaW5naWZ5KG9iamVjdFtmaWVsZE5hbWVdKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdPYmplY3QnOlxuICAgICAgICBjYXNlICdCeXRlcyc6XG4gICAgICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICAgIGNhc2UgJ051bWJlcic6XG4gICAgICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdGaWxlJzpcbiAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdLm5hbWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdQb2x5Z29uJzoge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gY29udmVydFBvbHlnb25Ub1NRTChvYmplY3RbZmllbGROYW1lXS5jb29yZGluYXRlcyk7XG4gICAgICAgICAgdmFsdWVzQXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgICAgIC8vIHBvcCB0aGUgcG9pbnQgYW5kIHByb2Nlc3MgbGF0ZXJcbiAgICAgICAgICBnZW9Qb2ludHNbZmllbGROYW1lXSA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICAgIGNvbHVtbnNBcnJheS5wb3AoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBgVHlwZSAke3NjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlfSBub3Qgc3VwcG9ydGVkIHlldGA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb2x1bW5zQXJyYXkgPSBjb2x1bW5zQXJyYXkuY29uY2F0KE9iamVjdC5rZXlzKGdlb1BvaW50cykpO1xuICAgIGNvbnN0IGluaXRpYWxWYWx1ZXMgPSB2YWx1ZXNBcnJheS5tYXAoKHZhbCwgaW5kZXgpID0+IHtcbiAgICAgIGxldCB0ZXJtaW5hdGlvbiA9ICcnO1xuICAgICAgY29uc3QgZmllbGROYW1lID0gY29sdW1uc0FycmF5W2luZGV4XTtcbiAgICAgIGlmIChbJ19ycGVybScsICdfd3Blcm0nXS5pbmRleE9mKGZpZWxkTmFtZSkgPj0gMCkge1xuICAgICAgICB0ZXJtaW5hdGlvbiA9ICc6OnRleHRbXSc7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheSdcbiAgICAgICkge1xuICAgICAgICB0ZXJtaW5hdGlvbiA9ICc6Ompzb25iJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBgJCR7aW5kZXggKyAyICsgY29sdW1uc0FycmF5Lmxlbmd0aH0ke3Rlcm1pbmF0aW9ufWA7XG4gICAgfSk7XG4gICAgY29uc3QgZ2VvUG9pbnRzSW5qZWN0cyA9IE9iamVjdC5rZXlzKGdlb1BvaW50cykubWFwKGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdlb1BvaW50c1trZXldO1xuICAgICAgdmFsdWVzQXJyYXkucHVzaCh2YWx1ZS5sb25naXR1ZGUsIHZhbHVlLmxhdGl0dWRlKTtcbiAgICAgIGNvbnN0IGwgPSB2YWx1ZXNBcnJheS5sZW5ndGggKyBjb2x1bW5zQXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGBQT0lOVCgkJHtsfSwgJCR7bCArIDF9KWA7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjb2x1bW5zUGF0dGVybiA9IGNvbHVtbnNBcnJheVxuICAgICAgLm1hcCgoY29sLCBpbmRleCkgPT4gYCQke2luZGV4ICsgMn06bmFtZWApXG4gICAgICAuam9pbigpO1xuICAgIGNvbnN0IHZhbHVlc1BhdHRlcm4gPSBpbml0aWFsVmFsdWVzLmNvbmNhdChnZW9Qb2ludHNJbmplY3RzKS5qb2luKCk7XG5cbiAgICBjb25zdCBxcyA9IGBJTlNFUlQgSU5UTyAkMTpuYW1lICgke2NvbHVtbnNQYXR0ZXJufSkgVkFMVUVTICgke3ZhbHVlc1BhdHRlcm59KWA7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4uY29sdW1uc0FycmF5LCAuLi52YWx1ZXNBcnJheV07XG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgPyB0cmFuc2FjdGlvbmFsU2Vzc2lvbi50XG4gICAgICA6IHRoaXMuX2NsaWVudFxuICAgIClcbiAgICAgIC5ub25lKHFzLCB2YWx1ZXMpXG4gICAgICAudGhlbigoKSA9PiAoeyBvcHM6IFtvYmplY3RdIH0pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvcikge1xuICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgZXJyLnVuZGVybHlpbmdFcnJvciA9IGVycm9yO1xuICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50KSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gZXJyb3IuY29uc3RyYWludC5tYXRjaCgvdW5pcXVlXyhbYS16QS1aXSspLyk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBBcnJheS5pc0FycmF5KG1hdGNoZXMpKSB7XG4gICAgICAgICAgICAgIGVyci51c2VySW5mbyA9IHsgZHVwbGljYXRlZF9maWVsZDogbWF0Y2hlc1sxXSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBlcnJvciA9IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICAgIGlmICh0cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChwcm9taXNlKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICAvLyBSZW1vdmUgYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIC8vIElmIG5vIG9iamVjdHMgbWF0Y2gsIHJlamVjdCB3aXRoIE9CSkVDVF9OT1RfRk9VTkQuIElmIG9iamVjdHMgYXJlIGZvdW5kIGFuZCBkZWxldGVkLCByZXNvbHZlIHdpdGggdW5kZWZpbmVkLlxuICAvLyBJZiB0aGVyZSBpcyBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBJTlRFUk5BTF9TRVJWRVJfRVJST1IuXG4gIGFzeW5jIGRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCdkZWxldGVPYmplY3RzQnlRdWVyeScsIGNsYXNzTmFtZSwgcXVlcnkpO1xuICAgIGNvbnN0IHZhbHVlcyA9IFtjbGFzc05hbWVdO1xuICAgIGNvbnN0IGluZGV4ID0gMjtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgaW5kZXgsXG4gICAgICBxdWVyeSxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcbiAgICBpZiAoT2JqZWN0LmtleXMocXVlcnkpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgd2hlcmUucGF0dGVybiA9ICdUUlVFJztcbiAgICB9XG4gICAgY29uc3QgcXMgPSBgV0lUSCBkZWxldGVkIEFTIChERUxFVEUgRlJPTSAkMTpuYW1lIFdIRVJFICR7d2hlcmUucGF0dGVybn0gUkVUVVJOSU5HICopIFNFTEVDVCBjb3VudCgqKSBGUk9NIGRlbGV0ZWRgO1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIGNvbnN0IHByb21pc2UgPSAodHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgID8gdHJhbnNhY3Rpb25hbFNlc3Npb24udFxuICAgICAgOiB0aGlzLl9jbGllbnRcbiAgICApXG4gICAgICAub25lKHFzLCB2YWx1ZXMsIGEgPT4gK2EuY291bnQpXG4gICAgICAudGhlbihjb3VudCA9PiB7XG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAnT2JqZWN0IG5vdCBmb3VuZC4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRUxTRTogRG9uJ3QgZGVsZXRlIGFueXRoaW5nIGlmIGRvZXNuJ3QgZXhpc3RcbiAgICAgIH0pO1xuICAgIGlmICh0cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChwcm9taXNlKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cbiAgLy8gUmV0dXJuIHZhbHVlIG5vdCBjdXJyZW50bHkgd2VsbCBzcGVjaWZpZWQuXG4gIGFzeW5jIGZpbmRPbmVBbmRVcGRhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBkZWJ1ZygnZmluZE9uZUFuZFVwZGF0ZScsIGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT2JqZWN0c0J5UXVlcnkoXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBzY2hlbWEsXG4gICAgICBxdWVyeSxcbiAgICAgIHVwZGF0ZSxcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgKS50aGVuKHZhbCA9PiB2YWxbMF0pO1xuICB9XG5cbiAgLy8gQXBwbHkgdGhlIHVwZGF0ZSB0byBhbGwgb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBnaXZlbiBQYXJzZSBRdWVyeS5cbiAgYXN5bmMgdXBkYXRlT2JqZWN0c0J5UXVlcnkoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKTogUHJvbWlzZTxbYW55XT4ge1xuICAgIGRlYnVnKCd1cGRhdGVPYmplY3RzQnlRdWVyeScsIGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSk7XG4gICAgY29uc3QgdXBkYXRlUGF0dGVybnMgPSBbXTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBsZXQgaW5kZXggPSAyO1xuICAgIHNjaGVtYSA9IHRvUG9zdGdyZXNTY2hlbWEoc2NoZW1hKTtcblxuICAgIGNvbnN0IG9yaWdpbmFsVXBkYXRlID0geyAuLi51cGRhdGUgfTtcblxuICAgIC8vIFNldCBmbGFnIGZvciBkb3Qgbm90YXRpb24gZmllbGRzXG4gICAgY29uc3QgZG90Tm90YXRpb25PcHRpb25zID0ge307XG4gICAgT2JqZWN0LmtleXModXBkYXRlKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA+IC0xKSB7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBmaWVsZE5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgY29uc3QgZmlyc3QgPSBjb21wb25lbnRzLnNoaWZ0KCk7XG4gICAgICAgIGRvdE5vdGF0aW9uT3B0aW9uc1tmaXJzdF0gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG90Tm90YXRpb25PcHRpb25zW2ZpZWxkTmFtZV0gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB1cGRhdGUgPSBoYW5kbGVEb3RGaWVsZHModXBkYXRlKTtcbiAgICAvLyBSZXNvbHZlIGF1dGhEYXRhIGZpcnN0LFxuICAgIC8vIFNvIHdlIGRvbid0IGVuZCB1cCB3aXRoIG11bHRpcGxlIGtleSB1cGRhdGVzXG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gdXBkYXRlKSB7XG4gICAgICBjb25zdCBhdXRoRGF0YU1hdGNoID0gZmllbGROYW1lLm1hdGNoKC9eX2F1dGhfZGF0YV8oW2EtekEtWjAtOV9dKykkLyk7XG4gICAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgICB2YXIgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgICBkZWxldGUgdXBkYXRlW2ZpZWxkTmFtZV07XG4gICAgICAgIHVwZGF0ZVsnYXV0aERhdGEnXSA9IHVwZGF0ZVsnYXV0aERhdGEnXSB8fCB7fTtcbiAgICAgICAgdXBkYXRlWydhdXRoRGF0YSddW3Byb3ZpZGVyXSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHVwZGF0ZSkge1xuICAgICAgY29uc3QgZmllbGRWYWx1ZSA9IHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgLy8gRHJvcCBhbnkgdW5kZWZpbmVkIHZhbHVlcy5cbiAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZGVsZXRlIHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gTlVMTGApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZE5hbWUgPT0gJ2F1dGhEYXRhJykge1xuICAgICAgICAvLyBUaGlzIHJlY3Vyc2l2ZWx5IHNldHMgdGhlIGpzb25fb2JqZWN0XG4gICAgICAgIC8vIE9ubHkgMSBsZXZlbCBkZWVwXG4gICAgICAgIGNvbnN0IGdlbmVyYXRlID0gKGpzb25iOiBzdHJpbmcsIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGBqc29uX29iamVjdF9zZXRfa2V5KENPQUxFU0NFKCR7anNvbmJ9LCAne30nOjpqc29uYiksICR7a2V5fSwgJHt2YWx1ZX0pOjpqc29uYmA7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGxhc3RLZXkgPSBgJCR7aW5kZXh9Om5hbWVgO1xuICAgICAgICBjb25zdCBmaWVsZE5hbWVJbmRleCA9IGluZGV4O1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICBjb25zdCB1cGRhdGUgPSBPYmplY3Qua2V5cyhmaWVsZFZhbHVlKS5yZWR1Y2UoXG4gICAgICAgICAgKGxhc3RLZXk6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IGdlbmVyYXRlKFxuICAgICAgICAgICAgICBsYXN0S2V5LFxuICAgICAgICAgICAgICBgJCR7aW5kZXh9Ojp0ZXh0YCxcbiAgICAgICAgICAgICAgYCQke2luZGV4ICsgMX06Ompzb25iYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBmaWVsZFZhbHVlW2tleV07XG4gICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgaWYgKHZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYXN0S2V5XG4gICAgICAgICk7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2ZpZWxkTmFtZUluZGV4fTpuYW1lID0gJHt1cGRhdGV9YCk7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX19vcCA9PT0gJ0luY3JlbWVudCcpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChcbiAgICAgICAgICBgJCR7aW5kZXh9Om5hbWUgPSBDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgMCkgKyAkJHtpbmRleCArIDF9YFxuICAgICAgICApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuYW1vdW50KTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnQWRkJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9IGFycmF5X2FkZChDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ1tdJzo6anNvbmIpLCAkJHtcbiAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgIH06Ompzb25iKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLm9iamVjdHMpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBudWxsKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnUmVtb3ZlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9IGFycmF5X3JlbW92ZShDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ1tdJzo6anNvbmIpLCAkJHtcbiAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgIH06Ompzb25iKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLm9iamVjdHMpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnQWRkVW5pcXVlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9IGFycmF5X2FkZF91bmlxdWUoQ09BTEVTQ0UoJCR7aW5kZXh9Om5hbWUsICdbXSc6Ompzb25iKSwgJCR7XG4gICAgICAgICAgICBpbmRleCArIDFcbiAgICAgICAgICB9Ojpqc29uYilgXG4gICAgICAgICk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZS5vYmplY3RzKSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkTmFtZSA9PT0gJ3VwZGF0ZWRBdCcpIHtcbiAgICAgICAgLy9UT0RPOiBzdG9wIHNwZWNpYWwgY2FzaW5nIHRoaXMuIEl0IHNob3VsZCBjaGVjayBmb3IgX190eXBlID09PSAnRGF0ZScgYW5kIHVzZSAuaXNvXG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS5vYmplY3RJZCk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnRGF0ZScpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgdG9Qb3N0Z3Jlc1ZhbHVlKGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnRmlsZScpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgdG9Qb3N0Z3Jlc1ZhbHVlKGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChcbiAgICAgICAgICBgJCR7aW5kZXh9Om5hbWUgPSBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtpbmRleCArIDJ9KWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmxvbmdpdHVkZSwgZmllbGRWYWx1ZS5sYXRpdHVkZSk7XG4gICAgICAgIGluZGV4ICs9IDM7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBjb252ZXJ0UG9seWdvblRvU1FMKGZpZWxkVmFsdWUuY29vcmRpbmF0ZXMpO1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX06OnBvbHlnb25gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCB2YWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIC8vIG5vb3BcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIGZpZWxkVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ09iamVjdCdcbiAgICAgICkge1xuICAgICAgICAvLyBHYXRoZXIga2V5cyB0byBpbmNyZW1lbnRcbiAgICAgICAgY29uc3Qga2V5c1RvSW5jcmVtZW50ID0gT2JqZWN0LmtleXMob3JpZ2luYWxVcGRhdGUpXG4gICAgICAgICAgLmZpbHRlcihrID0+IHtcbiAgICAgICAgICAgIC8vIGNob29zZSB0b3AgbGV2ZWwgZmllbGRzIHRoYXQgaGF2ZSBhIGRlbGV0ZSBvcGVyYXRpb24gc2V0XG4gICAgICAgICAgICAvLyBOb3RlIHRoYXQgT2JqZWN0LmtleXMgaXMgaXRlcmF0aW5nIG92ZXIgdGhlICoqb3JpZ2luYWwqKiB1cGRhdGUgb2JqZWN0XG4gICAgICAgICAgICAvLyBhbmQgdGhhdCBzb21lIG9mIHRoZSBrZXlzIG9mIHRoZSBvcmlnaW5hbCB1cGRhdGUgY291bGQgYmUgbnVsbCBvciB1bmRlZmluZWQ6XG4gICAgICAgICAgICAvLyAoU2VlIHRoZSBhYm92ZSBjaGVjayBgaWYgKGZpZWxkVmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIGZpZWxkVmFsdWUgPT0gXCJ1bmRlZmluZWRcIilgKVxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBvcmlnaW5hbFVwZGF0ZVtrXTtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIHZhbHVlICYmXG4gICAgICAgICAgICAgIHZhbHVlLl9fb3AgPT09ICdJbmNyZW1lbnQnICYmXG4gICAgICAgICAgICAgIGsuc3BsaXQoJy4nKS5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgICAgICAgay5zcGxpdCgnLicpWzBdID09PSBmaWVsZE5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAubWFwKGsgPT4gay5zcGxpdCgnLicpWzFdKTtcblxuICAgICAgICBsZXQgaW5jcmVtZW50UGF0dGVybnMgPSAnJztcbiAgICAgICAgaWYgKGtleXNUb0luY3JlbWVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaW5jcmVtZW50UGF0dGVybnMgPVxuICAgICAgICAgICAgJyB8fCAnICtcbiAgICAgICAgICAgIGtleXNUb0luY3JlbWVudFxuICAgICAgICAgICAgICAubWFwKGMgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IGZpZWxkVmFsdWVbY10uYW1vdW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBgQ09OQ0FUKCd7XCIke2N9XCI6JywgQ09BTEVTQ0UoJCR7aW5kZXh9Om5hbWUtPj4nJHtjfScsJzAnKTo6aW50ICsgJHthbW91bnR9LCAnfScpOjpqc29uYmA7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5qb2luKCcgfHwgJyk7XG4gICAgICAgICAgLy8gU3RyaXAgdGhlIGtleXNcbiAgICAgICAgICBrZXlzVG9JbmNyZW1lbnQuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgZGVsZXRlIGZpZWxkVmFsdWVba2V5XTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGtleXNUb0RlbGV0ZTogQXJyYXk8c3RyaW5nPiA9IE9iamVjdC5rZXlzKG9yaWdpbmFsVXBkYXRlKVxuICAgICAgICAgIC5maWx0ZXIoayA9PiB7XG4gICAgICAgICAgICAvLyBjaG9vc2UgdG9wIGxldmVsIGZpZWxkcyB0aGF0IGhhdmUgYSBkZWxldGUgb3BlcmF0aW9uIHNldC5cbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gb3JpZ2luYWxVcGRhdGVba107XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICB2YWx1ZSAmJlxuICAgICAgICAgICAgICB2YWx1ZS5fX29wID09PSAnRGVsZXRlJyAmJlxuICAgICAgICAgICAgICBrLnNwbGl0KCcuJykubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICAgIGsuc3BsaXQoJy4nKVswXSA9PT0gZmllbGROYW1lXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLm1hcChrID0+IGsuc3BsaXQoJy4nKVsxXSk7XG5cbiAgICAgICAgY29uc3QgZGVsZXRlUGF0dGVybnMgPSBrZXlzVG9EZWxldGUucmVkdWNlKFxuICAgICAgICAgIChwOiBzdHJpbmcsIGM6IHN0cmluZywgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcCArIGAgLSAnJCR7aW5kZXggKyAxICsgaX06dmFsdWUnYDtcbiAgICAgICAgICB9LFxuICAgICAgICAgICcnXG4gICAgICAgICk7XG4gICAgICAgIC8vIE92ZXJyaWRlIE9iamVjdFxuICAgICAgICBsZXQgdXBkYXRlT2JqZWN0ID0gXCIne30nOjpqc29uYlwiO1xuXG4gICAgICAgIGlmIChkb3ROb3RhdGlvbk9wdGlvbnNbZmllbGROYW1lXSkge1xuICAgICAgICAgIC8vIE1lcmdlIE9iamVjdFxuICAgICAgICAgIHVwZGF0ZU9iamVjdCA9IGBDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ3t9Jzo6anNvbmIpYDtcbiAgICAgICAgfVxuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9ICgke3VwZGF0ZU9iamVjdH0gJHtkZWxldGVQYXR0ZXJuc30gJHtpbmNyZW1lbnRQYXR0ZXJuc30gfHwgJCR7XG4gICAgICAgICAgICBpbmRleCArIDEgKyBrZXlzVG9EZWxldGUubGVuZ3RoXG4gICAgICAgICAgfTo6anNvbmIgKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCAuLi5rZXlzVG9EZWxldGUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMiArIGtleXNUb0RlbGV0ZS5sZW5ndGg7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUpICYmXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0FycmF5J1xuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSk7XG4gICAgICAgIGlmIChleHBlY3RlZFR5cGUgPT09ICd0ZXh0W10nKSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojp0ZXh0W11gKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZSkpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnKCdOb3Qgc3VwcG9ydGVkIHVwZGF0ZScsIGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB1cGRhdGUgJHtKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlKX0geWV0YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgaW5kZXgsXG4gICAgICBxdWVyeSxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlQ2xhdXNlID1cbiAgICAgIHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IHFzID0gYFVQREFURSAkMTpuYW1lIFNFVCAke3VwZGF0ZVBhdHRlcm5zLmpvaW4oKX0gJHt3aGVyZUNsYXVzZX0gUkVUVVJOSU5HICpgO1xuICAgIGRlYnVnKCd1cGRhdGU6ICcsIHFzLCB2YWx1ZXMpO1xuICAgIGNvbnN0IHByb21pc2UgPSAodHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgID8gdHJhbnNhY3Rpb25hbFNlc3Npb24udFxuICAgICAgOiB0aGlzLl9jbGllbnRcbiAgICApLmFueShxcywgdmFsdWVzKTtcbiAgICBpZiAodHJhbnNhY3Rpb25hbFNlc3Npb24pIHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLmJhdGNoLnB1c2gocHJvbWlzZSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5LCB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGlzLiBJdCdzIG9ubHkgdXNlZCBmb3IgY29uZmlnIGFuZCBob29rcy5cbiAgdXBzZXJ0T25lT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCd1cHNlcnRPbmVPYmplY3QnLCB7IGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSB9KTtcbiAgICBjb25zdCBjcmVhdGVWYWx1ZSA9IE9iamVjdC5hc3NpZ24oe30sIHF1ZXJ5LCB1cGRhdGUpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZU9iamVjdChcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHNjaGVtYSxcbiAgICAgIGNyZWF0ZVZhbHVlLFxuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICApLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIC8vIGlnbm9yZSBkdXBsaWNhdGUgdmFsdWUgZXJyb3JzIGFzIGl0J3MgdXBzZXJ0XG4gICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZmluZE9uZUFuZFVwZGF0ZShcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBzY2hlbWEsXG4gICAgICAgIHF1ZXJ5LFxuICAgICAgICB1cGRhdGUsXG4gICAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCBjYXNlSW5zZW5zaXRpdmUsIGV4cGxhaW4gfTogUXVlcnlPcHRpb25zXG4gICkge1xuICAgIGRlYnVnKCdmaW5kJywgY2xhc3NOYW1lLCBxdWVyeSwge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgc29ydCxcbiAgICAgIGtleXMsXG4gICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICBleHBsYWluLFxuICAgIH0pO1xuICAgIGNvbnN0IGhhc0xpbWl0ID0gbGltaXQgIT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBoYXNTa2lwID0gc2tpcCAhPT0gdW5kZWZpbmVkO1xuICAgIGxldCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogMixcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICB9KTtcbiAgICB2YWx1ZXMucHVzaCguLi53aGVyZS52YWx1ZXMpO1xuXG4gICAgY29uc3Qgd2hlcmVQYXR0ZXJuID1cbiAgICAgIHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IGxpbWl0UGF0dGVybiA9IGhhc0xpbWl0ID8gYExJTUlUICQke3ZhbHVlcy5sZW5ndGggKyAxfWAgOiAnJztcbiAgICBpZiAoaGFzTGltaXQpIHtcbiAgICAgIHZhbHVlcy5wdXNoKGxpbWl0KTtcbiAgICB9XG4gICAgY29uc3Qgc2tpcFBhdHRlcm4gPSBoYXNTa2lwID8gYE9GRlNFVCAkJHt2YWx1ZXMubGVuZ3RoICsgMX1gIDogJyc7XG4gICAgaWYgKGhhc1NraXApIHtcbiAgICAgIHZhbHVlcy5wdXNoKHNraXApO1xuICAgIH1cblxuICAgIGxldCBzb3J0UGF0dGVybiA9ICcnO1xuICAgIGlmIChzb3J0KSB7XG4gICAgICBjb25zdCBzb3J0Q29weTogYW55ID0gc29ydDtcbiAgICAgIGNvbnN0IHNvcnRpbmcgPSBPYmplY3Qua2V5cyhzb3J0KVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtS2V5ID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoa2V5KS5qb2luKCctPicpO1xuICAgICAgICAgIC8vIFVzaW5nICRpZHggcGF0dGVybiBnaXZlczogIG5vbi1pbnRlZ2VyIGNvbnN0YW50IGluIE9SREVSIEJZXG4gICAgICAgICAgaWYgKHNvcnRDb3B5W2tleV0gPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IEFTQ2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IERFU0NgO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbigpO1xuICAgICAgc29ydFBhdHRlcm4gPVxuICAgICAgICBzb3J0ICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LmtleXMoc29ydCkubGVuZ3RoID4gMFxuICAgICAgICAgID8gYE9SREVSIEJZICR7c29ydGluZ31gXG4gICAgICAgICAgOiAnJztcbiAgICB9XG4gICAgaWYgKHdoZXJlLnNvcnRzICYmIE9iamVjdC5rZXlzKCh3aGVyZS5zb3J0czogYW55KSkubGVuZ3RoID4gMCkge1xuICAgICAgc29ydFBhdHRlcm4gPSBgT1JERVIgQlkgJHt3aGVyZS5zb3J0cy5qb2luKCl9YDtcbiAgICB9XG5cbiAgICBsZXQgY29sdW1ucyA9ICcqJztcbiAgICBpZiAoa2V5cykge1xuICAgICAgLy8gRXhjbHVkZSBlbXB0eSBrZXlzXG4gICAgICAvLyBSZXBsYWNlIEFDTCBieSBpdCdzIGtleXNcbiAgICAgIGtleXMgPSBrZXlzLnJlZHVjZSgobWVtbywga2V5KSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09ICdBQ0wnKSB7XG4gICAgICAgICAgbWVtby5wdXNoKCdfcnBlcm0nKTtcbiAgICAgICAgICBtZW1vLnB1c2goJ193cGVybScpO1xuICAgICAgICB9IGVsc2UgaWYgKGtleS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbWVtby5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9LCBbXSk7XG4gICAgICBjb2x1bW5zID0ga2V5c1xuICAgICAgICAubWFwKChrZXksIGluZGV4KSA9PiB7XG4gICAgICAgICAgaWYgKGtleSA9PT0gJyRzY29yZScpIHtcbiAgICAgICAgICAgIHJldHVybiBgdHNfcmFua19jZCh0b190c3ZlY3RvcigkJHsyfSwgJCR7M306bmFtZSksIHRvX3RzcXVlcnkoJCR7NH0sICQkezV9KSwgMzIpIGFzIHNjb3JlYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGAkJHtpbmRleCArIHZhbHVlcy5sZW5ndGggKyAxfTpuYW1lYDtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oKTtcbiAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoa2V5cyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JpZ2luYWxRdWVyeSA9IGBTRUxFQ1QgJHtjb2x1bW5zfSBGUk9NICQxOm5hbWUgJHt3aGVyZVBhdHRlcm59ICR7c29ydFBhdHRlcm59ICR7bGltaXRQYXR0ZXJufSAke3NraXBQYXR0ZXJufWA7XG4gICAgY29uc3QgcXMgPSBleHBsYWluXG4gICAgICA/IHRoaXMuY3JlYXRlRXhwbGFpbmFibGVRdWVyeShvcmlnaW5hbFF1ZXJ5KVxuICAgICAgOiBvcmlnaW5hbFF1ZXJ5O1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5hbnkocXMsIHZhbHVlcylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFF1ZXJ5IG9uIG5vbiBleGlzdGluZyB0YWJsZSwgZG9uJ3QgY3Jhc2hcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+XG4gICAgICAgICAgdGhpcy5wb3N0Z3Jlc09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gQ29udmVydHMgZnJvbSBhIHBvc3RncmVzLWZvcm1hdCBvYmplY3QgdG8gYSBSRVNULWZvcm1hdCBvYmplY3QuXG4gIC8vIERvZXMgbm90IHN0cmlwIG91dCBhbnl0aGluZyBiYXNlZCBvbiBhIGxhY2sgb2YgYXV0aGVudGljYXRpb24uXG4gIHBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHNjaGVtYTogYW55KSB7XG4gICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicgJiYgb2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdFtmaWVsZE5hbWVdLFxuICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnRhcmdldENsYXNzLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50YXJnZXRDbGFzcyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBvYmplY3RbZmllbGROYW1lXSA9IHtcbiAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgbGF0aXR1ZGU6IG9iamVjdFtmaWVsZE5hbWVdLnksXG4gICAgICAgICAgbG9uZ2l0dWRlOiBvYmplY3RbZmllbGROYW1lXS54LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgbGV0IGNvb3JkcyA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICBjb29yZHMgPSBjb29yZHMuc3Vic3RyKDIsIGNvb3Jkcy5sZW5ndGggLSA0KS5zcGxpdCgnKSwoJyk7XG4gICAgICAgIGNvb3JkcyA9IGNvb3Jkcy5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBwYXJzZUZsb2F0KHBvaW50LnNwbGl0KCcsJylbMV0pLFxuICAgICAgICAgICAgcGFyc2VGbG9hdChwb2ludC5zcGxpdCgnLCcpWzBdKSxcbiAgICAgICAgICBdO1xuICAgICAgICB9KTtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgICAgICAgY29vcmRpbmF0ZXM6IGNvb3JkcyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0ZpbGUnKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ0ZpbGUnLFxuICAgICAgICAgIG5hbWU6IG9iamVjdFtmaWVsZE5hbWVdLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vVE9ETzogcmVtb3ZlIHRoaXMgcmVsaWFuY2Ugb24gdGhlIG1vbmdvIGZvcm1hdC4gREIgYWRhcHRlciBzaG91bGRuJ3Qga25vdyB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiBjcmVhdGVkIGF0IGFuZCBhbnkgb3RoZXIgZGF0ZSBmaWVsZC5cbiAgICBpZiAob2JqZWN0LmNyZWF0ZWRBdCkge1xuICAgICAgb2JqZWN0LmNyZWF0ZWRBdCA9IG9iamVjdC5jcmVhdGVkQXQudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC51cGRhdGVkQXQpIHtcbiAgICAgIG9iamVjdC51cGRhdGVkQXQgPSBvYmplY3QudXBkYXRlZEF0LnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChvYmplY3QuZXhwaXJlc0F0KSB7XG4gICAgICBvYmplY3QuZXhwaXJlc0F0ID0ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBvYmplY3QuZXhwaXJlc0F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAob2JqZWN0Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCkge1xuICAgICAgb2JqZWN0Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdC50b0lTT1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQpIHtcbiAgICAgIG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQudG9JU09TdHJpbmcoKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChvYmplY3QuX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCkge1xuICAgICAgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAob2JqZWN0Ll9wYXNzd29yZF9jaGFuZ2VkX2F0KSB7XG4gICAgICBvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5fcGFzc3dvcmRfY2hhbmdlZF9hdC50b0lTT1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICAgIGlzbzogb2JqZWN0W2ZpZWxkTmFtZV0udG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgdW5pcXVlIGluZGV4LiBVbmlxdWUgaW5kZXhlcyBvbiBudWxsYWJsZSBmaWVsZHMgYXJlIG5vdCBhbGxvd2VkLiBTaW5jZSB3ZSBkb24ndFxuICAvLyBjdXJyZW50bHkga25vdyB3aGljaCBmaWVsZHMgYXJlIG51bGxhYmxlIGFuZCB3aGljaCBhcmVuJ3QsIHdlIGlnbm9yZSB0aGF0IGNyaXRlcmlhLlxuICAvLyBBcyBzdWNoLCB3ZSBzaG91bGRuJ3QgZXhwb3NlIHRoaXMgZnVuY3Rpb24gdG8gdXNlcnMgb2YgcGFyc2UgdW50aWwgd2UgaGF2ZSBhbiBvdXQtb2YtYmFuZFxuICAvLyBXYXkgb2YgZGV0ZXJtaW5pbmcgaWYgYSBmaWVsZCBpcyBudWxsYWJsZS4gVW5kZWZpbmVkIGRvZXNuJ3QgY291bnQgYWdhaW5zdCB1bmlxdWVuZXNzLFxuICAvLyB3aGljaCBpcyB3aHkgd2UgdXNlIHNwYXJzZSBpbmRleGVzLlxuICBhc3luYyBlbnN1cmVVbmlxdWVuZXNzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXVxuICApIHtcbiAgICBjb25zdCBjb25zdHJhaW50TmFtZSA9IGAke2NsYXNzTmFtZX1fdW5pcXVlXyR7ZmllbGROYW1lcy5zb3J0KCkuam9pbignXycpfWA7XG4gICAgY29uc3QgY29uc3RyYWludFBhdHRlcm5zID0gZmllbGROYW1lcy5tYXAoXG4gICAgICAoZmllbGROYW1lLCBpbmRleCkgPT4gYCQke2luZGV4ICsgM306bmFtZWBcbiAgICApO1xuICAgIGNvbnN0IHFzID0gYENSRUFURSBVTklRVUUgSU5ERVggSUYgTk9UIEVYSVNUUyAkMjpuYW1lIE9OICQxOm5hbWUoJHtjb25zdHJhaW50UGF0dGVybnMuam9pbigpfSlgO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5ub25lKHFzLCBbY2xhc3NOYW1lLCBjb25zdHJhaW50TmFtZSwgLi4uZmllbGROYW1lc10pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yICYmXG4gICAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhjb25zdHJhaW50TmFtZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gSW5kZXggYWxyZWFkeSBleGlzdHMuIElnbm9yZSBlcnJvci5cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBlcnJvci5jb2RlID09PSBQb3N0Z3Jlc1VuaXF1ZUluZGV4VmlvbGF0aW9uRXJyb3IgJiZcbiAgICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGNvbnN0cmFpbnROYW1lKVxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBDYXN0IHRoZSBlcnJvciBpbnRvIHRoZSBwcm9wZXIgcGFyc2UgZXJyb3JcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIEV4ZWN1dGVzIGEgY291bnQuXG4gIGFzeW5jIGNvdW50KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHJlYWRQcmVmZXJlbmNlPzogc3RyaW5nLFxuICAgIGVzdGltYXRlPzogYm9vbGVhbiA9IHRydWVcbiAgKSB7XG4gICAgZGVidWcoJ2NvdW50JywgY2xhc3NOYW1lLCBxdWVyeSwgcmVhZFByZWZlcmVuY2UsIGVzdGltYXRlKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogMixcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9XG4gICAgICB3aGVyZS5wYXR0ZXJuLmxlbmd0aCA+IDAgPyBgV0hFUkUgJHt3aGVyZS5wYXR0ZXJufWAgOiAnJztcbiAgICBsZXQgcXMgPSAnJztcblxuICAgIGlmICh3aGVyZS5wYXR0ZXJuLmxlbmd0aCA+IDAgfHwgIWVzdGltYXRlKSB7XG4gICAgICBxcyA9IGBTRUxFQ1QgY291bnQoKikgRlJPTSAkMTpuYW1lICR7d2hlcmVQYXR0ZXJufWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHFzID1cbiAgICAgICAgJ1NFTEVDVCByZWx0dXBsZXMgQVMgYXBwcm94aW1hdGVfcm93X2NvdW50IEZST00gcGdfY2xhc3MgV0hFUkUgcmVsbmFtZSA9ICQxJztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAub25lKHFzLCB2YWx1ZXMsIGEgPT4ge1xuICAgICAgICBpZiAoYS5hcHByb3hpbWF0ZV9yb3dfY291bnQgIT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiArYS5hcHByb3hpbWF0ZV9yb3dfY291bnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICthLmNvdW50O1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBkaXN0aW5jdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICBmaWVsZE5hbWU6IHN0cmluZ1xuICApIHtcbiAgICBkZWJ1ZygnZGlzdGluY3QnLCBjbGFzc05hbWUsIHF1ZXJ5KTtcbiAgICBsZXQgZmllbGQgPSBmaWVsZE5hbWU7XG4gICAgbGV0IGNvbHVtbiA9IGZpZWxkTmFtZTtcbiAgICBjb25zdCBpc05lc3RlZCA9IGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMDtcbiAgICBpZiAoaXNOZXN0ZWQpIHtcbiAgICAgIGZpZWxkID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoZmllbGROYW1lKS5qb2luKCctPicpO1xuICAgICAgY29sdW1uID0gZmllbGROYW1lLnNwbGl0KCcuJylbMF07XG4gICAgfVxuICAgIGNvbnN0IGlzQXJyYXlGaWVsZCA9XG4gICAgICBzY2hlbWEuZmllbGRzICYmXG4gICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnQXJyYXknO1xuICAgIGNvbnN0IGlzUG9pbnRlckZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHMgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB2YWx1ZXMgPSBbZmllbGQsIGNvbHVtbiwgY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogNCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9XG4gICAgICB3aGVyZS5wYXR0ZXJuLmxlbmd0aCA+IDAgPyBgV0hFUkUgJHt3aGVyZS5wYXR0ZXJufWAgOiAnJztcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IGlzQXJyYXlGaWVsZCA/ICdqc29uYl9hcnJheV9lbGVtZW50cycgOiAnT04nO1xuICAgIGxldCBxcyA9IGBTRUxFQ1QgRElTVElOQ1QgJHt0cmFuc2Zvcm1lcn0oJDE6bmFtZSkgJDI6bmFtZSBGUk9NICQzOm5hbWUgJHt3aGVyZVBhdHRlcm59YDtcbiAgICBpZiAoaXNOZXN0ZWQpIHtcbiAgICAgIHFzID0gYFNFTEVDVCBESVNUSU5DVCAke3RyYW5zZm9ybWVyfSgkMTpyYXcpICQyOnJhdyBGUk9NICQzOm5hbWUgJHt3aGVyZVBhdHRlcm59YDtcbiAgICB9XG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudFxuICAgICAgLmFueShxcywgdmFsdWVzKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAoIWlzTmVzdGVkKSB7XG4gICAgICAgICAgcmVzdWx0cyA9IHJlc3VsdHMuZmlsdGVyKG9iamVjdCA9PiBvYmplY3RbZmllbGRdICE9PSBudWxsKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICAgIGlmICghaXNQb2ludGVyRmllbGQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdFtmaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICAgICAgY2xhc3NOYW1lOiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgIG9iamVjdElkOiBvYmplY3RbZmllbGRdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGlsZCA9IGZpZWxkTmFtZS5zcGxpdCgnLicpWzFdO1xuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+IG9iamVjdFtjb2x1bW5dW2NoaWxkXSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PlxuICAgICAgICByZXN1bHRzLm1hcChvYmplY3QgPT5cbiAgICAgICAgICB0aGlzLnBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKVxuICAgICAgICApXG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgYWdncmVnYXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogYW55LFxuICAgIHBpcGVsaW5lOiBhbnksXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgaGludDogP21peGVkLFxuICAgIGV4cGxhaW4/OiBib29sZWFuXG4gICkge1xuICAgIGRlYnVnKCdhZ2dyZWdhdGUnLCBjbGFzc05hbWUsIHBpcGVsaW5lLCByZWFkUHJlZmVyZW5jZSwgaGludCwgZXhwbGFpbik7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZV07XG4gICAgbGV0IGluZGV4OiBudW1iZXIgPSAyO1xuICAgIGxldCBjb2x1bW5zOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBjb3VudEZpZWxkID0gbnVsbDtcbiAgICBsZXQgZ3JvdXBWYWx1ZXMgPSBudWxsO1xuICAgIGxldCB3aGVyZVBhdHRlcm4gPSAnJztcbiAgICBsZXQgbGltaXRQYXR0ZXJuID0gJyc7XG4gICAgbGV0IHNraXBQYXR0ZXJuID0gJyc7XG4gICAgbGV0IHNvcnRQYXR0ZXJuID0gJyc7XG4gICAgbGV0IGdyb3VwUGF0dGVybiA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGlwZWxpbmUubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IHN0YWdlID0gcGlwZWxpbmVbaV07XG4gICAgICBpZiAoc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdGFnZS4kZ3JvdXBbZmllbGRdO1xuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZpZWxkID09PSAnX2lkJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlICE9PSAnJykge1xuICAgICAgICAgICAgY29sdW1ucy5wdXNoKGAkJHtpbmRleH06bmFtZSBBUyBcIm9iamVjdElkXCJgKTtcbiAgICAgICAgICAgIGdyb3VwUGF0dGVybiA9IGBHUk9VUCBCWSAkJHtpbmRleH06bmFtZWA7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaCh0cmFuc2Zvcm1BZ2dyZWdhdGVGaWVsZCh2YWx1ZSkpO1xuICAgICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBmaWVsZCA9PT0gJ19pZCcgJiZcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGggIT09IDBcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGdyb3VwVmFsdWVzID0gdmFsdWU7XG4gICAgICAgICAgICBjb25zdCBncm91cEJ5RmllbGRzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFsaWFzIGluIHZhbHVlKSB7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWVbYWxpYXNdID09PSAnc3RyaW5nJyAmJiB2YWx1ZVthbGlhc10pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSB0cmFuc2Zvcm1BZ2dyZWdhdGVGaWVsZCh2YWx1ZVthbGlhc10pO1xuICAgICAgICAgICAgICAgIGlmICghZ3JvdXBCeUZpZWxkcy5pbmNsdWRlcyhgXCIke3NvdXJjZX1cImApKSB7XG4gICAgICAgICAgICAgICAgICBncm91cEJ5RmllbGRzLnB1c2goYFwiJHtzb3VyY2V9XCJgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goc291cmNlLCBhbGlhcyk7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGAkJHtpbmRleH06bmFtZSBBUyAkJHtpbmRleCArIDF9Om5hbWVgKTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IE9iamVjdC5rZXlzKHZhbHVlW2FsaWFzXSlbMF07XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gdHJhbnNmb3JtQWdncmVnYXRlRmllbGQodmFsdWVbYWxpYXNdW29wZXJhdGlvbl0pO1xuICAgICAgICAgICAgICAgIGlmIChtb25nb0FnZ3JlZ2F0ZVRvUG9zdGdyZXNbb3BlcmF0aW9uXSkge1xuICAgICAgICAgICAgICAgICAgaWYgKCFncm91cEJ5RmllbGRzLmluY2x1ZGVzKGBcIiR7c291cmNlfVwiYCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBCeUZpZWxkcy5wdXNoKGBcIiR7c291cmNlfVwiYCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIGBFWFRSQUNUKCR7XG4gICAgICAgICAgICAgICAgICAgICAgbW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzW29wZXJhdGlvbl1cbiAgICAgICAgICAgICAgICAgICAgfSBGUk9NICQke2luZGV4fTpuYW1lIEFUIFRJTUUgWk9ORSAnVVRDJykgQVMgJCR7XG4gICAgICAgICAgICAgICAgICAgICAgaW5kZXggKyAxXG4gICAgICAgICAgICAgICAgICAgIH06bmFtZWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChzb3VyY2UsIGFsaWFzKTtcbiAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBncm91cFBhdHRlcm4gPSBgR1JPVVAgQlkgJCR7aW5kZXh9OnJhd2A7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChncm91cEJ5RmllbGRzLmpvaW4oKSk7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUuJHN1bSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlLiRzdW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBTVU0oJCR7aW5kZXh9Om5hbWUpIEFTICQke2luZGV4ICsgMX06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRzdW0pLCBmaWVsZCk7XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudEZpZWxkID0gZmllbGQ7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBDT1VOVCgqKSBBUyAkJHtpbmRleH06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1heCkge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1BWCgkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtYXgpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1pbikge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1JTigkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtaW4pLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJGF2Zykge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYEFWRygkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRhdmcpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW5zLnB1c2goJyonKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBpZiAoY29sdW1ucy5pbmNsdWRlcygnKicpKSB7XG4gICAgICAgICAgY29sdW1ucyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJHByb2plY3QpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHN0YWdlLiRwcm9qZWN0W2ZpZWxkXTtcbiAgICAgICAgICBpZiAodmFsdWUgPT09IDEgfHwgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbHVtbnMucHVzaChgJCR7aW5kZXh9Om5hbWVgKTtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5zID0gW107XG4gICAgICAgIGNvbnN0IG9yT3JBbmQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoXG4gICAgICAgICAgc3RhZ2UuJG1hdGNoLFxuICAgICAgICAgICckb3InXG4gICAgICAgIClcbiAgICAgICAgICA/ICcgT1IgJ1xuICAgICAgICAgIDogJyBBTkQgJztcblxuICAgICAgICBpZiAoc3RhZ2UuJG1hdGNoLiRvcikge1xuICAgICAgICAgIGNvbnN0IGNvbGxhcHNlID0ge307XG4gICAgICAgICAgc3RhZ2UuJG1hdGNoLiRvci5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZWxlbWVudCkge1xuICAgICAgICAgICAgICBjb2xsYXBzZVtrZXldID0gZWxlbWVudFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YWdlLiRtYXRjaCA9IGNvbGxhcHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdGFnZS4kbWF0Y2hbZmllbGRdO1xuICAgICAgICAgIGNvbnN0IG1hdGNoUGF0dGVybnMgPSBbXTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3IpLmZvckVhY2goY21wID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZVtjbXBdKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHBnQ29tcGFyYXRvciA9IFBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvcltjbXBdO1xuICAgICAgICAgICAgICBtYXRjaFBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgICAgICAgYCQke2luZGV4fTpuYW1lICR7cGdDb21wYXJhdG9yfSAkJHtpbmRleCArIDF9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZCwgdG9Qb3N0Z3Jlc1ZhbHVlKHZhbHVlW2NtcF0pKTtcbiAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAobWF0Y2hQYXR0ZXJucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAoJHttYXRjaFBhdHRlcm5zLmpvaW4oJyBBTkQgJyl9KWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJlxuICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSAmJlxuICAgICAgICAgICAgbWF0Y2hQYXR0ZXJucy5sZW5ndGggPT09IDBcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZmllbGQsIHZhbHVlKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHdoZXJlUGF0dGVybiA9XG4gICAgICAgICAgcGF0dGVybnMubGVuZ3RoID4gMCA/IGBXSEVSRSAke3BhdHRlcm5zLmpvaW4oYCAke29yT3JBbmR9IGApfWAgOiAnJztcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kbGltaXQpIHtcbiAgICAgICAgbGltaXRQYXR0ZXJuID0gYExJTUlUICQke2luZGV4fWA7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0YWdlLiRsaW1pdCk7XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJHNraXApIHtcbiAgICAgICAgc2tpcFBhdHRlcm4gPSBgT0ZGU0VUICQke2luZGV4fWA7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0YWdlLiRza2lwKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kc29ydCkge1xuICAgICAgICBjb25zdCBzb3J0ID0gc3RhZ2UuJHNvcnQ7XG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhzb3J0KTtcbiAgICAgICAgY29uc3Qgc29ydGluZyA9IGtleXNcbiAgICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lciA9IHNvcnRba2V5XSA9PT0gMSA/ICdBU0MnIDogJ0RFU0MnO1xuICAgICAgICAgICAgY29uc3Qgb3JkZXIgPSBgJCR7aW5kZXh9Om5hbWUgJHt0cmFuc2Zvcm1lcn1gO1xuICAgICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICAgIHJldHVybiBvcmRlcjtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5qb2luKCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKC4uLmtleXMpO1xuICAgICAgICBzb3J0UGF0dGVybiA9XG4gICAgICAgICAgc29ydCAhPT0gdW5kZWZpbmVkICYmIHNvcnRpbmcubGVuZ3RoID4gMCA/IGBPUkRFUiBCWSAke3NvcnRpbmd9YCA6ICcnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChncm91cFBhdHRlcm4pIHtcbiAgICAgIGNvbHVtbnMuZm9yRWFjaCgoZSwgaSwgYSkgPT4ge1xuICAgICAgICBpZiAoZSAmJiBlLnRyaW0oKSA9PT0gJyonKSB7XG4gICAgICAgICAgYVtpXSA9ICcnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFF1ZXJ5ID0gYFNFTEVDVCAke2NvbHVtbnNcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKCl9IEZST00gJDE6bmFtZSAke3doZXJlUGF0dGVybn0gJHtza2lwUGF0dGVybn0gJHtncm91cFBhdHRlcm59ICR7c29ydFBhdHRlcm59ICR7bGltaXRQYXR0ZXJufWA7XG4gICAgY29uc3QgcXMgPSBleHBsYWluXG4gICAgICA/IHRoaXMuY3JlYXRlRXhwbGFpbmFibGVRdWVyeShvcmlnaW5hbFF1ZXJ5KVxuICAgICAgOiBvcmlnaW5hbFF1ZXJ5O1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQuYW55KHFzLCB2YWx1ZXMpLnRoZW4oYSA9PiB7XG4gICAgICBpZiAoZXhwbGFpbikge1xuICAgICAgICByZXR1cm4gYTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhLm1hcChvYmplY3QgPT5cbiAgICAgICAgdGhpcy5wb3N0Z3Jlc09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSlcbiAgICAgICk7XG4gICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCAnb2JqZWN0SWQnKSkge1xuICAgICAgICAgIHJlc3VsdC5vYmplY3RJZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdyb3VwVmFsdWVzKSB7XG4gICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0ge307XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZ3JvdXBWYWx1ZXMpIHtcbiAgICAgICAgICAgIHJlc3VsdC5vYmplY3RJZFtrZXldID0gcmVzdWx0W2tleV07XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0W2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb3VudEZpZWxkKSB7XG4gICAgICAgICAgcmVzdWx0W2NvdW50RmllbGRdID0gcGFyc2VJbnQocmVzdWx0W2NvdW50RmllbGRdLCAxMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBwZXJmb3JtSW5pdGlhbGl6YXRpb24oeyBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzIH06IGFueSkge1xuICAgIC8vIFRPRE86IFRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB0byBtYWtlIHByb3BlciB1c2Ugb2YgY29ubmVjdGlvbnMgKEB2aXRhbHktdClcbiAgICBkZWJ1ZygncGVyZm9ybUluaXRpYWxpemF0aW9uJyk7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzLm1hcChzY2hlbWEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVGFibGUoc2NoZW1hLmNsYXNzTmFtZSwgc2NoZW1hKVxuICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBlcnIuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIHx8XG4gICAgICAgICAgICBlcnIuY29kZSA9PT0gUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5zY2hlbWFVcGdyYWRlKHNjaGVtYS5jbGFzc05hbWUsIHNjaGVtYSkpO1xuICAgIH0pO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcylcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudC50eCgncGVyZm9ybS1pbml0aWFsaXphdGlvbicsIHQgPT4ge1xuICAgICAgICAgIHJldHVybiB0LmJhdGNoKFtcbiAgICAgICAgICAgIHQubm9uZShzcWwubWlzYy5qc29uT2JqZWN0U2V0S2V5cyksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmFkZCksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmFkZFVuaXF1ZSksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LnJlbW92ZSksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zQWxsKSxcbiAgICAgICAgICAgIHQubm9uZShzcWwuYXJyYXkuY29udGFpbnNBbGxSZWdleCksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zKSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgIGRlYnVnKGBpbml0aWFsaXphdGlvbkRvbmUgaW4gJHtkYXRhLmR1cmF0aW9ufWApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4ZXMoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgaW5kZXhlczogYW55LFxuICAgIGNvbm46ID9hbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIChjb25uIHx8IHRoaXMuX2NsaWVudCkudHgodCA9PlxuICAgICAgdC5iYXRjaChcbiAgICAgICAgaW5kZXhlcy5tYXAoaSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHQubm9uZSgnQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgJDE6bmFtZSBPTiAkMjpuYW1lICgkMzpuYW1lKScsIFtcbiAgICAgICAgICAgIGkubmFtZSxcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIGkua2V5LFxuICAgICAgICAgIF0pO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVJbmRleGVzSWZOZWVkZWQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgdHlwZTogYW55LFxuICAgIGNvbm46ID9hbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgKFxuICAgICAgY29ubiB8fCB0aGlzLl9jbGllbnRcbiAgICApLm5vbmUoJ0NSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTICQxOm5hbWUgT04gJDI6bmFtZSAoJDM6bmFtZSknLCBbXG4gICAgICBmaWVsZE5hbWUsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0eXBlLFxuICAgIF0pO1xuICB9XG5cbiAgYXN5bmMgZHJvcEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4ZXM6IGFueSwgY29ubjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcXVlcmllcyA9IGluZGV4ZXMubWFwKGkgPT4gKHtcbiAgICAgIHF1ZXJ5OiAnRFJPUCBJTkRFWCAkMTpuYW1lJyxcbiAgICAgIHZhbHVlczogaSxcbiAgICB9KSk7XG4gICAgYXdhaXQgKGNvbm4gfHwgdGhpcy5fY2xpZW50KS50eCh0ID0+XG4gICAgICB0Lm5vbmUodGhpcy5fcGdwLmhlbHBlcnMuY29uY2F0KHF1ZXJpZXMpKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcXMgPSAnU0VMRUNUICogRlJPTSBwZ19pbmRleGVzIFdIRVJFIHRhYmxlbmFtZSA9ICR7Y2xhc3NOYW1lfSc7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5hbnkocXMsIHsgY2xhc3NOYW1lIH0pO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlU2NoZW1hV2l0aEluZGV4ZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gVXNlZCBmb3IgdGVzdGluZyBwdXJwb3Nlc1xuICBhc3luYyB1cGRhdGVFc3RpbWF0ZWRDb3VudChjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQubm9uZSgnQU5BTFlaRSAkMTpuYW1lJywgW2NsYXNzTmFtZV0pO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbmFsU2Vzc2lvbiA9IHt9O1xuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0ID0gdGhpcy5fY2xpZW50LnR4KHQgPT4ge1xuICAgICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi50ID0gdDtcbiAgICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucHJvbWlzZSA9IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICB9KTtcbiAgICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2ggPSBbXTtcbiAgICAgICAgcmVzb2x2ZSh0cmFuc2FjdGlvbmFsU2Vzc2lvbik7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5wcm9taXNlO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2Vzc2lvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzb2x2ZShcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQuYmF0Y2godHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gpXG4gICAgKTtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0O1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2Vzc2lvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0LmNhdGNoKCk7XG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChQcm9taXNlLnJlamVjdCgpKTtcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXNvbHZlKFxuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24udC5iYXRjaCh0cmFuc2FjdGlvbmFsU2Vzc2lvbi5iYXRjaClcbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBlbnN1cmVJbmRleChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgZmllbGROYW1lczogc3RyaW5nW10sXG4gICAgaW5kZXhOYW1lOiA/c3RyaW5nLFxuICAgIGNhc2VJbnNlbnNpdGl2ZTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIG9wdGlvbnM/OiBPYmplY3QgPSB7fVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGNvbm4gPSBvcHRpb25zLmNvbm4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29ubiA6IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBkZWZhdWx0SW5kZXhOYW1lID0gYHBhcnNlX2RlZmF1bHRfJHtmaWVsZE5hbWVzLnNvcnQoKS5qb2luKCdfJyl9YDtcbiAgICBjb25zdCBpbmRleE5hbWVPcHRpb25zOiBPYmplY3QgPVxuICAgICAgaW5kZXhOYW1lICE9IG51bGwgPyB7IG5hbWU6IGluZGV4TmFtZSB9IDogeyBuYW1lOiBkZWZhdWx0SW5kZXhOYW1lIH07XG4gICAgY29uc3QgY29uc3RyYWludFBhdHRlcm5zID0gY2FzZUluc2Vuc2l0aXZlXG4gICAgICA/IGZpZWxkTmFtZXMubWFwKFxuICAgICAgICAoZmllbGROYW1lLCBpbmRleCkgPT4gYGxvd2VyKCQke2luZGV4ICsgM306bmFtZSkgdmFyY2hhcl9wYXR0ZXJuX29wc2BcbiAgICAgIClcbiAgICAgIDogZmllbGROYW1lcy5tYXAoKGZpZWxkTmFtZSwgaW5kZXgpID0+IGAkJHtpbmRleCArIDN9Om5hbWVgKTtcbiAgICBjb25zdCBxcyA9IGBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyAkMTpuYW1lIE9OICQyOm5hbWUgKCR7Y29uc3RyYWludFBhdHRlcm5zLmpvaW4oKX0pYDtcbiAgICBhd2FpdCBjb25uXG4gICAgICAubm9uZShxcywgW2luZGV4TmFtZU9wdGlvbnMubmFtZSwgY2xhc3NOYW1lLCAuLi5maWVsZE5hbWVzXSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlcnJvci5jb2RlID09PSBQb3N0Z3Jlc0R1cGxpY2F0ZVJlbGF0aW9uRXJyb3IgJiZcbiAgICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGluZGV4TmFtZU9wdGlvbnMubmFtZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gSW5kZXggYWxyZWFkeSBleGlzdHMuIElnbm9yZSBlcnJvci5cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBlcnJvci5jb2RlID09PSBQb3N0Z3Jlc1VuaXF1ZUluZGV4VmlvbGF0aW9uRXJyb3IgJiZcbiAgICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGluZGV4TmFtZU9wdGlvbnMubmFtZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gQ2FzdCB0aGUgZXJyb3IgaW50byB0aGUgcHJvcGVyIHBhcnNlIGVycm9yXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ0EgZHVwbGljYXRlIHZhbHVlIGZvciBhIGZpZWxkIHdpdGggdW5pcXVlIHZhbHVlcyB3YXMgcHJvdmlkZWQnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydFBvbHlnb25Ub1NRTChwb2x5Z29uKSB7XG4gIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgUG9seWdvbiBtdXN0IGhhdmUgYXQgbGVhc3QgMyB2YWx1ZXNgXG4gICAgKTtcbiAgfVxuICBpZiAoXG4gICAgcG9seWdvblswXVswXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzBdIHx8XG4gICAgcG9seWdvblswXVsxXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzFdXG4gICkge1xuICAgIHBvbHlnb24ucHVzaChwb2x5Z29uWzBdKTtcbiAgfVxuICBjb25zdCB1bmlxdWUgPSBwb2x5Z29uLmZpbHRlcigoaXRlbSwgaW5kZXgsIGFyKSA9PiB7XG4gICAgbGV0IGZvdW5kSW5kZXggPSAtMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBwdCA9IGFyW2ldO1xuICAgICAgaWYgKHB0WzBdID09PSBpdGVtWzBdICYmIHB0WzFdID09PSBpdGVtWzFdKSB7XG4gICAgICAgIGZvdW5kSW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kSW5kZXggPT09IGluZGV4O1xuICB9KTtcbiAgaWYgKHVuaXF1ZS5sZW5ndGggPCAzKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgJ0dlb0pTT046IExvb3AgbXVzdCBoYXZlIGF0IGxlYXN0IDMgZGlmZmVyZW50IHZlcnRpY2VzJ1xuICAgICk7XG4gIH1cbiAgY29uc3QgcG9pbnRzID0gcG9seWdvblxuICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBhcnNlRmxvYXQocG9pbnRbMV0pLCBwYXJzZUZsb2F0KHBvaW50WzBdKSk7XG4gICAgICByZXR1cm4gYCgke3BvaW50WzFdfSwgJHtwb2ludFswXX0pYDtcbiAgICB9KVxuICAgIC5qb2luKCcsICcpO1xuICByZXR1cm4gYCgke3BvaW50c30pYDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCkge1xuICBpZiAoIXJlZ2V4LmVuZHNXaXRoKCdcXG4nKSkge1xuICAgIHJlZ2V4ICs9ICdcXG4nO1xuICB9XG5cbiAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIGNvbW1lbnRzXG4gIHJldHVybiAoXG4gICAgcmVnZXhcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSkjLipcXG4vZ2ltLCAnJDEnKVxuICAgICAgLy8gcmVtb3ZlIGxpbmVzIHN0YXJ0aW5nIHdpdGggYSBjb21tZW50XG4gICAgICAucmVwbGFjZSgvXiMuKlxcbi9naW0sICcnKVxuICAgICAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIHdoaXRlc3BhY2VcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSlcXHMrL2dpbSwgJyQxJylcbiAgICAgIC8vIHJlbW92ZSB3aGl0ZXNwYWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBsaW5lXG4gICAgICAucmVwbGFjZSgvXlxccysvLCAnJylcbiAgICAgIC50cmltKClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1JlZ2V4UGF0dGVybihzKSB7XG4gIGlmIChzICYmIHMuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgLy8gcmVnZXggZm9yIHN0YXJ0c1dpdGhcbiAgICByZXR1cm4gJ14nICsgbGl0ZXJhbGl6ZVJlZ2V4UGFydChzLnNsaWNlKDEpKTtcbiAgfSBlbHNlIGlmIChzICYmIHMuZW5kc1dpdGgoJyQnKSkge1xuICAgIC8vIHJlZ2V4IGZvciBlbmRzV2l0aFxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHMuc2xpY2UoMCwgcy5sZW5ndGggLSAxKSkgKyAnJCc7XG4gIH1cblxuICAvLyByZWdleCBmb3IgY29udGFpbnNcbiAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocyk7XG59XG5cbmZ1bmN0aW9uIGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCAhdmFsdWUuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IHZhbHVlLm1hdGNoKC9cXF5cXFxcUS4qXFxcXEUvKTtcbiAgcmV0dXJuICEhbWF0Y2hlcztcbn1cblxuZnVuY3Rpb24gaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSh2YWx1ZXMpIHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0uJHJlZ2V4KTtcbiAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZmlyc3RWYWx1ZXNJc1JlZ2V4O1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDEsIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmIChmaXJzdFZhbHVlc0lzUmVnZXggIT09IGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlc1tpXS4kcmVnZXgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgodmFsdWVzKSB7XG4gIHJldHVybiB2YWx1ZXMuc29tZShmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNTdGFydHNXaXRoUmVnZXgodmFsdWUuJHJlZ2V4KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpIHtcbiAgcmV0dXJuIHJlbWFpbmluZ1xuICAgIC5zcGxpdCgnJylcbiAgICAubWFwKGMgPT4ge1xuICAgICAgY29uc3QgcmVnZXggPSBSZWdFeHAoJ1swLTkgXXxcXFxccHtMfScsICd1Jyk7IC8vIFN1cHBvcnQgYWxsIHVuaWNvZGUgbGV0dGVyIGNoYXJzXG4gICAgICBpZiAoYy5tYXRjaChyZWdleCkgIT09IG51bGwpIHtcbiAgICAgICAgLy8gZG9uJ3QgZXNjYXBlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzXG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfVxuICAgICAgLy8gZXNjYXBlIGV2ZXJ5dGhpbmcgZWxzZSAoc2luZ2xlIHF1b3RlcyB3aXRoIHNpbmdsZSBxdW90ZXMsIGV2ZXJ5dGhpbmcgZWxzZSB3aXRoIGEgYmFja3NsYXNoKVxuICAgICAgcmV0dXJuIGMgPT09IGAnYCA/IGAnJ2AgOiBgXFxcXCR7Y31gO1xuICAgIH0pXG4gICAgLmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBsaXRlcmFsaXplUmVnZXhQYXJ0KHM6IHN0cmluZykge1xuICBjb25zdCBtYXRjaGVyMSA9IC9cXFxcUSgoPyFcXFxcRSkuKilcXFxcRSQvO1xuICBjb25zdCByZXN1bHQxOiBhbnkgPSBzLm1hdGNoKG1hdGNoZXIxKTtcbiAgaWYgKHJlc3VsdDEgJiYgcmVzdWx0MS5sZW5ndGggPiAxICYmIHJlc3VsdDEuaW5kZXggPiAtMSkge1xuICAgIC8vIHByb2Nlc3MgcmVnZXggdGhhdCBoYXMgYSBiZWdpbm5pbmcgYW5kIGFuIGVuZCBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgICBjb25zdCBwcmVmaXggPSBzLnN1YnN0cigwLCByZXN1bHQxLmluZGV4KTtcbiAgICBjb25zdCByZW1haW5pbmcgPSByZXN1bHQxWzFdO1xuXG4gICAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocHJlZml4KSArIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpO1xuICB9XG5cbiAgLy8gcHJvY2VzcyByZWdleCB0aGF0IGhhcyBhIGJlZ2lubmluZyBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgY29uc3QgbWF0Y2hlcjIgPSAvXFxcXFEoKD8hXFxcXEUpLiopJC87XG4gIGNvbnN0IHJlc3VsdDI6IGFueSA9IHMubWF0Y2gobWF0Y2hlcjIpO1xuICBpZiAocmVzdWx0MiAmJiByZXN1bHQyLmxlbmd0aCA+IDEgJiYgcmVzdWx0Mi5pbmRleCA+IC0xKSB7XG4gICAgY29uc3QgcHJlZml4ID0gcy5zdWJzdHIoMCwgcmVzdWx0Mi5pbmRleCk7XG4gICAgY29uc3QgcmVtYWluaW5nID0gcmVzdWx0MlsxXTtcblxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHByZWZpeCkgKyBjcmVhdGVMaXRlcmFsUmVnZXgocmVtYWluaW5nKTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBhbGwgaW5zdGFuY2VzIG9mIFxcUSBhbmQgXFxFIGZyb20gdGhlIHJlbWFpbmluZyB0ZXh0ICYgZXNjYXBlIHNpbmdsZSBxdW90ZXNcbiAgcmV0dXJuIHNcbiAgICAucmVwbGFjZSgvKFteXFxcXF0pKFxcXFxFKS8sICckMScpXG4gICAgLnJlcGxhY2UoLyhbXlxcXFxdKShcXFxcUSkvLCAnJDEnKVxuICAgIC5yZXBsYWNlKC9eXFxcXEUvLCAnJylcbiAgICAucmVwbGFjZSgvXlxcXFxRLywgJycpXG4gICAgLnJlcGxhY2UoLyhbXiddKScvLCBgJDEnJ2ApXG4gICAgLnJlcGxhY2UoL14nKFteJ10pLywgYCcnJDFgKTtcbn1cblxudmFyIEdlb1BvaW50Q29kZXIgPSB7XG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnXG4gICAgKTtcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFBvc3RncmVzU3RvcmFnZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql b/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql new file mode 100644 index 0000000000..aad90d45f5 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_add_unique( + "array" jsonb, + "values" jsonb +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT array_to_json(ARRAY(SELECT DISTINCT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT DISTINCT jsonb_array_elements("values")))))::jsonb; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/add.sql b/lib/Adapters/Storage/Postgres/sql/array/add.sql new file mode 100644 index 0000000000..a0b5859908 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/add.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_add( + "array" jsonb, + "values" jsonb +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT array_to_json(ARRAY(SELECT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT jsonb_array_elements("values")))))::jsonb; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql new file mode 100644 index 0000000000..7ca5853a9f --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql @@ -0,0 +1,14 @@ +CREATE OR REPLACE FUNCTION array_contains_all_regex( + "array" jsonb, + "values" jsonb +) + RETURNS boolean + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT CASE + WHEN 0 = jsonb_array_length("values") THEN true = false + ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt LIKE ANY (SELECT jsonb_array_elements_text("values"))) as RES) + END; +$function$; \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql new file mode 100644 index 0000000000..8db1ca0e7b --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql @@ -0,0 +1,14 @@ +CREATE OR REPLACE FUNCTION array_contains_all( + "array" jsonb, + "values" jsonb +) + RETURNS boolean + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT CASE + WHEN 0 = jsonb_array_length("values") THEN true = false + ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt IN (SELECT jsonb_array_elements_text("values"))) as RES) + END; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains.sql b/lib/Adapters/Storage/Postgres/sql/array/contains.sql new file mode 100644 index 0000000000..f7c458782e --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/contains.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_contains( + "array" jsonb, + "values" jsonb +) + RETURNS boolean + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT RES.CNT >= 1 FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements("array") as elt WHERE elt IN (SELECT jsonb_array_elements("values"))) as RES; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/remove.sql b/lib/Adapters/Storage/Postgres/sql/array/remove.sql new file mode 100644 index 0000000000..52895d2f46 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/remove.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_remove( + "array" jsonb, + "values" jsonb +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT array_to_json(ARRAY(SELECT * FROM jsonb_array_elements("array") as elt WHERE elt NOT IN (SELECT * FROM (SELECT jsonb_array_elements("values")) AS sub)))::jsonb; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/index.js b/lib/Adapters/Storage/Postgres/sql/index.js new file mode 100644 index 0000000000..2fc76f3ab1 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/index.js @@ -0,0 +1,35 @@ +'use strict'; + +var QueryFile = require('pg-promise').QueryFile; + +var path = require('path'); + +module.exports = { + array: { + add: sql('array/add.sql'), + addUnique: sql('array/add-unique.sql'), + contains: sql('array/contains.sql'), + containsAll: sql('array/contains-all.sql'), + containsAllRegex: sql('array/contains-all-regex.sql'), + remove: sql('array/remove.sql') + }, + misc: { + jsonObjectSetKeys: sql('misc/json-object-set-keys.sql') + } +}; /////////////////////////////////////////////// +// Helper for linking to external query files; + +function sql(file) { + var fullPath = path.join(__dirname, file); // generating full path; + + var qf = new QueryFile(fullPath, { + minify: true + }); + + if (qf.error) { + throw qf.error; + } + + return qf; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL3NxbC9pbmRleC5qcyJdLCJuYW1lcyI6WyJRdWVyeUZpbGUiLCJyZXF1aXJlIiwicGF0aCIsIm1vZHVsZSIsImV4cG9ydHMiLCJhcnJheSIsImFkZCIsInNxbCIsImFkZFVuaXF1ZSIsImNvbnRhaW5zIiwiY29udGFpbnNBbGwiLCJjb250YWluc0FsbFJlZ2V4IiwicmVtb3ZlIiwibWlzYyIsImpzb25PYmplY3RTZXRLZXlzIiwiZmlsZSIsImZ1bGxQYXRoIiwiam9pbiIsIl9fZGlybmFtZSIsInFmIiwibWluaWZ5IiwiZXJyb3IiXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBLElBQUlBLFNBQVMsR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsU0FBdEM7O0FBQ0EsSUFBSUUsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFsQjs7QUFFQUUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZDLEVBQUFBLEtBQUssRUFBRTtBQUNMQyxJQUFBQSxHQUFHLEVBQUVDLEdBQUcsQ0FBQyxlQUFELENBREg7QUFFTEMsSUFBQUEsU0FBUyxFQUFFRCxHQUFHLENBQUMsc0JBQUQsQ0FGVDtBQUdMRSxJQUFBQSxRQUFRLEVBQUVGLEdBQUcsQ0FBQyxvQkFBRCxDQUhSO0FBSUxHLElBQUFBLFdBQVcsRUFBRUgsR0FBRyxDQUFDLHdCQUFELENBSlg7QUFLTEksSUFBQUEsZ0JBQWdCLEVBQUVKLEdBQUcsQ0FBQyw4QkFBRCxDQUxoQjtBQU1MSyxJQUFBQSxNQUFNLEVBQUVMLEdBQUcsQ0FBQyxrQkFBRDtBQU5OLEdBRFE7QUFTZk0sRUFBQUEsSUFBSSxFQUFFO0FBQ0pDLElBQUFBLGlCQUFpQixFQUFFUCxHQUFHLENBQUMsK0JBQUQ7QUFEbEI7QUFUUyxDQUFqQixDLENBY0E7QUFDQTs7QUFDQSxTQUFTQSxHQUFULENBQWFRLElBQWIsRUFBbUI7QUFDakIsTUFBSUMsUUFBUSxHQUFHZCxJQUFJLENBQUNlLElBQUwsQ0FBVUMsU0FBVixFQUFxQkgsSUFBckIsQ0FBZixDQURpQixDQUMwQjs7QUFFM0MsTUFBSUksRUFBRSxHQUFHLElBQUluQixTQUFKLENBQWNnQixRQUFkLEVBQXdCO0FBQUVJLElBQUFBLE1BQU0sRUFBRTtBQUFWLEdBQXhCLENBQVQ7O0FBRUEsTUFBSUQsRUFBRSxDQUFDRSxLQUFQLEVBQWM7QUFDWixVQUFNRixFQUFFLENBQUNFLEtBQVQ7QUFDRDs7QUFFRCxTQUFPRixFQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBRdWVyeUZpbGUgPSByZXF1aXJlKCdwZy1wcm9taXNlJykuUXVlcnlGaWxlO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhcnJheToge1xuICAgIGFkZDogc3FsKCdhcnJheS9hZGQuc3FsJyksXG4gICAgYWRkVW5pcXVlOiBzcWwoJ2FycmF5L2FkZC11bmlxdWUuc3FsJyksXG4gICAgY29udGFpbnM6IHNxbCgnYXJyYXkvY29udGFpbnMuc3FsJyksXG4gICAgY29udGFpbnNBbGw6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLnNxbCcpLFxuICAgIGNvbnRhaW5zQWxsUmVnZXg6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLXJlZ2V4LnNxbCcpLFxuICAgIHJlbW92ZTogc3FsKCdhcnJheS9yZW1vdmUuc3FsJyksXG4gIH0sXG4gIG1pc2M6IHtcbiAgICBqc29uT2JqZWN0U2V0S2V5czogc3FsKCdtaXNjL2pzb24tb2JqZWN0LXNldC1rZXlzLnNxbCcpLFxuICB9LFxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEhlbHBlciBmb3IgbGlua2luZyB0byBleHRlcm5hbCBxdWVyeSBmaWxlcztcbmZ1bmN0aW9uIHNxbChmaWxlKSB7XG4gIHZhciBmdWxsUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsIGZpbGUpOyAvLyBnZW5lcmF0aW5nIGZ1bGwgcGF0aDtcblxuICB2YXIgcWYgPSBuZXcgUXVlcnlGaWxlKGZ1bGxQYXRoLCB7IG1pbmlmeTogdHJ1ZSB9KTtcblxuICBpZiAocWYuZXJyb3IpIHtcbiAgICB0aHJvdyBxZi5lcnJvcjtcbiAgfVxuXG4gIHJldHVybiBxZjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql b/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql new file mode 100644 index 0000000000..eb28b36928 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql @@ -0,0 +1,19 @@ +-- Function to set a key on a nested JSON document + +CREATE OR REPLACE FUNCTION json_object_set_key( + "json" jsonb, + key_to_set TEXT, + value_to_set anyelement +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ +SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::jsonb + FROM (SELECT * + FROM jsonb_each("json") + WHERE key <> key_to_set + UNION ALL + SELECT key_to_set, to_json("value_to_set")::jsonb) AS fields +$function$; diff --git a/lib/Adapters/Storage/StorageAdapter.js b/lib/Adapters/Storage/StorageAdapter.js new file mode 100644 index 0000000000..4310b4ffac --- /dev/null +++ b/lib/Adapters/Storage/StorageAdapter.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSAdapter.js b/lib/Adapters/WebSocketServer/WSAdapter.js new file mode 100644 index 0000000000..a586fbcd8a --- /dev/null +++ b/lib/Adapters/WebSocketServer/WSAdapter.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.WSAdapter = void 0; + +var _WSSAdapter = require("./WSSAdapter"); + +/*eslint no-unused-vars: "off"*/ +const WebSocketServer = require('ws').Server; +/** + * Wrapper for ws node module + */ + + +class WSAdapter extends _WSSAdapter.WSSAdapter { + constructor(options) { + super(options); + this.options = options; + } + + onListen() {} + + onConnection(ws) {} + + onError(error) {} + + start() { + const wss = new WebSocketServer({ + server: this.options.server + }); + wss.on('listening', this.onListen); + wss.on('connection', this.onConnection); + wss.on('error', this.onError); + } + + close() {} + +} + +exports.WSAdapter = WSAdapter; +var _default = WSAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIldlYlNvY2tldFNlcnZlciIsInJlcXVpcmUiLCJTZXJ2ZXIiLCJXU0FkYXB0ZXIiLCJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uRXJyb3IiLCJlcnJvciIsInN0YXJ0Iiwid3NzIiwic2VydmVyIiwib24iLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQURBO0FBRUEsTUFBTUEsZUFBZSxHQUFHQyxPQUFPLENBQUMsSUFBRCxDQUFQLENBQWNDLE1BQXRDO0FBRUE7Ozs7O0FBR08sTUFBTUMsU0FBTixTQUF3QkMsc0JBQXhCLENBQW1DO0FBQ3hDQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBZTtBQUN4QixVQUFNQSxPQUFOO0FBQ0EsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRURDLEVBQUFBLFFBQVEsR0FBRyxDQUFFOztBQUNiQyxFQUFBQSxZQUFZLENBQUNDLEVBQUQsRUFBSyxDQUFFOztBQUNuQkMsRUFBQUEsT0FBTyxDQUFDQyxLQUFELEVBQVEsQ0FBRTs7QUFDakJDLEVBQUFBLEtBQUssR0FBRztBQUNOLFVBQU1DLEdBQUcsR0FBRyxJQUFJYixlQUFKLENBQW9CO0FBQUVjLE1BQUFBLE1BQU0sRUFBRSxLQUFLUixPQUFMLENBQWFRO0FBQXZCLEtBQXBCLENBQVo7QUFDQUQsSUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sV0FBUCxFQUFvQixLQUFLUixRQUF6QjtBQUNBTSxJQUFBQSxHQUFHLENBQUNFLEVBQUosQ0FBTyxZQUFQLEVBQXFCLEtBQUtQLFlBQTFCO0FBQ0FLLElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE9BQVAsRUFBZ0IsS0FBS0wsT0FBckI7QUFDRDs7QUFDRE0sRUFBQUEsS0FBSyxHQUFHLENBQUU7O0FBZjhCOzs7ZUFrQjNCYixTIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuaW1wb3J0IHsgV1NTQWRhcHRlciB9IGZyb20gJy4vV1NTQWRhcHRlcic7XG5jb25zdCBXZWJTb2NrZXRTZXJ2ZXIgPSByZXF1aXJlKCd3cycpLlNlcnZlcjtcblxuLyoqXG4gKiBXcmFwcGVyIGZvciB3cyBub2RlIG1vZHVsZVxuICovXG5leHBvcnQgY2xhc3MgV1NBZGFwdGVyIGV4dGVuZHMgV1NTQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IGFueSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBvbkxpc3RlbigpIHt9XG4gIG9uQ29ubmVjdGlvbih3cykge31cbiAgb25FcnJvcihlcnJvcikge31cbiAgc3RhcnQoKSB7XG4gICAgY29uc3Qgd3NzID0gbmV3IFdlYlNvY2tldFNlcnZlcih7IHNlcnZlcjogdGhpcy5vcHRpb25zLnNlcnZlciB9KTtcbiAgICB3c3Mub24oJ2xpc3RlbmluZycsIHRoaXMub25MaXN0ZW4pO1xuICAgIHdzcy5vbignY29ubmVjdGlvbicsIHRoaXMub25Db25uZWN0aW9uKTtcbiAgICB3c3Mub24oJ2Vycm9yJywgdGhpcy5vbkVycm9yKTtcbiAgfVxuICBjbG9zZSgpIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFdTQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSSAdapter.js b/lib/Adapters/WebSocketServer/WSSAdapter.js new file mode 100644 index 0000000000..d3a836e02d --- /dev/null +++ b/lib/Adapters/WebSocketServer/WSSAdapter.js @@ -0,0 +1,74 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.WSSAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ +// WebSocketServer Adapter +// +// Adapter classes must implement the following functions: +// * onListen() +// * onConnection(ws) +// * onError(error) +// * start() +// * close() +// +// Default is WSAdapter. The above functions will be binded. + +/** + * @module Adapters + */ + +/** + * @interface WSSAdapter + */ +class WSSAdapter { + /** + * @param {Object} options - {http.Server|https.Server} server + */ + constructor(options) { + this.onListen = () => {}; + + this.onConnection = () => {}; + + this.onError = () => {}; + } // /** + // * Emitted when the underlying server has been bound. + // */ + // onListen() {} + // /** + // * Emitted when the handshake is complete. + // * + // * @param {WebSocket} ws - RFC 6455 WebSocket. + // */ + // onConnection(ws) {} + // /** + // * Emitted when error event is called. + // * + // * @param {Error} error - WebSocketServer error + // */ + // onError(error) {} + + /** + * Initialize Connection. + * + * @param {Object} options + */ + + + start(options) {} + /** + * Closes server. + */ + + + close() {} + +} + +exports.WSSAdapter = WSSAdapter; +var _default = WSSAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJvbkVycm9yIiwic3RhcnQiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7QUFHQTs7O0FBR08sTUFBTUEsVUFBTixDQUFpQjtBQUN0Qjs7O0FBR0FDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVO0FBQ25CLFNBQUtDLFFBQUwsR0FBZ0IsTUFBTSxDQUFFLENBQXhCOztBQUNBLFNBQUtDLFlBQUwsR0FBb0IsTUFBTSxDQUFFLENBQTVCOztBQUNBLFNBQUtDLE9BQUwsR0FBZSxNQUFNLENBQUUsQ0FBdkI7QUFDRCxHQVJxQixDQVV0QjtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQUtBQyxFQUFBQSxLQUFLLENBQUNKLE9BQUQsRUFBVSxDQUFFO0FBRWpCOzs7OztBQUdBSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF2Q1k7OztlQTBDVFAsVSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8vIFdlYlNvY2tldFNlcnZlciBBZGFwdGVyXG4vL1xuLy8gQWRhcHRlciBjbGFzc2VzIG11c3QgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuLy8gKiBvbkxpc3RlbigpXG4vLyAqIG9uQ29ubmVjdGlvbih3cylcbi8vICogb25FcnJvcihlcnJvcilcbi8vICogc3RhcnQoKVxuLy8gKiBjbG9zZSgpXG4vL1xuLy8gRGVmYXVsdCBpcyBXU0FkYXB0ZXIuIFRoZSBhYm92ZSBmdW5jdGlvbnMgd2lsbCBiZSBiaW5kZWQuXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgV1NTQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgV1NTQWRhcHRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIHtodHRwLlNlcnZlcnxodHRwcy5TZXJ2ZXJ9IHNlcnZlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHRoaXMub25MaXN0ZW4gPSAoKSA9PiB7fTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbiA9ICgpID0+IHt9O1xuICAgIHRoaXMub25FcnJvciA9ICgpID0+IHt9O1xuICB9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgdW5kZXJseWluZyBzZXJ2ZXIgaGFzIGJlZW4gYm91bmQuXG4gIC8vICAqL1xuICAvLyBvbkxpc3RlbigpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgaGFuZHNoYWtlIGlzIGNvbXBsZXRlLlxuICAvLyAgKlxuICAvLyAgKiBAcGFyYW0ge1dlYlNvY2tldH0gd3MgLSBSRkMgNjQ1NSBXZWJTb2NrZXQuXG4gIC8vICAqL1xuICAvLyBvbkNvbm5lY3Rpb24od3MpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiBlcnJvciBldmVudCBpcyBjYWxsZWQuXG4gIC8vICAqXG4gIC8vICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gV2ViU29ja2V0U2VydmVyIGVycm9yXG4gIC8vICAqL1xuICAvLyBvbkVycm9yKGVycm9yKSB7fVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIENvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqL1xuICBzdGFydChvcHRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgc2VydmVyLlxuICAgKi9cbiAgY2xvc2UoKSB7fVxufVxuXG5leHBvcnQgZGVmYXVsdCBXU1NBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Auth.js b/lib/Auth.js new file mode 100644 index 0000000000..7fe33b66de --- /dev/null +++ b/lib/Auth.js @@ -0,0 +1,373 @@ +"use strict"; + +const cryptoUtils = require('./cryptoUtils'); + +const RestQuery = require('./RestQuery'); + +const Parse = require('parse/node'); // An Auth object tells you who is requesting something and whether +// the master key was used. +// userObject is a Parse.User and can be null if there's no user. + + +function Auth({ + config, + cacheController = undefined, + isMaster = false, + isReadOnly = false, + user, + installationId +}) { + this.config = config; + this.cacheController = cacheController || config && config.cacheController; + this.installationId = installationId; + this.isMaster = isMaster; + this.user = user; + this.isReadOnly = isReadOnly; // Assuming a users roles won't change during a single request, we'll + // only load them once. + + this.userRoles = []; + this.fetchedRoles = false; + this.rolePromise = null; +} // Whether this auth could possibly modify the given user id. +// It still could be forbidden via ACLs even if this returns true. + + +Auth.prototype.isUnauthenticated = function () { + if (this.isMaster) { + return false; + } + + if (this.user) { + return false; + } + + return true; +}; // A helper to get a master-level Auth object + + +function master(config) { + return new Auth({ + config, + isMaster: true + }); +} // A helper to get a master-level Auth object + + +function readOnly(config) { + return new Auth({ + config, + isMaster: true, + isReadOnly: true + }); +} // A helper to get a nobody-level Auth object + + +function nobody(config) { + return new Auth({ + config, + isMaster: false + }); +} // Returns a promise that resolves to an Auth object + + +const getAuthForSessionToken = async function ({ + config, + cacheController, + sessionToken, + installationId +}) { + cacheController = cacheController || config && config.cacheController; + + if (cacheController) { + const userJSON = await cacheController.user.get(sessionToken); + + if (userJSON) { + const cachedUser = Parse.Object.fromJSON(userJSON); + return Promise.resolve(new Auth({ + config, + cacheController, + isMaster: false, + installationId, + user: cachedUser + })); + } + } + + let results; + + if (config) { + const restOptions = { + limit: 1, + include: 'user' + }; + const query = new RestQuery(config, master(config), '_Session', { + sessionToken + }, restOptions); + results = (await query.execute()).results; + } else { + results = (await new Parse.Query(Parse.Session).limit(1).include('user').equalTo('sessionToken', sessionToken).find({ + useMasterKey: true + })).map(obj => obj.toJSON()); + } + + if (results.length !== 1 || !results[0]['user']) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + const now = new Date(), + expiresAt = results[0].expiresAt ? new Date(results[0].expiresAt.iso) : undefined; + + if (expiresAt < now) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.'); + } + + const obj = results[0]['user']; + delete obj.password; + obj['className'] = '_User'; + obj['sessionToken'] = sessionToken; + + if (cacheController) { + cacheController.user.put(sessionToken, obj); + } + + const userObject = Parse.Object.fromJSON(obj); + return new Auth({ + config, + cacheController, + isMaster: false, + installationId, + user: userObject + }); +}; + +var getAuthForLegacySessionToken = function ({ + config, + sessionToken, + installationId +}) { + var restOptions = { + limit: 1 + }; + var query = new RestQuery(config, master(config), '_User', { + sessionToken + }, restOptions); + return query.execute().then(response => { + var results = response.results; + + if (results.length !== 1) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token'); + } + + const obj = results[0]; + obj.className = '_User'; + const userObject = Parse.Object.fromJSON(obj); + return new Auth({ + config, + isMaster: false, + installationId, + user: userObject + }); + }); +}; // Returns a promise that resolves to an array of role names + + +Auth.prototype.getUserRoles = function () { + if (this.isMaster || !this.user) { + return Promise.resolve([]); + } + + if (this.fetchedRoles) { + return Promise.resolve(this.userRoles); + } + + if (this.rolePromise) { + return this.rolePromise; + } + + this.rolePromise = this._loadRoles(); + return this.rolePromise; +}; + +Auth.prototype.getRolesForUser = async function () { + //Stack all Parse.Role + const results = []; + + if (this.config) { + const restWhere = { + users: { + __type: 'Pointer', + className: '_User', + objectId: this.user.id + } + }; + await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); + } else { + await new Parse.Query(Parse.Role).equalTo('users', this.user).each(result => results.push(result.toJSON()), { + useMasterKey: true + }); + } + + return results; +}; // Iterates through the role tree and compiles a user's roles + + +Auth.prototype._loadRoles = async function () { + if (this.cacheController) { + const cachedRoles = await this.cacheController.role.get(this.user.id); + + if (cachedRoles != null) { + this.fetchedRoles = true; + this.userRoles = cachedRoles; + return cachedRoles; + } + } // First get the role ids this user is directly a member of + + + const results = await this.getRolesForUser(); + + if (!results.length) { + this.userRoles = []; + this.fetchedRoles = true; + this.rolePromise = null; + this.cacheRoles(); + return this.userRoles; + } + + const rolesMap = results.reduce((m, r) => { + m.names.push(r.name); + m.ids.push(r.objectId); + return m; + }, { + ids: [], + names: [] + }); // run the recursive finding + + const roleNames = await this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names); + this.userRoles = roleNames.map(r => { + return 'role:' + r; + }); + this.fetchedRoles = true; + this.rolePromise = null; + this.cacheRoles(); + return this.userRoles; +}; + +Auth.prototype.cacheRoles = function () { + if (!this.cacheController) { + return false; + } + + this.cacheController.role.put(this.user.id, Array(...this.userRoles)); + return true; +}; + +Auth.prototype.getRolesByIds = async function (ins) { + const results = []; // Build an OR query across all parentRoles + + if (!this.config) { + await new Parse.Query(Parse.Role).containedIn('roles', ins.map(id => { + const role = new Parse.Object(Parse.Role); + role.id = id; + return role; + })).each(result => results.push(result.toJSON()), { + useMasterKey: true + }); + } else { + const roles = ins.map(id => { + return { + __type: 'Pointer', + className: '_Role', + objectId: id + }; + }); + const restWhere = { + roles: { + $in: roles + } + }; + await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); + } + + return results; +}; // Given a list of roleIds, find all the parent roles, returns a promise with all names + + +Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], queriedRoles = {}) { + const ins = roleIDs.filter(roleID => { + const wasQueried = queriedRoles[roleID] !== true; + queriedRoles[roleID] = true; + return wasQueried; + }); // all roles are accounted for, return the names + + if (ins.length == 0) { + return Promise.resolve([...new Set(names)]); + } + + return this.getRolesByIds(ins).then(results => { + // Nothing found + if (!results.length) { + return Promise.resolve(names); + } // Map the results with all Ids and names + + + const resultMap = results.reduce((memo, role) => { + memo.names.push(role.name); + memo.ids.push(role.objectId); + return memo; + }, { + ids: [], + names: [] + }); // store the new found names + + names = names.concat(resultMap.names); // find the next ones, circular roles will be cut + + return this._getAllRolesNamesForRoleIds(resultMap.ids, names, queriedRoles); + }).then(names => { + return Promise.resolve([...new Set(names)]); + }); +}; + +const createSession = function (config, { + userId, + createdWith, + installationId, + additionalSessionData +}) { + const token = 'r:' + cryptoUtils.newToken(); + const expiresAt = config.generateSessionExpiresAt(); + const sessionData = { + sessionToken: token, + user: { + __type: 'Pointer', + className: '_User', + objectId: userId + }, + createdWith, + restricted: false, + expiresAt: Parse._encode(expiresAt) + }; + + if (installationId) { + sessionData.installationId = installationId; + } + + Object.assign(sessionData, additionalSessionData); // We need to import RestWrite at this point for the cyclic dependency it has to it + + const RestWrite = require('./RestWrite'); + + return { + sessionData, + createSession: () => new RestWrite(config, master(config), '_Session', null, sessionData).execute() + }; +}; + +module.exports = { + Auth, + master, + nobody, + readOnly, + getAuthForSessionToken, + getAuthForLegacySessionToken, + createSession +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BdXRoLmpzIl0sIm5hbWVzIjpbImNyeXB0b1V0aWxzIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlBhcnNlIiwiQXV0aCIsImNvbmZpZyIsImNhY2hlQ29udHJvbGxlciIsInVuZGVmaW5lZCIsImlzTWFzdGVyIiwiaXNSZWFkT25seSIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsInVzZXJSb2xlcyIsImZldGNoZWRSb2xlcyIsInJvbGVQcm9taXNlIiwicHJvdG90eXBlIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJtYXN0ZXIiLCJyZWFkT25seSIsIm5vYm9keSIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJzZXNzaW9uVG9rZW4iLCJ1c2VySlNPTiIsImdldCIsImNhY2hlZFVzZXIiLCJPYmplY3QiLCJmcm9tSlNPTiIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0cyIsInJlc3RPcHRpb25zIiwibGltaXQiLCJpbmNsdWRlIiwicXVlcnkiLCJleGVjdXRlIiwiUXVlcnkiLCJTZXNzaW9uIiwiZXF1YWxUbyIsImZpbmQiLCJ1c2VNYXN0ZXJLZXkiLCJtYXAiLCJvYmoiLCJ0b0pTT04iLCJsZW5ndGgiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIm5vdyIsIkRhdGUiLCJleHBpcmVzQXQiLCJpc28iLCJwYXNzd29yZCIsInB1dCIsInVzZXJPYmplY3QiLCJnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiY2xhc3NOYW1lIiwiZ2V0VXNlclJvbGVzIiwiX2xvYWRSb2xlcyIsImdldFJvbGVzRm9yVXNlciIsInJlc3RXaGVyZSIsInVzZXJzIiwiX190eXBlIiwib2JqZWN0SWQiLCJpZCIsImVhY2giLCJyZXN1bHQiLCJwdXNoIiwiUm9sZSIsImNhY2hlZFJvbGVzIiwicm9sZSIsImNhY2hlUm9sZXMiLCJyb2xlc01hcCIsInJlZHVjZSIsIm0iLCJyIiwibmFtZXMiLCJuYW1lIiwiaWRzIiwicm9sZU5hbWVzIiwiX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzIiwiQXJyYXkiLCJnZXRSb2xlc0J5SWRzIiwiaW5zIiwiY29udGFpbmVkSW4iLCJyb2xlcyIsIiRpbiIsInJvbGVJRHMiLCJxdWVyaWVkUm9sZXMiLCJmaWx0ZXIiLCJyb2xlSUQiLCJ3YXNRdWVyaWVkIiwiU2V0IiwicmVzdWx0TWFwIiwibWVtbyIsImNvbmNhdCIsImNyZWF0ZVNlc3Npb24iLCJ1c2VySWQiLCJjcmVhdGVkV2l0aCIsImFkZGl0aW9uYWxTZXNzaW9uRGF0YSIsInRva2VuIiwibmV3VG9rZW4iLCJnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQiLCJzZXNzaW9uRGF0YSIsInJlc3RyaWN0ZWQiLCJfZW5jb2RlIiwiYXNzaWduIiwiUmVzdFdyaXRlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFNQSxXQUFXLEdBQUdDLE9BQU8sQ0FBQyxlQUFELENBQTNCOztBQUNBLE1BQU1DLFNBQVMsR0FBR0QsT0FBTyxDQUFDLGFBQUQsQ0FBekI7O0FBQ0EsTUFBTUUsS0FBSyxHQUFHRixPQUFPLENBQUMsWUFBRCxDQUFyQixDLENBRUE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTRyxJQUFULENBQWM7QUFDWkMsRUFBQUEsTUFEWTtBQUVaQyxFQUFBQSxlQUFlLEdBQUdDLFNBRk47QUFHWkMsRUFBQUEsUUFBUSxHQUFHLEtBSEM7QUFJWkMsRUFBQUEsVUFBVSxHQUFHLEtBSkQ7QUFLWkMsRUFBQUEsSUFMWTtBQU1aQyxFQUFBQTtBQU5ZLENBQWQsRUFPRztBQUNELE9BQUtOLE1BQUwsR0FBY0EsTUFBZDtBQUNBLE9BQUtDLGVBQUwsR0FBdUJBLGVBQWUsSUFBS0QsTUFBTSxJQUFJQSxNQUFNLENBQUNDLGVBQTVEO0FBQ0EsT0FBS0ssY0FBTCxHQUFzQkEsY0FBdEI7QUFDQSxPQUFLSCxRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLE9BQUtFLElBQUwsR0FBWUEsSUFBWjtBQUNBLE9BQUtELFVBQUwsR0FBa0JB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LGNBQUosRUFBb0I7QUFDbEI0RixJQUFBQSxXQUFXLENBQUM1RixjQUFaLEdBQTZCQSxjQUE3QjtBQUNEOztBQUVEYyxFQUFBQSxNQUFNLENBQUNpRixNQUFQLENBQWNILFdBQWQsRUFBMkJKLHFCQUEzQixFQW5CQSxDQW9CQTs7QUFDQSxRQUFNUSxTQUFTLEdBQUcxRyxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFFQSxTQUFPO0FBQ0xzRyxJQUFBQSxXQURLO0FBRUxQLElBQUFBLGFBQWEsRUFBRSxNQUNiLElBQUlXLFNBQUosQ0FBY3RHLE1BQWQsRUFBc0JZLE1BQU0sQ0FBQ1osTUFBRCxDQUE1QixFQUFzQyxVQUF0QyxFQUFrRCxJQUFsRCxFQUF3RGtHLFdBQXhELEVBQXFFckUsT0FBckU7QUFIRyxHQUFQO0FBS0QsQ0EvQkQ7O0FBaUNBMEUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Z6RyxFQUFBQSxJQURlO0FBRWZhLEVBQUFBLE1BRmU7QUFHZkUsRUFBQUEsTUFIZTtBQUlmRCxFQUFBQSxRQUplO0FBS2ZFLEVBQUFBLHNCQUxlO0FBTWZpQyxFQUFBQSw0QkFOZTtBQU9mMkMsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xuY29uc3QgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi9SZXN0UXVlcnknKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuXG4vLyBBbiBBdXRoIG9iamVjdCB0ZWxscyB5b3Ugd2hvIGlzIHJlcXVlc3Rpbmcgc29tZXRoaW5nIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbi8vIHVzZXJPYmplY3QgaXMgYSBQYXJzZS5Vc2VyIGFuZCBjYW4gYmUgbnVsbCBpZiB0aGVyZSdzIG5vIHVzZXIuXG5mdW5jdGlvbiBBdXRoKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIgPSB1bmRlZmluZWQsXG4gIGlzTWFzdGVyID0gZmFsc2UsXG4gIGlzUmVhZE9ubHkgPSBmYWxzZSxcbiAgdXNlcixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gIHRoaXMuaXNNYXN0ZXIgPSBpc01hc3RlcjtcbiAgdGhpcy51c2VyID0gdXNlcjtcbiAgdGhpcy5pc1JlYWRPbmx5ID0gaXNSZWFkT25seTtcblxuICAvLyBBc3N1bWluZyBhIHVzZXJzIHJvbGVzIHdvbid0IGNoYW5nZSBkdXJpbmcgYSBzaW5nbGUgcmVxdWVzdCwgd2UnbGxcbiAgLy8gb25seSBsb2FkIHRoZW0gb25jZS5cbiAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSBmYWxzZTtcbiAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgdGhpcyBhdXRoIGNvdWxkIHBvc3NpYmx5IG1vZGlmeSB0aGUgZ2l2ZW4gdXNlciBpZC5cbi8vIEl0IHN0aWxsIGNvdWxkIGJlIGZvcmJpZGRlbiB2aWEgQUNMcyBldmVuIGlmIHRoaXMgcmV0dXJucyB0cnVlLlxuQXV0aC5wcm90b3R5cGUuaXNVbmF1dGhlbnRpY2F0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBtYXN0ZXItbGV2ZWwgQXV0aCBvYmplY3RcbmZ1bmN0aW9uIG1hc3Rlcihjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiByZWFkT25seShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSwgaXNSZWFkT25seTogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbm9ib2R5LWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBub2JvZHkoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IGZhbHNlIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEF1dGggb2JqZWN0XG5jb25zdCBnZXRBdXRoRm9yU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIsXG4gIHNlc3Npb25Ub2tlbixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIGNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICBpZiAoY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgdXNlckpTT04gPSBhd2FpdCBjYWNoZUNvbnRyb2xsZXIudXNlci5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlckpTT04pIHtcbiAgICAgIGNvbnN0IGNhY2hlZFVzZXIgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04odXNlckpTT04pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IEF1dGgoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHVzZXI6IGNhY2hlZFVzZXIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGxldCByZXN1bHRzO1xuICBpZiAoY29uZmlnKSB7XG4gICAgY29uc3QgcmVzdE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMSxcbiAgICAgIGluY2x1ZGU6ICd1c2VyJyxcbiAgICB9O1xuXG4gICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIHsgc2Vzc2lvblRva2VuIH0sIHJlc3RPcHRpb25zKTtcbiAgICByZXN1bHRzID0gKGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKSkucmVzdWx0cztcbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzID0gKFxuICAgICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlNlc3Npb24pXG4gICAgICAgIC5saW1pdCgxKVxuICAgICAgICAuaW5jbHVkZSgndXNlcicpXG4gICAgICAgIC5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pXG4gICAgICAgIC5maW5kKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pXG4gICAgKS5tYXAob2JqID0+IG9iai50b0pTT04oKSk7XG4gIH1cblxuICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEgfHwgIXJlc3VsdHNbMF1bJ3VzZXInXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfVxuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLFxuICAgIGV4cGlyZXNBdCA9IHJlc3VsdHNbMF0uZXhwaXJlc0F0ID8gbmV3IERhdGUocmVzdWx0c1swXS5leHBpcmVzQXQuaXNvKSA6IHVuZGVmaW5lZDtcbiAgaWYgKGV4cGlyZXNBdCA8IG5vdykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdTZXNzaW9uIHRva2VuIGlzIGV4cGlyZWQuJyk7XG4gIH1cbiAgY29uc3Qgb2JqID0gcmVzdWx0c1swXVsndXNlciddO1xuICBkZWxldGUgb2JqLnBhc3N3b3JkO1xuICBvYmpbJ2NsYXNzTmFtZSddID0gJ19Vc2VyJztcbiAgb2JqWydzZXNzaW9uVG9rZW4nXSA9IHNlc3Npb25Ub2tlbjtcbiAgaWYgKGNhY2hlQ29udHJvbGxlcikge1xuICAgIGNhY2hlQ29udHJvbGxlci51c2VyLnB1dChzZXNzaW9uVG9rZW4sIG9iaik7XG4gIH1cbiAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICByZXR1cm4gbmV3IEF1dGgoe1xuICAgIGNvbmZpZyxcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIGluc3RhbGxhdGlvbklkLFxuICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gIH0pO1xufTtcblxudmFyIGdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4gPSBmdW5jdGlvbiAoeyBjb25maWcsIHNlc3Npb25Ub2tlbiwgaW5zdGFsbGF0aW9uSWQgfSkge1xuICB2YXIgcmVzdE9wdGlvbnMgPSB7XG4gICAgbGltaXQ6IDEsXG4gIH07XG4gIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBtYXN0ZXIoY29uZmlnKSwgJ19Vc2VyJywgeyBzZXNzaW9uVG9rZW4gfSwgcmVzdE9wdGlvbnMpO1xuICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHZhciByZXN1bHRzID0gcmVzcG9uc2UucmVzdWx0cztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdpbnZhbGlkIGxlZ2FjeSBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IG9iaiA9IHJlc3VsdHNbMF07XG4gICAgb2JqLmNsYXNzTmFtZSA9ICdfVXNlcic7XG4gICAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICAgIHJldHVybiBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByb2xlIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5nZXRVc2VyUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyIHx8ICF0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfVxuICBpZiAodGhpcy5mZXRjaGVkUm9sZXMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMudXNlclJvbGVzKTtcbiAgfVxuICBpZiAodGhpcy5yb2xlUHJvbWlzZSkge1xuICAgIHJldHVybiB0aGlzLnJvbGVQcm9taXNlO1xuICB9XG4gIHRoaXMucm9sZVByb21pc2UgPSB0aGlzLl9sb2FkUm9sZXMoKTtcbiAgcmV0dXJuIHRoaXMucm9sZVByb21pc2U7XG59O1xuXG5BdXRoLnByb3RvdHlwZS5nZXRSb2xlc0ZvclVzZXIgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gIC8vU3RhY2sgYWxsIFBhcnNlLlJvbGVcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICBpZiAodGhpcy5jb25maWcpIHtcbiAgICBjb25zdCByZXN0V2hlcmUgPSB7XG4gICAgICB1c2Vyczoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy51c2VyLmlkLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGF3YWl0IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIG1hc3Rlcih0aGlzLmNvbmZpZyksICdfUm9sZScsIHJlc3RXaGVyZSwge30pLmVhY2gocmVzdWx0ID0+XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuZXF1YWxUbygndXNlcnMnLCB0aGlzLnVzZXIpXG4gICAgICAuZWFjaChyZXN1bHQgPT4gcmVzdWx0cy5wdXNoKHJlc3VsdC50b0pTT04oKSksIHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gSXRlcmF0ZXMgdGhyb3VnaCB0aGUgcm9sZSB0cmVlIGFuZCBjb21waWxlcyBhIHVzZXIncyByb2xlc1xuQXV0aC5wcm90b3R5cGUuX2xvYWRSb2xlcyA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY2FjaGVkUm9sZXMgPSBhd2FpdCB0aGlzLmNhY2hlQ29udHJvbGxlci5yb2xlLmdldCh0aGlzLnVzZXIuaWQpO1xuICAgIGlmIChjYWNoZWRSb2xlcyAhPSBudWxsKSB7XG4gICAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgICB0aGlzLnVzZXJSb2xlcyA9IGNhY2hlZFJvbGVzO1xuICAgICAgcmV0dXJuIGNhY2hlZFJvbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpcnN0IGdldCB0aGUgcm9sZSBpZHMgdGhpcyB1c2VyIGlzIGRpcmVjdGx5IGEgbWVtYmVyIG9mXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmdldFJvbGVzRm9yVXNlcigpO1xuICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG5cbiAgICB0aGlzLmNhY2hlUm9sZXMoKTtcbiAgICByZXR1cm4gdGhpcy51c2VyUm9sZXM7XG4gIH1cblxuICBjb25zdCByb2xlc01hcCA9IHJlc3VsdHMucmVkdWNlKFxuICAgIChtLCByKSA9PiB7XG4gICAgICBtLm5hbWVzLnB1c2goci5uYW1lKTtcbiAgICAgIG0uaWRzLnB1c2goci5vYmplY3RJZCk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9LFxuICAgIHsgaWRzOiBbXSwgbmFtZXM6IFtdIH1cbiAgKTtcblxuICAvLyBydW4gdGhlIHJlY3Vyc2l2ZSBmaW5kaW5nXG4gIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJvbGVzTWFwLmlkcywgcm9sZXNNYXAubmFtZXMpO1xuICB0aGlzLnVzZXJSb2xlcyA9IHJvbGVOYW1lcy5tYXAociA9PiB7XG4gICAgcmV0dXJuICdyb2xlOicgKyByO1xuICB9KTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbiAgdGhpcy5jYWNoZVJvbGVzKCk7XG4gIHJldHVybiB0aGlzLnVzZXJSb2xlcztcbn07XG5cbkF1dGgucHJvdG90eXBlLmNhY2hlUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jYWNoZUNvbnRyb2xsZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdGhpcy5jYWNoZUNvbnRyb2xsZXIucm9sZS5wdXQodGhpcy51c2VyLmlkLCBBcnJheSguLi50aGlzLnVzZXJSb2xlcykpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmdldFJvbGVzQnlJZHMgPSBhc3luYyBmdW5jdGlvbiAoaW5zKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgLy8gQnVpbGQgYW4gT1IgcXVlcnkgYWNyb3NzIGFsbCBwYXJlbnRSb2xlc1xuICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuY29udGFpbmVkSW4oXG4gICAgICAgICdyb2xlcycsXG4gICAgICAgIGlucy5tYXAoaWQgPT4ge1xuICAgICAgICAgIGNvbnN0IHJvbGUgPSBuZXcgUGFyc2UuT2JqZWN0KFBhcnNlLlJvbGUpO1xuICAgICAgICAgIHJvbGUuaWQgPSBpZDtcbiAgICAgICAgICByZXR1cm4gcm9sZTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0LnRvSlNPTigpKSwgeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgcm9sZXMgPSBpbnMubWFwKGlkID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfUm9sZScsXG4gICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgcmVzdFdoZXJlID0geyByb2xlczogeyAkaW46IHJvbGVzIH0gfTtcbiAgICBhd2FpdCBuZXcgUmVzdFF1ZXJ5KHRoaXMuY29uZmlnLCBtYXN0ZXIodGhpcy5jb25maWcpLCAnX1JvbGUnLCByZXN0V2hlcmUsIHt9KS5lYWNoKHJlc3VsdCA9PlxuICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdClcbiAgICApO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gR2l2ZW4gYSBsaXN0IG9mIHJvbGVJZHMsIGZpbmQgYWxsIHRoZSBwYXJlbnQgcm9sZXMsIHJldHVybnMgYSBwcm9taXNlIHdpdGggYWxsIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMgPSBmdW5jdGlvbiAocm9sZUlEcywgbmFtZXMgPSBbXSwgcXVlcmllZFJvbGVzID0ge30pIHtcbiAgY29uc3QgaW5zID0gcm9sZUlEcy5maWx0ZXIocm9sZUlEID0+IHtcbiAgICBjb25zdCB3YXNRdWVyaWVkID0gcXVlcmllZFJvbGVzW3JvbGVJRF0gIT09IHRydWU7XG4gICAgcXVlcmllZFJvbGVzW3JvbGVJRF0gPSB0cnVlO1xuICAgIHJldHVybiB3YXNRdWVyaWVkO1xuICB9KTtcblxuICAvLyBhbGwgcm9sZXMgYXJlIGFjY291bnRlZCBmb3IsIHJldHVybiB0aGUgbmFtZXNcbiAgaWYgKGlucy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoWy4uLm5ldyBTZXQobmFtZXMpXSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5nZXRSb2xlc0J5SWRzKGlucylcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIC8vIE5vdGhpbmcgZm91bmRcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuYW1lcyk7XG4gICAgICB9XG4gICAgICAvLyBNYXAgdGhlIHJlc3VsdHMgd2l0aCBhbGwgSWRzIGFuZCBuYW1lc1xuICAgICAgY29uc3QgcmVzdWx0TWFwID0gcmVzdWx0cy5yZWR1Y2UoXG4gICAgICAgIChtZW1vLCByb2xlKSA9PiB7XG4gICAgICAgICAgbWVtby5uYW1lcy5wdXNoKHJvbGUubmFtZSk7XG4gICAgICAgICAgbWVtby5pZHMucHVzaChyb2xlLm9iamVjdElkKTtcbiAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgfSxcbiAgICAgICAgeyBpZHM6IFtdLCBuYW1lczogW10gfVxuICAgICAgKTtcbiAgICAgIC8vIHN0b3JlIHRoZSBuZXcgZm91bmQgbmFtZXNcbiAgICAgIG5hbWVzID0gbmFtZXMuY29uY2F0KHJlc3VsdE1hcC5uYW1lcyk7XG4gICAgICAvLyBmaW5kIHRoZSBuZXh0IG9uZXMsIGNpcmN1bGFyIHJvbGVzIHdpbGwgYmUgY3V0XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMocmVzdWx0TWFwLmlkcywgbmFtZXMsIHF1ZXJpZWRSb2xlcyk7XG4gICAgfSlcbiAgICAudGhlbihuYW1lcyA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFsuLi5uZXcgU2V0KG5hbWVzKV0pO1xuICAgIH0pO1xufTtcblxuY29uc3QgY3JlYXRlU2Vzc2lvbiA9IGZ1bmN0aW9uIChcbiAgY29uZmlnLFxuICB7IHVzZXJJZCwgY3JlYXRlZFdpdGgsIGluc3RhbGxhdGlvbklkLCBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEgfVxuKSB7XG4gIGNvbnN0IHRva2VuID0gJ3I6JyArIGNyeXB0b1V0aWxzLm5ld1Rva2VuKCk7XG4gIGNvbnN0IGV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKTtcbiAgY29uc3Qgc2Vzc2lvbkRhdGEgPSB7XG4gICAgc2Vzc2lvblRva2VuOiB0b2tlbixcbiAgICB1c2VyOiB7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgIG9iamVjdElkOiB1c2VySWQsXG4gICAgfSxcbiAgICBjcmVhdGVkV2l0aCxcbiAgICByZXN0cmljdGVkOiBmYWxzZSxcbiAgICBleHBpcmVzQXQ6IFBhcnNlLl9lbmNvZGUoZXhwaXJlc0F0KSxcbiAgfTtcblxuICBpZiAoaW5zdGFsbGF0aW9uSWQpIHtcbiAgICBzZXNzaW9uRGF0YS5pbnN0YWxsYXRpb25JZCA9IGluc3RhbGxhdGlvbklkO1xuICB9XG5cbiAgT2JqZWN0LmFzc2lnbihzZXNzaW9uRGF0YSwgYWRkaXRpb25hbFNlc3Npb25EYXRhKTtcbiAgLy8gV2UgbmVlZCB0byBpbXBvcnQgUmVzdFdyaXRlIGF0IHRoaXMgcG9pbnQgZm9yIHRoZSBjeWNsaWMgZGVwZW5kZW5jeSBpdCBoYXMgdG8gaXRcbiAgY29uc3QgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcblxuICByZXR1cm4ge1xuICAgIHNlc3Npb25EYXRhLFxuICAgIGNyZWF0ZVNlc3Npb246ICgpID0+XG4gICAgICBuZXcgUmVzdFdyaXRlKGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIG51bGwsIHNlc3Npb25EYXRhKS5leGVjdXRlKCksXG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQXV0aCxcbiAgbWFzdGVyLFxuICBub2JvZHksXG4gIHJlYWRPbmx5LFxuICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLFxuICBnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuLFxuICBjcmVhdGVTZXNzaW9uLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/ClientSDK.js b/lib/ClientSDK.js new file mode 100644 index 0000000000..ed5cf3beab --- /dev/null +++ b/lib/ClientSDK.js @@ -0,0 +1,47 @@ +"use strict"; + +var semver = require('semver'); + +function compatible(compatibleSDK) { + return function (clientSDK) { + if (typeof clientSDK === 'string') { + clientSDK = fromString(clientSDK); + } // REST API, or custom SDK + + + if (!clientSDK) { + return true; + } + + const clientVersion = clientSDK.version; + const compatiblityVersion = compatibleSDK[clientSDK.sdk]; + return semver.satisfies(clientVersion, compatiblityVersion); + }; +} + +function supportsForwardDelete(clientSDK) { + return compatible({ + js: '>=1.9.0' + })(clientSDK); +} + +function fromString(version) { + const versionRE = /([-a-zA-Z]+)([0-9\.]+)/; + const match = version.toLowerCase().match(versionRE); + + if (match && match.length === 3) { + return { + sdk: match[1], + version: match[2] + }; + } + + return undefined; +} + +module.exports = { + compatible, + supportsForwardDelete, + fromString +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9DbGllbnRTREsuanMiXSwibmFtZXMiOlsic2VtdmVyIiwicmVxdWlyZSIsImNvbXBhdGlibGUiLCJjb21wYXRpYmxlU0RLIiwiY2xpZW50U0RLIiwiZnJvbVN0cmluZyIsImNsaWVudFZlcnNpb24iLCJ2ZXJzaW9uIiwiY29tcGF0aWJsaXR5VmVyc2lvbiIsInNkayIsInNhdGlzZmllcyIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImpzIiwidmVyc2lvblJFIiwibWF0Y2giLCJ0b0xvd2VyQ2FzZSIsImxlbmd0aCIsInVuZGVmaW5lZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBSUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsUUFBRCxDQUFwQjs7QUFFQSxTQUFTQyxVQUFULENBQW9CQyxhQUFwQixFQUFtQztBQUNqQyxTQUFPLFVBQVVDLFNBQVYsRUFBcUI7QUFDMUIsUUFBSSxPQUFPQSxTQUFQLEtBQXFCLFFBQXpCLEVBQW1DO0FBQ2pDQSxNQUFBQSxTQUFTLEdBQUdDLFVBQVUsQ0FBQ0QsU0FBRCxDQUF0QjtBQUNELEtBSHlCLENBSTFCOzs7QUFDQSxRQUFJLENBQUNBLFNBQUwsRUFBZ0I7QUFDZCxhQUFPLElBQVA7QUFDRDs7QUFDRCxVQUFNRSxhQUFhLEdBQUdGLFNBQVMsQ0FBQ0csT0FBaEM7QUFDQSxVQUFNQyxtQkFBbUIsR0FBR0wsYUFBYSxDQUFDQyxTQUFTLENBQUNLLEdBQVgsQ0FBekM7QUFDQSxXQUFPVCxNQUFNLENBQUNVLFNBQVAsQ0FBaUJKLGFBQWpCLEVBQWdDRSxtQkFBaEMsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTRyxxQkFBVCxDQUErQlAsU0FBL0IsRUFBMEM7QUFDeEMsU0FBT0YsVUFBVSxDQUFDO0FBQ2hCVSxJQUFBQSxFQUFFLEVBQUU7QUFEWSxHQUFELENBQVYsQ0FFSlIsU0FGSSxDQUFQO0FBR0Q7O0FBRUQsU0FBU0MsVUFBVCxDQUFvQkUsT0FBcEIsRUFBNkI7QUFDM0IsUUFBTU0sU0FBUyxHQUFHLHdCQUFsQjtBQUNBLFFBQU1DLEtBQUssR0FBR1AsT0FBTyxDQUFDUSxXQUFSLEdBQXNCRCxLQUF0QixDQUE0QkQsU0FBNUIsQ0FBZDs7QUFDQSxNQUFJQyxLQUFLLElBQUlBLEtBQUssQ0FBQ0UsTUFBTixLQUFpQixDQUE5QixFQUFpQztBQUMvQixXQUFPO0FBQ0xQLE1BQUFBLEdBQUcsRUFBRUssS0FBSyxDQUFDLENBQUQsQ0FETDtBQUVMUCxNQUFBQSxPQUFPLEVBQUVPLEtBQUssQ0FBQyxDQUFEO0FBRlQsS0FBUDtBQUlEOztBQUNELFNBQU9HLFNBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZqQixFQUFBQSxVQURlO0FBRWZTLEVBQUFBLHFCQUZlO0FBR2ZOLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgc2VtdmVyID0gcmVxdWlyZSgnc2VtdmVyJyk7XG5cbmZ1bmN0aW9uIGNvbXBhdGlibGUoY29tcGF0aWJsZVNESykge1xuICByZXR1cm4gZnVuY3Rpb24gKGNsaWVudFNESykge1xuICAgIGlmICh0eXBlb2YgY2xpZW50U0RLID09PSAnc3RyaW5nJykge1xuICAgICAgY2xpZW50U0RLID0gZnJvbVN0cmluZyhjbGllbnRTREspO1xuICAgIH1cbiAgICAvLyBSRVNUIEFQSSwgb3IgY3VzdG9tIFNES1xuICAgIGlmICghY2xpZW50U0RLKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50VmVyc2lvbiA9IGNsaWVudFNESy52ZXJzaW9uO1xuICAgIGNvbnN0IGNvbXBhdGlibGl0eVZlcnNpb24gPSBjb21wYXRpYmxlU0RLW2NsaWVudFNESy5zZGtdO1xuICAgIHJldHVybiBzZW12ZXIuc2F0aXNmaWVzKGNsaWVudFZlcnNpb24sIGNvbXBhdGlibGl0eVZlcnNpb24pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c0ZvcndhcmREZWxldGUoY2xpZW50U0RLKSB7XG4gIHJldHVybiBjb21wYXRpYmxlKHtcbiAgICBqczogJz49MS45LjAnLFxuICB9KShjbGllbnRTREspO1xufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHZlcnNpb24pIHtcbiAgY29uc3QgdmVyc2lvblJFID0gLyhbLWEtekEtWl0rKShbMC05XFwuXSspLztcbiAgY29uc3QgbWF0Y2ggPSB2ZXJzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2godmVyc2lvblJFKTtcbiAgaWYgKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA9PT0gMykge1xuICAgIHJldHVybiB7XG4gICAgICBzZGs6IG1hdGNoWzFdLFxuICAgICAgdmVyc2lvbjogbWF0Y2hbMl0sXG4gICAgfTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tcGF0aWJsZSxcbiAgc3VwcG9ydHNGb3J3YXJkRGVsZXRlLFxuICBmcm9tU3RyaW5nLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Config.js b/lib/Config.js new file mode 100644 index 0000000000..9efd47eaec --- /dev/null +++ b/lib/Config.js @@ -0,0 +1,348 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.Config = void 0; + +var _cache = _interopRequireDefault(require("./cache")); + +var _SchemaCache = _interopRequireDefault(require("./Controllers/SchemaCache")); + +var _DatabaseController = _interopRequireDefault(require("./Controllers/DatabaseController")); + +var _net = _interopRequireDefault(require("net")); + +var _Definitions = require("./Options/Definitions"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// A Config object provides information about how a specific app is +// configured. +// mount is the URL for the root of the API; includes http, domain, etc. +function removeTrailingSlash(str) { + if (!str) { + return str; + } + + if (str.endsWith('/')) { + str = str.substr(0, str.length - 1); + } + + return str; +} + +class Config { + static get(applicationId, mount) { + const cacheInfo = _cache.default.get(applicationId); + + if (!cacheInfo) { + return; + } + + const config = new Config(); + config.applicationId = applicationId; + Object.keys(cacheInfo).forEach(key => { + if (key == 'databaseController') { + const schemaCache = new _SchemaCache.default(cacheInfo.cacheController, cacheInfo.schemaCacheTTL, cacheInfo.enableSingleSchemaCache); + config.database = new _DatabaseController.default(cacheInfo.databaseController.adapter, schemaCache); + } else { + config[key] = cacheInfo[key]; + } + }); + config.mount = removeTrailingSlash(mount); + config.generateSessionExpiresAt = config.generateSessionExpiresAt.bind(config); + config.generateEmailVerifyTokenExpiresAt = config.generateEmailVerifyTokenExpiresAt.bind(config); + return config; + } + + static put(serverConfiguration) { + Config.validate(serverConfiguration); + + _cache.default.put(serverConfiguration.appId, serverConfiguration); + + Config.setupPasswordValidator(serverConfiguration.passwordPolicy); + return serverConfiguration; + } + + static validate({ + verifyUserEmails, + userController, + appName, + publicServerURL, + revokeSessionOnPasswordReset, + expireInactiveSessions, + sessionLength, + maxLimit, + emailVerifyTokenValidityDuration, + accountLockout, + passwordPolicy, + masterKeyIps, + masterKey, + readOnlyMasterKey, + allowHeaders, + idempotencyOptions + }) { + if (masterKey === readOnlyMasterKey) { + throw new Error('masterKey and readOnlyMasterKey should be different'); + } + + const emailAdapter = userController.adapter; + + if (verifyUserEmails) { + this.validateEmailConfiguration({ + emailAdapter, + appName, + publicServerURL, + emailVerifyTokenValidityDuration + }); + } + + this.validateAccountLockoutPolicy(accountLockout); + this.validatePasswordPolicy(passwordPolicy); + + if (typeof revokeSessionOnPasswordReset !== 'boolean') { + throw 'revokeSessionOnPasswordReset must be a boolean value'; + } + + if (publicServerURL) { + if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) { + throw 'publicServerURL should be a valid HTTPS URL starting with https://'; + } + } + + this.validateSessionConfiguration(sessionLength, expireInactiveSessions); + this.validateMasterKeyIps(masterKeyIps); + this.validateMaxLimit(maxLimit); + this.validateAllowHeaders(allowHeaders); + this.validateIdempotencyOptions(idempotencyOptions); + } + + static validateIdempotencyOptions(idempotencyOptions) { + if (!idempotencyOptions) { + return; + } + + if (idempotencyOptions.ttl === undefined) { + idempotencyOptions.ttl = _Definitions.IdempotencyOptions.ttl.default; + } else if (!isNaN(idempotencyOptions.ttl) && idempotencyOptions.ttl <= 0) { + throw 'idempotency TTL value must be greater than 0 seconds'; + } else if (isNaN(idempotencyOptions.ttl)) { + throw 'idempotency TTL value must be a number'; + } + + if (!idempotencyOptions.paths) { + idempotencyOptions.paths = _Definitions.IdempotencyOptions.paths.default; + } else if (!(idempotencyOptions.paths instanceof Array)) { + throw 'idempotency paths must be of an array of strings'; + } + } + + static validateAccountLockoutPolicy(accountLockout) { + if (accountLockout) { + if (typeof accountLockout.duration !== 'number' || accountLockout.duration <= 0 || accountLockout.duration > 99999) { + throw 'Account lockout duration should be greater than 0 and less than 100000'; + } + + if (!Number.isInteger(accountLockout.threshold) || accountLockout.threshold < 1 || accountLockout.threshold > 999) { + throw 'Account lockout threshold should be an integer greater than 0 and less than 1000'; + } + } + } + + static validatePasswordPolicy(passwordPolicy) { + if (passwordPolicy) { + if (passwordPolicy.maxPasswordAge !== undefined && (typeof passwordPolicy.maxPasswordAge !== 'number' || passwordPolicy.maxPasswordAge < 0)) { + throw 'passwordPolicy.maxPasswordAge must be a positive number'; + } + + if (passwordPolicy.resetTokenValidityDuration !== undefined && (typeof passwordPolicy.resetTokenValidityDuration !== 'number' || passwordPolicy.resetTokenValidityDuration <= 0)) { + throw 'passwordPolicy.resetTokenValidityDuration must be a positive number'; + } + + if (passwordPolicy.validatorPattern) { + if (typeof passwordPolicy.validatorPattern === 'string') { + passwordPolicy.validatorPattern = new RegExp(passwordPolicy.validatorPattern); + } else if (!(passwordPolicy.validatorPattern instanceof RegExp)) { + throw 'passwordPolicy.validatorPattern must be a regex string or RegExp object.'; + } + } + + if (passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') { + throw 'passwordPolicy.validatorCallback must be a function.'; + } + + if (passwordPolicy.doNotAllowUsername && typeof passwordPolicy.doNotAllowUsername !== 'boolean') { + throw 'passwordPolicy.doNotAllowUsername must be a boolean value.'; + } + + if (passwordPolicy.maxPasswordHistory && (!Number.isInteger(passwordPolicy.maxPasswordHistory) || passwordPolicy.maxPasswordHistory <= 0 || passwordPolicy.maxPasswordHistory > 20)) { + throw 'passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20'; + } + } + } // if the passwordPolicy.validatorPattern is configured then setup a callback to process the pattern + + + static setupPasswordValidator(passwordPolicy) { + if (passwordPolicy && passwordPolicy.validatorPattern) { + passwordPolicy.patternValidator = value => { + return passwordPolicy.validatorPattern.test(value); + }; + } + } + + static validateEmailConfiguration({ + emailAdapter, + appName, + publicServerURL, + emailVerifyTokenValidityDuration + }) { + if (!emailAdapter) { + throw 'An emailAdapter is required for e-mail verification and password resets.'; + } + + if (typeof appName !== 'string') { + throw 'An app name is required for e-mail verification and password resets.'; + } + + if (typeof publicServerURL !== 'string') { + throw 'A public server url is required for e-mail verification and password resets.'; + } + + if (emailVerifyTokenValidityDuration) { + if (isNaN(emailVerifyTokenValidityDuration)) { + throw 'Email verify token validity duration must be a valid number.'; + } else if (emailVerifyTokenValidityDuration <= 0) { + throw 'Email verify token validity duration must be a value greater than 0.'; + } + } + } + + static validateMasterKeyIps(masterKeyIps) { + for (const ip of masterKeyIps) { + if (!_net.default.isIP(ip)) { + throw `Invalid ip in masterKeyIps: ${ip}`; + } + } + } + + get mount() { + var mount = this._mount; + + if (this.publicServerURL) { + mount = this.publicServerURL; + } + + return mount; + } + + set mount(newValue) { + this._mount = newValue; + } + + static validateSessionConfiguration(sessionLength, expireInactiveSessions) { + if (expireInactiveSessions) { + if (isNaN(sessionLength)) { + throw 'Session length must be a valid number.'; + } else if (sessionLength <= 0) { + throw 'Session length must be a value greater than 0.'; + } + } + } + + static validateMaxLimit(maxLimit) { + if (maxLimit <= 0) { + throw 'Max limit must be a value greater than 0.'; + } + } + + static validateAllowHeaders(allowHeaders) { + if (![null, undefined].includes(allowHeaders)) { + if (Array.isArray(allowHeaders)) { + allowHeaders.forEach(header => { + if (typeof header !== 'string') { + throw 'Allow headers must only contain strings'; + } else if (!header.trim().length) { + throw 'Allow headers must not contain empty strings'; + } + }); + } else { + throw 'Allow headers must be an array'; + } + } + } + + generateEmailVerifyTokenExpiresAt() { + if (!this.verifyUserEmails || !this.emailVerifyTokenValidityDuration) { + return undefined; + } + + var now = new Date(); + return new Date(now.getTime() + this.emailVerifyTokenValidityDuration * 1000); + } + + generatePasswordResetTokenExpiresAt() { + if (!this.passwordPolicy || !this.passwordPolicy.resetTokenValidityDuration) { + return undefined; + } + + const now = new Date(); + return new Date(now.getTime() + this.passwordPolicy.resetTokenValidityDuration * 1000); + } + + generateSessionExpiresAt() { + if (!this.expireInactiveSessions) { + return undefined; + } + + var now = new Date(); + return new Date(now.getTime() + this.sessionLength * 1000); + } + + get invalidLinkURL() { + return this.customPages.invalidLink || `${this.publicServerURL}/apps/invalid_link.html`; + } + + get invalidVerificationLinkURL() { + return this.customPages.invalidVerificationLink || `${this.publicServerURL}/apps/invalid_verification_link.html`; + } + + get linkSendSuccessURL() { + return this.customPages.linkSendSuccess || `${this.publicServerURL}/apps/link_send_success.html`; + } + + get linkSendFailURL() { + return this.customPages.linkSendFail || `${this.publicServerURL}/apps/link_send_fail.html`; + } + + get verifyEmailSuccessURL() { + return this.customPages.verifyEmailSuccess || `${this.publicServerURL}/apps/verify_email_success.html`; + } + + get choosePasswordURL() { + return this.customPages.choosePassword || `${this.publicServerURL}/apps/choose_password`; + } + + get requestResetPasswordURL() { + return `${this.publicServerURL}/apps/${this.applicationId}/request_password_reset`; + } + + get passwordResetSuccessURL() { + return this.customPages.passwordResetSuccess || `${this.publicServerURL}/apps/password_reset_success.html`; + } + + get parseFrameURL() { + return this.customPages.parseFrameURL; + } + + get verifyEmailURL() { + return `${this.publicServerURL}/apps/${this.applicationId}/verify_email`; + } + +} + +exports.Config = Config; +var _default = Config; +exports.default = _default; +module.exports = Config; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db25maWcuanMiXSwibmFtZXMiOlsicmVtb3ZlVHJhaWxpbmdTbGFzaCIsInN0ciIsImVuZHNXaXRoIiwic3Vic3RyIiwibGVuZ3RoIiwiQ29uZmlnIiwiZ2V0IiwiYXBwbGljYXRpb25JZCIsIm1vdW50IiwiY2FjaGVJbmZvIiwiQXBwQ2FjaGUiLCJjb25maWciLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsInNjaGVtYUNhY2hlIiwiU2NoZW1hQ2FjaGUiLCJjYWNoZUNvbnRyb2xsZXIiLCJzY2hlbWFDYWNoZVRUTCIsImVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIiwiZGF0YWJhc2UiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0IiwiYmluZCIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInB1dCIsInNlcnZlckNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZSIsImFwcElkIiwic2V0dXBQYXNzd29yZFZhbGlkYXRvciIsInBhc3N3b3JkUG9saWN5IiwidmVyaWZ5VXNlckVtYWlscyIsInVzZXJDb250cm9sbGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwic2Vzc2lvbkxlbmd0aCIsIm1heExpbWl0IiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJhY2NvdW50TG9ja291dCIsIm1hc3RlcktleUlwcyIsIm1hc3RlcktleSIsInJlYWRPbmx5TWFzdGVyS2V5IiwiYWxsb3dIZWFkZXJzIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwiRXJyb3IiLCJlbWFpbEFkYXB0ZXIiLCJ2YWxpZGF0ZUVtYWlsQ29uZmlndXJhdGlvbiIsInZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3kiLCJ2YWxpZGF0ZVBhc3N3b3JkUG9saWN5Iiwic3RhcnRzV2l0aCIsInZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZU1hc3RlcktleUlwcyIsInZhbGlkYXRlTWF4TGltaXQiLCJ2YWxpZGF0ZUFsbG93SGVhZGVycyIsInZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zIiwidHRsIiwidW5kZWZpbmVkIiwiSWRlbXBvdGVuY3lPcHRpb25zIiwiZGVmYXVsdCIsImlzTmFOIiwicGF0aHMiLCJBcnJheSIsImR1cmF0aW9uIiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwidGhyZXNob2xkIiwibWF4UGFzc3dvcmRBZ2UiLCJyZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiIsInZhbGlkYXRvclBhdHRlcm4iLCJSZWdFeHAiLCJ2YWxpZGF0b3JDYWxsYmFjayIsImRvTm90QWxsb3dVc2VybmFtZSIsIm1heFBhc3N3b3JkSGlzdG9yeSIsInBhdHRlcm5WYWxpZGF0b3IiLCJ2YWx1ZSIsInRlc3QiLCJpcCIsIm5ldCIsImlzSVAiLCJfbW91bnQiLCJuZXdWYWx1ZSIsImluY2x1ZGVzIiwiaXNBcnJheSIsImhlYWRlciIsInRyaW0iLCJub3ciLCJEYXRlIiwiZ2V0VGltZSIsImdlbmVyYXRlUGFzc3dvcmRSZXNldFRva2VuRXhwaXJlc0F0IiwiaW52YWxpZExpbmtVUkwiLCJjdXN0b21QYWdlcyIsImludmFsaWRMaW5rIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGluayIsImxpbmtTZW5kU3VjY2Vzc1VSTCIsImxpbmtTZW5kU3VjY2VzcyIsImxpbmtTZW5kRmFpbFVSTCIsImxpbmtTZW5kRmFpbCIsInZlcmlmeUVtYWlsU3VjY2Vzc1VSTCIsInZlcmlmeUVtYWlsU3VjY2VzcyIsImNob29zZVBhc3N3b3JkVVJMIiwiY2hvb3NlUGFzc3dvcmQiLCJyZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwicGFzc3dvcmRSZXNldFN1Y2Nl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ZUFBZ0Isc0NBRjFCO0FBSUQ7O0FBRUQsTUFBSThELGtCQUFKLEdBQXlCO0FBQ3ZCLFdBQ0UsS0FBS0osV0FBTCxDQUFpQkssZUFBakIsSUFBcUMsR0FBRSxLQUFLL0QsZUFBZ0IsOEJBRDlEO0FBR0Q7O0FBRUQsTUFBSWdFLGVBQUosR0FBc0I7QUFDcEIsV0FBTyxLQUFLTixXQUFMLENBQWlCTyxZQUFqQixJQUFrQyxHQUFFLEtBQUtqRSxlQUFnQiwyQkFBaEU7QUFDRDs7QUFFRCxNQUFJa0UscUJBQUosR0FBNEI7QUFDMUIsV0FDRSxLQUFLUixXQUFMLENBQWlCUyxrQkFBakIsSUFDQyxHQUFFLEtBQUtuRSxlQUFnQixpQ0FGMUI7QUFJRDs7QUFFRCxNQUFJb0UsaUJBQUosR0FBd0I7QUFDdEIsV0FBTyxLQUFLVixXQUFMLENBQWlCVyxjQUFqQixJQUFvQyxHQUFFLEtBQUtyRSxlQUFnQix1QkFBbEU7QUFDRDs7QUFFRCxNQUFJc0UsdUJBQUosR0FBOEI7QUFDNUIsV0FBUSxHQUFFLEtBQUt0RSxlQUFnQixTQUFRLEtBQUs5QixhQUFjLHlCQUExRDtBQUNEOztBQUVELE1BQUlxRyx1QkFBSixHQUE4QjtBQUM1QixXQUNFLEtBQUtiLFdBQUwsQ0FBaUJjLG9CQUFqQixJQUNDLEdBQUUsS0FBS3hFLGVBQWdCLG1DQUYxQjtBQUlEOztBQUVELE1BQUl5RSxhQUFKLEdBQW9CO0FBQ2xCLFdBQU8sS0FBS2YsV0FBTCxDQUFpQmUsYUFBeEI7QUFDRDs7QUFFRCxNQUFJQyxjQUFKLEdBQXFCO0FBQ25CLFdBQVEsR0FBRSxLQUFLMUUsZUFBZ0IsU0FBUSxLQUFLOUIsYUFBYyxlQUExRDtBQUNEOztBQTdVaUI7OztlQWdWTEYsTTs7QUFDZjJHLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjVHLE1BQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBDb25maWcgb2JqZWN0IHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGhvdyBhIHNwZWNpZmljIGFwcCBpc1xuLy8gY29uZmlndXJlZC5cbi8vIG1vdW50IGlzIHRoZSBVUkwgZm9yIHRoZSByb290IG9mIHRoZSBBUEk7IGluY2x1ZGVzIGh0dHAsIGRvbWFpbiwgZXRjLlxuXG5pbXBvcnQgQXBwQ2FjaGUgZnJvbSAnLi9jYWNoZSc7XG5pbXBvcnQgU2NoZW1hQ2FjaGUgZnJvbSAnLi9Db250cm9sbGVycy9TY2hlbWFDYWNoZSc7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4vQ29udHJvbGxlcnMvRGF0YWJhc2VDb250cm9sbGVyJztcbmltcG9ydCBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCB7IElkZW1wb3RlbmN5T3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucy9EZWZpbml0aW9ucyc7XG5cbmZ1bmN0aW9uIHJlbW92ZVRyYWlsaW5nU2xhc2goc3RyKSB7XG4gIGlmICghc3RyKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuICBpZiAoc3RyLmVuZHNXaXRoKCcvJykpIHtcbiAgICBzdHIgPSBzdHIuc3Vic3RyKDAsIHN0ci5sZW5ndGggLSAxKTtcbiAgfVxuICByZXR1cm4gc3RyO1xufVxuXG5leHBvcnQgY2xhc3MgQ29uZmlnIHtcbiAgc3RhdGljIGdldChhcHBsaWNhdGlvbklkOiBzdHJpbmcsIG1vdW50OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjYWNoZUluZm8gPSBBcHBDYWNoZS5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCFjYWNoZUluZm8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnID0gbmV3IENvbmZpZygpO1xuICAgIGNvbmZpZy5hcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZDtcbiAgICBPYmplY3Qua2V5cyhjYWNoZUluZm8pLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmIChrZXkgPT0gJ2RhdGFiYXNlQ29udHJvbGxlcicpIHtcbiAgICAgICAgY29uc3Qgc2NoZW1hQ2FjaGUgPSBuZXcgU2NoZW1hQ2FjaGUoXG4gICAgICAgICAgY2FjaGVJbmZvLmNhY2hlQ29udHJvbGxlcixcbiAgICAgICAgICBjYWNoZUluZm8uc2NoZW1hQ2FjaGVUVEwsXG4gICAgICAgICAgY2FjaGVJbmZvLmVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlXG4gICAgICAgICk7XG4gICAgICAgIGNvbmZpZy5kYXRhYmFzZSA9IG5ldyBEYXRhYmFzZUNvbnRyb2xsZXIoY2FjaGVJbmZvLmRhdGFiYXNlQ29udHJvbGxlci5hZGFwdGVyLCBzY2hlbWFDYWNoZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25maWdba2V5XSA9IGNhY2hlSW5mb1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbmZpZy5tb3VudCA9IHJlbW92ZVRyYWlsaW5nU2xhc2gobW91bnQpO1xuICAgIGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQgPSBjb25maWcuZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0LmJpbmQoY29uZmlnKTtcbiAgICBjb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0ID0gY29uZmlnLmdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdC5iaW5kKFxuICAgICAgY29uZmlnXG4gICAgKTtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgc3RhdGljIHB1dChzZXJ2ZXJDb25maWd1cmF0aW9uKSB7XG4gICAgQ29uZmlnLnZhbGlkYXRlKHNlcnZlckNvbmZpZ3VyYXRpb24pO1xuICAgIEFwcENhY2hlLnB1dChzZXJ2ZXJDb25maWd1cmF0aW9uLmFwcElkLCBzZXJ2ZXJDb25maWd1cmF0aW9uKTtcbiAgICBDb25maWcuc2V0dXBQYXNzd29yZFZhbGlkYXRvcihzZXJ2ZXJDb25maWd1cmF0aW9uLnBhc3N3b3JkUG9saWN5KTtcbiAgICByZXR1cm4gc2VydmVyQ29uZmlndXJhdGlvbjtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZSh7XG4gICAgdmVyaWZ5VXNlckVtYWlscyxcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0LFxuICAgIGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMsXG4gICAgc2Vzc2lvbkxlbmd0aCxcbiAgICBtYXhMaW1pdCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICBhY2NvdW50TG9ja291dCxcbiAgICBwYXNzd29yZFBvbGljeSxcbiAgICBtYXN0ZXJLZXlJcHMsXG4gICAgbWFzdGVyS2V5LFxuICAgIHJlYWRPbmx5TWFzdGVyS2V5LFxuICAgIGFsbG93SGVhZGVycyxcbiAgICBpZGVtcG90ZW5jeU9wdGlvbnMsXG4gIH0pIHtcbiAgICBpZiAobWFzdGVyS2V5ID09PSByZWFkT25seU1hc3RlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtYXN0ZXJLZXkgYW5kIHJlYWRPbmx5TWFzdGVyS2V5IHNob3VsZCBiZSBkaWZmZXJlbnQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbWFpbEFkYXB0ZXIgPSB1c2VyQ29udHJvbGxlci5hZGFwdGVyO1xuICAgIGlmICh2ZXJpZnlVc2VyRW1haWxzKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtcbiAgICAgICAgZW1haWxBZGFwdGVyLFxuICAgICAgICBhcHBOYW1lLFxuICAgICAgICBwdWJsaWNTZXJ2ZXJVUkwsXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy52YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5KGFjY291bnRMb2Nrb3V0KTtcblxuICAgIHRoaXMudmFsaWRhdGVQYXNzd29yZFBvbGljeShwYXNzd29yZFBvbGljeSk7XG5cbiAgICBpZiAodHlwZW9mIHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ3Jldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUnO1xuICAgIH1cblxuICAgIGlmIChwdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgIGlmICghcHVibGljU2VydmVyVVJMLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSAmJiAhcHVibGljU2VydmVyVVJMLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICAgICAgdGhyb3cgJ3B1YmxpY1NlcnZlclVSTCBzaG91bGQgYmUgYSB2YWxpZCBIVFRQUyBVUkwgc3RhcnRpbmcgd2l0aCBodHRwczovLyc7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbihzZXNzaW9uTGVuZ3RoLCBleHBpcmVJbmFjdGl2ZVNlc3Npb25zKTtcbiAgICB0aGlzLnZhbGlkYXRlTWFzdGVyS2V5SXBzKG1hc3RlcktleUlwcyk7XG4gICAgdGhpcy52YWxpZGF0ZU1heExpbWl0KG1heExpbWl0KTtcbiAgICB0aGlzLnZhbGlkYXRlQWxsb3dIZWFkZXJzKGFsbG93SGVhZGVycyk7XG4gICAgdGhpcy52YWxpZGF0ZUlkZW1wb3RlbmN5T3B0aW9ucyhpZGVtcG90ZW5jeU9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zKGlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIGlmICghaWRlbXBvdGVuY3lPcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpZGVtcG90ZW5jeU9wdGlvbnMudHRsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy50dGwgPSBJZGVtcG90ZW5jeU9wdGlvbnMudHRsLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNOYU4oaWRlbXBvdGVuY3lPcHRpb25zLnR0bCkgJiYgaWRlbXBvdGVuY3lPcHRpb25zLnR0bCA8PSAwKSB7XG4gICAgICB0aHJvdyAnaWRlbXBvdGVuY3kgVFRMIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgc2Vjb25kcyc7XG4gICAgfSBlbHNlIGlmIChpc05hTihpZGVtcG90ZW5jeU9wdGlvbnMudHRsKSkge1xuICAgICAgdGhyb3cgJ2lkZW1wb3RlbmN5IFRUTCB2YWx1ZSBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9XG4gICAgaWYgKCFpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy5wYXRocyA9IElkZW1wb3RlbmN5T3B0aW9ucy5wYXRocy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIShpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgIHRocm93ICdpZGVtcG90ZW5jeSBwYXRocyBtdXN0IGJlIG9mIGFuIGFycmF5IG9mIHN0cmluZ3MnO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5KGFjY291bnRMb2Nrb3V0KSB7XG4gICAgaWYgKGFjY291bnRMb2Nrb3V0KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBhY2NvdW50TG9ja291dC5kdXJhdGlvbiAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gPD0gMCB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC5kdXJhdGlvbiA+IDk5OTk5XG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ0FjY291bnQgbG9ja291dCBkdXJhdGlvbiBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAxMDAwMDAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFOdW1iZXIuaXNJbnRlZ2VyKGFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCkgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQudGhyZXNob2xkIDwgMSB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC50aHJlc2hvbGQgPiA5OTlcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAnQWNjb3VudCBsb2Nrb3V0IHRocmVzaG9sZCBzaG91bGQgYmUgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDEwMDAnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVBhc3N3b3JkUG9saWN5KHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHR5cGVvZiBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSAhPT0gJ251bWJlcicgfHwgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgPCAwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gIT09ICdudW1iZXInIHx8XG4gICAgICAgICAgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gPD0gMClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcic7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKTtcbiAgICAgICAgfSBlbHNlIGlmICghKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApKSB7XG4gICAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gbXVzdCBiZSBhIHJlZ2V4IHN0cmluZyBvciBSZWdFeHAgb2JqZWN0Lic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayAmJlxuICAgICAgICB0eXBlb2YgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgIT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uLic7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcGFzc3dvcmRQb2xpY3kuZG9Ob3RBbGxvd1VzZXJuYW1lICYmXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgIT09ICdib29sZWFuJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgJiZcbiAgICAgICAgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSkgfHxcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgPD0gMCB8fFxuICAgICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSA+IDIwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgbXVzdCBiZSBhbiBpbnRlZ2VyIHJhbmdpbmcgMCAtIDIwJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpcyBjb25maWd1cmVkIHRoZW4gc2V0dXAgYSBjYWxsYmFjayB0byBwcm9jZXNzIHRoZSBwYXR0ZXJuXG4gIHN0YXRpYyBzZXR1cFBhc3N3b3JkVmFsaWRhdG9yKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5ICYmIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgIHBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgPSB2YWx1ZSA9PiB7XG4gICAgICAgIHJldHVybiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuLnRlc3QodmFsdWUpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgIGVtYWlsQWRhcHRlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgfSkge1xuICAgIGlmICghZW1haWxBZGFwdGVyKSB7XG4gICAgICB0aHJvdyAnQW4gZW1haWxBZGFwdGVyIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBhcHBOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgJ0FuIGFwcCBuYW1lIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwdWJsaWNTZXJ2ZXJVUkwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyAnQSBwdWJsaWMgc2VydmVyIHVybCBpcyByZXF1aXJlZCBmb3IgZS1tYWlsIHZlcmlmaWNhdGlvbiBhbmQgcGFzc3dvcmQgcmVzZXRzLic7XG4gICAgfVxuICAgIGlmIChlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgaWYgKGlzTmFOKGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSkge1xuICAgICAgICB0aHJvdyAnRW1haWwgdmVyaWZ5IHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uIG11c3QgYmUgYSB2YWxpZCBudW1iZXIuJztcbiAgICAgIH0gZWxzZSBpZiAoZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gPD0gMCkge1xuICAgICAgICB0aHJvdyAnRW1haWwgdmVyaWZ5IHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uIG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gMC4nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZU1hc3RlcktleUlwcyhtYXN0ZXJLZXlJcHMpIHtcbiAgICBmb3IgKGNvbnN0IGlwIG9mIG1hc3RlcktleUlwcykge1xuICAgICAgaWYgKCFuZXQuaXNJUChpcCkpIHtcbiAgICAgICAgdGhyb3cgYEludmFsaWQgaXAgaW4gbWFzdGVyS2V5SXBzOiAke2lwfWA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IG1vdW50KCkge1xuICAgIHZhciBtb3VudCA9IHRoaXMuX21vdW50O1xuICAgIGlmICh0aGlzLnB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgbW91bnQgPSB0aGlzLnB1YmxpY1NlcnZlclVSTDtcbiAgICB9XG4gICAgcmV0dXJuIG1vdW50O1xuICB9XG5cbiAgc2V0IG1vdW50KG5ld1ZhbHVlKSB7XG4gICAgdGhpcy5fbW91bnQgPSBuZXdWYWx1ZTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVNlc3Npb25Db25maWd1cmF0aW9uKHNlc3Npb25MZW5ndGgsIGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICBpZiAoZXhwaXJlSW5hY3RpdmVTZXNzaW9ucykge1xuICAgICAgaWYgKGlzTmFOKHNlc3Npb25MZW5ndGgpKSB7XG4gICAgICAgIHRocm93ICdTZXNzaW9uIGxlbmd0aCBtdXN0IGJlIGEgdmFsaWQgbnVtYmVyLic7XG4gICAgICB9IGVsc2UgaWYgKHNlc3Npb25MZW5ndGggPD0gMCkge1xuICAgICAgICB0aHJvdyAnU2Vzc2lvbiBsZW5ndGggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlTWF4TGltaXQobWF4TGltaXQpIHtcbiAgICBpZiAobWF4TGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgJ01heCBsaW1pdCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIDAuJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVBbGxvd0hlYWRlcnMoYWxsb3dIZWFkZXJzKSB7XG4gICAgaWYgKCFbbnVsbCwgdW5kZWZpbmVkXS5pbmNsdWRlcyhhbGxvd0hlYWRlcnMpKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhbGxvd0hlYWRlcnMpKSB7XG4gICAgICAgIGFsbG93SGVhZGVycy5mb3JFYWNoKGhlYWRlciA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyAnQWxsb3cgaGVhZGVycyBtdXN0IG9ubHkgY29udGFpbiBzdHJpbmdzJztcbiAgICAgICAgICB9IGVsc2UgaWYgKCFoZWFkZXIudHJpbSgpLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBub3QgY29udGFpbiBlbXB0eSBzdHJpbmdzJztcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBiZSBhbiBhcnJheSc7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KCkge1xuICAgIGlmICghdGhpcy52ZXJpZnlVc2VyRW1haWxzIHx8ICF0aGlzLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gbmV3IERhdGUobm93LmdldFRpbWUoKSArIHRoaXMuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gKiAxMDAwKTtcbiAgfVxuXG4gIGdlbmVyYXRlUGFzc3dvcmRSZXNldFRva2VuRXhwaXJlc0F0KCkge1xuICAgIGlmICghdGhpcy5wYXNzd29yZFBvbGljeSB8fCAhdGhpcy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gbmV3IERhdGUobm93LmdldFRpbWUoKSArIHRoaXMucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gKiAxMDAwKTtcbiAgfVxuXG4gIGdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdCgpIHtcbiAgICBpZiAoIXRoaXMuZXhwaXJlSW5hY3RpdmVTZXNzaW9ucykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLnNlc3Npb25MZW5ndGggKiAxMDAwKTtcbiAgfVxuXG4gIGdldCBpbnZhbGlkTGlua1VSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5pbnZhbGlkTGluayB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9pbnZhbGlkX2xpbmsuaHRtbGA7XG4gIH1cblxuICBnZXQgaW52YWxpZFZlcmlmaWNhdGlvbkxpbmtVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMuaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2ludmFsaWRfdmVyaWZpY2F0aW9uX2xpbmsuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IGxpbmtTZW5kU3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy5saW5rU2VuZFN1Y2Nlc3MgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvbGlua19zZW5kX3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IGxpbmtTZW5kRmFpbFVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5saW5rU2VuZEZhaWwgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvbGlua19zZW5kX2ZhaWwuaHRtbGA7XG4gIH1cblxuICBnZXQgdmVyaWZ5RW1haWxTdWNjZXNzVVJMKCkge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmN1c3RvbVBhZ2VzLnZlcmlmeUVtYWlsU3VjY2VzcyB8fFxuICAgICAgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvdmVyaWZ5X2VtYWlsX3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IGNob29zZVBhc3N3b3JkVVJMKCkge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVBhZ2VzLmNob29zZVBhc3N3b3JkIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2Nob29zZV9wYXNzd29yZGA7XG4gIH1cblxuICBnZXQgcmVxdWVzdFJlc2V0UGFzc3dvcmRVUkwoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzLyR7dGhpcy5hcHBsaWNhdGlvbklkfS9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0YDtcbiAgfVxuXG4gIGdldCBwYXNzd29yZFJlc2V0U3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy5wYXNzd29yZFJlc2V0U3VjY2VzcyB8fFxuICAgICAgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvcGFzc3dvcmRfcmVzZXRfc3VjY2Vzcy5odG1sYFxuICAgICk7XG4gIH1cblxuICBnZXQgcGFyc2VGcmFtZVVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5wYXJzZUZyYW1lVVJMO1xuICB9XG5cbiAgZ2V0IHZlcmlmeUVtYWlsVVJMKCkge1xuICAgIHJldHVybiBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy8ke3RoaXMuYXBwbGljYXRpb25JZH0vdmVyaWZ5X2VtYWlsYDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb25maWc7XG5tb2R1bGUuZXhwb3J0cyA9IENvbmZpZztcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/AdaptableController.js b/lib/Controllers/AdaptableController.js new file mode 100644 index 0000000000..520cd57406 --- /dev/null +++ b/lib/Controllers/AdaptableController.js @@ -0,0 +1,88 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AdaptableController = void 0; + +var _Config = _interopRequireDefault(require("../Config")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* +AdaptableController.js + +AdaptableController is the base class for all controllers +that support adapter, +The super class takes care of creating the right instance for the adapter +based on the parameters passed + + */ +// _adapter is private, use Symbol +var _adapter = Symbol(); + +class AdaptableController { + constructor(adapter, appId, options) { + this.options = options; + this.appId = appId; + this.adapter = adapter; + } + + set adapter(adapter) { + this.validateAdapter(adapter); + this[_adapter] = adapter; + } + + get adapter() { + return this[_adapter]; + } + + get config() { + return _Config.default.get(this.appId); + } + + expectedAdapterType() { + throw new Error('Subclasses should implement expectedAdapterType()'); + } + + validateAdapter(adapter) { + AdaptableController.validateAdapter(adapter, this); + } + + static validateAdapter(adapter, self, ExpectedType) { + if (!adapter) { + throw new Error(this.constructor.name + ' requires an adapter'); + } + + const Type = ExpectedType || self.expectedAdapterType(); // Allow skipping for testing + + if (!Type) { + return; + } // Makes sure the prototype matches + + + const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => { + const adapterType = typeof adapter[key]; + const expectedType = typeof Type.prototype[key]; + + if (adapterType !== expectedType) { + obj[key] = { + expected: expectedType, + actual: adapterType + }; + } + + return obj; + }, {}); + + if (Object.keys(mismatches).length > 0) { + throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches); + } + } + +} + +exports.AdaptableController = AdaptableController; +var _default = AdaptableController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIl9hZGFwdGVyIiwiU3ltYm9sIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsImNvbmZpZyIsIkNvbmZpZyIsImdldCIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJFcnJvciIsInNlbGYiLCJFeHBlY3RlZFR5cGUiLCJuYW1lIiwiVHlwZSIsIm1pc21hdGNoZXMiLCJPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwicHJvdG90eXBlIiwicmVkdWNlIiwib2JqIiwia2V5IiwiYWRhcHRlclR5cGUiLCJleHBlY3RlZFR5cGUiLCJleHBlY3RlZCIsImFjdHVhbCIsImtleXMiLCJsZW5ndGgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFZQTs7OztBQVpBOzs7Ozs7Ozs7QUFVQTtBQUNBLElBQUlBLFFBQVEsR0FBR0MsTUFBTSxFQUFyQjs7QUFHTyxNQUFNQyxtQkFBTixDQUEwQjtBQUMvQkMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQWpCLEVBQTBCO0FBQ25DLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNBLFNBQUtELEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtELE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVELE1BQUlBLE9BQUosQ0FBWUEsT0FBWixFQUFxQjtBQUNuQixTQUFLRyxlQUFMLENBQXFCSCxPQUFyQjtBQUNBLFNBQUtKLFFBQUwsSUFBaUJJLE9BQWpCO0FBQ0Q7O0FBRUQsTUFBSUEsT0FBSixHQUFjO0FBQ1osV0FBTyxLQUFLSixRQUFMLENBQVA7QUFDRDs7QUFFRCxNQUFJUSxNQUFKLEdBQWE7QUFDWCxXQUFPQyxnQkFBT0MsR0FBUCxDQUFXLEtBQUtMLEtBQWhCLENBQVA7QUFDRDs7QUFFRE0sRUFBQUEsbUJBQW1CLEdBQUc7QUFDcEIsVUFBTSxJQUFJQyxLQUFKLENBQVUsbURBQVYsQ0FBTjtBQUNEOztBQUVETCxFQUFBQSxlQUFlLENBQUNILE9BQUQsRUFBVTtBQUN2QkYsSUFBQUEsbUJBQW1CLENBQUNLLGVBQXBCLENBQW9DSCxPQUFwQyxFQUE2QyxJQUE3QztBQUNEOztBQUVELFNBQU9HLGVBQVAsQ0FBdUJILE9BQXZCLEVBQWdDUyxJQUFoQyxFQUFzQ0MsWUFBdEMsRUFBb0Q7QUFDbEQsUUFBSSxDQUFDVixPQUFMLEVBQWM7QUFDWixZQUFNLElBQUlRLEtBQUosQ0FBVSxLQUFLVCxXQUFMLENBQWlCWSxJQUFqQixHQUF3QixzQkFBbEMsQ0FBTjtBQUNEOztBQUVELFVBQU1DLElBQUksR0FBR0YsWUFBWSxJQUFJRCxJQUFJLENBQUNGLG1CQUFMLEVBQTdCLENBTGtELENBTWxEOztBQUNBLFFBQUksQ0FBQ0ssSUFBTCxFQUFXO0FBQ1Q7QUFDRCxLQVRpRCxDQVdsRDs7O0FBQ0EsVUFBTUMsVUFBVSxHQUFHQyxNQUFNLENBQUNDLG1CQUFQLENBQTJCSCxJQUFJLENBQUNJLFNBQWhDLEVBQTJDQyxNQUEzQyxDQUFrRCxDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUNqRixZQUFNQyxXQUFXLEdBQUcsT0FBT3BCLE9BQU8sQ0FBQ21CLEdBQUQsQ0FBbEM7QUFDQSxZQUFNRSxZQUFZLEdBQUcsT0FBT1QsSUFBSSxDQUFDSSxTQUFMLENBQWVHLEdBQWYsQ0FBNUI7O0FBQ0EsVUFBSUMsV0FBVyxLQUFLQyxZQUFwQixFQUFrQztBQUNoQ0gsUUFBQUEsR0FBRyxDQUFDQyxHQUFELENBQUgsR0FBVztBQUNURyxVQUFBQSxRQUFRLEVBQUVELFlBREQ7QUFFVEUsVUFBQUEsTUFBTSxFQUFFSDtBQUZDLFNBQVg7QUFJRDs7QUFDRCxhQUFPRixHQUFQO0FBQ0QsS0FWa0IsRUFVaEIsRUFWZ0IsQ0FBbkI7O0FBWUEsUUFBSUosTUFBTSxDQUFDVSxJQUFQLENBQVlYLFVBQVosRUFBd0JZLE1BQXhCLEdBQWlDLENBQXJDLEVBQXdDO0FBQ3RDLFlBQU0sSUFBSWpCLEtBQUosQ0FBVSxrREFBVixFQUE4RFIsT0FBOUQsRUFBdUVhLFVBQXZFLENBQU47QUFDRDtBQUNGOztBQXZEOEI7OztlQTBEbEJmLG1CIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkFkYXB0YWJsZUNvbnRyb2xsZXIuanNcblxuQWRhcHRhYmxlQ29udHJvbGxlciBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsIGNvbnRyb2xsZXJzXG50aGF0IHN1cHBvcnQgYWRhcHRlcixcblRoZSBzdXBlciBjbGFzcyB0YWtlcyBjYXJlIG9mIGNyZWF0aW5nIHRoZSByaWdodCBpbnN0YW5jZSBmb3IgdGhlIGFkYXB0ZXJcbmJhc2VkIG9uIHRoZSBwYXJhbWV0ZXJzIHBhc3NlZFxuXG4gKi9cblxuLy8gX2FkYXB0ZXIgaXMgcHJpdmF0ZSwgdXNlIFN5bWJvbFxudmFyIF9hZGFwdGVyID0gU3ltYm9sKCk7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuYXBwSWQgPSBhcHBJZDtcbiAgICB0aGlzLmFkYXB0ZXIgPSBhZGFwdGVyO1xuICB9XG5cbiAgc2V0IGFkYXB0ZXIoYWRhcHRlcikge1xuICAgIHRoaXMudmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpO1xuICAgIHRoaXNbX2FkYXB0ZXJdID0gYWRhcHRlcjtcbiAgfVxuXG4gIGdldCBhZGFwdGVyKCkge1xuICAgIHJldHVybiB0aGlzW19hZGFwdGVyXTtcbiAgfVxuXG4gIGdldCBjb25maWcoKSB7XG4gICAgcmV0dXJuIENvbmZpZy5nZXQodGhpcy5hcHBJZCk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3ViY2xhc3NlcyBzaG91bGQgaW1wbGVtZW50IGV4cGVjdGVkQWRhcHRlclR5cGUoKScpO1xuICB9XG5cbiAgdmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpIHtcbiAgICBBZGFwdGFibGVDb250cm9sbGVyLnZhbGlkYXRlQWRhcHRlcihhZGFwdGVyLCB0aGlzKTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlciwgc2VsZiwgRXhwZWN0ZWRUeXBlKSB7XG4gICAgaWYgKCFhZGFwdGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgJyByZXF1aXJlcyBhbiBhZGFwdGVyJyk7XG4gICAgfVxuXG4gICAgY29uc3QgVHlwZSA9IEV4cGVjdGVkVHlwZSB8fCBzZWxmLmV4cGVjdGVkQWRhcHRlclR5cGUoKTtcbiAgICAvLyBBbGxvdyBza2lwcGluZyBmb3IgdGVzdGluZ1xuICAgIGlmICghVHlwZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE1ha2VzIHN1cmUgdGhlIHByb3RvdHlwZSBtYXRjaGVzXG4gICAgY29uc3QgbWlzbWF0Y2hlcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFR5cGUucHJvdG90eXBlKS5yZWR1Y2UoKG9iaiwga2V5KSA9PiB7XG4gICAgICBjb25zdCBhZGFwdGVyVHlwZSA9IHR5cGVvZiBhZGFwdGVyW2tleV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0eXBlb2YgVHlwZS5wcm90b3R5cGVba2V5XTtcbiAgICAgIGlmIChhZGFwdGVyVHlwZSAhPT0gZXhwZWN0ZWRUeXBlKSB7XG4gICAgICAgIG9ialtrZXldID0ge1xuICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZFR5cGUsXG4gICAgICAgICAgYWN0dWFsOiBhZGFwdGVyVHlwZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfSwge30pO1xuXG4gICAgaWYgKE9iamVjdC5rZXlzKG1pc21hdGNoZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkFkYXB0ZXIgcHJvdG90eXBlIGRvbid0IG1hdGNoIGV4cGVjdGVkIHByb3RvdHlwZVwiLCBhZGFwdGVyLCBtaXNtYXRjaGVzKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQWRhcHRhYmxlQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/AnalyticsController.js b/lib/Controllers/AnalyticsController.js new file mode 100644 index 0000000000..1416558aca --- /dev/null +++ b/lib/Controllers/AnalyticsController.js @@ -0,0 +1,52 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AnalyticsController = void 0; + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class AnalyticsController extends _AdaptableController.default { + appOpened(req) { + return Promise.resolve().then(() => { + return this.adapter.appOpened(req.body, req); + }).then(response => { + return { + response: response || {} + }; + }).catch(() => { + return { + response: {} + }; + }); + } + + trackEvent(req) { + return Promise.resolve().then(() => { + return this.adapter.trackEvent(req.params.eventName, req.body, req); + }).then(response => { + return { + response: response || {} + }; + }).catch(() => { + return { + response: {} + }; + }); + } + + expectedAdapterType() { + return _AnalyticsAdapter.AnalyticsAdapter; + } + +} + +exports.AnalyticsController = AnalyticsController; +var _default = AnalyticsController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BbmFseXRpY3NDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiYXBwT3BlbmVkIiwicmVxIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiYWRhcHRlciIsImJvZHkiLCJyZXNwb25zZSIsImNhdGNoIiwidHJhY2tFdmVudCIsInBhcmFtcyIsImV2ZW50TmFtZSIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJBbmFseXRpY3NBZGFwdGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxNQUFNQSxtQkFBTixTQUFrQ0MsNEJBQWxDLENBQXNEO0FBQzNEQyxFQUFBQSxTQUFTLENBQUNDLEdBQUQsRUFBTTtBQUNiLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixHQUNKQyxJQURJLENBQ0MsTUFBTTtBQUNWLGFBQU8sS0FBS0MsT0FBTCxDQUFhTCxTQUFiLENBQXVCQyxHQUFHLENBQUNLLElBQTNCLEVBQWlDTCxHQUFqQyxDQUFQO0FBQ0QsS0FISSxFQUlKRyxJQUpJLENBSUNHLFFBQVEsSUFBSTtBQUNoQixhQUFPO0FBQUVBLFFBQUFBLFFBQVEsRUFBRUEsUUFBUSxJQUFJO0FBQXhCLE9BQVA7QUFDRCxLQU5JLEVBT0pDLEtBUEksQ0FPRSxNQUFNO0FBQ1gsYUFBTztBQUFFRCxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQO0FBQ0QsS0FUSSxDQUFQO0FBVUQ7O0FBRURFLEVBQUFBLFVBQVUsQ0FBQ1IsR0FBRCxFQUFNO0FBQ2QsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBTyxLQUFLQyxPQUFMLENBQWFJLFVBQWIsQ0FBd0JSLEdBQUcsQ0FBQ1MsTUFBSixDQUFXQyxTQUFuQyxFQUE4Q1YsR0FBRyxDQUFDSyxJQUFsRCxFQUF3REwsR0FBeEQsQ0FBUDtBQUNELEtBSEksRUFJSkcsSUFKSSxDQUlDRyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBLFFBQVEsSUFBSTtBQUF4QixPQUFQO0FBQ0QsS0FOSSxFQU9KQyxLQVBJLENBT0UsTUFBTTtBQUNYLGFBQU87QUFBRUQsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVEksQ0FBUDtBQVVEOztBQUVESyxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixXQUFPQyxrQ0FBUDtBQUNEOztBQTdCMEQ7OztlQWdDOUNmLG1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IEFuYWx5dGljc0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlcic7XG5cbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGFwcE9wZW5lZChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hcHBPcGVuZWQocmVxLmJvZHksIHJlcSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfHwge30gfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgdHJhY2tFdmVudChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci50cmFja0V2ZW50KHJlcS5wYXJhbXMuZXZlbnROYW1lLCByZXEuYm9keSwgcmVxKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB8fCB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBBbmFseXRpY3NBZGFwdGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuYWx5dGljc0NvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/CacheController.js b/lib/Controllers/CacheController.js new file mode 100644 index 0000000000..9feaa778f9 --- /dev/null +++ b/lib/Controllers/CacheController.js @@ -0,0 +1,92 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.CacheController = exports.SubCache = void 0; + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _CacheAdapter = _interopRequireDefault(require("../Adapters/Cache/CacheAdapter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const KEY_SEPARATOR_CHAR = ':'; + +function joinKeys(...keys) { + return keys.join(KEY_SEPARATOR_CHAR); +} +/** + * Prefix all calls to the cache via a prefix string, useful when grouping Cache by object type. + * + * eg "Role" or "Session" + */ + + +class SubCache { + constructor(prefix, cacheController, ttl) { + this.prefix = prefix; + this.cache = cacheController; + this.ttl = ttl; + } + + get(key) { + const cacheKey = joinKeys(this.prefix, key); + return this.cache.get(cacheKey); + } + + put(key, value, ttl) { + const cacheKey = joinKeys(this.prefix, key); + return this.cache.put(cacheKey, value, ttl); + } + + del(key) { + const cacheKey = joinKeys(this.prefix, key); + return this.cache.del(cacheKey); + } + + clear() { + return this.cache.clear(); + } + +} + +exports.SubCache = SubCache; + +class CacheController extends _AdaptableController.default { + constructor(adapter, appId, options = {}) { + super(adapter, appId, options); + this.role = new SubCache('role', this); + this.user = new SubCache('user', this); + this.graphQL = new SubCache('graphQL', this); + } + + get(key) { + const cacheKey = joinKeys(this.appId, key); + return this.adapter.get(cacheKey).then(null, () => Promise.resolve(null)); + } + + put(key, value, ttl) { + const cacheKey = joinKeys(this.appId, key); + return this.adapter.put(cacheKey, value, ttl); + } + + del(key) { + const cacheKey = joinKeys(this.appId, key); + return this.adapter.del(cacheKey); + } + + clear() { + return this.adapter.clear(); + } + + expectedAdapterType() { + return _CacheAdapter.default; + } + +} + +exports.CacheController = CacheController; +var _default = CacheController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9DYWNoZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiS0VZX1NFUEFSQVRPUl9DSEFSIiwiam9pbktleXMiLCJrZXlzIiwiam9pbiIsIlN1YkNhY2hlIiwiY29uc3RydWN0b3IiLCJwcmVmaXgiLCJjYWNoZUNvbnRyb2xsZXIiLCJ0dGwiLCJjYWNoZSIsImdldCIsImtleSIsImNhY2hlS2V5IiwicHV0IiwidmFsdWUiLCJkZWwiLCJjbGVhciIsIkNhY2hlQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwicm9sZSIsInVzZXIiLCJncmFwaFFMIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkNhY2hlQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRUEsTUFBTUEsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRUEsU0FBU0MsUUFBVCxDQUFrQixHQUFHQyxJQUFyQixFQUEyQjtBQUN6QixTQUFPQSxJQUFJLENBQUNDLElBQUwsQ0FBVUgsa0JBQVYsQ0FBUDtBQUNEO0FBRUQ7Ozs7Ozs7QUFLTyxNQUFNSSxRQUFOLENBQWU7QUFDcEJDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFTQyxlQUFULEVBQTBCQyxHQUExQixFQUErQjtBQUN4QyxTQUFLRixNQUFMLEdBQWNBLE1BQWQ7QUFDQSxTQUFLRyxLQUFMLEdBQWFGLGVBQWI7QUFDQSxTQUFLQyxHQUFMLEdBQVdBLEdBQVg7QUFDRDs7QUFFREUsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU07QUFDUCxVQUFNQyxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLSyxNQUFOLEVBQWNLLEdBQWQsQ0FBekI7QUFDQSxXQUFPLEtBQUtGLEtBQUwsQ0FBV0MsR0FBWCxDQUFlRSxRQUFmLENBQVA7QUFDRDs7QUFFREMsRUFBQUEsR0FBRyxDQUFDRixHQUFELEVBQU1HLEtBQU4sRUFBYU4sR0FBYixFQUFrQjtBQUNuQixVQUFNSSxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLSyxNQUFOLEVBQWNLLEdBQWQsQ0FBekI7QUFDQSxXQUFPLEtBQUtGLEtBQUwsQ0FBV0ksR0FBWCxDQUFlRCxRQUFmLEVBQXlCRSxLQUF6QixFQUFnQ04sR0FBaEMsQ0FBUDtBQUNEOztBQUVETyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTTtBQUNQLFVBQU1DLFFBQVEsR0FBR1gsUUFBUSxDQUFDLEtBQUtLLE1BQU4sRUFBY0ssR0FBZCxDQUF6QjtBQUNBLFdBQU8sS0FBS0YsS0FBTCxDQUFXTSxHQUFYLENBQWVILFFBQWYsQ0FBUDtBQUNEOztBQUVESSxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtQLEtBQUwsQ0FBV08sS0FBWCxFQUFQO0FBQ0Q7O0FBeEJtQjs7OztBQTJCZixNQUFNQyxlQUFOLFNBQThCQyw0QkFBOUIsQ0FBa0Q7QUFDdkRiLEVBQUFBLFdBQVcsQ0FBQ2MsT0FBRCxFQUFVQyxLQUFWLEVBQWlCQyxPQUFPLEdBQUcsRUFBM0IsRUFBK0I7QUFDeEMsVUFBTUYsT0FBTixFQUFlQyxLQUFmLEVBQXNCQyxPQUF0QjtBQUVBLFNBQUtDLElBQUwsR0FBWSxJQUFJbEIsUUFBSixDQUFhLE1BQWIsRUFBcUIsSUFBckIsQ0FBWjtBQUNBLFNBQUttQixJQUFMLEdBQVksSUFBSW5CLFFBQUosQ0FBYSxNQUFiLEVBQXFCLElBQXJCLENBQVo7QUFDQSxTQUFLb0IsT0FBTCxHQUFlLElBQUlwQixRQUFKLENBQWEsU0FBYixFQUF3QixJQUF4QixDQUFmO0FBQ0Q7O0FBRURNLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS21CLEtBQU4sRUFBYVQsR0FBYixDQUF6QjtBQUNBLFdBQU8sS0FBS1EsT0FBTCxDQUFhVCxHQUFiLENBQWlCRSxRQUFqQixFQUEyQmEsSUFBM0IsQ0FBZ0MsSUFBaEMsRUFBc0MsTUFBTUMsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQTVDLENBQVA7QUFDRDs7QUFFRGQsRUFBQUEsR0FBRyxDQUFDRixHQUFELEVBQU1HLEtBQU4sRUFBYU4sR0FBYixFQUFrQjtBQUNuQixVQUFNSSxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLbUIsS0FBTixFQUFhVCxHQUFiLENBQXpCO0FBQ0EsV0FBTyxLQUFLUSxPQUFMLENBQWFOLEdBQWIsQ0FBaUJELFFBQWpCLEVBQTJCRSxLQUEzQixFQUFrQ04sR0FBbEMsQ0FBUDtBQUNEOztBQUVETyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTTtBQUNQLFVBQU1DLFFBQVEsR0FBR1gsUUFBUSxDQUFDLEtBQUttQixLQUFOLEVBQWFULEdBQWIsQ0FBekI7QUFDQSxXQUFPLEtBQUtRLE9BQUwsQ0FBYUosR0FBYixDQUFpQkgsUUFBakIsQ0FBUDtBQUNEOztBQUVESSxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtHLE9BQUwsQ0FBYUgsS0FBYixFQUFQO0FBQ0Q7O0FBRURZLEVBQUFBLG1CQUFtQixHQUFHO0FBQ3BCLFdBQU9DLHFCQUFQO0FBQ0Q7O0FBOUJzRDs7O2VBaUMxQ1osZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgQ2FjaGVBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0NhY2hlL0NhY2hlQWRhcHRlcic7XG5cbmNvbnN0IEtFWV9TRVBBUkFUT1JfQ0hBUiA9ICc6JztcblxuZnVuY3Rpb24gam9pbktleXMoLi4ua2V5cykge1xuICByZXR1cm4ga2V5cy5qb2luKEtFWV9TRVBBUkFUT1JfQ0hBUik7XG59XG5cbi8qKlxuICogUHJlZml4IGFsbCBjYWxscyB0byB0aGUgY2FjaGUgdmlhIGEgcHJlZml4IHN0cmluZywgdXNlZnVsIHdoZW4gZ3JvdXBpbmcgQ2FjaGUgYnkgb2JqZWN0IHR5cGUuXG4gKlxuICogZWcgXCJSb2xlXCIgb3IgXCJTZXNzaW9uXCJcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YkNhY2hlIHtcbiAgY29uc3RydWN0b3IocHJlZml4LCBjYWNoZUNvbnRyb2xsZXIsIHR0bCkge1xuICAgIHRoaXMucHJlZml4ID0gcHJlZml4O1xuICAgIHRoaXMuY2FjaGUgPSBjYWNoZUNvbnRyb2xsZXI7XG4gICAgdGhpcy50dGwgPSB0dGw7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBqb2luS2V5cyh0aGlzLnByZWZpeCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXQoY2FjaGVLZXkpO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5wcmVmaXgsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUucHV0KGNhY2hlS2V5LCB2YWx1ZSwgdHRsKTtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMucHJlZml4LCBrZXkpO1xuICAgIHJldHVybiB0aGlzLmNhY2hlLmRlbChjYWNoZUtleSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5jbGVhcigpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBDYWNoZUNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcblxuICAgIHRoaXMucm9sZSA9IG5ldyBTdWJDYWNoZSgncm9sZScsIHRoaXMpO1xuICAgIHRoaXMudXNlciA9IG5ldyBTdWJDYWNoZSgndXNlcicsIHRoaXMpO1xuICAgIHRoaXMuZ3JhcGhRTCA9IG5ldyBTdWJDYWNoZSgnZ3JhcGhRTCcsIHRoaXMpO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5hcHBJZCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmdldChjYWNoZUtleSkudGhlbihudWxsLCAoKSA9PiBQcm9taXNlLnJlc29sdmUobnVsbCkpO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5hcHBJZCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnB1dChjYWNoZUtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBqb2luS2V5cyh0aGlzLmFwcElkLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGVsKGNhY2hlS2V5KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY2xlYXIoKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIENhY2hlQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYWNoZUNvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/DatabaseController.js b/lib/Controllers/DatabaseController.js new file mode 100644 index 0000000000..aa1087cfd4 --- /dev/null +++ b/lib/Controllers/DatabaseController.js @@ -0,0 +1,1485 @@ +"use strict"; + +var _node = require("parse/node"); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _intersect = _interopRequireDefault(require("intersect")); + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +var _logger = _interopRequireDefault(require("../logger")); + +var SchemaController = _interopRequireWildcard(require("./SchemaController")); + +var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); + +var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function addWriteACL(query, acl) { + const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_wperm' query, we don't allow client queries on that, no need to $and + + + newQuery._wperm = { + $in: [null, ...acl] + }; + return newQuery; +} + +function addReadACL(query, acl) { + const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_rperm' query, we don't allow client queries on that, no need to $and + + + newQuery._rperm = { + $in: [null, '*', ...acl] + }; + return newQuery; +} // Transforms a REST API formatted ACL object to our two-field mongo format. + + +const transformObjectACL = (_ref) => { + let { + ACL + } = _ref, + result = _objectWithoutProperties(_ref, ["ACL"]); + + if (!ACL) { + return result; + } + + result._wperm = []; + result._rperm = []; + + for (const entry in ACL) { + if (ACL[entry].read) { + result._rperm.push(entry); + } + + if (ACL[entry].write) { + result._wperm.push(entry); + } + } + + return result; +}; + +const specialQuerykeys = ['$and', '$or', '$nor', '_rperm', '_wperm', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count']; + +const isSpecialQueryKey = key => { + return specialQuerykeys.indexOf(key) >= 0; +}; + +const validateQuery = query => { + if (query.ACL) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Cannot query on ACL.'); + } + + if (query.$or) { + if (query.$or instanceof Array) { + query.$or.forEach(validateQuery); + } else { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.'); + } + } + + if (query.$and) { + if (query.$and instanceof Array) { + query.$and.forEach(validateQuery); + } else { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $and format - use an array value.'); + } + } + + if (query.$nor) { + if (query.$nor instanceof Array && query.$nor.length > 0) { + query.$nor.forEach(validateQuery); + } else { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $nor format - use an array of at least 1 value.'); + } + } + + Object.keys(query).forEach(key => { + if (query && query[key] && query[key].$regex) { + if (typeof query[key].$options === 'string') { + if (!query[key].$options.match(/^[imxs]+$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, `Bad $options value for query: ${query[key].$options}`); + } + } + } + + if (!isSpecialQueryKey(key) && !key.match(/^[a-zA-Z][a-zA-Z0-9_\.]*$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid key name: ${key}`); + } + }); +}; // Filters out any data that shouldn't be on this REST-formatted object. + + +const filterSensitiveData = (isMaster, aclGroup, auth, operation, schema, className, protectedFields, object) => { + let userId = null; + if (auth && auth.user) userId = auth.user.id; // replace protectedFields when using pointer-permissions + + const perms = schema.getClassLevelPermissions(className); + + if (perms) { + const isReadOperation = ['get', 'find'].indexOf(operation) > -1; + + if (isReadOperation && perms.protectedFields) { + // extract protectedFields added with the pointer-permission prefix + const protectedFieldsPointerPerm = Object.keys(perms.protectedFields).filter(key => key.startsWith('userField:')).map(key => { + return { + key: key.substring(10), + value: perms.protectedFields[key] + }; + }); + const newProtectedFields = []; + let overrideProtectedFields = false; // check if the object grants the current user access based on the extracted fields + + protectedFieldsPointerPerm.forEach(pointerPerm => { + let pointerPermIncludesUser = false; + const readUserFieldValue = object[pointerPerm.key]; + + if (readUserFieldValue) { + if (Array.isArray(readUserFieldValue)) { + pointerPermIncludesUser = readUserFieldValue.some(user => user.objectId && user.objectId === userId); + } else { + pointerPermIncludesUser = readUserFieldValue.objectId && readUserFieldValue.objectId === userId; + } + } + + if (pointerPermIncludesUser) { + overrideProtectedFields = true; + newProtectedFields.push(pointerPerm.value); + } + }); // if at least one pointer-permission affected the current user + // intersect vs protectedFields from previous stage (@see addProtectedFields) + // Sets theory (intersections): A x (B x C) == (A x B) x C + + if (overrideProtectedFields && protectedFields) { + newProtectedFields.push(protectedFields); + } // intersect all sets of protectedFields + + + newProtectedFields.forEach(fields => { + if (fields) { + // if there're no protctedFields by other criteria ( id / role / auth) + // then we must intersect each set (per userField) + if (!protectedFields) { + protectedFields = fields; + } else { + protectedFields = protectedFields.filter(v => fields.includes(v)); + } + } + }); + } + } + + const isUserClass = className === '_User'; + /* special treat for the user class: don't filter protectedFields if currently loggedin user is + the retrieved user */ + + if (!(isUserClass && userId && object.objectId === userId)) { + protectedFields && protectedFields.forEach(k => delete object[k]); // fields not requested by client (excluded), + //but were needed to apply protecttedFields + + perms.protectedFields && perms.protectedFields.temporaryKeys && perms.protectedFields.temporaryKeys.forEach(k => delete object[k]); + } + + if (!isUserClass) { + return object; + } + + object.password = object._hashed_password; + delete object._hashed_password; + delete object.sessionToken; + + if (isMaster) { + return object; + } + + delete object._email_verify_token; + delete object._perishable_token; + delete object._perishable_token_expires_at; + delete object._tombstone; + delete object._email_verify_token_expires_at; + delete object._failed_login_count; + delete object._account_lockout_expires_at; + delete object._password_changed_at; + delete object._password_history; + + if (aclGroup.indexOf(object.objectId) > -1) { + return object; + } + + delete object.authData; + return object; +}; + +// Runs an update on the database. +// Returns a promise for an object with the new values for field +// modifications that don't know their results ahead of time, like +// 'increment'. +// Options: +// acl: a list of strings. If the object to be updated has an ACL, +// one of the provided strings must provide the caller with +// write permissions. +const specialKeysForUpdate = ['_hashed_password', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count', '_perishable_token_expires_at', '_password_changed_at', '_password_history']; + +const isSpecialUpdateKey = key => { + return specialKeysForUpdate.indexOf(key) >= 0; +}; + +function expandResultOnKeyPath(object, key, value) { + if (key.indexOf('.') < 0) { + object[key] = value[key]; + return object; + } + + const path = key.split('.'); + const firstKey = path[0]; + const nextPath = path.slice(1).join('.'); + object[firstKey] = expandResultOnKeyPath(object[firstKey] || {}, nextPath, value[firstKey]); + delete object[key]; + return object; +} + +function sanitizeDatabaseResult(originalObject, result) { + const response = {}; + + if (!result) { + return Promise.resolve(response); + } + + Object.keys(originalObject).forEach(key => { + const keyUpdate = originalObject[key]; // determine if that was an op + + if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op && ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) { + // only valid ops that produce an actionable result + // the op may have happend on a keypath + expandResultOnKeyPath(response, key, result); + } + }); + return Promise.resolve(response); +} + +function joinTableName(className, key) { + return `_Join:${key}:${className}`; +} + +const flattenUpdateOperatorsForCreate = object => { + for (const key in object) { + if (object[key] && object[key].__op) { + switch (object[key].__op) { + case 'Increment': + if (typeof object[key].amount !== 'number') { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = object[key].amount; + break; + + case 'Add': + if (!(object[key].objects instanceof Array)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = object[key].objects; + break; + + case 'AddUnique': + if (!(object[key].objects instanceof Array)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = object[key].objects; + break; + + case 'Remove': + if (!(object[key].objects instanceof Array)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = []; + break; + + case 'Delete': + delete object[key]; + break; + + default: + throw new _node.Parse.Error(_node.Parse.Error.COMMAND_UNAVAILABLE, `The ${object[key].__op} operator is not supported yet.`); + } + } + } +}; + +const transformAuthData = (className, object, schema) => { + if (object.authData && className === '_User') { + Object.keys(object.authData).forEach(provider => { + const providerData = object.authData[provider]; + const fieldName = `_auth_data_${provider}`; + + if (providerData == null) { + object[fieldName] = { + __op: 'Delete' + }; + } else { + object[fieldName] = providerData; + schema.fields[fieldName] = { + type: 'Object' + }; + } + }); + delete object.authData; + } +}; // Transforms a Database format ACL to a REST API format ACL + + +const untransformObjectACL = (_ref2) => { + let { + _rperm, + _wperm + } = _ref2, + output = _objectWithoutProperties(_ref2, ["_rperm", "_wperm"]); + + if (_rperm || _wperm) { + output.ACL = {}; + + (_rperm || []).forEach(entry => { + if (!output.ACL[entry]) { + output.ACL[entry] = { + read: true + }; + } else { + output.ACL[entry]['read'] = true; + } + }); + + (_wperm || []).forEach(entry => { + if (!output.ACL[entry]) { + output.ACL[entry] = { + write: true + }; + } else { + output.ACL[entry]['write'] = true; + } + }); + } + + return output; +}; +/** + * When querying, the fieldName may be compound, extract the root fieldName + * `temperature.celsius` becomes `temperature` + * @param {string} fieldName that may be a compound field name + * @returns {string} the root name of the field + */ + + +const getRootFieldName = fieldName => { + return fieldName.split('.')[0]; +}; + +const relationSchema = { + fields: { + relatedId: { + type: 'String' + }, + owningId: { + type: 'String' + } + } +}; + +class DatabaseController { + constructor(adapter, schemaCache) { + this.adapter = adapter; + this.schemaCache = schemaCache; // We don't want a mutable this.schema, because then you could have + // one request that uses different schemas for different parts of + // it. Instead, use loadSchema to get a schema. + + this.schemaPromise = null; + this._transactionalSession = null; + } + + collectionExists(className) { + return this.adapter.classExists(className); + } + + purgeCollection(className) { + return this.loadSchema().then(schemaController => schemaController.getOneSchema(className)).then(schema => this.adapter.deleteObjectsByQuery(className, schema, {})); + } + + validateClassName(className) { + if (!SchemaController.classNameIsValid(className)) { + return Promise.reject(new _node.Parse.Error(_node.Parse.Error.INVALID_CLASS_NAME, 'invalid className: ' + className)); + } + + return Promise.resolve(); + } // Returns a promise for a schemaController. + + + loadSchema(options = { + clearCache: false + }) { + if (this.schemaPromise != null) { + return this.schemaPromise; + } + + this.schemaPromise = SchemaController.load(this.adapter, this.schemaCache, options); + this.schemaPromise.then(() => delete this.schemaPromise, () => delete this.schemaPromise); + return this.loadSchema(options); + } + + loadSchemaIfNeeded(schemaController, options = { + clearCache: false + }) { + return schemaController ? Promise.resolve(schemaController) : this.loadSchema(options); + } // Returns a promise for the classname that is related to the given + // classname through the key. + // TODO: make this not in the DatabaseController interface + + + redirectClassNameForKey(className, key) { + return this.loadSchema().then(schema => { + var t = schema.getExpectedType(className, key); + + if (t != null && typeof t !== 'string' && t.type === 'Relation') { + return t.targetClass; + } + + return className; + }); + } // Uses the schema to validate the object (REST API format). + // Returns a promise that resolves to the new schema. + // This does not update this.schema, because in a situation like a + // batch request, that could confuse other users of the schema. + + + validateObject(className, object, query, runOptions) { + let schema; + const acl = runOptions.acl; + const isMaster = acl === undefined; + var aclGroup = acl || []; + return this.loadSchema().then(s => { + schema = s; + + if (isMaster) { + return Promise.resolve(); + } + + return this.canAddField(schema, className, object, aclGroup, runOptions); + }).then(() => { + return schema.validateObject(className, object, query); + }); + } + + update(className, query, update, { + acl, + many, + upsert, + addsField + } = {}, skipSanitization = false, validateOnly = false, validSchemaController) { + const originalQuery = query; + const originalUpdate = update; // Make a copy of the object, so we don't mutate the incoming data. + + update = (0, _deepcopy.default)(update); + var relationUpdates = []; + var isMaster = acl === undefined; + var aclGroup = acl || []; + return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'update')).then(() => { + relationUpdates = this.collectRelationUpdates(className, originalQuery.objectId, update); + + if (!isMaster) { + query = this.addPointerPermissions(schemaController, className, 'update', query, aclGroup); + + if (addsField) { + query = { + $and: [query, this.addPointerPermissions(schemaController, className, 'addField', query, aclGroup)] + }; + } + } + + if (!query) { + return Promise.resolve(); + } + + if (acl) { + query = addWriteACL(query, acl); + } + + validateQuery(query); + return schemaController.getOneSchema(className, true).catch(error => { + // If the schema doesn't exist, pretend it exists with no fields. This behavior + // will likely need revisiting. + if (error === undefined) { + return { + fields: {} + }; + } + + throw error; + }).then(schema => { + Object.keys(update).forEach(fieldName => { + if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); + } + + const rootFieldName = getRootFieldName(fieldName); + + if (!SchemaController.fieldNameIsValid(rootFieldName) && !isSpecialUpdateKey(rootFieldName)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); + } + }); + + for (const updateOperation in update) { + if (update[updateOperation] && typeof update[updateOperation] === 'object' && Object.keys(update[updateOperation]).some(innerKey => innerKey.includes('$') || innerKey.includes('.'))) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } + } + + update = transformObjectACL(update); + transformAuthData(className, update, schema); + + if (validateOnly) { + return this.adapter.find(className, schema, query, {}).then(result => { + if (!result || !result.length) { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + return {}; + }); + } + + if (many) { + return this.adapter.updateObjectsByQuery(className, schema, query, update, this._transactionalSession); + } else if (upsert) { + return this.adapter.upsertOneObject(className, schema, query, update, this._transactionalSession); + } else { + return this.adapter.findOneAndUpdate(className, schema, query, update, this._transactionalSession); + } + }); + }).then(result => { + if (!result) { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + if (validateOnly) { + return result; + } + + return this.handleRelationUpdates(className, originalQuery.objectId, update, relationUpdates).then(() => { + return result; + }); + }).then(result => { + if (skipSanitization) { + return Promise.resolve(result); + } + + return sanitizeDatabaseResult(originalUpdate, result); + }); + }); + } // Collect all relation-updating operations from a REST-format update. + // Returns a list of all relation updates to perform + // This mutates update. + + + collectRelationUpdates(className, objectId, update) { + var ops = []; + var deleteMe = []; + objectId = update.objectId || objectId; + + var process = (op, key) => { + if (!op) { + return; + } + + if (op.__op == 'AddRelation') { + ops.push({ + key, + op + }); + deleteMe.push(key); + } + + if (op.__op == 'RemoveRelation') { + ops.push({ + key, + op + }); + deleteMe.push(key); + } + + if (op.__op == 'Batch') { + for (var x of op.ops) { + process(x, key); + } + } + }; + + for (const key in update) { + process(update[key], key); + } + + for (const key of deleteMe) { + delete update[key]; + } + + return ops; + } // Processes relation-updating operations from a REST-format update. + // Returns a promise that resolves when all updates have been performed + + + handleRelationUpdates(className, objectId, update, ops) { + var pending = []; + objectId = update.objectId || objectId; + ops.forEach(({ + key, + op + }) => { + if (!op) { + return; + } + + if (op.__op == 'AddRelation') { + for (const object of op.objects) { + pending.push(this.addRelation(key, className, objectId, object.objectId)); + } + } + + if (op.__op == 'RemoveRelation') { + for (const object of op.objects) { + pending.push(this.removeRelation(key, className, objectId, object.objectId)); + } + } + }); + return Promise.all(pending); + } // Adds a relation. + // Returns a promise that resolves successfully iff the add was successful. + + + addRelation(key, fromClassName, fromId, toId) { + const doc = { + relatedId: toId, + owningId: fromId + }; + return this.adapter.upsertOneObject(`_Join:${key}:${fromClassName}`, relationSchema, doc, doc, this._transactionalSession); + } // Removes a relation. + // Returns a promise that resolves successfully iff the remove was + // successful. + + + removeRelation(key, fromClassName, fromId, toId) { + var doc = { + relatedId: toId, + owningId: fromId + }; + return this.adapter.deleteObjectsByQuery(`_Join:${key}:${fromClassName}`, relationSchema, doc, this._transactionalSession).catch(error => { + // We don't care if they try to delete a non-existent relation. + if (error.code == _node.Parse.Error.OBJECT_NOT_FOUND) { + return; + } + + throw error; + }); + } // Removes objects matches this query from the database. + // Returns a promise that resolves successfully iff the object was + // deleted. + // Options: + // acl: a list of strings. If the object to be updated has an ACL, + // one of the provided strings must provide the caller with + // write permissions. + + + destroy(className, query, { + acl + } = {}, validSchemaController) { + const isMaster = acl === undefined; + const aclGroup = acl || []; + return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'delete')).then(() => { + if (!isMaster) { + query = this.addPointerPermissions(schemaController, className, 'delete', query, aclGroup); + + if (!query) { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + } // delete by query + + + if (acl) { + query = addWriteACL(query, acl); + } + + validateQuery(query); + return schemaController.getOneSchema(className).catch(error => { + // If the schema doesn't exist, pretend it exists with no fields. This behavior + // will likely need revisiting. + if (error === undefined) { + return { + fields: {} + }; + } + + throw error; + }).then(parseFormatSchema => this.adapter.deleteObjectsByQuery(className, parseFormatSchema, query, this._transactionalSession)).catch(error => { + // When deleting sessions while changing passwords, don't throw an error if they don't have any sessions. + if (className === '_Session' && error.code === _node.Parse.Error.OBJECT_NOT_FOUND) { + return Promise.resolve({}); + } + + throw error; + }); + }); + }); + } // Inserts an object into the database. + // Returns a promise that resolves successfully iff the object saved. + + + create(className, object, { + acl + } = {}, validateOnly = false, validSchemaController) { + // Make a copy of the object, so we don't mutate the incoming data. + const originalObject = object; + object = transformObjectACL(object); + object.createdAt = { + iso: object.createdAt, + __type: 'Date' + }; + object.updatedAt = { + iso: object.updatedAt, + __type: 'Date' + }; + var isMaster = acl === undefined; + var aclGroup = acl || []; + const relationUpdates = this.collectRelationUpdates(className, null, object); + return this.validateClassName(className).then(() => this.loadSchemaIfNeeded(validSchemaController)).then(schemaController => { + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'create')).then(() => schemaController.enforceClassExists(className)).then(() => schemaController.getOneSchema(className, true)).then(schema => { + transformAuthData(className, object, schema); + flattenUpdateOperatorsForCreate(object); + + if (validateOnly) { + return {}; + } + + return this.adapter.createObject(className, SchemaController.convertSchemaToAdapterSchema(schema), object, this._transactionalSession); + }).then(result => { + if (validateOnly) { + return originalObject; + } + + return this.handleRelationUpdates(className, object.objectId, object, relationUpdates).then(() => { + return sanitizeDatabaseResult(originalObject, result.ops[0]); + }); + }); + }); + } + + canAddField(schema, className, object, aclGroup, runOptions) { + const classSchema = schema.schemaData[className]; + + if (!classSchema) { + return Promise.resolve(); + } + + const fields = Object.keys(object); + const schemaFields = Object.keys(classSchema.fields); + const newKeys = fields.filter(field => { + // Skip fields that are unset + if (object[field] && object[field].__op && object[field].__op === 'Delete') { + return false; + } + + return schemaFields.indexOf(field) < 0; + }); + + if (newKeys.length > 0) { + // adds a marker that new field is being adding during update + runOptions.addsField = true; + const action = runOptions.action; + return schema.validatePermission(className, aclGroup, 'addField', action); + } + + return Promise.resolve(); + } // Won't delete collections in the system namespace + + /** + * Delete all classes and clears the schema cache + * + * @param {boolean} fast set to true if it's ok to just delete rows and not indexes + * @returns {Promise} when the deletions completes + */ + + + deleteEverything(fast = false) { + this.schemaPromise = null; + return Promise.all([this.adapter.deleteAllClasses(fast), this.schemaCache.clear()]); + } // Returns a promise for a list of related ids given an owning id. + // className here is the owning className. + + + relatedIds(className, key, owningId, queryOptions) { + const { + skip, + limit, + sort + } = queryOptions; + const findOptions = {}; + + if (sort && sort.createdAt && this.adapter.canSortOnJoinTables) { + findOptions.sort = { + _id: sort.createdAt + }; + findOptions.limit = limit; + findOptions.skip = skip; + queryOptions.skip = 0; + } + + return this.adapter.find(joinTableName(className, key), relationSchema, { + owningId + }, findOptions).then(results => results.map(result => result.relatedId)); + } // Returns a promise for a list of owning ids given some related ids. + // className here is the owning className. + + + owningIds(className, key, relatedIds) { + return this.adapter.find(joinTableName(className, key), relationSchema, { + relatedId: { + $in: relatedIds + } + }, { + keys: ['owningId'] + }).then(results => results.map(result => result.owningId)); + } // Modifies query so that it no longer has $in on relation fields, or + // equal-to-pointer constraints on relation fields. + // Returns a promise that resolves when query is mutated + + + reduceInRelation(className, query, schema) { + // Search for an in-relation or equal-to-relation + // Make it sequential for now, not sure of paralleization side effects + if (query['$or']) { + const ors = query['$or']; + return Promise.all(ors.map((aQuery, index) => { + return this.reduceInRelation(className, aQuery, schema).then(aQuery => { + query['$or'][index] = aQuery; + }); + })).then(() => { + return Promise.resolve(query); + }); + } + + const promises = Object.keys(query).map(key => { + const t = schema.getExpectedType(className, key); + + if (!t || t.type !== 'Relation') { + return Promise.resolve(query); + } + + let queries = null; + + if (query[key] && (query[key]['$in'] || query[key]['$ne'] || query[key]['$nin'] || query[key].__type == 'Pointer')) { + // Build the list of queries + queries = Object.keys(query[key]).map(constraintKey => { + let relatedIds; + let isNegation = false; + + if (constraintKey === 'objectId') { + relatedIds = [query[key].objectId]; + } else if (constraintKey == '$in') { + relatedIds = query[key]['$in'].map(r => r.objectId); + } else if (constraintKey == '$nin') { + isNegation = true; + relatedIds = query[key]['$nin'].map(r => r.objectId); + } else if (constraintKey == '$ne') { + isNegation = true; + relatedIds = [query[key]['$ne'].objectId]; + } else { + return; + } + + return { + isNegation, + relatedIds + }; + }); + } else { + queries = [{ + isNegation: false, + relatedIds: [] + }]; + } // remove the current queryKey as we don,t need it anymore + + + delete query[key]; // execute each query independently to build the list of + // $in / $nin + + const promises = queries.map(q => { + if (!q) { + return Promise.resolve(); + } + + return this.owningIds(className, key, q.relatedIds).then(ids => { + if (q.isNegation) { + this.addNotInObjectIdsIds(ids, query); + } else { + this.addInObjectIdsIds(ids, query); + } + + return Promise.resolve(); + }); + }); + return Promise.all(promises).then(() => { + return Promise.resolve(); + }); + }); + return Promise.all(promises).then(() => { + return Promise.resolve(query); + }); + } // Modifies query so that it no longer has $relatedTo + // Returns a promise that resolves when query is mutated + + + reduceRelationKeys(className, query, queryOptions) { + if (query['$or']) { + return Promise.all(query['$or'].map(aQuery => { + return this.reduceRelationKeys(className, aQuery, queryOptions); + })); + } + + var relatedTo = query['$relatedTo']; + + if (relatedTo) { + return this.relatedIds(relatedTo.object.className, relatedTo.key, relatedTo.object.objectId, queryOptions).then(ids => { + delete query['$relatedTo']; + this.addInObjectIdsIds(ids, query); + return this.reduceRelationKeys(className, query, queryOptions); + }).then(() => {}); + } + } + + addInObjectIdsIds(ids = null, query) { + const idsFromString = typeof query.objectId === 'string' ? [query.objectId] : null; + const idsFromEq = query.objectId && query.objectId['$eq'] ? [query.objectId['$eq']] : null; + const idsFromIn = query.objectId && query.objectId['$in'] ? query.objectId['$in'] : null; // -disable-next + + const allIds = [idsFromString, idsFromEq, idsFromIn, ids].filter(list => list !== null); + const totalLength = allIds.reduce((memo, list) => memo + list.length, 0); + let idsIntersection = []; + + if (totalLength > 125) { + idsIntersection = _intersect.default.big(allIds); + } else { + idsIntersection = (0, _intersect.default)(allIds); + } // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. + + + if (!('objectId' in query)) { + query.objectId = { + $in: undefined + }; + } else if (typeof query.objectId === 'string') { + query.objectId = { + $in: undefined, + $eq: query.objectId + }; + } + + query.objectId['$in'] = idsIntersection; + return query; + } + + addNotInObjectIdsIds(ids = [], query) { + const idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : []; + let allIds = [...idsFromNin, ...ids].filter(list => list !== null); // make a set and spread to remove duplicates + + allIds = [...new Set(allIds)]; // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. + + if (!('objectId' in query)) { + query.objectId = { + $nin: undefined + }; + } else if (typeof query.objectId === 'string') { + query.objectId = { + $nin: undefined, + $eq: query.objectId + }; + } + + query.objectId['$nin'] = allIds; + return query; + } // Runs a query on the database. + // Returns a promise that resolves to a list of items. + // Options: + // skip number of results to skip. + // limit limit to this number of results. + // sort an object where keys are the fields to sort by. + // the value is +1 for ascending, -1 for descending. + // count run a count instead of returning results. + // acl restrict this operation with an ACL for the provided array + // of user objectIds and roles. acl: null means no user. + // when this field is not present, don't do anything regarding ACLs. + // caseInsensitive make string comparisons case insensitive + // TODO: make userIds not needed here. The db adapter shouldn't know + // anything about users, ideally. Then, improve the format of the ACL + // arg to work like the others. + + + find(className, query, { + skip, + limit, + acl, + sort = {}, + count, + keys, + op, + distinct, + pipeline, + readPreference, + hint, + caseInsensitive = false, + explain + } = {}, auth = {}, validSchemaController) { + const isMaster = acl === undefined; + const aclGroup = acl || []; + op = op || (typeof query.objectId == 'string' && Object.keys(query).length === 1 ? 'get' : 'find'); // Count operation if counting + + op = count === true ? 'count' : op; + let classExists = true; + return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { + //Allow volatile classes if querying with Master (for _PushStatus) + //TODO: Move volatile classes concept into mongo adapter, postgres adapter shouldn't care + //that api.parse.com breaks when _PushStatus exists in mongo. + return schemaController.getOneSchema(className, isMaster).catch(error => { + // Behavior for non-existent classes is kinda weird on Parse.com. Probably doesn't matter too much. + // For now, pretend the class exists but has no objects, + if (error === undefined) { + classExists = false; + return { + fields: {} + }; + } + + throw error; + }).then(schema => { + // Parse.com treats queries on _created_at and _updated_at as if they were queries on createdAt and updatedAt, + // so duplicate that behavior here. If both are specified, the correct behavior to match Parse.com is to + // use the one that appears first in the sort list. + if (sort._created_at) { + sort.createdAt = sort._created_at; + delete sort._created_at; + } + + if (sort._updated_at) { + sort.updatedAt = sort._updated_at; + delete sort._updated_at; + } + + const queryOptions = { + skip, + limit, + sort, + keys, + readPreference, + hint, + caseInsensitive, + explain + }; + Object.keys(sort).forEach(fieldName => { + if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Cannot sort by ${fieldName}`); + } + + const rootFieldName = getRootFieldName(fieldName); + + if (!SchemaController.fieldNameIsValid(rootFieldName)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); + } + }); + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, op)).then(() => this.reduceRelationKeys(className, query, queryOptions)).then(() => this.reduceInRelation(className, query, schemaController)).then(() => { + let protectedFields; + + if (!isMaster) { + query = this.addPointerPermissions(schemaController, className, op, query, aclGroup); + /* Don't use projections to optimize the protectedFields since the protectedFields + based on pointer-permissions are determined after querying. The filtering can + overwrite the protected fields. */ + + protectedFields = this.addProtectedFields(schemaController, className, query, aclGroup, auth, queryOptions); + } + + if (!query) { + if (op === 'get') { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } else { + return []; + } + } + + if (!isMaster) { + if (op === 'update' || op === 'delete') { + query = addWriteACL(query, aclGroup); + } else { + query = addReadACL(query, aclGroup); + } + } + + validateQuery(query); + + if (count) { + if (!classExists) { + return 0; + } else { + return this.adapter.count(className, schema, query, readPreference, undefined, hint); + } + } else if (distinct) { + if (!classExists) { + return []; + } else { + return this.adapter.distinct(className, schema, query, distinct); + } + } else if (pipeline) { + if (!classExists) { + return []; + } else { + return this.adapter.aggregate(className, schema, pipeline, readPreference, hint, explain); + } + } else if (explain) { + return this.adapter.find(className, schema, query, queryOptions); + } else { + return this.adapter.find(className, schema, query, queryOptions).then(objects => objects.map(object => { + object = untransformObjectACL(object); + return filterSensitiveData(isMaster, aclGroup, auth, op, schemaController, className, protectedFields, object); + })).catch(error => { + throw new _node.Parse.Error(_node.Parse.Error.INTERNAL_SERVER_ERROR, error); + }); + } + }); + }); + }); + } + + deleteSchema(className) { + return this.loadSchema({ + clearCache: true + }).then(schemaController => schemaController.getOneSchema(className, true)).catch(error => { + if (error === undefined) { + return { + fields: {} + }; + } else { + throw error; + } + }).then(schema => { + return this.collectionExists(className).then(() => this.adapter.count(className, { + fields: {} + }, null, '', false)).then(count => { + if (count > 0) { + throw new _node.Parse.Error(255, `Class ${className} is not empty, contains ${count} objects, cannot drop schema.`); + } + + return this.adapter.deleteClass(className); + }).then(wasParseCollection => { + if (wasParseCollection) { + const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); + return Promise.all(relationFieldNames.map(name => this.adapter.deleteClass(joinTableName(className, name)))).then(() => { + return; + }); + } else { + return Promise.resolve(); + } + }); + }); + } // Constraints query using CLP's pointer permissions (PP) if any. + // 1. Etract the user id from caller's ACLgroup; + // 2. Exctract a list of field names that are PP for target collection and operation; + // 3. Constraint the original query so that each PP field must + // point to caller's id (or contain it in case of PP field being an array) + + + addPointerPermissions(schema, className, operation, query, aclGroup = []) { + // Check if class has public permission for operation + // If the BaseCLP pass, let go through + if (schema.testPermissionsForClassName(className, aclGroup, operation)) { + return query; + } + + const perms = schema.getClassLevelPermissions(className); + const userACL = aclGroup.filter(acl => { + return acl.indexOf('role:') != 0 && acl != '*'; + }); + const groupKey = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; + const permFields = []; + + if (perms[operation] && perms[operation].pointerFields) { + permFields.push(...perms[operation].pointerFields); + } + + if (perms[groupKey]) { + for (const field of perms[groupKey]) { + if (!permFields.includes(field)) { + permFields.push(field); + } + } + } // the ACL should have exactly 1 user + + + if (permFields.length > 0) { + // the ACL should have exactly 1 user + // No user set return undefined + // If the length is > 1, that means we didn't de-dupe users correctly + if (userACL.length != 1) { + return; + } + + const userId = userACL[0]; + const userPointer = { + __type: 'Pointer', + className: '_User', + objectId: userId + }; + const queries = permFields.map(key => { + const fieldDescriptor = schema.getExpectedType(className, key); + const fieldType = fieldDescriptor && typeof fieldDescriptor === 'object' && Object.prototype.hasOwnProperty.call(fieldDescriptor, 'type') ? fieldDescriptor.type : null; + let queryClause; + + if (fieldType === 'Pointer') { + // constraint for single pointer setup + queryClause = { + [key]: userPointer + }; + } else if (fieldType === 'Array') { + // constraint for users-array setup + queryClause = { + [key]: { + $all: [userPointer] + } + }; + } else if (fieldType === 'Object') { + // constraint for object setup + queryClause = { + [key]: userPointer + }; + } else { + // This means that there is a CLP field of an unexpected type. This condition should not happen, which is + // why is being treated as an error. + throw Error(`An unexpected condition occurred when resolving pointer permissions: ${className} ${key}`); + } // if we already have a constraint on the key, use the $and + + + if (Object.prototype.hasOwnProperty.call(query, key)) { + return { + $and: [queryClause, query] + }; + } // otherwise just add the constaint + + + return Object.assign({}, query, queryClause); + }); + return queries.length === 1 ? queries[0] : { + $or: queries + }; + } else { + return query; + } + } + + addProtectedFields(schema, className, query = {}, aclGroup = [], auth = {}, queryOptions = {}) { + const perms = schema.getClassLevelPermissions(className); + if (!perms) return null; + const protectedFields = perms.protectedFields; + if (!protectedFields) return null; + if (aclGroup.indexOf(query.objectId) > -1) return null; // for queries where "keys" are set and do not include all 'userField':{field}, + // we have to transparently include it, and then remove before returning to client + // Because if such key not projected the permission won't be enforced properly + // PS this is called when 'excludeKeys' already reduced to 'keys' + + const preserveKeys = queryOptions.keys; // these are keys that need to be included only + // to be able to apply protectedFields by pointer + // and then unset before returning to client (later in filterSensitiveFields) + + const serverOnlyKeys = []; + const authenticated = auth.user; // map to allow check without array search + + const roles = (auth.userRoles || []).reduce((acc, r) => { + acc[r] = protectedFields[r]; + return acc; + }, {}); // array of sets of protected fields. separate item for each applicable criteria + + const protectedKeysSets = []; + + for (const key in protectedFields) { + // skip userFields + if (key.startsWith('userField:')) { + if (preserveKeys) { + const fieldName = key.substring(10); + + if (!preserveKeys.includes(fieldName)) { + // 1. put it there temporarily + queryOptions.keys && queryOptions.keys.push(fieldName); // 2. preserve it delete later + + serverOnlyKeys.push(fieldName); + } + } + + continue; + } // add public tier + + + if (key === '*') { + protectedKeysSets.push(protectedFields[key]); + continue; + } + + if (authenticated) { + if (key === 'authenticated') { + // for logged in users + protectedKeysSets.push(protectedFields[key]); + continue; + } + + if (roles[key] && key.startsWith('role:')) { + // add applicable roles + protectedKeysSets.push(roles[key]); + } + } + } // check if there's a rule for current user's id + + + if (authenticated) { + const userId = auth.user.id; + + if (perms.protectedFields[userId]) { + protectedKeysSets.push(perms.protectedFields[userId]); + } + } // preserve fields to be removed before sending response to client + + + if (serverOnlyKeys.length > 0) { + perms.protectedFields.temporaryKeys = serverOnlyKeys; + } + + let protectedKeys = protectedKeysSets.reduce((acc, next) => { + if (next) { + acc.push(...next); + } + + return acc; + }, []); // intersect all sets of protectedFields + + protectedKeysSets.forEach(fields => { + if (fields) { + protectedKeys = protectedKeys.filter(v => fields.includes(v)); + } + }); + return protectedKeys; + } + + createTransactionalSession() { + return this.adapter.createTransactionalSession().then(transactionalSession => { + this._transactionalSession = transactionalSession; + }); + } + + commitTransactionalSession() { + if (!this._transactionalSession) { + throw new Error('There is no transactional session to commit'); + } + + return this.adapter.commitTransactionalSession(this._transactionalSession).then(() => { + this._transactionalSession = null; + }); + } + + abortTransactionalSession() { + if (!this._transactionalSession) { + throw new Error('There is no transactional session to abort'); + } + + return this.adapter.abortTransactionalSession(this._transactionalSession).then(() => { + this._transactionalSession = null; + }); + } // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to + // have a Parse app without it having a _User collection. + + + performInitialization() { + const requiredUserFields = { + fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._User) + }; + const requiredRoleFields = { + fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Role) + }; + const requiredIdempotencyFields = { + fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Idempotency) + }; + const userClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_User')); + const roleClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_Role')); + const idempotencyClassPromise = this.adapter instanceof _MongoStorageAdapter.default ? this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')) : Promise.resolve(); + const usernameUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['username'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for usernames: ', error); + + throw error; + }); + const usernameCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)).catch(error => { + _logger.default.warn('Unable to create case insensitive username index: ', error); + + throw error; + }); + const emailUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['email'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for user email addresses: ', error); + + throw error; + }); + const emailCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true)).catch(error => { + _logger.default.warn('Unable to create case insensitive email index: ', error); + + throw error; + }); + const roleUniqueness = roleClassPromise.then(() => this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for role name: ', error); + + throw error; + }); + const idempotencyRequestIdIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureUniqueness('_Idempotency', requiredIdempotencyFields, ['reqId'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for idempotency request ID: ', error); + + throw error; + }) : Promise.resolve(); + const idempotencyExpireIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureIndex('_Idempotency', requiredIdempotencyFields, ['expire'], 'ttl', false, { + ttl: 0 + })).catch(error => { + _logger.default.warn('Unable to create TTL index for idempotency expire date: ', error); + + throw error; + }) : Promise.resolve(); + const indexPromise = this.adapter.updateSchemaWithIndexes(); // Create tables for volatile classes + + const adapterInit = this.adapter.performInitialization({ + VolatileClassesSchemas: SchemaController.VolatileClassesSchemas + }); + return Promise.all([usernameUniqueness, usernameCaseInsensitiveIndex, emailUniqueness, emailCaseInsensitiveIndex, roleUniqueness, idempotencyRequestIdIndex, idempotencyExpireIndex, adapterInit, indexPromise]); + } + +} + +module.exports = DatabaseController; // Expose validateQuery for tests + +module.exports._validateQuery = validateQuery; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9EYXRhYmFzZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiYWRkV3JpdGVBQ0wiLCJxdWVyeSIsImFjbCIsIm5ld1F1ZXJ5IiwiXyIsImNsb25lRGVlcCIsIl93cGVybSIsIiRpbiIsImFkZFJlYWRBQ0wiLCJfcnBlcm0iLCJ0cmFuc2Zvcm1PYmplY3RBQ0wiLCJBQ0wiLCJyZXN1bHQiLCJlbnRyeSIsInJlYWQiLCJwdXNoIiwid3JpdGUiLCJzcGVjaWFsUXVlcnlrZXlzIiwiaXNTcGVjaWFsUXVlcnlLZXkiLCJrZXkiLCJpbmRleE9mIiwidmFsaWRhdGVRdWVyeSIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1FVRVJZIiwiJG9yIiwiQXJyYXkiLCJmb3JFYWNoIiwiJGFuZCIsIiRub3IiLCJsZW5ndGgiLCJPYmplY3QiLCJrZXlzIiwiJHJlZ2V4IiwiJG9wdGlvbnMiLCJtYXRjaCIsIklOVkFMSURfS0VZX05BTUUiLCJmaWx0ZXJTZW5zaXRpdmVEYXRhIiwiaXNNYXN0ZXIiLCJhY2xHcm91cCIsImF1dGgiLCJvcGVyYXRpb24iLCJzY2hlbWEiLCJjbGFzc05hbWUiLCJwcm90ZWN0ZWRGaWVsZHMiLCJvYmplY3QiLCJ1c2VySWQiLCJ1c2VyIiwiaWQiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlzUmVhZE9wZXJhdGlvbiIsInByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtIiwiZmlsdGVyIiwic3RhcnRzV2l0aCIsIm1hcCIsInN1YnN0cmluZyIsInZhbHVlIiwibmV3UHJvdGVjdGVkRmllbGRzIiwib3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMiLCJwb2ludGVyUGVybSIsInBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyIiwicmVhZFVzZXJGaWVsZFZhbHVlIiwiaXNBcnJheSIsInNvbWUiLCJvYmplY3RJZCIsImZpZWxkcyIsInYiLCJpbmNsdWRlcyIsImlzVXNlckNsYXNzIiwiayIsInRlbXBvcmFyeUtleXMiLCJwYXNzd29yZCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJzZXNzaW9uVG9rZW4iLCJfZW1haWxfdmVyaWZ5X3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX3RvbWJzdG9uZSIsIl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCIsIl9mYWlsZWRfbG9naW5fY291bnQiLCJfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsIl9wYXNzd29yZF9oaXN0b3J5IiwiYXV0aERhdGEiLCJzcGVjaWFsS2V5c0ZvclVwZGF0ZSIsImlzU3BlY2lhbFVwZGF0ZUtleSIsImV4cGFuZFJlc3VsdE9uS2V5UGF0aCIsInBhdGgiLCJzcGxpdCIsImZpcnN0S2V5IiwibmV4dFBhdGgiLCJzbGljZSIsImpvaW4iLCJzYW5pdGl6ZURhdGFiYXNlUmVzdWx0Iiwib3JpZ2luYWxPYmplY3QiLCJyZXNwb25zZSIsIlByb21pc2UiLCJyZXNvbHZlIiwia2V5VXBkYXRlIiwiX19vcCIsImpvaW5UYWJsZU5hbWUiLCJmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlIiwiYW1vdW50IiwiSU5WQUxJRF9KU09OIiwib2JqZWN0cyIsIkNPTU1BTkRfVU5BVkFJTEFCTEUiLCJ0cmFuc2Zvcm1BdXRoRGF0YSIsInByb3ZpZGVyIiwicHJvdmlkZXJEYXRhIiwiZmllbGROYW1lIiwidHlwZSIsInVudHJhbnNmb3JtT2JqZWN0QUNMIiwib3V0cHV0IiwiZ2V0Um9vdEZpZWxkTmFtZSIsInJlbGF0aW9uU2NoZW1hIiwicmVsYXRlZElkIiwib3duaW5nSWQiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJzY2hlbWFDYWNoZSIsInNjaGVtYVByb21pc2UiLCJfdHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb2xsZWN0aW9uRXhpc3RzIiwiY2xhc3NFeGlzdHMiLCJwdXJnZUNvbGxlY3Rpb24iLCJsb2FkU2NoZW1hIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRPbmVTY2hlbWEiLCJkZWxldGVPYmplY3RzQnlRdWVyeSIsInZhbGlkYXRlQ2xhc3NOYW1lIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZUlzVmFsaWQiLCJyZWplY3QiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJvcHRpb25zIiwiY2xlYXJDYWNoZSIsImxvYWQiLCJsb2FkU2NoZW1hSWZOZWVkZWQiLCJyZWRpcmVjdENsYXNzTmFtZUZvcktleSIsInQiLCJnZXRFeHBlY3RlZFR5cGUiLCJ0YXJnZXRDbGFzcyIsInZhbGlkYXRlT2JqZWN0IiwicnVuT3B0aW9ucyIsInVuZGVmaW5lZCIsInMiLCJjYW5BZGRGaWVsZCIsInVwZGF0ZSIsIm1hbnkiLCJ1cHNlcnQiLCJhZGRzRmllbGQiLCJza2lwU2FuaXRpemF0aW9uIiwidmFsaWRhdGVPbmx5IiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwib3JpZ2luYWxRdWVyeSIsIm9yaWdpbmFsVXBkYXRlIiwicmVsYXRpb25VcGRhdGVzIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiY29sbGVjdFJlbGF0aW9uVXBkYXRlcyIsImFkZFBvaW50ZXJQZXJtaXNzaW9ucyIsImNhdGNoIiwiZXJyb3IiLCJyb290RmllbGROYW1lIiwiZmllbGROYW1lSXNWYWxpZCIsInVwZGF0ZU9wZXJhdGlvbiIsImlubmVyS2V5IiwiSU5WQUxJRF9ORVNURURfS0VZIiwiZmluZCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1cGRhdGVPYmplY3RzQnlRdWVyeSIsInVwc2VydE9uZU9iamVjdCIsImZpbmRPbmVBbmRVcGRhdGUiLCJoYW5kbGVSZWxhdGlvblVwZGF0ZXMiLCJvcHMiLCJkZWxldGVNZSIsInByb2Nlc3MiLCJvcCIsIngiLCJwZW5kaW5nIiwiYWRkUmVsYXRpb24iLCJyZW1vdmVSZWxhdGlvbiIsImFsbCIsImZyb21DbGFzc05hbWUiLCJmcm9tSWQiLCJ0b0lkIiwiZG9jIiwiY29kZSIsImRlc3Ryb3kiLCJwYXJzZUZvcm1hdFNjaGVtYSIsImNyZWF0ZSIsImNyZWF0ZWRBdCIsImlzbyIsIl9fdHlwZSIsInVwZGF0ZWRBdCIsImVuZm9yY2VDbGFzc0V4aXN0cyIsImNyZWF0ZU9iamVjdCIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJjbGFzc1NjaGVtYSIsInNjaGVtYURhdGEiLCJzY2hlbWFGaWVsZHMiLCJuZXdLZXlzIiwiZmllbGQiLCJhY3Rpb24iLCJkZWxldGVFdmVyeXRoaW5nIiwiZmFzdCIsImRlbGV0ZUFsbENsYXNzZXMiLCJjbGVhciIsInJlbGF0ZWRJZHMiLCJxdWVyeU9wdGlvbnMiLCJza2lwIiwibGltaXQiLCJzb3J0IiwiZmluZE9wdGlvbnMiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiX2lkIiwicmVzdWx0cyIsIm93bmluZ0lkcyIsInJlZHVjZUluUmVsYXRpb24iLCJvcnMiLCJhUXVlcnkiLCJpbmRleCIsInByb21pc2VzIiwicXVlcmllcyIsImNvbnN0cmFpbnRLZXkiLCJpc05lZ2F0aW9uIiwiciIsInEiLCJpZHMiLCJhZGROb3RJbk9iamVjdElkc0lkcyIsImFkZEluT2JqZWN0SWRzSWRzIiwicmVkdWNlUmVsYXRpb25LZXlzIiwicmVsYXRlZFRvIiwiaWRzRnJvbVN0cmluZyIsImlkc0Zyb21FcSIsImlkc0Zyb21JbiIsImFsbElkcyIsImxpc3QiLCJ0b3RhbExlbmd0aCIsInJlZHVjZSIsIm1lbW8iLCJpZHNJbnRlcnNlY3Rpb24iLCJpbnRlcnNlY3QiLCJiaWciLCIkZXEiLCJpZHNGcm9tTmluIiwiU2V0IiwiJG5pbiIsImNvdW50IiwiZGlzdGluY3QiLCJwaXBlbGluZSIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCJfY3JlYXRlZF9hdCIsIl91cGRhdGVkX2F0IiwiYWRkUHJvdGVjdGVkRmllbGRzIiwiYWdncmVnYXRlIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiZGVsZXRlU2NoZW1hIiwiZGVsZXRlQ2xhc3MiLCJ3YXNQYXJzZUNvbGxlY3Rpb24iLCJyZWxhdGlvbkZpZWxkTmFtZXMiLCJuYW1lIiwidGVzdFBlcm1pc3Npb25zRm9yQ2xhc3NOYW1lIiwidXNlckFDTCIsImdyb3VwS2V5IiwicGVybUZpZWxkcyIsInBvaW50ZXJGaWVsZHMiLCJ1c2VyUG9pbnRlciIsImZpZWxkRGVzY3JpcHRvciIsImZpZWxkVHlwZSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInF1ZXJ5Q2xhdXNlIiwiJGFsbCIsImFzc2lnbiIsInByZXNlcnZlS2V5cyIsInNlcnZlck9ubHlLZXlzIiwiYXV0aGVudGljYXRlZCIsInJvbGVzIiwidXNlclJvbGVzIiwiYWNjIiwicHJvdGVjdGVkS2V5c1NldHMiLCJwcm90ZWN0ZWRLZXlzIiwibmV4dCIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCJyZXF1aXJlZFVzZXJGaWVsZHMiLCJkZWZhdWx0Q29sdW1ucyIsIl9EZWZhdWx0IiwiX1VzZXIiLCJyZXF1aXJlZFJvbGVGaWVsZHMiLCJfUm9sZSIsInJlcXVpcmVkSWRlbXBvdGVuY3lGaWVsZHMiLCJfSWRlbXBvdGVuY3kiLCJ1c2VyQ2xhc3NQcm9taXNlIiwicm9sZUNsYXNzUHJvbWlzZSIsImlkZW1wb3RlbmN5Q2xhc3NQcm9taXNlIiwiTW9uZ29TdG9yYWdlQWRhcHRlciIsInVzZXJuYW1lVW5pcXVlbmVzcyIsImVuc3VyZVVuaXF1ZW5lc3MiLCJsb2dnZXIiLCJ3YXJuIiwidXNlcm5hbWVDYXNlSW5zZW5zaXRpdmVJbmRleCIsImVuc3VyZUluZGV4IiwiZW1haWxVbmlxdWVuZXNzIiwiZW1haWxDYXNlSW5zZW5zaXRpdmVJbmRleCIsInJvbGVVbmlxdWVuZXNzIiwiaWRlbXBvdGVuY3lSZXF1ZXN0SWRJbmRleCIsImlkZW1wb3RlbmN5RXhwaXJlSW5kZXgiLCJ0dGwiLCJpbmRleFByb21pc2UiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsImFkYXB0ZXJJbml0IiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsIm1vZHVsZSIsImV4cG9ydHMiLCJfdmFsaWRhdGVRdWVyeSJdLCJtYXBwaW5ncyI6Ijs7QUFLQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUEyTkE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXhOQSxTQUFTQSxXQUFULENBQXFCQyxLQUFyQixFQUE0QkMsR0FBNUIsRUFBaUM7QUFDL0IsUUFBTUMsUUFBUSxHQUFHQyxnQkFBRUMsU0FBRixDQUFZSixLQUFaLENBQWpCLENBRCtCLENBRS9COzs7QUFDQUUsRUFBQUEsUUFBUSxDQUFDRyxNQUFULEdBQWtCO0FBQUVDLElBQUFBLEdBQUcsRUFBRSxDQUFDLElBQUQsRUFBTyxHQUFHTCxHQUFWO0FBQVAsR0FBbEI7QUFDQSxTQUFPQyxRQUFQO0FBQ0Q7O0FBRUQsU0FBU0ssVUFBVCxDQUFvQlAsS0FBcEIsRUFBMkJDLEdBQTNCLEVBQWdDO0FBQzlCLFFBQU1DLFFBQVEsR0FBR0MsZ0JBQUVDLFNBQUYsQ0FBWUosS0FBWixDQUFqQixDQUQ4QixDQUU5Qjs7O0FBQ0FFLEVBQUFBLFFBQVEsQ0FBQ00sTUFBVCxHQUFrQjtBQUFFRixJQUFBQSxHQUFHLEVBQUUsQ0FBQyxJQUFELEVBQU8sR0FBUCxFQUFZLEdBQUdMLEdBQWY7QUFBUCxHQUFsQjtBQUNBLFNBQU9DLFFBQVA7QUFDRCxDLENBRUQ7OztBQUNBLE1BQU1PLGtCQUFrQixHQUFHLFVBQXdCO0FBQUEsTUFBdkI7QUFBRUMsSUFBQUE7QUFBRixHQUF1QjtBQUFBLE1BQWJDLE1BQWE7O0FBQ2pELE1BQUksQ0FBQ0QsR0FBTCxFQUFVO0FBQ1IsV0FBT0MsTUFBUDtBQUNEOztBQUVEQSxFQUFBQSxNQUFNLENBQUNOLE1BQVAsR0FBZ0IsRUFBaEI7QUFDQU0sRUFBQUEsTUFBTSxDQUFDSCxN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QUFMLENBQWF3TSx1QkFBYixFQUFyQixDQTdHc0IsQ0ErR3RCOztBQUNBLFVBQU1DLFdBQVcsR0FBRyxLQUFLek0sT0FBTCxDQUFhOEsscUJBQWIsQ0FBbUM7QUFDckQ0QixNQUFBQSxzQkFBc0IsRUFBRTdMLGdCQUFnQixDQUFDNkw7QUFEWSxLQUFuQyxDQUFwQjtBQUdBLFdBQU9qTyxPQUFPLENBQUN1RixHQUFSLENBQVksQ0FDakIySCxrQkFEaUIsRUFFakJJLDRCQUZpQixFQUdqQkUsZUFIaUIsRUFJakJDLHlCQUppQixFQUtqQkMsY0FMaUIsRUFNakJDLHlCQU5pQixFQU9qQkMsc0JBUGlCLEVBUWpCSSxXQVJpQixFQVNqQkYsWUFUaUIsQ0FBWixDQUFQO0FBV0Q7O0FBM3lDc0I7O0FBZ3pDekJJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjlNLGtCQUFqQixDLENBQ0E7O0FBQ0E2TSxNQUFNLENBQUNDLE9BQVAsQ0FBZUMsY0FBZixHQUFnQ2hULGFBQWhDIiwic291cmNlc0NvbnRlbnQiOlsi77u/Ly8gQGZsb3dcbi8vIEEgZGF0YWJhc2UgYWRhcHRlciB0aGF0IHdvcmtzIHdpdGggZGF0YSBleHBvcnRlZCBmcm9tIHRoZSBob3N0ZWRcbi8vIFBhcnNlIGRhdGFiYXNlLlxuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBpbnRlcnNlY3QgZnJvbSAnaW50ZXJzZWN0Jztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IGRlZXBjb3B5IGZyb20gJ2RlZXBjb3B5JztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCAqIGFzIFNjaGVtYUNvbnRyb2xsZXIgZnJvbSAnLi9TY2hlbWFDb250cm9sbGVyJztcbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7IFF1ZXJ5T3B0aW9ucywgRnVsbFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuXG5mdW5jdGlvbiBhZGRXcml0ZUFDTChxdWVyeSwgYWNsKSB7XG4gIGNvbnN0IG5ld1F1ZXJ5ID0gXy5jbG9uZURlZXAocXVlcnkpO1xuICAvL0Nhbid0IGJlIGFueSBleGlzdGluZyAnX3dwZXJtJyBxdWVyeSwgd2UgZG9uJ3QgYWxsb3cgY2xpZW50IHF1ZXJpZXMgb24gdGhhdCwgbm8gbmVlZCB0byAkYW5kXG4gIG5ld1F1ZXJ5Ll93cGVybSA9IHsgJGluOiBbbnVsbCwgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbmZ1bmN0aW9uIGFkZFJlYWRBQ0wocXVlcnksIGFjbCkge1xuICBjb25zdCBuZXdRdWVyeSA9IF8uY2xvbmVEZWVwKHF1ZXJ5KTtcbiAgLy9DYW4ndCBiZSBhbnkgZXhpc3RpbmcgJ19ycGVybScgcXVlcnksIHdlIGRvbid0IGFsbG93IGNsaWVudCBxdWVyaWVzIG9uIHRoYXQsIG5vIG5lZWQgdG8gJGFuZFxuICBuZXdRdWVyeS5fcnBlcm0gPSB7ICRpbjogW251bGwsICcqJywgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbi8vIFRyYW5zZm9ybXMgYSBSRVNUIEFQSSBmb3JtYXR0ZWQgQUNMIG9iamVjdCB0byBvdXIgdHdvLWZpZWxkIG1vbmdvIGZvcm1hdC5cbmNvbnN0IHRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IEFDTCwgLi4ucmVzdWx0IH0pID0+IHtcbiAgaWYgKCFBQ0wpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcmVzdWx0Ll93cGVybSA9IFtdO1xuICByZXN1bHQuX3JwZXJtID0gW107XG5cbiAgZm9yIChjb25zdCBlbnRyeSBpbiBBQ0wpIHtcbiAgICBpZiAoQUNMW2VudHJ5XS5yZWFkKSB7XG4gICAgICByZXN1bHQuX3JwZXJtLnB1c2goZW50cnkpO1xuICAgIH1cbiAgICBpZiAoQUNMW2VudHJ5XS53cml0ZSkge1xuICAgICAgcmVzdWx0Ll93cGVybS5wdXNoKGVudHJ5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbnN0IHNwZWNpYWxRdWVyeWtleXMgPSBbXG4gICckYW5kJyxcbiAgJyRvcicsXG4gICckbm9yJyxcbiAgJ19ycGVybScsXG4gICdfd3Blcm0nLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuXTtcblxuY29uc3QgaXNTcGVjaWFsUXVlcnlLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbFF1ZXJ5a2V5cy5pbmRleE9mKGtleSkgPj0gMDtcbn07XG5cbmNvbnN0IHZhbGlkYXRlUXVlcnkgPSAocXVlcnk6IGFueSk6IHZvaWQgPT4ge1xuICBpZiAocXVlcnkuQUNMKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdDYW5ub3QgcXVlcnkgb24gQUNMLicpO1xuICB9XG5cbiAgaWYgKHF1ZXJ5LiRvcikge1xuICAgIGlmIChxdWVyeS4kb3IgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcXVlcnkuJG9yLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRvciBmb3JtYXQgLSB1c2UgYW4gYXJyYXkgdmFsdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXJ5LiRhbmQpIHtcbiAgICBpZiAocXVlcnkuJGFuZCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBxdWVyeS4kYW5kLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRhbmQgZm9ybWF0IC0gdXNlIGFuIGFycmF5IHZhbHVlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChxdWVyeS4kbm9yKSB7XG4gICAgaWYgKHF1ZXJ5LiRub3IgaW5zdGFuY2VvZiBBcnJheSAmJiBxdWVyeS4kbm9yLmxlbmd0aCA+IDApIHtcbiAgICAgIHF1ZXJ5LiRub3IuZm9yRWFjaCh2YWxpZGF0ZVF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnQmFkICRub3IgZm9ybWF0IC0gdXNlIGFuIGFycmF5IG9mIGF0IGxlYXN0IDEgdmFsdWUuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGlmIChxdWVyeSAmJiBxdWVyeVtrZXldICYmIHF1ZXJ5W2tleV0uJHJlZ2V4KSB7XG4gICAgICBpZiAodHlwZW9mIHF1ZXJ5W2tleV0uJG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICghcXVlcnlba2V5XS4kb3B0aW9ucy5tYXRjaCgvXltpbXhzXSskLykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgICAgYEJhZCAkb3B0aW9ucyB2YWx1ZSBmb3IgcXVlcnk6ICR7cXVlcnlba2V5XS4kb3B0aW9uc31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWlzU3BlY2lhbFF1ZXJ5S2V5KGtleSkgJiYgIWtleS5tYXRjaCgvXlthLXpBLVpdW2EtekEtWjAtOV9cXC5dKiQvKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGtleSBuYW1lOiAke2tleX1gKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLy8gRmlsdGVycyBvdXQgYW55IGRhdGEgdGhhdCBzaG91bGRuJ3QgYmUgb24gdGhpcyBSRVNULWZvcm1hdHRlZCBvYmplY3QuXG5jb25zdCBmaWx0ZXJTZW5zaXRpdmVEYXRhID0gKFxuICBpc01hc3RlcjogYm9vbGVhbixcbiAgYWNsR3JvdXA6IGFueVtdLFxuICBhdXRoOiBhbnksXG4gIG9wZXJhdGlvbjogYW55LFxuICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gIHByb3RlY3RlZEZpZWxkczogbnVsbCB8IEFycmF5PGFueT4sXG4gIG9iamVjdDogYW55XG4pID0+IHtcbiAgbGV0IHVzZXJJZCA9IG51bGw7XG4gIGlmIChhdXRoICYmIGF1dGgudXNlcikgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuXG4gIC8vIHJlcGxhY2UgcHJvdGVjdGVkRmllbGRzIHdoZW4gdXNpbmcgcG9pbnRlci1wZXJtaXNzaW9uc1xuICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgaWYgKHBlcm1zKSB7XG4gICAgY29uc3QgaXNSZWFkT3BlcmF0aW9uID0gWydnZXQnLCAnZmluZCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xO1xuXG4gICAgaWYgKGlzUmVhZE9wZXJhdGlvbiAmJiBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgIC8vIGV4dHJhY3QgcHJvdGVjdGVkRmllbGRzIGFkZGVkIHdpdGggdGhlIHBvaW50ZXItcGVybWlzc2lvbiBwcmVmaXhcbiAgICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtID0gT2JqZWN0LmtleXMocGVybXMucHJvdGVjdGVkRmllbGRzKVxuICAgICAgICAuZmlsdGVyKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgndXNlckZpZWxkOicpKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsga2V5OiBrZXkuc3Vic3RyaW5nKDEwKSwgdmFsdWU6IHBlcm1zLnByb3RlY3RlZEZpZWxkc1trZXldIH07XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBuZXdQcm90ZWN0ZWRGaWVsZHM6IEFycmF5PHN0cmluZz5bXSA9IFtdO1xuICAgICAgbGV0IG92ZXJyaWRlUHJvdGVjdGVkRmllbGRzID0gZmFsc2U7XG5cbiAgICAgIC8vIGNoZWNrIGlmIHRoZSBvYmplY3QgZ3JhbnRzIHRoZSBjdXJyZW50IHVzZXIgYWNjZXNzIGJhc2VkIG9uIHRoZSBleHRyYWN0ZWQgZmllbGRzXG4gICAgICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUGVybS5mb3JFYWNoKHBvaW50ZXJQZXJtID0+IHtcbiAgICAgICAgbGV0IHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHJlYWRVc2VyRmllbGRWYWx1ZSA9IG9iamVjdFtwb2ludGVyUGVybS5rZXldO1xuICAgICAgICBpZiAocmVhZFVzZXJGaWVsZFZhbHVlKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVhZFVzZXJGaWVsZFZhbHVlKSkge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPSByZWFkVXNlckZpZWxkVmFsdWUuc29tZShcbiAgICAgICAgICAgICAgdXNlciA9PiB1c2VyLm9iamVjdElkICYmIHVzZXIub2JqZWN0SWQgPT09IHVzZXJJZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPVxuICAgICAgICAgICAgICByZWFkVXNlckZpZWxkVmFsdWUub2JqZWN0SWQgJiYgcmVhZFVzZXJGaWVsZFZhbHVlLm9iamVjdElkID09PSB1c2VySWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyKSB7XG4gICAgICAgICAgb3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMgPSB0cnVlO1xuICAgICAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5wdXNoKHBvaW50ZXJQZXJtLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIGlmIGF0IGxlYXN0IG9uZSBwb2ludGVyLXBlcm1pc3Npb24gYWZmZWN0ZWQgdGhlIGN1cnJlbnQgdXNlclxuICAgICAgLy8gaW50ZXJzZWN0IHZzIHByb3RlY3RlZEZpZWxkcyBmcm9tIHByZXZpb3VzIHN0YWdlIChAc2VlIGFkZFByb3RlY3RlZEZpZWxkcylcbiAgICAgIC8vIFNldHMgdGhlb3J5IChpbnRlcnNlY3Rpb25zKTogQSB4IChCIHggQykgPT0gKEEgeCBCKSB4IENcbiAgICAgIGlmIChvdmVycmlkZVByb3RlY3RlZEZpZWxkcyAmJiBwcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgICAgbmV3UHJvdGVjdGVkRmllbGRzLnB1c2gocHJvdGVjdGVkRmllbGRzKTtcbiAgICAgIH1cbiAgICAgIC8vIGludGVyc2VjdCBhbGwgc2V0cyBvZiBwcm90ZWN0ZWRGaWVsZHNcbiAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGZpZWxkcyA9PiB7XG4gICAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSdyZSBubyBwcm90Y3RlZEZpZWxkcyBieSBvdGhlciBjcml0ZXJpYSAoIGlkIC8gcm9sZSAvIGF1dGgpXG4gICAgICAgICAgLy8gdGhlbiB3ZSBtdXN0IGludGVyc2VjdCBlYWNoIHNldCAocGVyIHVzZXJGaWVsZClcbiAgICAgICAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzID0gZmllbGRzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHMuZmlsdGVyKHYgPT4gZmllbGRzLmluY2x1ZGVzKHYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGlzVXNlckNsYXNzID0gY2xhc3NOYW1lID09PSAnX1VzZXInO1xuXG4gIC8qIHNwZWNpYWwgdHJlYXQgZm9yIHRoZSB1c2VyIGNsYXNzOiBkb24ndCBmaWx0ZXIgcHJvdGVjdGVkRmllbGRzIGlmIGN1cnJlbnRseSBsb2dnZWRpbiB1c2VyIGlzXG4gIHRoZSByZXRyaWV2ZWQgdXNlciAqL1xuICBpZiAoIShpc1VzZXJDbGFzcyAmJiB1c2VySWQgJiYgb2JqZWN0Lm9iamVjdElkID09PSB1c2VySWQpKSB7XG4gICAgcHJvdGVjdGVkRmllbGRzICYmIHByb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGsgPT4gZGVsZXRlIG9iamVjdFtrXSk7XG5cbiAgICAvLyBmaWVsZHMgbm90IHJlcXVlc3RlZCBieSBjbGllbnQgKGV4Y2x1ZGVkKSxcbiAgICAvL2J1dCB3ZXJlIG5lZWRlZCB0byBhcHBseSBwcm90ZWN0dGVkRmllbGRzXG4gICAgcGVybXMucHJvdGVjdGVkRmllbGRzICYmXG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyAmJlxuICAgICAgcGVybXMucHJvdGVjdGVkRmllbGRzLnRlbXBvcmFyeUtleXMuZm9yRWFjaChrID0+IGRlbGV0ZSBvYmplY3Rba10pO1xuICB9XG5cbiAgaWYgKCFpc1VzZXJDbGFzcykge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICBvYmplY3QucGFzc3dvcmQgPSBvYmplY3QuX2hhc2hlZF9wYXNzd29yZDtcbiAgZGVsZXRlIG9iamVjdC5faGFzaGVkX3Bhc3N3b3JkO1xuXG4gIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuXG4gIGlmIChpc01hc3Rlcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3RvbWJzdG9uZTtcbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX2ZhaWxlZF9sb2dpbl9jb3VudDtcbiAgZGVsZXRlIG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2hpc3Rvcnk7XG5cbiAgaWYgKGFjbEdyb3VwLmluZGV4T2Yob2JqZWN0Lm9iamVjdElkKSA+IC0xKSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuaW1wb3J0IHR5cGUgeyBMb2FkU2NoZW1hT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcblxuLy8gUnVucyBhbiB1cGRhdGUgb24gdGhlIGRhdGFiYXNlLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGFuIG9iamVjdCB3aXRoIHRoZSBuZXcgdmFsdWVzIGZvciBmaWVsZFxuLy8gbW9kaWZpY2F0aW9ucyB0aGF0IGRvbid0IGtub3cgdGhlaXIgcmVzdWx0cyBhaGVhZCBvZiB0aW1lLCBsaWtlXG4vLyAnaW5jcmVtZW50Jy5cbi8vIE9wdGlvbnM6XG4vLyAgIGFjbDogIGEgbGlzdCBvZiBzdHJpbmdzLiBJZiB0aGUgb2JqZWN0IHRvIGJlIHVwZGF0ZWQgaGFzIGFuIEFDTCxcbi8vICAgICAgICAgb25lIG9mIHRoZSBwcm92aWRlZCBzdHJpbmdzIG11c3QgcHJvdmlkZSB0aGUgY2FsbGVyIHdpdGhcbi8vICAgICAgICAgd3JpdGUgcGVybWlzc2lvbnMuXG5jb25zdCBzcGVjaWFsS2V5c0ZvclVwZGF0ZSA9IFtcbiAgJ19oYXNoZWRfcGFzc3dvcmQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCcsXG4gICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsXG4gICdfcGFzc3dvcmRfaGlzdG9yeScsXG5dO1xuXG5jb25zdCBpc1NwZWNpYWxVcGRhdGVLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbEtleXNGb3JVcGRhdGUuaW5kZXhPZihrZXkpID49IDA7XG59O1xuXG5mdW5jdGlvbiBleHBhbmRSZXN1bHRPbktleVBhdGgob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkuaW5kZXhPZignLicpIDwgMCkge1xuICAgIG9iamVjdFtrZXldID0gdmFsdWVba2V5XTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG4gIGNvbnN0IHBhdGggPSBrZXkuc3BsaXQoJy4nKTtcbiAgY29uc3QgZmlyc3RLZXkgPSBwYXRoWzBdO1xuICBjb25zdCBuZXh0UGF0aCA9IHBhdGguc2xpY2UoMSkuam9pbignLicpO1xuICBvYmplY3RbZmlyc3RLZXldID0gZXhwYW5kUmVzdWx0T25LZXlQYXRoKG9iamVjdFtmaXJzdEtleV0gfHwge30sIG5leHRQYXRoLCB2YWx1ZVtmaXJzdEtleV0pO1xuICBkZWxldGUgb2JqZWN0W2tleV07XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbmZ1bmN0aW9uIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxPYmplY3QsIHJlc3VsdCk6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0ge307XG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XG4gIH1cbiAgT2JqZWN0LmtleXMob3JpZ2luYWxPYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICBjb25zdCBrZXlVcGRhdGUgPSBvcmlnaW5hbE9iamVjdFtrZXldO1xuICAgIC8vIGRldGVybWluZSBpZiB0aGF0IHdhcyBhbiBvcFxuICAgIGlmIChcbiAgICAgIGtleVVwZGF0ZSAmJlxuICAgICAgdHlwZW9mIGtleVVwZGF0ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIGtleVVwZGF0ZS5fX29wICYmXG4gICAgICBbJ0FkZCcsICdBZGRVbmlxdWUnLCAnUmVtb3ZlJywgJ0luY3JlbWVudCddLmluZGV4T2Yoa2V5VXBkYXRlLl9fb3ApID4gLTFcbiAgICApIHtcbiAgICAgIC8vIG9ubHkgdmFsaWQgb3BzIHRoYXQgcHJvZHVjZSBhbiBhY3Rpb25hYmxlIHJlc3VsdFxuICAgICAgLy8gdGhlIG9wIG1heSBoYXZlIGhhcHBlbmQgb24gYSBrZXlwYXRoXG4gICAgICBleHBhbmRSZXN1bHRPbktleVBhdGgocmVzcG9uc2UsIGtleSwgcmVzdWx0KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcbn1cblxuZnVuY3Rpb24gam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSkge1xuICByZXR1cm4gYF9Kb2luOiR7a2V5fToke2NsYXNzTmFtZX1gO1xufVxuXG5jb25zdCBmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlID0gb2JqZWN0ID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdFtrZXldICYmIG9iamVjdFtrZXldLl9fb3ApIHtcbiAgICAgIHN3aXRjaCAob2JqZWN0W2tleV0uX19vcCkge1xuICAgICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0W2tleV0uYW1vdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5hbW91bnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICAgICAgaWYgKCEob2JqZWN0W2tleV0ub2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5vYmplY3RzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgICAgIGlmICghKG9iamVjdFtrZXldLm9iamVjdHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdvYmplY3RzIHRvIGFkZCBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdFtrZXldID0gb2JqZWN0W2tleV0ub2JqZWN0cztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgICBpZiAoIShvYmplY3Rba2V5XS5vYmplY3RzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnb2JqZWN0cyB0byBhZGQgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICAgIGRlbGV0ZSBvYmplY3Rba2V5XTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5DT01NQU5EX1VOQVZBSUxBQkxFLFxuICAgICAgICAgICAgYFRoZSAke29iamVjdFtrZXldLl9fb3B9IG9wZXJhdG9yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LmBcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuY29uc3QgdHJhbnNmb3JtQXV0aERhdGEgPSAoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkgPT4ge1xuICBpZiAob2JqZWN0LmF1dGhEYXRhICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIE9iamVjdC5rZXlzKG9iamVjdC5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICBjb25zdCBwcm92aWRlckRhdGEgPSBvYmplY3QuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgY29uc3QgZmllbGROYW1lID0gYF9hdXRoX2RhdGFfJHtwcm92aWRlcn1gO1xuICAgICAgaWYgKHByb3ZpZGVyRGF0YSA9PSBudWxsKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fb3A6ICdEZWxldGUnLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSBwcm92aWRlckRhdGE7XG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSA9IHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICB9XG59O1xuLy8gVHJhbnNmb3JtcyBhIERhdGFiYXNlIGZvcm1hdCBBQ0wgdG8gYSBSRVNUIEFQSSBmb3JtYXQgQUNMXG5jb25zdCB1bnRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IF9ycGVybSwgX3dwZXJtLCAuLi5vdXRwdXQgfSkgPT4ge1xuICBpZiAoX3JwZXJtIHx8IF93cGVybSkge1xuICAgIG91dHB1dC5BQ0wgPSB7fTtcblxuICAgIChfcnBlcm0gfHwgW10pLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgaWYgKCFvdXRwdXQuQUNMW2VudHJ5XSkge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XSA9IHsgcmVhZDogdHJ1ZSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV1bJ3JlYWQnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAoX3dwZXJtIHx8IFtdKS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmICghb3V0cHV0LkFDTFtlbnRyeV0pIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV0gPSB7IHdyaXRlOiB0cnVlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XVsnd3JpdGUnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbi8qKlxuICogV2hlbiBxdWVyeWluZywgdGhlIGZpZWxkTmFtZSBtYXkgYmUgY29tcG91bmQsIGV4dHJhY3QgdGhlIHJvb3QgZmllbGROYW1lXG4gKiAgICAgYHRlbXBlcmF0dXJlLmNlbHNpdXNgIGJlY29tZXMgYHRlbXBlcmF0dXJlYFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkTmFtZSB0aGF0IG1heSBiZSBhIGNvbXBvdW5kIGZpZWxkIG5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSByb290IG5hbWUgb2YgdGhlIGZpZWxkXG4gKi9cbmNvbnN0IGdldFJvb3RGaWVsZE5hbWUgPSAoZmllbGROYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gZmllbGROYW1lLnNwbGl0KCcuJylbMF07XG59O1xuXG5jb25zdCByZWxhdGlvblNjaGVtYSA9IHtcbiAgZmllbGRzOiB7IHJlbGF0ZWRJZDogeyB0eXBlOiAnU3RyaW5nJyB9LCBvd25pbmdJZDogeyB0eXBlOiAnU3RyaW5nJyB9IH0sXG59O1xuXG5jbGFzcyBEYXRhYmFzZUNvbnRyb2xsZXIge1xuICBhZGFwdGVyOiBTdG9yYWdlQWRhcHRlcjtcbiAgc2NoZW1hQ2FjaGU6IGFueTtcbiAgc2NoZW1hUHJvbWlzZTogP1Byb21pc2U8U2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyPjtcbiAgX3RyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55O1xuXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5hZGFwdGVyID0gYWRhcHRlcjtcbiAgICB0aGlzLnNjaGVtYUNhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgLy8gV2UgZG9uJ3Qgd2FudCBhIG11dGFibGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgdGhlbiB5b3UgY291bGQgaGF2ZVxuICAgIC8vIG9uZSByZXF1ZXN0IHRoYXQgdXNlcyBkaWZmZXJlbnQgc2NoZW1hcyBmb3IgZGlmZmVyZW50IHBhcnRzIG9mXG4gICAgLy8gaXQuIEluc3RlYWQsIHVzZSBsb2FkU2NoZW1hIHRvIGdldCBhIHNjaGVtYS5cbiAgICB0aGlzLnNjaGVtYVByb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uID0gbnVsbDtcbiAgfVxuXG4gIGNvbGxlY3Rpb25FeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gIH1cblxuICBwdXJnZUNvbGxlY3Rpb24oY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKHNjaGVtYSA9PiB0aGlzLmFkYXB0ZXIuZGVsZXRlT2JqZWN0c0J5UXVlcnkoY2xhc3NOYW1lLCBzY2hlbWEsIHt9KSk7XG4gIH1cblxuICB2YWxpZGF0ZUNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghU2NoZW1hQ29udHJvbGxlci5jbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgJ2ludmFsaWQgY2xhc3NOYW1lOiAnICsgY2xhc3NOYW1lKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgc2NoZW1hQ29udHJvbGxlci5cbiAgbG9hZFNjaGVtYShcbiAgICBvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfVxuICApOiBQcm9taXNlPFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLnNjaGVtYVByb21pc2UgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2NoZW1hUHJvbWlzZTtcbiAgICB9XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlID0gU2NoZW1hQ29udHJvbGxlci5sb2FkKHRoaXMuYWRhcHRlciwgdGhpcy5zY2hlbWFDYWNoZSwgb3B0aW9ucyk7XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlLnRoZW4oXG4gICAgICAoKSA9PiBkZWxldGUgdGhpcy5zY2hlbWFQcm9taXNlLFxuICAgICAgKCkgPT4gZGVsZXRlIHRoaXMuc2NoZW1hUHJvbWlzZVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIGxvYWRTY2hlbWFJZk5lZWRlZChcbiAgICBzY2hlbWFDb250cm9sbGVyOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXI+IHtcbiAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlciA/IFByb21pc2UucmVzb2x2ZShzY2hlbWFDb250cm9sbGVyKSA6IHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgY2xhc3NuYW1lIHRoYXQgaXMgcmVsYXRlZCB0byB0aGUgZ2l2ZW5cbiAgLy8gY2xhc3NuYW1lIHRocm91Z2ggdGhlIGtleS5cbiAgLy8gVE9ETzogbWFrZSB0aGlzIG5vdCBpbiB0aGUgRGF0YWJhc2VDb250cm9sbGVyIGludGVyZmFjZVxuICByZWRpcmVjdENsYXNzTmFtZUZvcktleShjbGFzc05hbWU6IHN0cmluZywga2V5OiBzdHJpbmcpOiBQcm9taXNlPD9zdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4ge1xuICAgICAgdmFyIHQgPSBzY2hlbWEuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwga2V5KTtcbiAgICAgIGlmICh0ICE9IG51bGwgJiYgdHlwZW9mIHQgIT09ICdzdHJpbmcnICYmIHQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICByZXR1cm4gdC50YXJnZXRDbGFzcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGFzc05hbWU7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVc2VzIHRoZSBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIG9iamVjdCAoUkVTVCBBUEkgZm9ybWF0KS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYS5cbiAgLy8gVGhpcyBkb2VzIG5vdCB1cGRhdGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgaW4gYSBzaXR1YXRpb24gbGlrZSBhXG4gIC8vIGJhdGNoIHJlcXVlc3QsIHRoYXQgY291bGQgY29uZnVzZSBvdGhlciB1c2VycyBvZiB0aGUgc2NoZW1hLlxuICB2YWxpZGF0ZU9iamVjdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvYmplY3Q6IGFueSxcbiAgICBxdWVyeTogYW55LFxuICAgIHJ1bk9wdGlvbnM6IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgc2NoZW1hO1xuICAgIGNvbnN0IGFjbCA9IHJ1bk9wdGlvbnMuYWNsO1xuICAgIGNvbnN0IGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwOiBzdHJpbmdbXSA9IGFjbCB8fCBbXTtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHMgPT4ge1xuICAgICAgICBzY2hlbWEgPSBzO1xuICAgICAgICBpZiAoaXNNYXN0ZXIpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY2FuQWRkRmllbGQoc2NoZW1hLCBjbGFzc05hbWUsIG9iamVjdCwgYWNsR3JvdXAsIHJ1bk9wdGlvbnMpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS52YWxpZGF0ZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB7IGFjbCwgbWFueSwgdXBzZXJ0LCBhZGRzRmllbGQgfTogRnVsbFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHNraXBTYW5pdGl6YXRpb246IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZGF0ZU9ubHk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IG9yaWdpbmFsUXVlcnkgPSBxdWVyeTtcbiAgICBjb25zdCBvcmlnaW5hbFVwZGF0ZSA9IHVwZGF0ZTtcbiAgICAvLyBNYWtlIGEgY29weSBvZiB0aGUgb2JqZWN0LCBzbyB3ZSBkb24ndCBtdXRhdGUgdGhlIGluY29taW5nIGRhdGEuXG4gICAgdXBkYXRlID0gZGVlcGNvcHkodXBkYXRlKTtcbiAgICB2YXIgcmVsYXRpb25VcGRhdGVzID0gW107XG4gICAgdmFyIGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwID0gYWNsIHx8IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICd1cGRhdGUnKVxuICAgICAgKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmVsYXRpb25VcGRhdGVzID0gdGhpcy5jb2xsZWN0UmVsYXRpb25VcGRhdGVzKGNsYXNzTmFtZSwgb3JpZ2luYWxRdWVyeS5vYmplY3RJZCwgdXBkYXRlKTtcbiAgICAgICAgICBpZiAoIWlzTWFzdGVyKSB7XG4gICAgICAgICAgICBxdWVyeSA9IHRoaXMuYWRkUG9pbnRlclBlcm1pc3Npb25zKFxuICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICd1cGRhdGUnLFxuICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChhZGRzRmllbGQpIHtcbiAgICAgICAgICAgICAgcXVlcnkgPSB7XG4gICAgICAgICAgICAgICAgJGFuZDogW1xuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB0aGlzLmFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAnYWRkRmllbGQnLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFxdWVyeSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYWNsKSB7XG4gICAgICAgICAgICBxdWVyeSA9IGFkZFdyaXRlQUNMKHF1ZXJ5LCBhY2wpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlclxuICAgICAgICAgICAgLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAvLyBJZiB0aGUgc2NoZW1hIGRvZXNuJ3QgZXhpc3QsIHByZXRlbmQgaXQgZXhpc3RzIHdpdGggbm8gZmllbGRzLiBUaGlzIGJlaGF2aW9yXG4gICAgICAgICAgICAgIC8vIHdpbGwgbGlrZWx5IG5lZWQgcmV2aXNpdGluZy5cbiAgICAgICAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBmaWVsZHM6IHt9IH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXModXBkYXRlKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5tYXRjaCgvXmF1dGhEYXRhXFwuKFthLXpBLVowLTlfXSspXFwuaWQkLykpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgYEludmFsaWQgZmllbGQgbmFtZSBmb3IgdXBkYXRlOiAke2ZpZWxkTmFtZX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByb290RmllbGROYW1lID0gZ2V0Um9vdEZpZWxkTmFtZShmaWVsZE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICFTY2hlbWFDb250cm9sbGVyLmZpZWxkTmFtZUlzVmFsaWQocm9vdEZpZWxkTmFtZSkgJiZcbiAgICAgICAgICAgICAgICAgICFpc1NwZWNpYWxVcGRhdGVLZXkocm9vdEZpZWxkTmFtZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgYEludmFsaWQgZmllbGQgbmFtZSBmb3IgdXBkYXRlOiAke2ZpZWxkTmFtZX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgdXBkYXRlT3BlcmF0aW9uIGluIHVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZVt1cGRhdGVPcGVyYXRpb25dICYmXG4gICAgICAgICAgICAgICAgICB0eXBlb2YgdXBkYXRlW3VwZGF0ZU9wZXJhdGlvbl0gPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh1cGRhdGVbdXBkYXRlT3BlcmF0aW9uXSkuc29tZShcbiAgICAgICAgICAgICAgICAgICAgaW5uZXJLZXkgPT4gaW5uZXJLZXkuaW5jbHVkZXMoJyQnKSB8fCBpbm5lcktleS5pbmNsdWRlcygnLicpXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfTkVTVEVEX0tFWSxcbiAgICAgICAgICAgICAgICAgICAgXCJOZXN0ZWQga2V5cyBzaG91bGQgbm90IGNvbnRhaW4gdGhlICckJyBvciAnLicgY2hhcmFjdGVyc1wiXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB1cGRhdGUgPSB0cmFuc2Zvcm1PYmplY3RBQ0wodXBkYXRlKTtcbiAgICAgICAgICAgICAgdHJhbnNmb3JtQXV0aERhdGEoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgICAgICAgICAgIGlmICh2YWxpZGF0ZU9ubHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmZpbmQoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCB7fSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChtYW55KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cGRhdGVPYmplY3RzQnlRdWVyeShcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgdXBkYXRlLFxuICAgICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVwc2VydCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0T25lT2JqZWN0KFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5maW5kT25lQW5kVXBkYXRlKFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFsaWRhdGVPbmx5KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZWxhdGlvblVwZGF0ZXMoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICBvcmlnaW5hbFF1ZXJ5Lm9iamVjdElkLFxuICAgICAgICAgICAgdXBkYXRlLFxuICAgICAgICAgICAgcmVsYXRpb25VcGRhdGVzXG4gICAgICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKHNraXBTYW5pdGl6YXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxVcGRhdGUsIHJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ29sbGVjdCBhbGwgcmVsYXRpb24tdXBkYXRpbmcgb3BlcmF0aW9ucyBmcm9tIGEgUkVTVC1mb3JtYXQgdXBkYXRlLlxuICAvLyBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgcmVsYXRpb24gdXBkYXRlcyB0byBwZXJmb3JtXG4gIC8vIFRoaXMgbXV0YXRlcyB1cGRhdGUuXG4gIGNvbGxlY3RSZWxhdGlvblVwZGF0ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdElkOiA/c3RyaW5nLCB1cGRhdGU6IGFueSkge1xuICAgIHZhciBvcHMgPSBbXTtcbiAgICB2YXIgZGVsZXRlTWUgPSBbXTtcbiAgICBvYmplY3RJZCA9IHVwZGF0ZS5vYmplY3RJZCB8fCBvYmplY3RJZDtcblxuICAgIHZhciBwcm9jZXNzID0gKG9wLCBrZXkpID0+IHtcbiAgICAgIGlmICghb3ApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ0FkZFJlbGF0aW9uJykge1xuICAgICAgICBvcHMucHVzaCh7IGtleSwgb3AgfSk7XG4gICAgICAgIGRlbGV0ZU1lLnB1c2goa2V5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ1JlbW92ZVJlbGF0aW9uJykge1xuICAgICAgICBvcHMucHVzaCh7IGtleSwgb3AgfSk7XG4gICAgICAgIGRlbGV0ZU1lLnB1c2goa2V5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ0JhdGNoJykge1xuICAgICAgICBmb3IgKHZhciB4IG9mIG9wLm9wcykge1xuICAgICAgICAgIHByb2Nlc3MoeCwga2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiB1cGRhdGUpIHtcbiAgICAgIHByb2Nlc3ModXBkYXRlW2tleV0sIGtleSk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGRlbGV0ZU1lKSB7XG4gICAgICBkZWxldGUgdXBkYXRlW2tleV07XG4gICAgfVxuICAgIHJldHVybiBvcHM7XG4gIH1cblxuICAvLyBQcm9jZXNzZXMgcmVsYXRpb24tdXBkYXRpbmcgb3BlcmF0aW9ucyBmcm9tIGEgUkVTVC1mb3JtYXQgdXBkYXRlLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIHVwZGF0ZXMgaGF2ZSBiZWVuIHBlcmZvcm1lZFxuICBoYW5kbGVSZWxhdGlvblVwZGF0ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdElkOiBzdHJpbmcsIHVwZGF0ZTogYW55LCBvcHM6IGFueSkge1xuICAgIHZhciBwZW5kaW5nID0gW107XG4gICAgb2JqZWN0SWQgPSB1cGRhdGUub2JqZWN0SWQgfHwgb2JqZWN0SWQ7XG4gICAgb3BzLmZvckVhY2goKHsga2V5LCBvcCB9KSA9PiB7XG4gICAgICBpZiAoIW9wKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChvcC5fX29wID09ICdBZGRSZWxhdGlvbicpIHtcbiAgICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2Ygb3Aub2JqZWN0cykge1xuICAgICAgICAgIHBlbmRpbmcucHVzaCh0aGlzLmFkZFJlbGF0aW9uKGtleSwgY2xhc3NOYW1lLCBvYmplY3RJZCwgb2JqZWN0Lm9iamVjdElkKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ1JlbW92ZVJlbGF0aW9uJykge1xuICAgICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBvcC5vYmplY3RzKSB7XG4gICAgICAgICAgcGVuZGluZy5wdXNoKHRoaXMucmVtb3ZlUmVsYXRpb24oa2V5LCBjbGFzc05hbWUsIG9iamVjdElkLCBvYmplY3Qub2JqZWN0SWQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHBlbmRpbmcpO1xuICB9XG5cbiAgLy8gQWRkcyBhIHJlbGF0aW9uLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIGFkZCB3YXMgc3VjY2Vzc2Z1bC5cbiAgYWRkUmVsYXRpb24oa2V5OiBzdHJpbmcsIGZyb21DbGFzc05hbWU6IHN0cmluZywgZnJvbUlkOiBzdHJpbmcsIHRvSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGRvYyA9IHtcbiAgICAgIHJlbGF0ZWRJZDogdG9JZCxcbiAgICAgIG93bmluZ0lkOiBmcm9tSWQsXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwc2VydE9uZU9iamVjdChcbiAgICAgIGBfSm9pbjoke2tleX06JHtmcm9tQ2xhc3NOYW1lfWAsXG4gICAgICByZWxhdGlvblNjaGVtYSxcbiAgICAgIGRvYyxcbiAgICAgIGRvYyxcbiAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlbW92ZXMgYSByZWxhdGlvbi5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgaWZmIHRoZSByZW1vdmUgd2FzXG4gIC8vIHN1Y2Nlc3NmdWwuXG4gIHJlbW92ZVJlbGF0aW9uKGtleTogc3RyaW5nLCBmcm9tQ2xhc3NOYW1lOiBzdHJpbmcsIGZyb21JZDogc3RyaW5nLCB0b0lkOiBzdHJpbmcpIHtcbiAgICB2YXIgZG9jID0ge1xuICAgICAgcmVsYXRlZElkOiB0b0lkLFxuICAgICAgb3duaW5nSWQ6IGZyb21JZCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXJcbiAgICAgIC5kZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICAgICAgYF9Kb2luOiR7a2V5fToke2Zyb21DbGFzc05hbWV9YCxcbiAgICAgICAgcmVsYXRpb25TY2hlbWEsXG4gICAgICAgIGRvYyxcbiAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFdlIGRvbid0IGNhcmUgaWYgdGhleSB0cnkgdG8gZGVsZXRlIGEgbm9uLWV4aXN0ZW50IHJlbGF0aW9uLlxuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZW1vdmVzIG9iamVjdHMgbWF0Y2hlcyB0aGlzIHF1ZXJ5IGZyb20gdGhlIGRhdGFiYXNlLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIG9iamVjdCB3YXNcbiAgLy8gZGVsZXRlZC5cbiAgLy8gT3B0aW9uczpcbiAgLy8gICBhY2w6ICBhIGxpc3Qgb2Ygc3RyaW5ncy4gSWYgdGhlIG9iamVjdCB0byBiZSB1cGRhdGVkIGhhcyBhbiBBQ0wsXG4gIC8vICAgICAgICAgb25lIG9mIHRoZSBwcm92aWRlZCBzdHJpbmdzIG11c3QgcHJvdmlkZSB0aGUgY2FsbGVyIHdpdGhcbiAgLy8gICAgICAgICB3cml0ZSBwZXJtaXNzaW9ucy5cbiAgZGVzdHJveShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55LFxuICAgIHsgYWNsIH06IFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHZhbGlkU2NoZW1hQ29udHJvbGxlcjogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgaXNNYXN0ZXIgPSBhY2wgPT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBhY2xHcm91cCA9IGFjbCB8fCBbXTtcblxuICAgIHJldHVybiB0aGlzLmxvYWRTY2hlbWFJZk5lZWRlZCh2YWxpZFNjaGVtYUNvbnRyb2xsZXIpLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiB7XG4gICAgICByZXR1cm4gKGlzTWFzdGVyXG4gICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgOiBzY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWUsIGFjbEdyb3VwLCAnZGVsZXRlJylcbiAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgIGlmICghaXNNYXN0ZXIpIHtcbiAgICAgICAgICBxdWVyeSA9IHRoaXMuYWRkUG9pbnRlclBlcm1pc3Npb25zKFxuICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICdkZWxldGUnLFxuICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICBhY2xHcm91cFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFxdWVyeSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBkZWxldGUgYnkgcXVlcnlcbiAgICAgICAgaWYgKGFjbCkge1xuICAgICAgICAgIHF1ZXJ5ID0gYWRkV3JpdGVBQ0wocXVlcnksIGFjbCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVRdWVyeShxdWVyeSk7XG4gICAgICAgIHJldHVybiBzY2hlbWFDb250cm9sbGVyXG4gICAgICAgICAgLmdldE9uZVNjaGVtYShjbGFzc05hbWUpXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBzY2hlbWEgZG9lc24ndCBleGlzdCwgcHJldGVuZCBpdCBleGlzdHMgd2l0aCBubyBmaWVsZHMuIFRoaXMgYmVoYXZpb3JcbiAgICAgICAgICAgIC8vIHdpbGwgbGlrZWx5IG5lZWQgcmV2aXNpdGluZy5cbiAgICAgICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IGZpZWxkczoge30gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4ocGFyc2VGb3JtYXRTY2hlbWEgPT5cbiAgICAgICAgICAgIHRoaXMuYWRhcHRlci5kZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBwYXJzZUZvcm1hdFNjaGVtYSxcbiAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAvLyBXaGVuIGRlbGV0aW5nIHNlc3Npb25zIHdoaWxlIGNoYW5naW5nIHBhc3N3b3JkcywgZG9uJ3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhleSBkb24ndCBoYXZlIGFueSBzZXNzaW9ucy5cbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfU2Vzc2lvbicgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBJbnNlcnRzIGFuIG9iamVjdCBpbnRvIHRoZSBkYXRhYmFzZS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgaWZmIHRoZSBvYmplY3Qgc2F2ZWQuXG4gIGNyZWF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvYmplY3Q6IGFueSxcbiAgICB7IGFjbCB9OiBRdWVyeU9wdGlvbnMgPSB7fSxcbiAgICB2YWxpZGF0ZU9ubHk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIE1ha2UgYSBjb3B5IG9mIHRoZSBvYmplY3QsIHNvIHdlIGRvbid0IG11dGF0ZSB0aGUgaW5jb21pbmcgZGF0YS5cbiAgICBjb25zdCBvcmlnaW5hbE9iamVjdCA9IG9iamVjdDtcbiAgICBvYmplY3QgPSB0cmFuc2Zvcm1PYmplY3RBQ0wob2JqZWN0KTtcblxuICAgIG9iamVjdC5jcmVhdGVkQXQgPSB7IGlzbzogb2JqZWN0LmNyZWF0ZWRBdCwgX190eXBlOiAnRGF0ZScgfTtcbiAgICBvYmplY3QudXBkYXRlZEF0ID0geyBpc286IG9iamVjdC51cGRhdGVkQXQsIF9fdHlwZTogJ0RhdGUnIH07XG5cbiAgICB2YXIgaXNNYXN0ZXIgPSBhY2wgPT09IHVuZGVmaW5lZDtcbiAgICB2YXIgYWNsR3JvdXAgPSBhY2wgfHwgW107XG4gICAgY29uc3QgcmVsYXRpb25VcGRhdGVzID0gdGhpcy5jb2xsZWN0UmVsYXRpb25VcGRhdGVzKGNsYXNzTmFtZSwgbnVsbCwgb2JqZWN0KTtcblxuICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xhc3NOYW1lKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikpXG4gICAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgICAgcmV0dXJuIChpc01hc3RlclxuICAgICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICdjcmVhdGUnKVxuICAgICAgICApXG4gICAgICAgICAgLnRoZW4oKCkgPT4gc2NoZW1hQ29udHJvbGxlci5lbmZvcmNlQ2xhc3NFeGlzdHMoY2xhc3NOYW1lKSlcbiAgICAgICAgICAudGhlbigoKSA9PiBzY2hlbWFDb250cm9sbGVyLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpKVxuICAgICAgICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICAgICAgICB0cmFuc2Zvcm1BdXRoRGF0YShjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKTtcbiAgICAgICAgICAgIGZsYXR0ZW5VcGRhdGVPcGVyYXRvcnNGb3JDcmVhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIGlmICh2YWxpZGF0ZU9ubHkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5jcmVhdGVPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgU2NoZW1hQ29udHJvbGxlci5jb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKHNjaGVtYSksXG4gICAgICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbGlkYXRlT25seSkge1xuICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxPYmplY3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZWxhdGlvblVwZGF0ZXMoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgb2JqZWN0Lm9iamVjdElkLFxuICAgICAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgICAgIHJlbGF0aW9uVXBkYXRlc1xuICAgICAgICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxPYmplY3QsIHJlc3VsdC5vcHNbMF0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNhbkFkZEZpZWxkKFxuICAgIHNjaGVtYTogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyLFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIG9iamVjdDogYW55LFxuICAgIGFjbEdyb3VwOiBzdHJpbmdbXSxcbiAgICBydW5PcHRpb25zOiBRdWVyeU9wdGlvbnNcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2xhc3NTY2hlbWEgPSBzY2hlbWEuc2NoZW1hRGF0YVtjbGFzc05hbWVdO1xuICAgIGlmICghY2xhc3NTY2hlbWEpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMob2JqZWN0KTtcbiAgICBjb25zdCBzY2hlbWFGaWVsZHMgPSBPYmplY3Qua2V5cyhjbGFzc1NjaGVtYS5maWVsZHMpO1xuICAgIGNvbnN0IG5ld0tleXMgPSBmaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIC8vIFNraXAgZmllbGRzIHRoYXQgYXJlIHVuc2V0XG4gICAgICBpZiAob2JqZWN0W2ZpZWxkXSAmJiBvYmplY3RbZmllbGRdLl9fb3AgJiYgb2JqZWN0W2ZpZWxkXS5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2NoZW1hRmllbGRzLmluZGV4T2YoZmllbGQpIDwgMDtcbiAgICB9KTtcbiAgICBpZiAobmV3S2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBhZGRzIGEgbWFya2VyIHRoYXQgbmV3IGZpZWxkIGlzIGJlaW5nIGFkZGluZyBkdXJpbmcgdXBkYXRlXG4gICAgICBydW5PcHRpb25zLmFkZHNGaWVsZCA9IHRydWU7XG5cbiAgICAgIGNvbnN0IGFjdGlvbiA9IHJ1bk9wdGlvbnMuYWN0aW9uO1xuICAgICAgcmV0dXJuIHNjaGVtYS52YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lLCBhY2xHcm91cCwgJ2FkZEZpZWxkJywgYWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gV29uJ3QgZGVsZXRlIGNvbGxlY3Rpb25zIGluIHRoZSBzeXN0ZW0gbmFtZXNwYWNlXG4gIC8qKlxuICAgKiBEZWxldGUgYWxsIGNsYXNzZXMgYW5kIGNsZWFycyB0aGUgc2NoZW1hIGNhY2hlXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZGVsZXRlIHJvd3MgYW5kIG5vdCBpbmRleGVzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSB3aGVuIHRoZSBkZWxldGlvbnMgY29tcGxldGVzXG4gICAqL1xuICBkZWxldGVFdmVyeXRoaW5nKGZhc3Q6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8YW55PiB7XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlID0gbnVsbDtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3RoaXMuYWRhcHRlci5kZWxldGVBbGxDbGFzc2VzKGZhc3QpLCB0aGlzLnNjaGVtYUNhY2hlLmNsZWFyKCldKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIGxpc3Qgb2YgcmVsYXRlZCBpZHMgZ2l2ZW4gYW4gb3duaW5nIGlkLlxuICAvLyBjbGFzc05hbWUgaGVyZSBpcyB0aGUgb3duaW5nIGNsYXNzTmFtZS5cbiAgcmVsYXRlZElkcyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyxcbiAgICBvd25pbmdJZDogc3RyaW5nLFxuICAgIHF1ZXJ5T3B0aW9uczogUXVlcnlPcHRpb25zXG4gICk6IFByb21pc2U8QXJyYXk8c3RyaW5nPj4ge1xuICAgIGNvbnN0IHsgc2tpcCwgbGltaXQsIHNvcnQgfSA9IHF1ZXJ5T3B0aW9ucztcbiAgICBjb25zdCBmaW5kT3B0aW9ucyA9IHt9O1xuICAgIGlmIChzb3J0ICYmIHNvcnQuY3JlYXRlZEF0ICYmIHRoaXMuYWRhcHRlci5jYW5Tb3J0T25Kb2luVGFibGVzKSB7XG4gICAgICBmaW5kT3B0aW9ucy5zb3J0ID0geyBfaWQ6IHNvcnQuY3JlYXRlZEF0IH07XG4gICAgICBmaW5kT3B0aW9ucy5saW1pdCA9IGxpbWl0O1xuICAgICAgZmluZE9wdGlvbnMuc2tpcCA9IHNraXA7XG4gICAgICBxdWVyeU9wdGlvbnMuc2tpcCA9IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXJcbiAgICAgIC5maW5kKGpvaW5UYWJsZU5hbWUoY2xhc3NOYW1lLCBrZXkpLCByZWxhdGlvblNjaGVtYSwgeyBvd25pbmdJZCB9LCBmaW5kT3B0aW9ucylcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4gcmVzdWx0cy5tYXAocmVzdWx0ID0+IHJlc3VsdC5yZWxhdGVkSWQpKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIGxpc3Qgb2Ygb3duaW5nIGlkcyBnaXZlbiBzb21lIHJlbGF0ZWQgaWRzLlxuICAvLyBjbGFzc05hbWUgaGVyZSBpcyB0aGUgb3duaW5nIGNsYXNzTmFtZS5cbiAgb3duaW5nSWRzKGNsYXNzTmFtZTogc3RyaW5nLCBrZXk6IHN0cmluZywgcmVsYXRlZElkczogc3RyaW5nW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLmZpbmQoXG4gICAgICAgIGpvaW5UYWJsZU5hbWUoY2xhc3NOYW1lLCBrZXkpLFxuICAgICAgICByZWxhdGlvblNjaGVtYSxcbiAgICAgICAgeyByZWxhdGVkSWQ6IHsgJGluOiByZWxhdGVkSWRzIH0gfSxcbiAgICAgICAgeyBrZXlzOiBbJ293bmluZ0lkJ10gfVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzLm1hcChyZXN1bHQgPT4gcmVzdWx0Lm93bmluZ0lkKSk7XG4gIH1cblxuICAvLyBNb2RpZmllcyBxdWVyeSBzbyB0aGF0IGl0IG5vIGxvbmdlciBoYXMgJGluIG9uIHJlbGF0aW9uIGZpZWxkcywgb3JcbiAgLy8gZXF1YWwtdG8tcG9pbnRlciBjb25zdHJhaW50cyBvbiByZWxhdGlvbiBmaWVsZHMuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBxdWVyeSBpcyBtdXRhdGVkXG4gIHJlZHVjZUluUmVsYXRpb24oY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBhbnksIHNjaGVtYTogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICAvLyBTZWFyY2ggZm9yIGFuIGluLXJlbGF0aW9uIG9yIGVxdWFsLXRvLXJlbGF0aW9uXG4gICAgLy8gTWFrZSBpdCBzZXF1ZW50aWFsIGZvciBub3csIG5vdCBzdXJlIG9mIHBhcmFsbGVpemF0aW9uIHNpZGUgZWZmZWN0c1xuICAgIGlmIChxdWVyeVsnJG9yJ10pIHtcbiAgICAgIGNvbnN0IG9ycyA9IHF1ZXJ5Wyckb3InXTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgICAgb3JzLm1hcCgoYVF1ZXJ5LCBpbmRleCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlZHVjZUluUmVsYXRpb24oY2xhc3NOYW1lLCBhUXVlcnksIHNjaGVtYSkudGhlbihhUXVlcnkgPT4ge1xuICAgICAgICAgICAgcXVlcnlbJyRvciddW2luZGV4XSA9IGFRdWVyeTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocXVlcnkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvbWlzZXMgPSBPYmplY3Qua2V5cyhxdWVyeSkubWFwKGtleSA9PiB7XG4gICAgICBjb25zdCB0ID0gc2NoZW1hLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGtleSk7XG4gICAgICBpZiAoIXQgfHwgdC50eXBlICE9PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocXVlcnkpO1xuICAgICAgfVxuICAgICAgbGV0IHF1ZXJpZXM6ID8oYW55W10pID0gbnVsbDtcbiAgICAgIGlmIChcbiAgICAgICAgcXVlcnlba2V5XSAmJlxuICAgICAgICAocXVlcnlba2V5XVsnJGluJ10gfHxcbiAgICAgICAgICBxdWVyeVtrZXldWyckbmUnXSB8fFxuICAgICAgICAgIHF1ZXJ5W2tleV1bJyRuaW4nXSB8fFxuICAgICAgICAgIHF1ZXJ5W2tleV0uX190eXBlID09ICdQb2ludGVyJylcbiAgICAgICkge1xuICAgICAgICAvLyBCdWlsZCB0aGUgbGlzdCBvZiBxdWVyaWVzXG4gICAgICAgIHF1ZXJpZXMgPSBPYmplY3Qua2V5cyhxdWVyeVtrZXldKS5tYXAoY29uc3RyYWludEtleSA9PiB7XG4gICAgICAgICAgbGV0IHJlbGF0ZWRJZHM7XG4gICAgICAgICAgbGV0IGlzTmVnYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICBpZiAoY29uc3RyYWludEtleSA9PT0gJ29iamVjdElkJykge1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IFtxdWVyeVtrZXldLm9iamVjdElkXTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN0cmFpbnRLZXkgPT0gJyRpbicpIHtcbiAgICAgICAgICAgIHJlbGF0ZWRJZHMgPSBxdWVyeVtrZXldWyckaW4nXS5tYXAociA9PiByLm9iamVjdElkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN0cmFpbnRLZXkgPT0gJyRuaW4nKSB7XG4gICAgICAgICAgICBpc05lZ2F0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlbGF0ZWRJZHMgPSBxdWVyeVtrZXldWyckbmluJ10ubWFwKHIgPT4gci5vYmplY3RJZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChjb25zdHJhaW50S2V5ID09ICckbmUnKSB7XG4gICAgICAgICAgICBpc05lZ2F0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlbGF0ZWRJZHMgPSBbcXVlcnlba2V5XVsnJG5lJ10ub2JqZWN0SWRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpc05lZ2F0aW9uLFxuICAgICAgICAgICAgcmVsYXRlZElkcyxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXJpZXMgPSBbeyBpc05lZ2F0aW9uOiBmYWxzZSwgcmVsYXRlZElkczogW10gfV07XG4gICAgICB9XG5cbiAgICAgIC8vIHJlbW92ZSB0aGUgY3VycmVudCBxdWVyeUtleSBhcyB3ZSBkb24sdCBuZWVkIGl0IGFueW1vcmVcbiAgICAgIGRlbGV0ZSBxdWVyeVtrZXldO1xuICAgICAgLy8gZXhlY3V0ZSBlYWNoIHF1ZXJ5IGluZGVwZW5kZW50bHkgdG8gYnVpbGQgdGhlIGxpc3Qgb2ZcbiAgICAgIC8vICRpbiAvICRuaW5cbiAgICAgIGNvbnN0IHByb21pc2VzID0gcXVlcmllcy5tYXAocSA9PiB7XG4gICAgICAgIGlmICghcSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5vd25pbmdJZHMoY2xhc3NOYW1lLCBrZXksIHEucmVsYXRlZElkcykudGhlbihpZHMgPT4ge1xuICAgICAgICAgIGlmIChxLmlzTmVnYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuYWRkTm90SW5PYmplY3RJZHNJZHMoaWRzLCBxdWVyeSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW5PYmplY3RJZHNJZHMoaWRzLCBxdWVyeSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShxdWVyeSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBNb2RpZmllcyBxdWVyeSBzbyB0aGF0IGl0IG5vIGxvbmdlciBoYXMgJHJlbGF0ZWRUb1xuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gcXVlcnkgaXMgbXV0YXRlZFxuICByZWR1Y2VSZWxhdGlvbktleXMoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBhbnksIHF1ZXJ5T3B0aW9uczogYW55KTogP1Byb21pc2U8dm9pZD4ge1xuICAgIGlmIChxdWVyeVsnJG9yJ10pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgICAgcXVlcnlbJyRvciddLm1hcChhUXVlcnkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlZHVjZVJlbGF0aW9uS2V5cyhjbGFzc05hbWUsIGFRdWVyeSwgcXVlcnlPcHRpb25zKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdmFyIHJlbGF0ZWRUbyA9IHF1ZXJ5WyckcmVsYXRlZFRvJ107XG4gICAgaWYgKHJlbGF0ZWRUbykge1xuICAgICAgcmV0dXJuIHRoaXMucmVsYXRlZElkcyhcbiAgICAgICAgcmVsYXRlZFRvLm9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgIHJlbGF0ZWRUby5rZXksXG4gICAgICAgIHJlbGF0ZWRUby5vYmplY3Qub2JqZWN0SWQsXG4gICAgICAgIHF1ZXJ5T3B0aW9uc1xuICAgICAgKVxuICAgICAgICAudGhlbihpZHMgPT4ge1xuICAgICAgICAgIGRlbGV0ZSBxdWVyeVsnJHJlbGF0ZWRUbyddO1xuICAgICAgICAgIHRoaXMuYWRkSW5PYmplY3RJZHNJZHMoaWRzLCBxdWVyeSk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVkdWNlUmVsYXRpb25LZXlzKGNsYXNzTmFtZSwgcXVlcnksIHF1ZXJ5T3B0aW9ucyk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHt9KTtcbiAgICB9XG4gIH1cblxuICBhZGRJbk9iamVjdElkc0lkcyhpZHM6ID9BcnJheTxzdHJpbmc+ID0gbnVsbCwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGlkc0Zyb21TdHJpbmc6ID9BcnJheTxzdHJpbmc+ID1cbiAgICAgIHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZycgPyBbcXVlcnkub2JqZWN0SWRdIDogbnVsbDtcbiAgICBjb25zdCBpZHNGcm9tRXE6ID9BcnJheTxzdHJpbmc+ID1cbiAgICAgIHF1ZXJ5Lm9iamVjdElkICYmIHF1ZXJ5Lm9iamVjdElkWyckZXEnXSA/IFtxdWVyeS5vYmplY3RJZFsnJGVxJ11dIDogbnVsbDtcbiAgICBjb25zdCBpZHNGcm9tSW46ID9BcnJheTxzdHJpbmc+ID1cbiAgICAgIHF1ZXJ5Lm9iamVjdElkICYmIHF1ZXJ5Lm9iamVjdElkWyckaW4nXSA/IHF1ZXJ5Lm9iamVjdElkWyckaW4nXSA6IG51bGw7XG5cbiAgICAvLyBAZmxvdy1kaXNhYmxlLW5leHRcbiAgICBjb25zdCBhbGxJZHM6IEFycmF5PEFycmF5PHN0cmluZz4+ID0gW2lkc0Zyb21TdHJpbmcsIGlkc0Zyb21FcSwgaWRzRnJvbUluLCBpZHNdLmZpbHRlcihcbiAgICAgIGxpc3QgPT4gbGlzdCAhPT0gbnVsbFxuICAgICk7XG4gICAgY29uc3QgdG90YWxMZW5ndGggPSBhbGxJZHMucmVkdWNlKChtZW1vLCBsaXN0KSA9PiBtZW1vICsgbGlzdC5sZW5ndGgsIDApO1xuXG4gICAgbGV0IGlkc0ludGVyc2VjdGlvbiA9IFtdO1xuICAgIGlmICh0b3RhbExlbmd0aCA+IDEyNSkge1xuICAgICAgaWRzSW50ZXJzZWN0aW9uID0gaW50ZXJzZWN0LmJpZyhhbGxJZHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHNJbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3QoYWxsSWRzKTtcbiAgICB9XG5cbiAgICAvLyBOZWVkIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBjbG9iYmVyIGV4aXN0aW5nIHNob3J0aGFuZCAkZXEgY29uc3RyYWludHMgb24gb2JqZWN0SWQuXG4gICAgaWYgKCEoJ29iamVjdElkJyBpbiBxdWVyeSkpIHtcbiAgICAgIHF1ZXJ5Lm9iamVjdElkID0ge1xuICAgICAgICAkaW46IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHtcbiAgICAgICAgJGluOiB1bmRlZmluZWQsXG4gICAgICAgICRlcTogcXVlcnkub2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cbiAgICBxdWVyeS5vYmplY3RJZFsnJGluJ10gPSBpZHNJbnRlcnNlY3Rpb247XG5cbiAgICByZXR1cm4gcXVlcnk7XG4gIH1cblxuICBhZGROb3RJbk9iamVjdElkc0lkcyhpZHM6IHN0cmluZ1tdID0gW10sIHF1ZXJ5OiBhbnkpIHtcbiAgICBjb25zdCBpZHNGcm9tTmluID0gcXVlcnkub2JqZWN0SWQgJiYgcXVlcnkub2JqZWN0SWRbJyRuaW4nXSA/IHF1ZXJ5Lm9iamVjdElkWyckbmluJ10gOiBbXTtcbiAgICBsZXQgYWxsSWRzID0gWy4uLmlkc0Zyb21OaW4sIC4uLmlkc10uZmlsdGVyKGxpc3QgPT4gbGlzdCAhPT0gbnVsbCk7XG5cbiAgICAvLyBtYWtlIGEgc2V0IGFuZCBzcHJlYWQgdG8gcmVtb3ZlIGR1cGxpY2F0ZXNcbiAgICBhbGxJZHMgPSBbLi4ubmV3IFNldChhbGxJZHMpXTtcblxuICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIHdlIGRvbid0IGNsb2JiZXIgZXhpc3Rpbmcgc2hvcnRoYW5kICRlcSBjb25zdHJhaW50cyBvbiBvYmplY3RJZC5cbiAgICBpZiAoISgnb2JqZWN0SWQnIGluIHF1ZXJ5KSkge1xuICAgICAgcXVlcnkub2JqZWN0SWQgPSB7XG4gICAgICAgICRuaW46IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHtcbiAgICAgICAgJG5pbjogdW5kZWZpbmVkLFxuICAgICAgICAkZXE6IHF1ZXJ5Lm9iamVjdElkLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBxdWVyeS5vYmplY3RJZFsnJG5pbiddID0gYWxsSWRzO1xuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8vIFJ1bnMgYSBxdWVyeSBvbiB0aGUgZGF0YWJhc2UuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBsaXN0IG9mIGl0ZW1zLlxuICAvLyBPcHRpb25zOlxuICAvLyAgIHNraXAgICAgbnVtYmVyIG9mIHJlc3VsdHMgdG8gc2tpcC5cbiAgLy8gICBsaW1pdCAgIGxpbWl0IHRvIHRoaXMgbnVtYmVyIG9mIHJlc3VsdHMuXG4gIC8vICAgc29ydCAgICBhbiBvYmplY3Qgd2hlcmUga2V5cyBhcmUgdGhlIGZpZWxkcyB0byBzb3J0IGJ5LlxuICAvLyAgICAgICAgICAgdGhlIHZhbHVlIGlzICsxIGZvciBhc2NlbmRpbmcsIC0xIGZvciBkZXNjZW5kaW5nLlxuICAvLyAgIGNvdW50ICAgcnVuIGEgY291bnQgaW5zdGVhZCBvZiByZXR1cm5pbmcgcmVzdWx0cy5cbiAgLy8gICBhY2wgICAgIHJlc3RyaWN0IHRoaXMgb3BlcmF0aW9uIHdpdGggYW4gQUNMIGZvciB0aGUgcHJvdmlkZWQgYXJyYXlcbiAgLy8gICAgICAgICAgIG9mIHVzZXIgb2JqZWN0SWRzIGFuZCByb2xlcy4gYWNsOiBudWxsIG1lYW5zIG5vIHVzZXIuXG4gIC8vICAgICAgICAgICB3aGVuIHRoaXMgZmllbGQgaXMgbm90IHByZXNlbnQsIGRvbid0IGRvIGFueXRoaW5nIHJlZ2FyZGluZyBBQ0xzLlxuICAvLyAgY2FzZUluc2Vuc2l0aXZlIG1ha2Ugc3RyaW5nIGNvbXBhcmlzb25zIGNhc2UgaW5zZW5zaXRpdmVcbiAgLy8gVE9ETzogbWFrZSB1c2VySWRzIG5vdCBuZWVkZWQgaGVyZS4gVGhlIGRiIGFkYXB0ZXIgc2hvdWxkbid0IGtub3dcbiAgLy8gYW55dGhpbmcgYWJvdXQgdXNlcnMsIGlkZWFsbHkuIFRoZW4sIGltcHJvdmUgdGhlIGZvcm1hdCBvZiB0aGUgQUNMXG4gIC8vIGFyZyB0byB3b3JrIGxpa2UgdGhlIG90aGVycy5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55LFxuICAgIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIGFjbCxcbiAgICAgIHNvcnQgPSB7fSxcbiAgICAgIGNvdW50LFxuICAgICAga2V5cyxcbiAgICAgIG9wLFxuICAgICAgZGlzdGluY3QsXG4gICAgICBwaXBlbGluZSxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlLFxuICAgICAgZXhwbGFpbixcbiAgICB9OiBhbnkgPSB7fSxcbiAgICBhdXRoOiBhbnkgPSB7fSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgY29uc3QgYWNsR3JvdXAgPSBhY2wgfHwgW107XG4gICAgb3AgPVxuICAgICAgb3AgfHwgKHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PSAnc3RyaW5nJyAmJiBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoID09PSAxID8gJ2dldCcgOiAnZmluZCcpO1xuICAgIC8vIENvdW50IG9wZXJhdGlvbiBpZiBjb3VudGluZ1xuICAgIG9wID0gY291bnQgPT09IHRydWUgPyAnY291bnQnIDogb3A7XG5cbiAgICBsZXQgY2xhc3NFeGlzdHMgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLmxvYWRTY2hlbWFJZk5lZWRlZCh2YWxpZFNjaGVtYUNvbnRyb2xsZXIpLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiB7XG4gICAgICAvL0FsbG93IHZvbGF0aWxlIGNsYXNzZXMgaWYgcXVlcnlpbmcgd2l0aCBNYXN0ZXIgKGZvciBfUHVzaFN0YXR1cylcbiAgICAgIC8vVE9ETzogTW92ZSB2b2xhdGlsZSBjbGFzc2VzIGNvbmNlcHQgaW50byBtb25nbyBhZGFwdGVyLCBwb3N0Z3JlcyBhZGFwdGVyIHNob3VsZG4ndCBjYXJlXG4gICAgICAvL3RoYXQgYXBpLnBhcnNlLmNvbSBicmVha3Mgd2hlbiBfUHVzaFN0YXR1cyBleGlzdHMgaW4gbW9uZ28uXG4gICAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlclxuICAgICAgICAuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgaXNNYXN0ZXIpXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgLy8gQmVoYXZpb3IgZm9yIG5vbi1leGlzdGVudCBjbGFzc2VzIGlzIGtpbmRhIHdlaXJkIG9uIFBhcnNlLmNvbS4gUHJvYmFibHkgZG9lc24ndCBtYXR0ZXIgdG9vIG11Y2guXG4gICAgICAgICAgLy8gRm9yIG5vdywgcHJldGVuZCB0aGUgY2xhc3MgZXhpc3RzIGJ1dCBoYXMgbm8gb2JqZWN0cyxcbiAgICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY2xhc3NFeGlzdHMgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB7IGZpZWxkczoge30gfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICAgICAgLy8gUGFyc2UuY29tIHRyZWF0cyBxdWVyaWVzIG9uIF9jcmVhdGVkX2F0IGFuZCBfdXBkYXRlZF9hdCBhcyBpZiB0aGV5IHdlcmUgcXVlcmllcyBvbiBjcmVhdGVkQXQgYW5kIHVwZGF0ZWRBdCxcbiAgICAgICAgICAvLyBzbyBkdXBsaWNhdGUgdGhhdCBiZWhhdmlvciBoZXJlLiBJZiBib3RoIGFyZSBzcGVjaWZpZWQsIHRoZSBjb3JyZWN0IGJlaGF2aW9yIHRvIG1hdGNoIFBhcnNlLmNvbSBpcyB0b1xuICAgICAgICAgIC8vIHVzZSB0aGUgb25lIHRoYXQgYXBwZWFycyBmaXJzdCBpbiB0aGUgc29ydCBsaXN0LlxuICAgICAgICAgIGlmIChzb3J0Ll9jcmVhdGVkX2F0KSB7XG4gICAgICAgICAgICBzb3J0LmNyZWF0ZWRBdCA9IHNvcnQuX2NyZWF0ZWRfYXQ7XG4gICAgICAgICAgICBkZWxldGUgc29ydC5fY3JlYXRlZF9hdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNvcnQuX3VwZGF0ZWRfYXQpIHtcbiAgICAgICAgICAgIHNvcnQudXBkYXRlZEF0ID0gc29ydC5fdXBkYXRlZF9hdDtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3J0Ll91cGRhdGVkX2F0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBxdWVyeU9wdGlvbnMgPSB7XG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgICAgICAgIGV4cGxhaW4sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhzb3J0KS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoZmllbGROYW1lLm1hdGNoKC9eYXV0aERhdGFcXC4oW2EtekEtWjAtOV9dKylcXC5pZCQvKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYENhbm5vdCBzb3J0IGJ5ICR7ZmllbGROYW1lfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgcm9vdEZpZWxkTmFtZSA9IGdldFJvb3RGaWVsZE5hbWUoZmllbGROYW1lKTtcbiAgICAgICAgICAgIGlmICghU2NoZW1hQ29udHJvbGxlci5maWVsZE5hbWVJc1ZhbGlkKHJvb3RGaWVsZE5hbWUpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICAgICAgIGBJbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfS5gXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIChpc01hc3RlclxuICAgICAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgICAgOiBzY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWUsIGFjbEdyb3VwLCBvcClcbiAgICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJlZHVjZVJlbGF0aW9uS2V5cyhjbGFzc05hbWUsIHF1ZXJ5LCBxdWVyeU9wdGlvbnMpKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWR1Y2VJblJlbGF0aW9uKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYUNvbnRyb2xsZXIpKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICBsZXQgcHJvdGVjdGVkRmllbGRzO1xuICAgICAgICAgICAgICBpZiAoIWlzTWFzdGVyKSB7XG4gICAgICAgICAgICAgICAgcXVlcnkgPSB0aGlzLmFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICAgICAgICAgICAgICAgIHNjaGVtYUNvbnRyb2xsZXIsXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICBvcCxcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIC8qIERvbid0IHVzZSBwcm9qZWN0aW9ucyB0byBvcHRpbWl6ZSB0aGUgcHJvdGVjdGVkRmllbGRzIHNpbmNlIHRoZSBwcm90ZWN0ZWRGaWVsZHNcbiAgICAgICAgICAgICAgICAgIGJhc2VkIG9uIHBvaW50ZXItcGVybWlzc2lvbnMgYXJlIGRldGVybWluZWQgYWZ0ZXIgcXVlcnlpbmcuIFRoZSBmaWx0ZXJpbmcgY2FuXG4gICAgICAgICAgICAgICAgICBvdmVyd3JpdGUgdGhlIHByb3RlY3RlZCBmaWVsZHMuICovXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzID0gdGhpcy5hZGRQcm90ZWN0ZWRGaWVsZHMoXG4gICAgICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgICAgICBxdWVyeU9wdGlvbnNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICghcXVlcnkpIHtcbiAgICAgICAgICAgICAgICBpZiAob3AgPT09ICdnZXQnKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKCFpc01hc3Rlcikge1xuICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gJ3VwZGF0ZScgfHwgb3AgPT09ICdkZWxldGUnKSB7XG4gICAgICAgICAgICAgICAgICBxdWVyeSA9IGFkZFdyaXRlQUNMKHF1ZXJ5LCBhY2xHcm91cCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5ID0gYWRkUmVhZEFDTChxdWVyeSwgYWNsR3JvdXApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGFzc0V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY291bnQoXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgaGludFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlzdGluY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNsYXNzRXhpc3RzKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGlzdGluY3QoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCBkaXN0aW5jdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBpcGVsaW5lKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGFzc0V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFnZ3JlZ2F0ZShcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgICAgIHBpcGVsaW5lLFxuICAgICAgICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgICAgICAgICAgZXhwbGFpblxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhwbGFpbikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZmluZChjbGFzc05hbWUsIHNjaGVtYSwgcXVlcnksIHF1ZXJ5T3B0aW9ucyk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgICAgICAgICAgICAgLmZpbmQoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCBxdWVyeU9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAudGhlbihvYmplY3RzID0+XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdHMubWFwKG9iamVjdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgb2JqZWN0ID0gdW50cmFuc2Zvcm1PYmplY3RBQ0wob2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyU2Vuc2l0aXZlRGF0YShcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzTWFzdGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3AsXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBkZWxldGVTY2hlbWEoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4geyBmaWVsZHM6IHt9IH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAudGhlbigoc2NoZW1hOiBhbnkpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29sbGVjdGlvbkV4aXN0cyhjbGFzc05hbWUpXG4gICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5hZGFwdGVyLmNvdW50KGNsYXNzTmFtZSwgeyBmaWVsZHM6IHt9IH0sIG51bGwsICcnLCBmYWxzZSkpXG4gICAgICAgICAgLnRoZW4oY291bnQgPT4ge1xuICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgMjU1LFxuICAgICAgICAgICAgICAgIGBDbGFzcyAke2NsYXNzTmFtZX0gaXMgbm90IGVtcHR5LCBjb250YWlucyAke2NvdW50fSBvYmplY3RzLCBjYW5ub3QgZHJvcCBzY2hlbWEuYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5kZWxldGVDbGFzcyhjbGFzc05hbWUpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4od2FzUGFyc2VDb2xsZWN0aW9uID0+IHtcbiAgICAgICAgICAgIGlmICh3YXNQYXJzZUNvbGxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgY29uc3QgcmVsYXRpb25GaWVsZE5hbWVzID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZmlsdGVyKFxuICAgICAgICAgICAgICAgIGZpZWxkTmFtZSA9PiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ1JlbGF0aW9uJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgICAgcmVsYXRpb25GaWVsZE5hbWVzLm1hcChuYW1lID0+XG4gICAgICAgICAgICAgICAgICB0aGlzLmFkYXB0ZXIuZGVsZXRlQ2xhc3Moam9pblRhYmxlTmFtZShjbGFzc05hbWUsIG5hbWUpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBDb25zdHJhaW50cyBxdWVyeSB1c2luZyBDTFAncyBwb2ludGVyIHBlcm1pc3Npb25zIChQUCkgaWYgYW55LlxuICAvLyAxLiBFdHJhY3QgdGhlIHVzZXIgaWQgZnJvbSBjYWxsZXIncyBBQ0xncm91cDtcbiAgLy8gMi4gRXhjdHJhY3QgYSBsaXN0IG9mIGZpZWxkIG5hbWVzIHRoYXQgYXJlIFBQIGZvciB0YXJnZXQgY29sbGVjdGlvbiBhbmQgb3BlcmF0aW9uO1xuICAvLyAzLiBDb25zdHJhaW50IHRoZSBvcmlnaW5hbCBxdWVyeSBzbyB0aGF0IGVhY2ggUFAgZmllbGQgbXVzdFxuICAvLyBwb2ludCB0byBjYWxsZXIncyBpZCAob3IgY29udGFpbiBpdCBpbiBjYXNlIG9mIFBQIGZpZWxkIGJlaW5nIGFuIGFycmF5KVxuICBhZGRQb2ludGVyUGVybWlzc2lvbnMoXG4gICAgc2NoZW1hOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueSxcbiAgICBhY2xHcm91cDogYW55W10gPSBbXVxuICApOiBhbnkge1xuICAgIC8vIENoZWNrIGlmIGNsYXNzIGhhcyBwdWJsaWMgcGVybWlzc2lvbiBmb3Igb3BlcmF0aW9uXG4gICAgLy8gSWYgdGhlIEJhc2VDTFAgcGFzcywgbGV0IGdvIHRocm91Z2hcbiAgICBpZiAoc2NoZW1hLnRlc3RQZXJtaXNzaW9uc0ZvckNsYXNzTmFtZShjbGFzc05hbWUsIGFjbEdyb3VwLCBvcGVyYXRpb24pKSB7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfVxuICAgIGNvbnN0IHBlcm1zID0gc2NoZW1hLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpO1xuXG4gICAgY29uc3QgdXNlckFDTCA9IGFjbEdyb3VwLmZpbHRlcihhY2wgPT4ge1xuICAgICAgcmV0dXJuIGFjbC5pbmRleE9mKCdyb2xlOicpICE9IDAgJiYgYWNsICE9ICcqJztcbiAgICB9KTtcblxuICAgIGNvbnN0IGdyb3VwS2V5ID1cbiAgICAgIFsnZ2V0JywgJ2ZpbmQnLCAnY291bnQnXS5pbmRleE9mKG9wZXJhdGlvbikgPiAtMSA/ICdyZWFkVXNlckZpZWxkcycgOiAnd3JpdGVVc2VyRmllbGRzJztcblxuICAgIGNvbnN0IHBlcm1GaWVsZHMgPSBbXTtcblxuICAgIGlmIChwZXJtc1tvcGVyYXRpb25dICYmIHBlcm1zW29wZXJhdGlvbl0ucG9pbnRlckZpZWxkcykge1xuICAgICAgcGVybUZpZWxkcy5wdXNoKC4uLnBlcm1zW29wZXJhdGlvbl0ucG9pbnRlckZpZWxkcyk7XG4gICAgfVxuXG4gICAgaWYgKHBlcm1zW2dyb3VwS2V5XSkge1xuICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiBwZXJtc1tncm91cEtleV0pIHtcbiAgICAgICAgaWYgKCFwZXJtRmllbGRzLmluY2x1ZGVzKGZpZWxkKSkge1xuICAgICAgICAgIHBlcm1GaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGhlIEFDTCBzaG91bGQgaGF2ZSBleGFjdGx5IDEgdXNlclxuICAgIGlmIChwZXJtRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIHRoZSBBQ0wgc2hvdWxkIGhhdmUgZXhhY3RseSAxIHVzZXJcbiAgICAgIC8vIE5vIHVzZXIgc2V0IHJldHVybiB1bmRlZmluZWRcbiAgICAgIC8vIElmIHRoZSBsZW5ndGggaXMgPiAxLCB0aGF0IG1lYW5zIHdlIGRpZG4ndCBkZS1kdXBlIHVzZXJzIGNvcnJlY3RseVxuICAgICAgaWYgKHVzZXJBQ0wubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdXNlcklkID0gdXNlckFDTFswXTtcbiAgICAgIGNvbnN0IHVzZXJQb2ludGVyID0ge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdXNlcklkLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcXVlcmllcyA9IHBlcm1GaWVsZHMubWFwKGtleSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkRGVzY3JpcHRvciA9IHNjaGVtYS5nZXRFeHBlY3RlZFR5cGUoY2xhc3NOYW1lLCBrZXkpO1xuICAgICAgICBjb25zdCBmaWVsZFR5cGUgPVxuICAgICAgICAgIGZpZWxkRGVzY3JpcHRvciAmJlxuICAgICAgICAgIHR5cGVvZiBmaWVsZERlc2NyaXB0b3IgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZpZWxkRGVzY3JpcHRvciwgJ3R5cGUnKVxuICAgICAgICAgICAgPyBmaWVsZERlc2NyaXB0b3IudHlwZVxuICAgICAgICAgICAgOiBudWxsO1xuXG4gICAgICAgIGxldCBxdWVyeUNsYXVzZTtcblxuICAgICAgICBpZiAoZmllbGRUeXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICAvLyBjb25zdHJhaW50IGZvciBzaW5nbGUgcG9pbnRlciBzZXR1cFxuICAgICAgICAgIHF1ZXJ5Q2xhdXNlID0geyBba2V5XTogdXNlclBvaW50ZXIgfTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgICAvLyBjb25zdHJhaW50IGZvciB1c2Vycy1hcnJheSBzZXR1cFxuICAgICAgICAgIHF1ZXJ5Q2xhdXNlID0geyBba2V5XTogeyAkYWxsOiBbdXNlclBvaW50ZXJdIH0gfTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFR5cGUgPT09ICdPYmplY3QnKSB7XG4gICAgICAgICAgLy8gY29uc3RyYWludCBmb3Igb2JqZWN0IHNldHVwXG4gICAgICAgICAgcXVlcnlDbGF1c2UgPSB7IFtrZXldOiB1c2VyUG9pbnRlciB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFRoaXMgbWVhbnMgdGhhdCB0aGVyZSBpcyBhIENMUCBmaWVsZCBvZiBhbiB1bmV4cGVjdGVkIHR5cGUuIFRoaXMgY29uZGl0aW9uIHNob3VsZCBub3QgaGFwcGVuLCB3aGljaCBpc1xuICAgICAgICAgIC8vIHdoeSBpcyBiZWluZyB0cmVhdGVkIGFzIGFuIGVycm9yLlxuICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgYEFuIHVuZXhwZWN0ZWQgY29uZGl0aW9uIG9jY3VycmVkIHdoZW4gcmVzb2x2aW5nIHBvaW50ZXIgcGVybWlzc2lvbnM6ICR7Y2xhc3NOYW1lfSAke2tleX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBjb25zdHJhaW50IG9uIHRoZSBrZXksIHVzZSB0aGUgJGFuZFxuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHF1ZXJ5LCBrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgJGFuZDogW3F1ZXJ5Q2xhdXNlLCBxdWVyeV0gfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBvdGhlcndpc2UganVzdCBhZGQgdGhlIGNvbnN0YWludFxuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgcXVlcnksIHF1ZXJ5Q2xhdXNlKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcXVlcmllcy5sZW5ndGggPT09IDEgPyBxdWVyaWVzWzBdIDogeyAkb3I6IHF1ZXJpZXMgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIGFkZFByb3RlY3RlZEZpZWxkcyhcbiAgICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55ID0ge30sXG4gICAgYWNsR3JvdXA6IGFueVtdID0gW10sXG4gICAgYXV0aDogYW55ID0ge30sXG4gICAgcXVlcnlPcHRpb25zOiBGdWxsUXVlcnlPcHRpb25zID0ge31cbiAgKTogbnVsbCB8IHN0cmluZ1tdIHtcbiAgICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgICBpZiAoIXBlcm1zKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkcyA9IHBlcm1zLnByb3RlY3RlZEZpZWxkcztcbiAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAoYWNsR3JvdXAuaW5kZXhPZihxdWVyeS5vYmplY3RJZCkgPiAtMSkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBmb3IgcXVlcmllcyB3aGVyZSBcImtleXNcIiBhcmUgc2V0IGFuZCBkbyBub3QgaW5jbHVkZSBhbGwgJ3VzZXJGaWVsZCc6e2ZpZWxkfSxcbiAgICAvLyB3ZSBoYXZlIHRvIHRyYW5zcGFyZW50bHkgaW5jbHVkZSBpdCwgYW5kIHRoZW4gcmVtb3ZlIGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50XG4gICAgLy8gQmVjYXVzZSBpZiBzdWNoIGtleSBub3QgcHJvamVjdGVkIHRoZSBwZXJtaXNzaW9uIHdvbid0IGJlIGVuZm9yY2VkIHByb3Blcmx5XG4gICAgLy8gUFMgdGhpcyBpcyBjYWxsZWQgd2hlbiAnZXhjbHVkZUtleXMnIGFscmVhZHkgcmVkdWNlZCB0byAna2V5cydcbiAgICBjb25zdCBwcmVzZXJ2ZUtleXMgPSBxdWVyeU9wdGlvbnMua2V5cztcblxuICAgIC8vIHRoZXNlIGFyZSBrZXlzIHRoYXQgbmVlZCB0byBiZSBpbmNsdWRlZCBvbmx5XG4gICAgLy8gdG8gYmUgYWJsZSB0byBhcHBseSBwcm90ZWN0ZWRGaWVsZHMgYnkgcG9pbnRlclxuICAgIC8vIGFuZCB0aGVuIHVuc2V0IGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50IChsYXRlciBpbiAgZmlsdGVyU2Vuc2l0aXZlRmllbGRzKVxuICAgIGNvbnN0IHNlcnZlck9ubHlLZXlzID0gW107XG5cbiAgICBjb25zdCBhdXRoZW50aWNhdGVkID0gYXV0aC51c2VyO1xuXG4gICAgLy8gbWFwIHRvIGFsbG93IGNoZWNrIHdpdGhvdXQgYXJyYXkgc2VhcmNoXG4gICAgY29uc3Qgcm9sZXMgPSAoYXV0aC51c2VyUm9sZXMgfHwgW10pLnJlZHVjZSgoYWNjLCByKSA9PiB7XG4gICAgICBhY2Nbcl0gPSBwcm90ZWN0ZWRGaWVsZHNbcl07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcblxuICAgIC8vIGFycmF5IG9mIHNldHMgb2YgcHJvdGVjdGVkIGZpZWxkcy4gc2VwYXJhdGUgaXRlbSBmb3IgZWFjaCBhcHBsaWNhYmxlIGNyaXRlcmlhXG4gICAgY29uc3QgcHJvdGVjdGVkS2V5c1NldHMgPSBbXTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgLy8gc2tpcCB1c2VyRmllbGRzXG4gICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ3VzZXJGaWVsZDonKSkge1xuICAgICAgICBpZiAocHJlc2VydmVLZXlzKSB7XG4gICAgICAgICAgY29uc3QgZmllbGROYW1lID0ga2V5LnN1YnN0cmluZygxMCk7XG4gICAgICAgICAgaWYgKCFwcmVzZXJ2ZUtleXMuaW5jbHVkZXMoZmllbGROYW1lKSkge1xuICAgICAgICAgICAgLy8gMS4gcHV0IGl0IHRoZXJlIHRlbXBvcmFyaWx5XG4gICAgICAgICAgICBxdWVyeU9wdGlvbnMua2V5cyAmJiBxdWVyeU9wdGlvbnMua2V5cy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgICAvLyAyLiBwcmVzZXJ2ZSBpdCBkZWxldGUgbGF0ZXJcbiAgICAgICAgICAgIHNlcnZlck9ubHlLZXlzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBwdWJsaWMgdGllclxuICAgICAgaWYgKGtleSA9PT0gJyonKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ2F1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgICAgLy8gZm9yIGxvZ2dlZCBpbiB1c2Vyc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJvbGVzW2tleV0gJiYga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpIHtcbiAgICAgICAgICAvLyBhZGQgYXBwbGljYWJsZSByb2xlc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocm9sZXNba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiB0aGVyZSdzIGEgcnVsZSBmb3IgY3VycmVudCB1c2VyJ3MgaWRcbiAgICBpZiAoYXV0aGVudGljYXRlZCkge1xuICAgICAgY29uc3QgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuICAgICAgaWYgKHBlcm1zLnByb3RlY3RlZEZpZWxkc1t1c2VySWRdKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocGVybXMucHJvdGVjdGVkRmllbGRzW3VzZXJJZF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHByZXNlcnZlIGZpZWxkcyB0byBiZSByZW1vdmVkIGJlZm9yZSBzZW5kaW5nIHJlc3BvbnNlIHRvIGNsaWVudFxuICAgIGlmIChzZXJ2ZXJPbmx5S2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyA9IHNlcnZlck9ubHlLZXlzO1xuICAgIH1cblxuICAgIGxldCBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5c1NldHMucmVkdWNlKChhY2MsIG5leHQpID0+IHtcbiAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgIGFjYy5wdXNoKC4uLm5leHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICAvLyBpbnRlcnNlY3QgYWxsIHNldHMgb2YgcHJvdGVjdGVkRmllbGRzXG4gICAgcHJvdGVjdGVkS2V5c1NldHMuZm9yRWFjaChmaWVsZHMgPT4ge1xuICAgICAgaWYgKGZpZWxkcykge1xuICAgICAgICBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5cy5maWx0ZXIodiA9PiBmaWVsZHMuaW5jbHVkZXModikpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHByb3RlY3RlZEtleXM7XG4gIH1cblxuICBjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCkudGhlbih0cmFuc2FjdGlvbmFsU2Vzc2lvbiA9PiB7XG4gICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbiA9IHRyYW5zYWN0aW9uYWxTZXNzaW9uO1xuICAgIH0pO1xuICB9XG5cbiAgY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKSB7XG4gICAgaWYgKCF0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGVyZSBpcyBubyB0cmFuc2FjdGlvbmFsIHNlc3Npb24gdG8gY29tbWl0Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICBpZiAoIXRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIHRyYW5zYWN0aW9uYWwgc2Vzc2lvbiB0byBhYm9ydCcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gVE9ETzogY3JlYXRlIGluZGV4ZXMgb24gZmlyc3QgY3JlYXRpb24gb2YgYSBfVXNlciBvYmplY3QuIE90aGVyd2lzZSBpdCdzIGltcG9zc2libGUgdG9cbiAgLy8gaGF2ZSBhIFBhcnNlIGFwcCB3aXRob3V0IGl0IGhhdmluZyBhIF9Vc2VyIGNvbGxlY3Rpb24uXG4gIHBlcmZvcm1Jbml0aWFsaXphdGlvbigpIHtcbiAgICBjb25zdCByZXF1aXJlZFVzZXJGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fVXNlcixcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZFJvbGVGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fUm9sZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZElkZW1wb3RlbmN5RmllbGRzID0ge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQsXG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlckNsYXNzUHJvbWlzZSA9IHRoaXMubG9hZFNjaGVtYSgpLnRoZW4oc2NoZW1hID0+IHNjaGVtYS5lbmZvcmNlQ2xhc3NFeGlzdHMoJ19Vc2VyJykpO1xuICAgIGNvbnN0IHJvbGVDbGFzc1Byb21pc2UgPSB0aGlzLmxvYWRTY2hlbWEoKS50aGVuKHNjaGVtYSA9PiBzY2hlbWEuZW5mb3JjZUNsYXNzRXhpc3RzKCdfUm9sZScpKTtcbiAgICBjb25zdCBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZSA9XG4gICAgICB0aGlzLmFkYXB0ZXIgaW5zdGFuY2VvZiBNb25nb1N0b3JhZ2VBZGFwdGVyXG4gICAgICAgID8gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4gc2NoZW1hLmVuZm9yY2VDbGFzc0V4aXN0cygnX0lkZW1wb3RlbmN5JykpXG4gICAgICAgIDogUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICBjb25zdCB1c2VybmFtZVVuaXF1ZW5lc3MgPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX1VzZXInLCByZXF1aXJlZFVzZXJGaWVsZHMsIFsndXNlcm5hbWUnXSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGVuc3VyZSB1bmlxdWVuZXNzIGZvciB1c2VybmFtZXM6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXggPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PlxuICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlSW5kZXgoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICByZXF1aXJlZFVzZXJGaWVsZHMsXG4gICAgICAgICAgWyd1c2VybmFtZSddLFxuICAgICAgICAgICdjYXNlX2luc2Vuc2l0aXZlX3VzZXJuYW1lJyxcbiAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gY3JlYXRlIGNhc2UgaW5zZW5zaXRpdmUgdXNlcm5hbWUgaW5kZXg6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGVtYWlsVW5pcXVlbmVzcyA9IHVzZXJDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfVXNlcicsIHJlcXVpcmVkVXNlckZpZWxkcywgWydlbWFpbCddKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gZW5zdXJlIHVuaXF1ZW5lc3MgZm9yIHVzZXIgZW1haWwgYWRkcmVzc2VzOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4ID0gdXNlckNsYXNzUHJvbWlzZVxuICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5hZGFwdGVyLmVuc3VyZUluZGV4KFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgcmVxdWlyZWRVc2VyRmllbGRzLFxuICAgICAgICAgIFsnZW1haWwnXSxcbiAgICAgICAgICAnY2FzZV9pbnNlbnNpdGl2ZV9lbWFpbCcsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGNyZWF0ZSBjYXNlIGluc2Vuc2l0aXZlIGVtYWlsIGluZGV4OiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCByb2xlVW5pcXVlbmVzcyA9IHJvbGVDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfUm9sZScsIHJlcXVpcmVkUm9sZUZpZWxkcywgWyduYW1lJ10pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3Igcm9sZSBuYW1lOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4ID1cbiAgICAgIHRoaXMuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXJcbiAgICAgICAgPyBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZVxuICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX0lkZW1wb3RlbmN5JywgcmVxdWlyZWRJZGVtcG90ZW5jeUZpZWxkcywgWydyZXFJZCddKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3IgaWRlbXBvdGVuY3kgcmVxdWVzdCBJRDogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGlkZW1wb3RlbmN5RXhwaXJlSW5kZXggPVxuICAgICAgdGhpcy5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlclxuICAgICAgICA/IGlkZW1wb3RlbmN5Q2xhc3NQcm9taXNlXG4gICAgICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgICAgIHRoaXMuYWRhcHRlci5lbnN1cmVJbmRleChcbiAgICAgICAgICAgICAgJ19JZGVtcG90ZW5jeScsXG4gICAgICAgICAgICAgIHJlcXVpcmVkSWRlbXBvdGVuY3lGaWVsZHMsXG4gICAgICAgICAgICAgIFsnZXhwaXJlJ10sXG4gICAgICAgICAgICAgICd0dGwnLFxuICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgeyB0dGw6IDAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBjcmVhdGUgVFRMIGluZGV4IGZvciBpZGVtcG90ZW5jeSBleHBpcmUgZGF0ZTogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGluZGV4UHJvbWlzZSA9IHRoaXMuYWRhcHRlci51cGRhdGVTY2hlbWFXaXRoSW5kZXhlcygpO1xuXG4gICAgLy8gQ3JlYXRlIHRhYmxlcyBmb3Igdm9sYXRpbGUgY2xhc3Nlc1xuICAgIGNvbnN0IGFkYXB0ZXJJbml0ID0gdGhpcy5hZGFwdGVyLnBlcmZvcm1Jbml0aWFsaXphdGlvbih7XG4gICAgICBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzOiBTY2hlbWFDb250cm9sbGVyLlZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMsXG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgIHVzZXJuYW1lVW5pcXVlbmVzcyxcbiAgICAgIHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXgsXG4gICAgICBlbWFpbFVuaXF1ZW5lc3MsXG4gICAgICBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4LFxuICAgICAgcm9sZVVuaXF1ZW5lc3MsXG4gICAgICBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4LFxuICAgICAgaWRlbXBvdGVuY3lFeHBpcmVJbmRleCxcbiAgICAgIGFkYXB0ZXJJbml0LFxuICAgICAgaW5kZXhQcm9taXNlLFxuICAgIF0pO1xuICB9XG5cbiAgc3RhdGljIF92YWxpZGF0ZVF1ZXJ5OiBhbnkgPT4gdm9pZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhYmFzZUNvbnRyb2xsZXI7XG4vLyBFeHBvc2UgdmFsaWRhdGVRdWVyeSBmb3IgdGVzdHNcbm1vZHVsZS5leHBvcnRzLl92YWxpZGF0ZVF1ZXJ5ID0gdmFsaWRhdGVRdWVyeTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/FilesController.js b/lib/Controllers/FilesController.js new file mode 100644 index 0000000000..c189e36093 --- /dev/null +++ b/lib/Controllers/FilesController.js @@ -0,0 +1,136 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.FilesController = void 0; + +var _cryptoUtils = require("../cryptoUtils"); + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); + +var _path = _interopRequireDefault(require("path")); + +var _mime = _interopRequireDefault(require("mime")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// FilesController.js +const Parse = require('parse').Parse; + +const legacyFilesRegex = new RegExp('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}-.*'); + +class FilesController extends _AdaptableController.default { + getFileData(config, filename) { + return this.adapter.getFileData(filename); + } + + createFile(config, filename, data, contentType, options) { + const extname = _path.default.extname(filename); + + const hasExtension = extname.length > 0; + + if (!hasExtension && contentType && _mime.default.getExtension(contentType)) { + filename = filename + '.' + _mime.default.getExtension(contentType); + } else if (hasExtension && !contentType) { + contentType = _mime.default.getType(filename); + } + + if (!this.options.preserveFileName) { + filename = (0, _cryptoUtils.randomHexString)(32) + '_' + filename; + } + + const location = this.adapter.getFileLocation(config, filename); + return this.adapter.createFile(filename, data, contentType, options).then(() => { + return Promise.resolve({ + url: location, + name: filename + }); + }); + } + + deleteFile(config, filename) { + return this.adapter.deleteFile(filename); + } + + getMetadata(filename) { + if (typeof this.adapter.getMetadata === 'function') { + return this.adapter.getMetadata(filename); + } + + return Promise.resolve({}); + } + /** + * Find file references in REST-format object and adds the url key + * with the current mount point and app id. + * Object may be a single object or list of REST-format objects. + */ + + + expandFilesInObject(config, object) { + if (object instanceof Array) { + object.map(obj => this.expandFilesInObject(config, obj)); + return; + } + + if (typeof object !== 'object') { + return; + } + + for (const key in object) { + const fileObject = object[key]; + + if (fileObject && fileObject['__type'] === 'File') { + if (fileObject['url']) { + continue; + } + + const filename = fileObject['name']; // all filenames starting with "tfss-" should be from files.parsetfss.com + // all filenames starting with a "-" seperated UUID should be from files.parse.com + // all other filenames have been migrated or created from Parse Server + + if (config.fileKey === undefined) { + fileObject['url'] = this.adapter.getFileLocation(config, filename); + } else { + if (filename.indexOf('tfss-') === 0) { + fileObject['url'] = 'http://files.parsetfss.com/' + config.fileKey + '/' + encodeURIComponent(filename); + } else if (legacyFilesRegex.test(filename)) { + fileObject['url'] = 'http://files.parse.com/' + config.fileKey + '/' + encodeURIComponent(filename); + } else { + fileObject['url'] = this.adapter.getFileLocation(config, filename); + } + } + } + } + } + + expectedAdapterType() { + return _FilesAdapter.FilesAdapter; + } + + handleFileStream(config, filename, req, res, contentType) { + return this.adapter.handleFileStream(filename, req, res, contentType); + } + + validateFilename(filename) { + if (typeof this.adapter.validateFilename === 'function') { + const error = this.adapter.validateFilename(filename); + + if (typeof error !== 'string') { + return error; + } + + return new Parse.Error(Parse.Error.INVALID_FILE_NAME, error); + } + + return (0, _FilesAdapter.validateFilename)(filename); + } + +} + +exports.FilesController = FilesController; +var _default = FilesController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9GaWxlc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwibGVnYWN5RmlsZXNSZWdleCIsIlJlZ0V4cCIsIkZpbGVzQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJnZXRGaWxlRGF0YSIsImNvbmZpZyIsImZpbGVuYW1lIiwiYWRhcHRlciIsImNyZWF0ZUZpbGUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJvcHRpb25zIiwiZXh0bmFtZSIsInBhdGgiLCJoYXNFeHRlbnNpb24iLCJsZW5ndGgiLCJtaW1lIiwiZ2V0RXh0ZW5zaW9uIiwiZ2V0VHlwZSIsInByZXNlcnZlRmlsZU5hbWUiLCJsb2NhdGlvbiIsImdldEZpbGVMb2NhdGlvbiIsInRoZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsInVybCIsIm5hbWUiLCJkZWxldGVGaWxlIiwiZ2V0TWV0YWRhdGEiLCJleHBhbmRGaWxlc0luT2JqZWN0Iiwib2JqZWN0IiwiQXJyYXkiLCJtYXAiLCJvYmoiLCJrZXkiLCJmaWxlT2JqZWN0IiwiZmlsZUtleSIsInVuZGVmaW5lZCIsImluZGV4T2YiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ0ZXN0IiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkZpbGVzQWRhcHRlciIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiZXJyb3IiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFMQTtBQU1BLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBUCxDQUFpQkQsS0FBL0I7O0FBRUEsTUFBTUUsZ0JBQWdCLEdBQUcsSUFBSUMsTUFBSixDQUN2QixpRkFEdUIsQ0FBekI7O0FBSU8sTUFBTUMsZUFBTixTQUE4QkMsNEJBQTlCLENBQWtEO0FBQ3ZE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QUFDekIsUUFBSSxPQUFPLEtBQUtDLE9BQUwsQ0FBYXVDLGdCQUFwQixLQUF5QyxVQUE3QyxFQUF5RDtBQUN2RCxZQUFNQyxLQUFLLEdBQUcsS0FBS3hDLE9BQUwsQ0FBYXVDLGdCQUFiLENBQThCeEMsUUFBOUIsQ0FBZDs7QUFDQSxVQUFJLE9BQU95QyxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLGVBQU9BLEtBQVA7QUFDRDs7QUFDRCxhQUFPLElBQUlqRCxLQUFLLENBQUNrRCxLQUFWLENBQWdCbEQsS0FBSyxDQUFDa0QsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0NGLEtBQS9DLENBQVA7QUFDRDs7QUFDRCxXQUFPLG9DQUFpQnpDLFFBQWpCLENBQVA7QUFDRDs7QUFqR3NEOzs7ZUFvRzFDSixlIiwic291cmNlc0NvbnRlbnQiOlsiLy8gRmlsZXNDb250cm9sbGVyLmpzXG5pbXBvcnQgeyByYW5kb21IZXhTdHJpbmcgfSBmcm9tICcuLi9jcnlwdG9VdGlscyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IHsgdmFsaWRhdGVGaWxlbmFtZSwgRmlsZXNBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRmlsZXMvRmlsZXNBZGFwdGVyJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IG1pbWUgZnJvbSAnbWltZSc7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlJykuUGFyc2U7XG5cbmNvbnN0IGxlZ2FjeUZpbGVzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAnXlswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfS0uKidcbik7XG5cbmV4cG9ydCBjbGFzcyBGaWxlc0NvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgZ2V0RmlsZURhdGEoY29uZmlnLCBmaWxlbmFtZSkge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZ2V0RmlsZURhdGEoZmlsZW5hbWUpO1xuICB9XG5cbiAgY3JlYXRlRmlsZShjb25maWcsIGZpbGVuYW1lLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucykge1xuICAgIGNvbnN0IGV4dG5hbWUgPSBwYXRoLmV4dG5hbWUoZmlsZW5hbWUpO1xuXG4gICAgY29uc3QgaGFzRXh0ZW5zaW9uID0gZXh0bmFtZS5sZW5ndGggPiAwO1xuXG4gICAgaWYgKCFoYXNFeHRlbnNpb24gJiYgY29udGVudFR5cGUgJiYgbWltZS5nZXRFeHRlbnNpb24oY29udGVudFR5cGUpKSB7XG4gICAgICBmaWxlbmFtZSA9IGZpbGVuYW1lICsgJy4nICsgbWltZS5nZXRFeHRlbnNpb24oY29udGVudFR5cGUpO1xuICAgIH0gZWxzZSBpZiAoaGFzRXh0ZW5zaW9uICYmICFjb250ZW50VHlwZSkge1xuICAgICAgY29udGVudFR5cGUgPSBtaW1lLmdldFR5cGUoZmlsZW5hbWUpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5vcHRpb25zLnByZXNlcnZlRmlsZU5hbWUpIHtcbiAgICAgIGZpbGVuYW1lID0gcmFuZG9tSGV4U3RyaW5nKDMyKSArICdfJyArIGZpbGVuYW1lO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5hZGFwdGVyLmdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZUZpbGUoZmlsZW5hbWUsIGRhdGEsIGNvbnRlbnRUeXBlLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICB1cmw6IGxvY2F0aW9uLFxuICAgICAgICBuYW1lOiBmaWxlbmFtZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRmlsZShjb25maWcsIGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5kZWxldGVGaWxlKGZpbGVuYW1lKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKGZpbGVuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmFkYXB0ZXIuZ2V0TWV0YWRhdGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZ2V0TWV0YWRhdGEoZmlsZW5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGZpbGUgcmVmZXJlbmNlcyBpbiBSRVNULWZvcm1hdCBvYmplY3QgYW5kIGFkZHMgdGhlIHVybCBrZXlcbiAgICogd2l0aCB0aGUgY3VycmVudCBtb3VudCBwb2ludCBhbmQgYXBwIGlkLlxuICAgKiBPYmplY3QgbWF5IGJlIGEgc2luZ2xlIG9iamVjdCBvciBsaXN0IG9mIFJFU1QtZm9ybWF0IG9iamVjdHMuXG4gICAqL1xuICBleHBhbmRGaWxlc0luT2JqZWN0KGNvbmZpZywgb2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBvYmplY3QubWFwKG9iaiA9PiB0aGlzLmV4cGFuZEZpbGVzSW5PYmplY3QoY29uZmlnLCBvYmopKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkge1xuICAgICAgY29uc3QgZmlsZU9iamVjdCA9IG9iamVjdFtrZXldO1xuICAgICAgaWYgKGZpbGVPYmplY3QgJiYgZmlsZU9iamVjdFsnX190eXBlJ10gPT09ICdGaWxlJykge1xuICAgICAgICBpZiAoZmlsZU9iamVjdFsndXJsJ10pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaWxlbmFtZSA9IGZpbGVPYmplY3RbJ25hbWUnXTtcbiAgICAgICAgLy8gYWxsIGZpbGVuYW1lcyBzdGFydGluZyB3aXRoIFwidGZzcy1cIiBzaG91bGQgYmUgZnJvbSBmaWxlcy5wYXJzZXRmc3MuY29tXG4gICAgICAgIC8vIGFsbCBmaWxlbmFtZXMgc3RhcnRpbmcgd2l0aCBhIFwiLVwiIHNlcGVyYXRlZCBVVUlEIHNob3VsZCBiZSBmcm9tIGZpbGVzLnBhcnNlLmNvbVxuICAgICAgICAvLyBhbGwgb3RoZXIgZmlsZW5hbWVzIGhhdmUgYmVlbiBtaWdyYXRlZCBvciBjcmVhdGVkIGZyb20gUGFyc2UgU2VydmVyXG4gICAgICAgIGlmIChjb25maWcuZmlsZUtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPSB0aGlzLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChmaWxlbmFtZS5pbmRleE9mKCd0ZnNzLScpID09PSAwKSB7XG4gICAgICAgICAgICBmaWxlT2JqZWN0Wyd1cmwnXSA9XG4gICAgICAgICAgICAgICdodHRwOi8vZmlsZXMucGFyc2V0ZnNzLmNvbS8nICsgY29uZmlnLmZpbGVLZXkgKyAnLycgKyBlbmNvZGVVUklDb21wb25lbnQoZmlsZW5hbWUpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobGVnYWN5RmlsZXNSZWdleC50ZXN0KGZpbGVuYW1lKSkge1xuICAgICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPVxuICAgICAgICAgICAgICAnaHR0cDovL2ZpbGVzLnBhcnNlLmNvbS8nICsgY29uZmlnLmZpbGVLZXkgKyAnLycgKyBlbmNvZGVVUklDb21wb25lbnQoZmlsZW5hbWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaWxlT2JqZWN0Wyd1cmwnXSA9IHRoaXMuYWRhcHRlci5nZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gRmlsZXNBZGFwdGVyO1xuICB9XG5cbiAgaGFuZGxlRmlsZVN0cmVhbShjb25maWcsIGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmhhbmRsZUZpbGVTdHJlYW0oZmlsZW5hbWUsIHJlcSwgcmVzLCBjb250ZW50VHlwZSk7XG4gIH1cblxuICB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmFkYXB0ZXIudmFsaWRhdGVGaWxlbmFtZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgZXJyb3IgPSB0aGlzLmFkYXB0ZXIudmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk7XG4gICAgICBpZiAodHlwZW9mIGVycm9yICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCBlcnJvcik7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBGaWxlc0NvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/HooksController.js b/lib/Controllers/HooksController.js new file mode 100644 index 0000000000..8ebe771207 --- /dev/null +++ b/lib/Controllers/HooksController.js @@ -0,0 +1,301 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.HooksController = void 0; + +var triggers = _interopRequireWildcard(require("../triggers")); + +var Parse = _interopRequireWildcard(require("parse/node")); + +var _request = _interopRequireDefault(require("../request")); + +var _logger = require("../logger"); + +var _http = _interopRequireDefault(require("http")); + +var _https = _interopRequireDefault(require("https")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +// -disable-next +// -disable-next +const DefaultHooksCollectionName = '_Hooks'; +const HTTPAgents = { + http: new _http.default.Agent({ + keepAlive: true + }), + https: new _https.default.Agent({ + keepAlive: true + }) +}; + +class HooksController { + constructor(applicationId, databaseController, webhookKey) { + this._applicationId = applicationId; + this._webhookKey = webhookKey; + this.database = databaseController; + } + + load() { + return this._getHooks().then(hooks => { + hooks = hooks || []; + hooks.forEach(hook => { + this.addHookToTriggers(hook); + }); + }); + } + + getFunction(functionName) { + return this._getHooks({ + functionName: functionName + }).then(results => results[0]); + } + + getFunctions() { + return this._getHooks({ + functionName: { + $exists: true + } + }); + } + + getTrigger(className, triggerName) { + return this._getHooks({ + className: className, + triggerName: triggerName + }).then(results => results[0]); + } + + getTriggers() { + return this._getHooks({ + className: { + $exists: true + }, + triggerName: { + $exists: true + } + }); + } + + deleteFunction(functionName) { + triggers.removeFunction(functionName, this._applicationId); + return this._removeHooks({ + functionName: functionName + }); + } + + deleteTrigger(className, triggerName) { + triggers.removeTrigger(triggerName, className, this._applicationId); + return this._removeHooks({ + className: className, + triggerName: triggerName + }); + } + + _getHooks(query = {}) { + return this.database.find(DefaultHooksCollectionName, query).then(results => { + return results.map(result => { + delete result.objectId; + return result; + }); + }); + } + + _removeHooks(query) { + return this.database.destroy(DefaultHooksCollectionName, query).then(() => { + return Promise.resolve({}); + }); + } + + saveHook(hook) { + var query; + + if (hook.functionName && hook.url) { + query = { + functionName: hook.functionName + }; + } else if (hook.triggerName && hook.className && hook.url) { + query = { + className: hook.className, + triggerName: hook.triggerName + }; + } else { + throw new Parse.Error(143, 'invalid hook declaration'); + } + + return this.database.update(DefaultHooksCollectionName, query, hook, { + upsert: true + }).then(() => { + return Promise.resolve(hook); + }); + } + + addHookToTriggers(hook) { + var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey); + wrappedFunction.url = hook.url; + + if (hook.className) { + triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId); + } else { + triggers.addFunction(hook.functionName, wrappedFunction, null, this._applicationId); + } + } + + addHook(hook) { + this.addHookToTriggers(hook); + return this.saveHook(hook); + } + + createOrUpdateHook(aHook) { + var hook; + + if (aHook && aHook.functionName && aHook.url) { + hook = {}; + hook.functionName = aHook.functionName; + hook.url = aHook.url; + } else if (aHook && aHook.className && aHook.url && aHook.triggerName && triggers.Types[aHook.triggerName]) { + hook = {}; + hook.className = aHook.className; + hook.url = aHook.url; + hook.triggerName = aHook.triggerName; + } else { + throw new Parse.Error(143, 'invalid hook declaration'); + } + + return this.addHook(hook); + } + + createHook(aHook) { + if (aHook.functionName) { + return this.getFunction(aHook.functionName).then(result => { + if (result) { + throw new Parse.Error(143, `function name: ${aHook.functionName} already exits`); + } else { + return this.createOrUpdateHook(aHook); + } + }); + } else if (aHook.className && aHook.triggerName) { + return this.getTrigger(aHook.className, aHook.triggerName).then(result => { + if (result) { + throw new Parse.Error(143, `class ${aHook.className} already has trigger ${aHook.triggerName}`); + } + + return this.createOrUpdateHook(aHook); + }); + } + + throw new Parse.Error(143, 'invalid hook declaration'); + } + + updateHook(aHook) { + if (aHook.functionName) { + return this.getFunction(aHook.functionName).then(result => { + if (result) { + return this.createOrUpdateHook(aHook); + } + + throw new Parse.Error(143, `no function named: ${aHook.functionName} is defined`); + }); + } else if (aHook.className && aHook.triggerName) { + return this.getTrigger(aHook.className, aHook.triggerName).then(result => { + if (result) { + return this.createOrUpdateHook(aHook); + } + + throw new Parse.Error(143, `class ${aHook.className} does not exist`); + }); + } + + throw new Parse.Error(143, 'invalid hook declaration'); + } + +} + +exports.HooksController = HooksController; + +function wrapToHTTPRequest(hook, key) { + return req => { + const jsonBody = {}; + + for (var i in req) { + jsonBody[i] = req[i]; + } + + if (req.object) { + jsonBody.object = req.object.toJSON(); + jsonBody.object.className = req.object.className; + } + + if (req.original) { + jsonBody.original = req.original.toJSON(); + jsonBody.original.className = req.original.className; + } + + const jsonRequest = { + url: hook.url, + headers: { + 'Content-Type': 'application/json' + }, + body: jsonBody, + method: 'POST' + }; + const agent = hook.url.startsWith('https') ? HTTPAgents['https'] : HTTPAgents['http']; + jsonRequest.agent = agent; + + if (key) { + jsonRequest.headers['X-Parse-Webhook-Key'] = key; + } else { + _logger.logger.warn('Making outgoing webhook request without webhookKey being set!'); + } + + return (0, _request.default)(jsonRequest).then(response => { + let err; + let result; + let body = response.data; + + if (body) { + if (typeof body === 'string') { + try { + body = JSON.parse(body); + } catch (e) { + err = { + error: 'Malformed response', + code: -1, + partialResponse: body.substring(0, 100) + }; + } + } + + if (!err) { + result = body.success; + err = body.error; + } + } + + if (err) { + throw err; + } else if (hook.triggerName === 'beforeSave') { + if (typeof result === 'object') { + delete result.createdAt; + delete result.updatedAt; + } + + return { + object: result + }; + } else { + return result; + } + }); + }; +} + +var _default = HooksController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Ib29rc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUiLCJIVFRQQWdlbnRzIiwiaHR0cCIsIkFnZW50Iiwia2VlcEFsaXZlIiwiaHR0cHMiLCJIb29rc0NvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcGxpY2F0aW9uSWQiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJ3ZWJob29rS2V5IiwiX2FwcGxpY2F0aW9uSWQiLCJfd2ViaG9va0tleSIsImRhdGFiYXNlIiwibG9hZCIsIl9nZXRIb29rcyIsInRoZW4iLCJob29rcyIsImZvckVhY2giLCJob29rIiwiYWRkSG9va1RvVHJpZ2dlcnMiLCJnZXRGdW5jdGlvbiIsImZ1bmN0aW9uTmFtZSIsInJlc3VsdHMiLCJnZXRGdW5jdGlvbnMiLCIkZXhpc3RzIiwiZ2V0VHJpZ2dlciIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlcnMiLCJkZWxldGVGdW5jdGlvbiIsInRyaWdnZXJzIiwicmVtb3ZlRnVuY3Rpb24iLCJfcmVtb3ZlSG9va3MiLCJkZWxldGVUcmlnZ2VyIiwicmVtb3ZlVHJpZ2dlciIsInF1ZXJ5IiwiZmluZCIsIm1hcCIsInJlc3VsdCIsIm9iamVjdElkIiwiZGVzdHJveSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2F2ZUhvb2siLCJ1cmwiLCJQYXJzZSIsIkVycm9yIiwidXBkYXRlIiwidXBzZXJ0Iiwid3JhcHBlZEZ1bmN0aW9uIiwid3JhcFRvSFRUUFJlcXVlc3QiLCJhZGRUcmlnZ2VyIiwiYWRkRnVuY3Rpb24iLCJhZGRIb29rIiwiY3JlYXRlT3JVcGRhdGVIb29rIiwiYUhvb2siLCJUeXBlcyIsImNyZWF0ZUhvb2siLCJ1cGRhdGVIb29rIiwia2V5IiwicmVxIiwianNvbkJvZHkiLCJpIiwib2JqZWN0IiwidG9KU09OIiwib3JpZ2luYWwiLCJqc29uUmVxdWVzdCIsImhlYWRlcnMiLCJib2R5IiwibWV0aG9kIiwiYWdlbnQiLCJzdGFydHNXaXRoIiwibG9nZ2VyIiwid2FybiIsInJlc3BvbnNlIiwiZXJyIiwiZGF0YSIsIkpTT04iLCJwYXJzZSIsImUiLCJlcnJvciIsImNvZGUiLCJwYXJ0aWFsUmVzcG9uc2UiLCJzdWJzdHJpbmciLCJzdWNjZXNzIiwiY3JlYXRlZEF0IiwidXBkYXRlZEF0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBRUE7O0FBRUE7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBTkE7QUFFQTtBQU1BLE1BQU1BLDBCQUEwQixHQUFHLFFBQW5DO0FBQ0EsTUFBTUMsVUFBVSxHQUFHO0FBQ2pCQyxFQUFBQSxJQUFJLEVBQUUsSUFBSUEsY0FBS0MsS0FBVCxDQUFlO0FBQUVDLElBQUFBLFNBQVMsRUFBRTtBQUFiLEdBQWYsQ0FEVztBQUVqQkMsRUFBQUEsS0FBSyxFQUFFLElBQUlBLGVBQU1GLEtBQVYsQ0FBZ0I7QUFBRUMsSUFBQUEsU0FBUyxFQUFFO0FBQWIsR0FBaEI7QUFGVSxDQUFuQjs7QUFLTyxNQUFNRSxlQUFOLENBQXNCO0FBSzNCQyxFQUFBQSxXQUFXLENBQUNDLGFBQUQsRUFBd0JDLGtCQUF4QixFQUE0Q0MsVUFBNUMsRUFBd0Q7QUFDakUsU0FBS0MsY0FBTCxHQUFzQkgsYUFBdEI7QUFDQSxTQUFLSSxXQUFMLEdBQW1CRixVQUFuQjtBQUNBLFNBQUtHLFFBQUwsR0FBZ0JKLGtCQUFoQjtBQUNEOztBQUVESyxFQUFBQSxJQUFJLEdBQUc7QUFDTCxXQUFPLEtBQUtDLFNBQUwsR0FBaUJDLElBQWpCLENBQXNCQyxLQUFLLElBQUk7QUFDcENBLE1BQUFBLEtBQUssR0FBR0EsS0FBSyxJQUFJLEVBQWpCO0FBQ0FBLE1BQUFBLEtBQUssQ0FBQ0MsT0FBTixDQUFjQyxJQUFJLElBQUk7QUFDcEIsYUFBS0MsaUJBQUwsQ0FBdUJELElBQXZCO0FBQ0QsT0FGRDtBQUdELEtBTE0sQ0FBUDtBQU1EOztBQUVERSxFQUFBQSxXQUFXLENBQUNDLFlBQUQsRUFBZTtB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RUpDLGNBQUFBLElBQUksRUFBRSxDQUFDLENBRkg7QUFHSkMsY0FBQUEsZUFBZSxFQUFFZCxJQUFJLENBQUNlLFNBQUwsQ0FBZSxDQUFmLEVBQWtCLEdBQWxCO0FBSGIsYUFBTjtBQUtEO0FBQ0Y7O0FBQ0QsWUFBSSxDQUFDUixHQUFMLEVBQVU7QUFDUnJDLFVBQUFBLE1BQU0sR0FBRzhCLElBQUksQ0FBQ2dCLE9BQWQ7QUFDQVQsVUFBQUEsR0FBRyxHQUFHUCxJQUFJLENBQUNZLEtBQVg7QUFDRDtBQUNGOztBQUNELFVBQUlMLEdBQUosRUFBUztBQUNQLGNBQU1BLEdBQU47QUFDRCxPQUZELE1BRU8sSUFBSXpELElBQUksQ0FBQ1MsV0FBTCxLQUFxQixZQUF6QixFQUF1QztBQUM1QyxZQUFJLE9BQU9XLE1BQVAsS0FBa0IsUUFBdEIsRUFBZ0M7QUFDOUIsaUJBQU9BLE1BQU0sQ0FBQytDLFNBQWQ7QUFDQSxpQkFBTy9DLE1BQU0sQ0FBQ2dELFNBQWQ7QUFDRDs7QUFDRCxlQUFPO0FBQUV2QixVQUFBQSxNQUFNLEVBQUV6QjtBQUFWLFNBQVA7QUFDRCxPQU5NLE1BTUE7QUFDTCxlQUFPQSxNQUFQO0FBQ0Q7QUFDRixLQWhDTSxDQUFQO0FBaUNELEdBL0REO0FBZ0VEOztlQUVjakMsZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBAZmxvdyB3ZWFrICovXG5cbmltcG9ydCAqIGFzIHRyaWdnZXJzIGZyb20gJy4uL3RyaWdnZXJzJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0ICogYXMgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCByZXF1ZXN0IGZyb20gJy4uL3JlcXVlc3QnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IGh0dHBzIGZyb20gJ2h0dHBzJztcblxuY29uc3QgRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUgPSAnX0hvb2tzJztcbmNvbnN0IEhUVFBBZ2VudHMgPSB7XG4gIGh0dHA6IG5ldyBodHRwLkFnZW50KHsga2VlcEFsaXZlOiB0cnVlIH0pLFxuICBodHRwczogbmV3IGh0dHBzLkFnZW50KHsga2VlcEFsaXZlOiB0cnVlIH0pLFxufTtcblxuZXhwb3J0IGNsYXNzIEhvb2tzQ29udHJvbGxlciB7XG4gIF9hcHBsaWNhdGlvbklkOiBzdHJpbmc7XG4gIF93ZWJob29rS2V5OiBzdHJpbmc7XG4gIGRhdGFiYXNlOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoYXBwbGljYXRpb25JZDogc3RyaW5nLCBkYXRhYmFzZUNvbnRyb2xsZXIsIHdlYmhvb2tLZXkpIHtcbiAgICB0aGlzLl9hcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZDtcbiAgICB0aGlzLl93ZWJob29rS2V5ID0gd2ViaG9va0tleTtcbiAgICB0aGlzLmRhdGFiYXNlID0gZGF0YWJhc2VDb250cm9sbGVyO1xuICB9XG5cbiAgbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3MoKS50aGVuKGhvb2tzID0+IHtcbiAgICAgIGhvb2tzID0gaG9va3MgfHwgW107XG4gICAgICBob29rcy5mb3JFYWNoKGhvb2sgPT4ge1xuICAgICAgICB0aGlzLmFkZEhvb2tUb1RyaWdnZXJzKGhvb2spO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRGdW5jdGlvbihmdW5jdGlvbk5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3MoeyBmdW5jdGlvbk5hbWU6IGZ1bmN0aW9uTmFtZSB9KS50aGVuKHJlc3VsdHMgPT4gcmVzdWx0c1swXSk7XG4gIH1cblxuICBnZXRGdW5jdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldEhvb2tzKHsgZnVuY3Rpb25OYW1lOiB7ICRleGlzdHM6IHRydWUgfSB9KTtcbiAgfVxuXG4gIGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyTmFtZSkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcyh7XG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyTmFtZSxcbiAgICB9KS50aGVuKHJlc3VsdHMgPT4gcmVzdWx0c1swXSk7XG4gIH1cblxuICBnZXRUcmlnZ2VycygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3Moe1xuICAgICAgY2xhc3NOYW1lOiB7ICRleGlzdHM6IHRydWUgfSxcbiAgICAgIHRyaWdnZXJOYW1lOiB7ICRleGlzdHM6IHRydWUgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGRlbGV0ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSkge1xuICAgIHRyaWdnZXJzLnJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgdGhpcy5fYXBwbGljYXRpb25JZCk7XG4gICAgcmV0dXJuIHRoaXMuX3JlbW92ZUhvb2tzKHsgZnVuY3Rpb25OYW1lOiBmdW5jdGlvbk5hbWUgfSk7XG4gIH1cblxuICBkZWxldGVUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlck5hbWUpIHtcbiAgICB0cmlnZ2Vycy5yZW1vdmVUcmlnZ2VyKHRyaWdnZXJOYW1lLCBjbGFzc05hbWUsIHRoaXMuX2FwcGxpY2F0aW9uSWQpO1xuICAgIHJldHVybiB0aGlzLl9yZW1vdmVIb29rcyh7XG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyTmFtZSxcbiAgICB9KTtcbiAgfVxuXG4gIF9nZXRIb29rcyhxdWVyeSA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UuZmluZChEZWZhdWx0SG9va3NDb2xsZWN0aW9uTmFtZSwgcXVlcnkpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXR1cm4gcmVzdWx0cy5tYXAocmVzdWx0ID0+IHtcbiAgICAgICAgZGVsZXRlIHJlc3VsdC5vYmplY3RJZDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3JlbW92ZUhvb2tzKHF1ZXJ5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UuZGVzdHJveShEZWZhdWx0SG9va3NDb2xsZWN0aW9uTmFtZSwgcXVlcnkpLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSk7XG4gIH1cblxuICBzYXZlSG9vayhob29rKSB7XG4gICAgdmFyIHF1ZXJ5O1xuICAgIGlmIChob29rLmZ1bmN0aW9uTmFtZSAmJiBob29rLnVybCkge1xuICAgICAgcXVlcnkgPSB7IGZ1bmN0aW9uTmFtZTogaG9vay5mdW5jdGlvbk5hbWUgfTtcbiAgICB9IGVsc2UgaWYgKGhvb2sudHJpZ2dlck5hbWUgJiYgaG9vay5jbGFzc05hbWUgJiYgaG9vay51cmwpIHtcbiAgICAgIHF1ZXJ5ID0geyBjbGFzc05hbWU6IGhvb2suY2xhc3NOYW1lLCB0cmlnZ2VyTmFtZTogaG9vay50cmlnZ2VyTmFtZSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlXG4gICAgICAudXBkYXRlKERlZmF1bHRIb29rc0NvbGxlY3Rpb25OYW1lLCBxdWVyeSwgaG9vaywgeyB1cHNlcnQ6IHRydWUgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShob29rKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgYWRkSG9va1RvVHJpZ2dlcnMoaG9vaykge1xuICAgIHZhciB3cmFwcGVkRnVuY3Rpb24gPSB3cmFwVG9IVFRQUmVxdWVzdChob29rLCB0aGlzLl93ZWJob29rS2V5KTtcbiAgICB3cmFwcGVkRnVuY3Rpb24udXJsID0gaG9vay51cmw7XG4gICAgaWYgKGhvb2suY2xhc3NOYW1lKSB7XG4gICAgICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKGhvb2sudHJpZ2dlck5hbWUsIGhvb2suY2xhc3NOYW1lLCB3cmFwcGVkRnVuY3Rpb24sIHRoaXMuX2FwcGxpY2F0aW9uSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmlnZ2Vycy5hZGRGdW5jdGlvbihob29rLmZ1bmN0aW9uTmFtZSwgd3JhcHBlZEZ1bmN0aW9uLCBudWxsLCB0aGlzLl9hcHBsaWNhdGlvbklkKTtcbiAgICB9XG4gIH1cblxuICBhZGRIb29rKGhvb2spIHtcbiAgICB0aGlzLmFkZEhvb2tUb1RyaWdnZXJzKGhvb2spO1xuICAgIHJldHVybiB0aGlzLnNhdmVIb29rKGhvb2spO1xuICB9XG5cbiAgY3JlYXRlT3JVcGRhdGVIb29rKGFIb29rKSB7XG4gICAgdmFyIGhvb2s7XG4gICAgaWYgKGFIb29rICYmIGFIb29rLmZ1bmN0aW9uTmFtZSAmJiBhSG9vay51cmwpIHtcbiAgICAgIGhvb2sgPSB7fTtcbiAgICAgIGhvb2suZnVuY3Rpb25OYW1lID0gYUhvb2suZnVuY3Rpb25OYW1lO1xuICAgICAgaG9vay51cmwgPSBhSG9vay51cmw7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGFIb29rICYmXG4gICAgICBhSG9vay5jbGFzc05hbWUgJiZcbiAgICAgIGFIb29rLnVybCAmJlxuICAgICAgYUhvb2sudHJpZ2dlck5hbWUgJiZcbiAgICAgIHRyaWdnZXJzLlR5cGVzW2FIb29rLnRyaWdnZXJOYW1lXVxuICAgICkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5jbGFzc05hbWUgPSBhSG9vay5jbGFzc05hbWU7XG4gICAgICBob29rLnVybCA9IGFIb29rLnVybDtcbiAgICAgIGhvb2sudHJpZ2dlck5hbWUgPSBhSG9vay50cmlnZ2VyTmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgJ2ludmFsaWQgaG9vayBkZWNsYXJhdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFkZEhvb2soaG9vayk7XG4gIH1cblxuICBjcmVhdGVIb29rKGFIb29rKSB7XG4gICAgaWYgKGFIb29rLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb24oYUhvb2suZnVuY3Rpb25OYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgZnVuY3Rpb24gbmFtZTogJHthSG9vay5mdW5jdGlvbk5hbWV9IGFscmVhZHkgZXhpdHNgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGFIb29rLmNsYXNzTmFtZSAmJiBhSG9vay50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHJpZ2dlcihhSG9vay5jbGFzc05hbWUsIGFIb29rLnRyaWdnZXJOYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAxNDMsXG4gICAgICAgICAgICBgY2xhc3MgJHthSG9vay5jbGFzc05hbWV9IGFscmVhZHkgaGFzIHRyaWdnZXIgJHthSG9vay50cmlnZ2VyTmFtZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgJ2ludmFsaWQgaG9vayBkZWNsYXJhdGlvbicpO1xuICB9XG5cbiAgdXBkYXRlSG9vayhhSG9vaykge1xuICAgIGlmIChhSG9vay5mdW5jdGlvbk5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEZ1bmN0aW9uKGFIb29rLmZ1bmN0aW9uTmFtZSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3JVcGRhdGVIb29rKGFIb29rKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgbm8gZnVuY3Rpb24gbmFtZWQ6ICR7YUhvb2suZnVuY3Rpb25OYW1lfSBpcyBkZWZpbmVkYCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGFIb29rLmNsYXNzTmFtZSAmJiBhSG9vay50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHJpZ2dlcihhSG9vay5jbGFzc05hbWUsIGFIb29rLnRyaWdnZXJOYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsIGBjbGFzcyAke2FIb29rLmNsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gd3JhcFRvSFRUUFJlcXVlc3QoaG9vaywga2V5KSB7XG4gIHJldHVybiByZXEgPT4ge1xuICAgIGNvbnN0IGpzb25Cb2R5ID0ge307XG4gICAgZm9yICh2YXIgaSBpbiByZXEpIHtcbiAgICAgIGpzb25Cb2R5W2ldID0gcmVxW2ldO1xuICAgIH1cbiAgICBpZiAocmVxLm9iamVjdCkge1xuICAgICAganNvbkJvZHkub2JqZWN0ID0gcmVxLm9iamVjdC50b0pTT04oKTtcbiAgICAgIGpzb25Cb2R5Lm9iamVjdC5jbGFzc05hbWUgPSByZXEub2JqZWN0LmNsYXNzTmFtZTtcbiAgICB9XG4gICAgaWYgKHJlcS5vcmlnaW5hbCkge1xuICAgICAganNvbkJvZHkub3JpZ2luYWwgPSByZXEub3JpZ2luYWwudG9KU09OKCk7XG4gICAgICBqc29uQm9keS5vcmlnaW5hbC5jbGFzc05hbWUgPSByZXEub3JpZ2luYWwuY2xhc3NOYW1lO1xuICAgIH1cbiAgICBjb25zdCBqc29uUmVxdWVzdDogYW55ID0ge1xuICAgICAgdXJsOiBob29rLnVybCxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBqc29uQm9keSxcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIH07XG5cbiAgICBjb25zdCBhZ2VudCA9IGhvb2sudXJsLnN0YXJ0c1dpdGgoJ2h0dHBzJykgPyBIVFRQQWdlbnRzWydodHRwcyddIDogSFRUUEFnZW50c1snaHR0cCddO1xuICAgIGpzb25SZXF1ZXN0LmFnZW50ID0gYWdlbnQ7XG5cbiAgICBpZiAoa2V5KSB7XG4gICAgICBqc29uUmVxdWVzdC5oZWFkZXJzWydYLVBhcnNlLVdlYmhvb2stS2V5J10gPSBrZXk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZ2dlci53YXJuKCdNYWtpbmcgb3V0Z29pbmcgd2ViaG9vayByZXF1ZXN0IHdpdGhvdXQgd2ViaG9va0tleSBiZWluZyBzZXQhJyk7XG4gICAgfVxuICAgIHJldHVybiByZXF1ZXN0KGpzb25SZXF1ZXN0KS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgIGxldCBlcnI7XG4gICAgICBsZXQgcmVzdWx0O1xuICAgICAgbGV0IGJvZHkgPSByZXNwb25zZS5kYXRhO1xuICAgICAgaWYgKGJvZHkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBlcnIgPSB7XG4gICAgICAgICAgICAgIGVycm9yOiAnTWFsZm9ybWVkIHJlc3BvbnNlJyxcbiAgICAgICAgICAgICAgY29kZTogLTEsXG4gICAgICAgICAgICAgIHBhcnRpYWxSZXNwb25zZTogYm9keS5zdWJzdHJpbmcoMCwgMTAwKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghZXJyKSB7XG4gICAgICAgICAgcmVzdWx0ID0gYm9keS5zdWNjZXNzO1xuICAgICAgICAgIGVyciA9IGJvZHkuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfSBlbHNlIGlmIChob29rLnRyaWdnZXJOYW1lID09PSAnYmVmb3JlU2F2ZScpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgZGVsZXRlIHJlc3VsdC5jcmVhdGVkQXQ7XG4gICAgICAgICAgZGVsZXRlIHJlc3VsdC51cGRhdGVkQXQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgb2JqZWN0OiByZXN1bHQgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IEhvb2tzQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/LiveQueryController.js b/lib/Controllers/LiveQueryController.js new file mode 100644 index 0000000000..208a38083c --- /dev/null +++ b/lib/Controllers/LiveQueryController.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LiveQueryController = void 0; + +var _ParseCloudCodePublisher = require("../LiveQuery/ParseCloudCodePublisher"); + +var _Options = require("../Options"); + +class LiveQueryController { + constructor(config) { + // If config is empty, we just assume no classs needs to be registered as LiveQuery + if (!config || !config.classNames) { + this.classNames = new Set(); + } else if (config.classNames instanceof Array) { + this.classNames = new Set(config.classNames); + } else { + throw 'liveQuery.classes should be an array of string'; + } + + this.liveQueryPublisher = new _ParseCloudCodePublisher.ParseCloudCodePublisher(config); + } + + onAfterSave(className, currentObject, originalObject, classLevelPermissions) { + if (!this.hasLiveQuery(className)) { + return; + } + + const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); + + this.liveQueryPublisher.onCloudCodeAfterSave(req); + } + + onAfterDelete(className, currentObject, originalObject, classLevelPermissions) { + if (!this.hasLiveQuery(className)) { + return; + } + + const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); + + this.liveQueryPublisher.onCloudCodeAfterDelete(req); + } + + hasLiveQuery(className) { + return this.classNames.has(className); + } + + _makePublisherRequest(currentObject, originalObject, classLevelPermissions) { + const req = { + object: currentObject + }; + + if (currentObject) { + req.original = originalObject; + } + + if (classLevelPermissions) { + req.classLevelPermissions = classLevelPermissions; + } + + return req; + } + +} + +exports.LiveQueryController = LiveQueryController; +var _default = LiveQueryController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9MaXZlUXVlcnlDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkxpdmVRdWVyeUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNsYXNzTmFtZXMiLCJTZXQiLCJBcnJheSIsImxpdmVRdWVyeVB1Ymxpc2hlciIsIlBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyIiwib25BZnRlclNhdmUiLCJjbGFzc05hbWUiLCJjdXJyZW50T2JqZWN0Iiwib3JpZ2luYWxPYmplY3QiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJoYXNMaXZlUXVlcnkiLCJyZXEiLCJfbWFrZVB1Ymxpc2hlclJlcXVlc3QiLCJvbkNsb3VkQ29kZUFmdGVyU2F2ZSIsIm9uQWZ0ZXJEZWxldGUiLCJvbkNsb3VkQ29kZUFmdGVyRGVsZXRlIiwiaGFzIiwib2JqZWN0Iiwib3JpZ2luYWwiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDTyxNQUFNQSxtQkFBTixDQUEwQjtBQUkvQkMsRUFBQUEsV0FBVyxDQUFDQyxNQUFELEVBQTRCO0FBQ3JDO0FBQ0EsUUFBSSxDQUFDQSxNQUFELElBQVcsQ0FBQ0EsTUFBTSxDQUFDQyxVQUF2QixFQUFtQztBQUNqQyxXQUFLQSxVQUFMLEdBQWtCLElBQUlDLEdBQUosRUFBbEI7QUFDRCxLQUZELE1BRU8sSUFBSUYsTUFBTSxDQUFDQyxVQUFQLFlBQTZCRSxLQUFqQyxFQUF3QztBQUM3QyxXQUFLRixVQUFMLEdBQWtCLElBQUlDLEdBQUosQ0FBUUYsTUFBTSxDQUFDQyxVQUFmLENBQWxCO0FBQ0QsS0FGTSxNQUVBO0FBQ0wsWUFBTSxnREFBTjtBQUNEOztBQUNELFNBQUtHLGtCQUFMLEdBQTBCLElBQUlDLGdEQUFKLENBQTRCTCxNQUE1QixDQUExQjtBQUNEOztBQUVETSxFQUFBQSxXQUFXLENBQ1RDLFNBRFMsRUFFVEMsYUFGUyxFQUdUQyxjQUhTLEVBSVRDLHFCQUpTLEVBS1Q7QUFDQSxRQUFJLENBQUMsS0FBS0MsWUFBTCxDQUFrQkosU0FBbEIsQ0FBTCxFQUFtQztBQUNqQztBQUNEOztBQUNELFVBQU1LLEdBQUcsR0FBRyxLQUFLQyxxQkFBTCxDQUEyQkwsYUFBM0IsRUFBMENDLGNBQTFDLEVBQTBEQyxxQkFBMUQsQ0FBWjs7QUFDQSxTQUFLTixrQkFBTCxDQUF3QlUsb0JBQXhCLENBQTZDRixHQUE3QztBQUNEOztBQUVERyxFQUFBQSxhQUFhLENBQ1hSLFNBRFcsRUFFWEMsYUFGVyxFQUdYQyxjQUhXLEVBSVhDLHFCQUpXLEVBS1g7QUFDQSxRQUFJLENBQUMsS0FBS0MsWUFBTCxDQUFrQkosU0FBbEIsQ0FBTCxFQUFtQztBQUNqQztBQUNEOztBQUNELFVBQU1LLEdBQUcsR0FBRyxLQUFLQyxxQkFBTCxDQUEyQkwsYUFBM0IsRUFBMENDLGNBQTFDLEVBQTBEQyxxQkFBMUQsQ0FBWjs7QUFDQSxTQUFLTixrQkFBTCxDQUF3Qlksc0JBQXhCLENBQStDSixHQUEvQztBQUNEOztBQUVERCxFQUFBQSxZQUFZLENBQUNKLFNBQUQsRUFBNkI7QUFDdkMsV0FBTyxLQUFLTixVQUFMLENBQWdCZ0IsR0FBaEIsQ0FBb0JWLFNBQXBCLENBQVA7QUFDRDs7QUFFRE0sRUFBQUEscUJBQXFCLENBQUNMLGFBQUQsRUFBcUJDLGNBQXJCLEVBQTBDQyxxQkFBMUMsRUFBNEU7QUFDL0YsVUFBTUUsR0FBRyxHQUFHO0FBQ1ZNLE1BQUFBLE1BQU0sRUFBRVY7QUFERSxLQUFaOztBQUdBLFFBQUlBLGFBQUosRUFBbUI7QUFDakJJLE1BQUFBLEdBQUcsQ0FBQ08sUUFBSixHQUFlVixjQUFmO0FBQ0Q7O0FBQ0QsUUFBSUMscUJBQUosRUFBMkI7QUFDekJFLE1BQUFBLEdBQUcsQ0FBQ0YscUJBQUosR0FBNEJBLHFCQUE1QjtBQUNEOztBQUNELFdBQU9FLEdBQVA7QUFDRDs7QUF6RDhCOzs7ZUE0RGxCZCxtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyIH0gZnJvbSAnLi4vTGl2ZVF1ZXJ5L1BhcnNlQ2xvdWRDb2RlUHVibGlzaGVyJztcbmltcG9ydCB7IExpdmVRdWVyeU9wdGlvbnMgfSBmcm9tICcuLi9PcHRpb25zJztcbmV4cG9ydCBjbGFzcyBMaXZlUXVlcnlDb250cm9sbGVyIHtcbiAgY2xhc3NOYW1lczogYW55O1xuICBsaXZlUXVlcnlQdWJsaXNoZXI6IGFueTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6ID9MaXZlUXVlcnlPcHRpb25zKSB7XG4gICAgLy8gSWYgY29uZmlnIGlzIGVtcHR5LCB3ZSBqdXN0IGFzc3VtZSBubyBjbGFzc3MgbmVlZHMgdG8gYmUgcmVnaXN0ZXJlZCBhcyBMaXZlUXVlcnlcbiAgICBpZiAoIWNvbmZpZyB8fCAhY29uZmlnLmNsYXNzTmFtZXMpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IG5ldyBTZXQoKTtcbiAgICB9IGVsc2UgaWYgKGNvbmZpZy5jbGFzc05hbWVzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IG5ldyBTZXQoY29uZmlnLmNsYXNzTmFtZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyAnbGl2ZVF1ZXJ5LmNsYXNzZXMgc2hvdWxkIGJlIGFuIGFycmF5IG9mIHN0cmluZyc7XG4gICAgfVxuICAgIHRoaXMubGl2ZVF1ZXJ5UHVibGlzaGVyID0gbmV3IFBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyKGNvbmZpZyk7XG4gIH1cblxuICBvbkFmdGVyU2F2ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBjdXJyZW50T2JqZWN0OiBhbnksXG4gICAgb3JpZ2luYWxPYmplY3Q6IGFueSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6ID9hbnlcbiAgKSB7XG4gICAgaWYgKCF0aGlzLmhhc0xpdmVRdWVyeShjbGFzc05hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlcSA9IHRoaXMuX21ha2VQdWJsaXNoZXJSZXF1ZXN0KGN1cnJlbnRPYmplY3QsIG9yaWdpbmFsT2JqZWN0LCBjbGFzc0xldmVsUGVybWlzc2lvbnMpO1xuICAgIHRoaXMubGl2ZVF1ZXJ5UHVibGlzaGVyLm9uQ2xvdWRDb2RlQWZ0ZXJTYXZlKHJlcSk7XG4gIH1cblxuICBvbkFmdGVyRGVsZXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGN1cnJlbnRPYmplY3Q6IGFueSxcbiAgICBvcmlnaW5hbE9iamVjdDogYW55LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55XG4gICkge1xuICAgIGlmICghdGhpcy5oYXNMaXZlUXVlcnkoY2xhc3NOYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXEgPSB0aGlzLl9tYWtlUHVibGlzaGVyUmVxdWVzdChjdXJyZW50T2JqZWN0LCBvcmlnaW5hbE9iamVjdCwgY2xhc3NMZXZlbFBlcm1pc3Npb25zKTtcbiAgICB0aGlzLmxpdmVRdWVyeVB1Ymxpc2hlci5vbkNsb3VkQ29kZUFmdGVyRGVsZXRlKHJlcSk7XG4gIH1cblxuICBoYXNMaXZlUXVlcnkoY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jbGFzc05hbWVzLmhhcyhjbGFzc05hbWUpO1xuICB9XG5cbiAgX21ha2VQdWJsaXNoZXJSZXF1ZXN0KGN1cnJlbnRPYmplY3Q6IGFueSwgb3JpZ2luYWxPYmplY3Q6IGFueSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55KTogYW55IHtcbiAgICBjb25zdCByZXEgPSB7XG4gICAgICBvYmplY3Q6IGN1cnJlbnRPYmplY3QsXG4gICAgfTtcbiAgICBpZiAoY3VycmVudE9iamVjdCkge1xuICAgICAgcmVxLm9yaWdpbmFsID0gb3JpZ2luYWxPYmplY3Q7XG4gICAgfVxuICAgIGlmIChjbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICAgIHJlcS5jbGFzc0xldmVsUGVybWlzc2lvbnMgPSBjbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgfVxuICAgIHJldHVybiByZXE7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTGl2ZVF1ZXJ5Q29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/LoggerController.js b/lib/Controllers/LoggerController.js new file mode 100644 index 0000000000..be11d8877f --- /dev/null +++ b/lib/Controllers/LoggerController.js @@ -0,0 +1,265 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LoggerController = exports.LogOrder = exports.LogLevel = void 0; + +var _node = require("parse/node"); + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); + +var _url = _interopRequireDefault(require("url")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; +const LOG_STRING_TRUNCATE_LENGTH = 1000; +const truncationMarker = '... (truncated)'; +const LogLevel = { + INFO: 'info', + ERROR: 'error' +}; +exports.LogLevel = LogLevel; +const LogOrder = { + DESCENDING: 'desc', + ASCENDING: 'asc' +}; +exports.LogOrder = LogOrder; +const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly']; + +class LoggerController extends _AdaptableController.default { + constructor(adapter, appId, options = { + logLevel: 'info' + }) { + super(adapter, appId, options); + let level = 'info'; + + if (options.verbose) { + level = 'verbose'; + } + + if (options.logLevel) { + level = options.logLevel; + } + + const index = logLevels.indexOf(level); // info by default + + logLevels.forEach((level, levelIndex) => { + if (levelIndex > index) { + // silence the levels that are > maxIndex + this[level] = () => {}; + } + }); + } + + maskSensitiveUrl(urlString) { + const urlObj = _url.default.parse(urlString, true); + + const query = urlObj.query; + let sanitizedQuery = '?'; + + for (const key in query) { + if (key !== 'password') { + // normal value + sanitizedQuery += key + '=' + query[key] + '&'; + } else { + // password value, redact it + sanitizedQuery += key + '=' + '********' + '&'; + } + } // trim last character, ? or & + + + sanitizedQuery = sanitizedQuery.slice(0, -1); // return original path name with sanitized params attached + + return urlObj.pathname + sanitizedQuery; + } + + maskSensitive(argArray) { + return argArray.map(e => { + if (!e) { + return e; + } + + if (typeof e === 'string') { + return e.replace(/(password".?:.?")[^"]*"/g, '$1********"'); + } // else it is an object... + // check the url + + + if (e.url) { + // for strings + if (typeof e.url === 'string') { + e.url = this.maskSensitiveUrl(e.url); + } else if (Array.isArray(e.url)) { + // for strings in array + e.url = e.url.map(item => { + if (typeof item === 'string') { + return this.maskSensitiveUrl(item); + } + + return item; + }); + } + } + + if (e.body) { + for (const key of Object.keys(e.body)) { + if (key === 'password') { + e.body[key] = '********'; + break; + } + } + } + + if (e.params) { + for (const key of Object.keys(e.params)) { + if (key === 'password') { + e.params[key] = '********'; + break; + } + } + } + + return e; + }); + } + + log(level, args) { + // make the passed in arguments object an array with the spread operator + args = this.maskSensitive([...args]); + args = [].concat(level, args.map(arg => { + if (typeof arg === 'function') { + return arg(); + } + + return arg; + })); + this.adapter.log.apply(this.adapter, args); + } + + info() { + return this.log('info', arguments); + } + + error() { + return this.log('error', arguments); + } + + warn() { + return this.log('warn', arguments); + } + + verbose() { + return this.log('verbose', arguments); + } + + debug() { + return this.log('debug', arguments); + } + + silly() { + return this.log('silly', arguments); + } + + logRequest({ + method, + url, + headers, + body + }) { + this.verbose(() => { + const stringifiedBody = JSON.stringify(body, null, 2); + return `REQUEST for [${method}] ${url}: ${stringifiedBody}`; + }, { + method, + url, + headers, + body + }); + } + + logResponse({ + method, + url, + result + }) { + this.verbose(() => { + const stringifiedResponse = JSON.stringify(result, null, 2); + return `RESPONSE from [${method}] ${url}: ${stringifiedResponse}`; + }, { + result: result + }); + } // check that date input is valid + + + static validDateTime(date) { + if (!date) { + return null; + } + + date = new Date(date); + + if (!isNaN(date.getTime())) { + return date; + } + + return null; + } + + truncateLogMessage(string) { + if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) { + const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker; + return truncated; + } + + return string; + } + + static parseOptions(options = {}) { + const from = LoggerController.validDateTime(options.from) || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); + const until = LoggerController.validDateTime(options.until) || new Date(); + const size = Number(options.size) || 10; + const order = options.order || LogOrder.DESCENDING; + const level = options.level || LogLevel.INFO; + return { + from, + until, + size, + order, + level + }; + } // Returns a promise for a {response} object. + // query params: + // level (optional) Level of logging you want to query for (info || error) + // from (optional) Start time for the search. Defaults to 1 week ago. + // until (optional) End time for the search. Defaults to current time. + // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. + // size (optional) Number of rows returned by search. Defaults to 10 + + + getLogs(options = {}) { + if (!this.adapter) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); + } + + if (typeof this.adapter.query !== 'function') { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Querying logs is not supported with this adapter'); + } + + options = LoggerController.parseOptions(options); + return this.adapter.query(options); + } + + expectedAdapterType() { + return _LoggerAdapter.LoggerAdapter; + } + +} + +exports.LoggerController = LoggerController; +var _default = LoggerController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Mb2dnZXJDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIk1JTExJU0VDT05EU19JTl9BX0RBWSIsIkxPR19TVFJJTkdfVFJVTkNBVEVfTEVOR1RIIiwidHJ1bmNhdGlvbk1hcmtlciIsIkxvZ0xldmVsIiwiSU5GTyIsIkVSUk9SIiwiTG9nT3JkZXIiLCJERVNDRU5ESU5HIiwiQVNDRU5ESU5HIiwibG9nTGV2ZWxzIiwiTG9nZ2VyQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJhcHBJZCIsIm9wdGlvbnMiLCJsb2dMZXZlbCIsImxldmVsIiwidmVyYm9zZSIsImluZGV4IiwiaW5kZXhPZiIsImZvckVhY2giLCJsZXZlbEluZGV4IiwibWFza1NlbnNpdGl2ZVVybCIsInVybFN0cmluZyIsInVybE9iaiIsInVybCIsInBhcnNlIiwicXVlcnkiLCJzYW5pdGl6ZWRRdWVyeSIsImtleSIsInNsaWNlIiwicGF0aG5hbWUiLCJtYXNrU2Vuc2l0aXZlIiwiYXJnQXJyYXkiLCJtYXAiLCJlIiwicmVwbGFjZSIsIkFycmF5IiwiaXNBcnJheSIsIml0ZW0iLCJib2R5IiwiT2JqZWN0Iiwia2V5cyIsInBhcmFtcyIsImxvZyIsImFyZ3MiLCJjb25jYXQiLCJhcmciLCJhcHBseSIsImluZm8iLCJhcmd1bWVudHMiLCJlcnJvciIsIndhcm4iLCJkZWJ1ZyIsInNpbGx5IiwibG9nUmVxdWVzdCIsIm1ldGhvZCIsImhlYWRlcnMiLCJzdHJpbmdpZmllZEJvZHkiLCJKU09OIiwic3RyaW5naWZ5IiwibG9nUmVzcG9uc2UiLCJyZXN1bHQiLCJzdHJpbmdpZmllZFJlc3BvbnNlIiwidmFsaWREYXRlVGltZSIsImRhdGUiLCJEYXRlIiwiaXNOYU4iLCJnZXRUaW1lIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwic3RyaW5nIiwibGVuZ3RoIiwidHJ1bmNhdGVkIiwic3Vic3RyaW5nIiwicGFyc2VPcHRpb25zIiwiZnJvbSIsIm5vdyIsInVudGlsIiwic2l6ZSIsIk51bWJlciIsIm9yZGVyIiwiZ2V0TG9ncyIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJleHBlY3RlZEFkYXB0ZXJUeXBlIiwiTG9nZ2VyQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEscUJBQXFCLEdBQUcsS0FBSyxFQUFMLEdBQVUsRUFBVixHQUFlLElBQTdDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQUcsSUFBbkM7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxpQkFBekI7QUFFTyxNQUFNQyxRQUFRLEdBQUc7QUFDdEJDLEVBQUFBLElBQUksRUFBRSxNQURnQjtBQUV0QkMsRUFBQUEsS0FBSyxFQUFFO0FBRmUsQ0FBakI7O0FBS0EsTUFBTUMsUUFBUSxHQUFHO0FBQ3RCQyxFQUFBQSxVQUFVLEVBQUUsTUFEVTtBQUV0QkMsRUFBQUEsU0FBUyxFQUFFO0FBRlcsQ0FBakI7O0FBS1AsTUFBTUMsU0FBUyxHQUFHLENBQUMsT0FBRCxFQUFVLE1BQVYsRUFBa0IsTUFBbEIsRUFBMEIsT0FBMUIsRUFBbUMsU0FBbkMsRUFBOEMsT0FBOUMsQ0FBbEI7O0FBRU8sTUFBTUMsZ0JBQU4sU0FBK0JDLDRCQUEvQixDQUFtRDtBQUN4REMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQU8sR0FBRztBQUFFQyxJQUFBQSxRQUFRLEVBQUU7QUFBWixHQUEzQixFQUFpRDtBQUMxRCxVQUFNSCxPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0EsUUFBSUUsS0FBSyxHQUFHLE1BQVo7O0FBQ0EsUUFBSUYsT0FBTyxDQUFDRyxPQUFaLEVBQXFCO0FBQ25CRCxNQUFBQSxLQUFLLEdBQUcsU0FBUjtBQUNEOztBQUNELFFBQUlGLE9BQU8sQ0FBQ0MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsS0FBSyxHQUFHRixPQUFPLENBQUND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LEtBSks7QUFLTGhFLE1BQUFBO0FBTEssS0FBUDtBQU9ELEdBak11RCxDQW1NeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBaUUsRUFBQUEsT0FBTyxDQUFDbkUsT0FBTyxHQUFHLEVBQVgsRUFBZTtBQUNwQixRQUFJLENBQUMsS0FBS0YsT0FBVixFQUFtQjtBQUNqQixZQUFNLElBQUlzRSxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEOztBQUNELFFBQUksT0FBTyxLQUFLeEUsT0FBTCxDQUFhZSxLQUFwQixLQUE4QixVQUFsQyxFQUE4QztBQUM1QyxZQUFNLElBQUl1RCxZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUMsa0JBRFIsRUFFSixrREFGSSxDQUFOO0FBSUQ7O0FBQ0R0RSxJQUFBQSxPQUFPLEdBQUdMLGdCQUFnQixDQUFDaUUsWUFBakIsQ0FBOEI1RCxPQUE5QixDQUFWO0FBQ0EsV0FBTyxLQUFLRixPQUFMLENBQWFlLEtBQWIsQ0FBbUJiLE9BQW5CLENBQVA7QUFDRDs7QUFFRHVFLEVBQUFBLG1CQUFtQixHQUFHO0FBQ3BCLFdBQU9DLDRCQUFQO0FBQ0Q7O0FBMU51RDs7O2VBNk4zQzdFLGdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgeyBMb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvTG9nZ2VyL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuXG5jb25zdCBNSUxMSVNFQ09ORFNfSU5fQV9EQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuY29uc3QgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEggPSAxMDAwO1xuY29uc3QgdHJ1bmNhdGlvbk1hcmtlciA9ICcuLi4gKHRydW5jYXRlZCknO1xuXG5leHBvcnQgY29uc3QgTG9nTGV2ZWwgPSB7XG4gIElORk86ICdpbmZvJyxcbiAgRVJST1I6ICdlcnJvcicsXG59O1xuXG5leHBvcnQgY29uc3QgTG9nT3JkZXIgPSB7XG4gIERFU0NFTkRJTkc6ICdkZXNjJyxcbiAgQVNDRU5ESU5HOiAnYXNjJyxcbn07XG5cbmNvbnN0IGxvZ0xldmVscyA9IFsnZXJyb3InLCAnd2FybicsICdpbmZvJywgJ2RlYnVnJywgJ3ZlcmJvc2UnLCAnc2lsbHknXTtcblxuZXhwb3J0IGNsYXNzIExvZ2dlckNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7IGxvZ0xldmVsOiAnaW5mbycgfSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcbiAgICBsZXQgbGV2ZWwgPSAnaW5mbyc7XG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgbGV2ZWwgPSAndmVyYm9zZSc7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxvZ0xldmVsKSB7XG4gICAgICBsZXZlbCA9IG9wdGlvbnMubG9nTGV2ZWw7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gbG9nTGV2ZWxzLmluZGV4T2YobGV2ZWwpOyAvLyBpbmZvIGJ5IGRlZmF1bHRcbiAgICBsb2dMZXZlbHMuZm9yRWFjaCgobGV2ZWwsIGxldmVsSW5kZXgpID0+IHtcbiAgICAgIGlmIChsZXZlbEluZGV4ID4gaW5kZXgpIHtcbiAgICAgICAgLy8gc2lsZW5jZSB0aGUgbGV2ZWxzIHRoYXQgYXJlID4gbWF4SW5kZXhcbiAgICAgICAgdGhpc1tsZXZlbF0gPSAoKSA9PiB7fTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmVVcmwodXJsU3RyaW5nKSB7XG4gICAgY29uc3QgdXJsT2JqID0gdXJsLnBhcnNlKHVybFN0cmluZywgdHJ1ZSk7XG4gICAgY29uc3QgcXVlcnkgPSB1cmxPYmoucXVlcnk7XG4gICAgbGV0IHNhbml0aXplZFF1ZXJ5ID0gJz8nO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcXVlcnkpIHtcbiAgICAgIGlmIChrZXkgIT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgLy8gbm9ybWFsIHZhbHVlXG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArIHF1ZXJ5W2tleV0gKyAnJic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXNzd29yZCB2YWx1ZSwgcmVkYWN0IGl0XG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArICcqKioqKioqKicgKyAnJic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHJpbSBsYXN0IGNoYXJhY3RlciwgPyBvciAmXG4gICAgc2FuaXRpemVkUXVlcnkgPSBzYW5pdGl6ZWRRdWVyeS5zbGljZSgwLCAtMSk7XG5cbiAgICAvLyByZXR1cm4gb3JpZ2luYWwgcGF0aCBuYW1lIHdpdGggc2FuaXRpemVkIHBhcmFtcyBhdHRhY2hlZFxuICAgIHJldHVybiB1cmxPYmoucGF0aG5hbWUgKyBzYW5pdGl6ZWRRdWVyeTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmUoYXJnQXJyYXkpIHtcbiAgICByZXR1cm4gYXJnQXJyYXkubWFwKGUgPT4ge1xuICAgICAgaWYgKCFlKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBlLnJlcGxhY2UoLyhwYXNzd29yZFwiLj86Lj9cIilbXlwiXSpcIi9nLCAnJDEqKioqKioqKlwiJyk7XG4gICAgICB9XG4gICAgICAvLyBlbHNlIGl0IGlzIGFuIG9iamVjdC4uLlxuXG4gICAgICAvLyBjaGVjayB0aGUgdXJsXG4gICAgICBpZiAoZS51cmwpIHtcbiAgICAgICAgLy8gZm9yIHN0cmluZ3NcbiAgICAgICAgaWYgKHR5cGVvZiBlLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBlLnVybCA9IHRoaXMubWFza1NlbnNpdGl2ZVVybChlLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShlLnVybCkpIHtcbiAgICAgICAgICAvLyBmb3Igc3RyaW5ncyBpbiBhcnJheVxuICAgICAgICAgIGUudXJsID0gZS51cmwubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXNrU2Vuc2l0aXZlVXJsKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5ib2R5KSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUuYm9keSkpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgICAgICBlLmJvZHlba2V5XSA9ICcqKioqKioqKic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUucGFyYW1zKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUucGFyYW1zKSkge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICAgIGUucGFyYW1zW2tleV0gPSAnKioqKioqKionO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlO1xuICAgIH0pO1xuICB9XG5cbiAgbG9nKGxldmVsLCBhcmdzKSB7XG4gICAgLy8gbWFrZSB0aGUgcGFzc2VkIGluIGFyZ3VtZW50cyBvYmplY3QgYW4gYXJyYXkgd2l0aCB0aGUgc3ByZWFkIG9wZXJhdG9yXG4gICAgYXJncyA9IHRoaXMubWFza1NlbnNpdGl2ZShbLi4uYXJnc10pO1xuICAgIGFyZ3MgPSBbXS5jb25jYXQoXG4gICAgICBsZXZlbCxcbiAgICAgIGFyZ3MubWFwKGFyZyA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcmc7XG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hZGFwdGVyLmxvZy5hcHBseSh0aGlzLmFkYXB0ZXIsIGFyZ3MpO1xuICB9XG5cbiAgaW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2luZm8nLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCdlcnJvcicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB3YXJuKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnd2FybicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB2ZXJib3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygndmVyYm9zZScsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBkZWJ1ZygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2RlYnVnJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHNpbGx5KCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnc2lsbHknLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgbG9nUmVxdWVzdCh7IG1ldGhvZCwgdXJsLCBoZWFkZXJzLCBib2R5IH0pIHtcbiAgICB0aGlzLnZlcmJvc2UoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ2lmaWVkQm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHksIG51bGwsIDIpO1xuICAgICAgICByZXR1cm4gYFJFUVVFU1QgZm9yIFske21ldGhvZH1dICR7dXJsfTogJHtzdHJpbmdpZmllZEJvZHl9YDtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBsb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSkge1xuICAgIHRoaXMudmVyYm9zZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RyaW5naWZpZWRSZXNwb25zZSA9IEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMik7XG4gICAgICAgIHJldHVybiBgUkVTUE9OU0UgZnJvbSBbJHttZXRob2R9XSAke3VybH06ICR7c3RyaW5naWZpZWRSZXNwb25zZX1gO1xuICAgICAgfSxcbiAgICAgIHsgcmVzdWx0OiByZXN1bHQgfVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgdGhhdCBkYXRlIGlucHV0IGlzIHZhbGlkXG4gIHN0YXRpYyB2YWxpZERhdGVUaW1lKGRhdGUpIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICBpZiAoIWlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnVuY2F0ZUxvZ01lc3NhZ2Uoc3RyaW5nKSB7XG4gICAgaWYgKHN0cmluZyAmJiBzdHJpbmcubGVuZ3RoID4gTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHRydW5jYXRlZCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpICsgdHJ1bmNhdGlvbk1hcmtlcjtcbiAgICAgIHJldHVybiB0cnVuY2F0ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0cmluZztcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBMb2dnZXJDb250cm9sbGVyLnZhbGlkRGF0ZVRpbWUob3B0aW9ucy5mcm9tKSB8fFxuICAgICAgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gTG9nZ2VyQ29udHJvbGxlci52YWxpZERhdGVUaW1lKG9wdGlvbnMudW50aWwpIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgc2l6ZSA9IE51bWJlcihvcHRpb25zLnNpemUpIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCBMb2dPcmRlci5ERVNDRU5ESU5HO1xuICAgIGNvbnN0IGxldmVsID0gb3B0aW9ucy5sZXZlbCB8fCBMb2dMZXZlbC5JTkZPO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbiAgLy8gcXVlcnkgcGFyYW1zOlxuICAvLyBsZXZlbCAob3B0aW9uYWwpIExldmVsIG9mIGxvZ2dpbmcgeW91IHdhbnQgdG8gcXVlcnkgZm9yIChpbmZvIHx8IGVycm9yKVxuICAvLyBmcm9tIChvcHRpb25hbCkgU3RhcnQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gMSB3ZWVrIGFnby5cbiAgLy8gdW50aWwgKG9wdGlvbmFsKSBFbmQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gY3VycmVudCB0aW1lLlxuICAvLyBvcmRlciAob3B0aW9uYWwpIERpcmVjdGlvbiBvZiByZXN1bHRzIHJldHVybmVkLCBlaXRoZXIg4oCcYXNj4oCdIG9yIOKAnGRlc2PigJ0uIERlZmF1bHRzIHRvIOKAnGRlc2PigJ0uXG4gIC8vIHNpemUgKG9wdGlvbmFsKSBOdW1iZXIgb2Ygcm93cyByZXR1cm5lZCBieSBzZWFyY2guIERlZmF1bHRzIHRvIDEwXG4gIGdldExvZ3Mob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdMb2dnZXIgYWRhcHRlciBpcyBub3QgYXZhaWxhYmxlJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnF1ZXJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1F1ZXJ5aW5nIGxvZ3MgaXMgbm90IHN1cHBvcnRlZCB3aXRoIHRoaXMgYWRhcHRlcidcbiAgICAgICk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBMb2dnZXJDb250cm9sbGVyLnBhcnNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnF1ZXJ5KG9wdGlvbnMpO1xuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gTG9nZ2VyQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dnZXJDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/ParseGraphQLController.js b/lib/Controllers/ParseGraphQLController.js new file mode 100644 index 0000000000..14da8815ed --- /dev/null +++ b/lib/Controllers/ParseGraphQLController.js @@ -0,0 +1,358 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.GraphQLConfigKey = exports.GraphQLConfigId = exports.GraphQLConfigClassName = exports.default = void 0; + +var _requiredParameter = _interopRequireDefault(require("../../lib/requiredParameter")); + +var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); + +var _CacheController = _interopRequireDefault(require("./CacheController")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const GraphQLConfigClassName = '_GraphQLConfig'; +exports.GraphQLConfigClassName = GraphQLConfigClassName; +const GraphQLConfigId = '1'; +exports.GraphQLConfigId = GraphQLConfigId; +const GraphQLConfigKey = 'config'; +exports.GraphQLConfigKey = GraphQLConfigKey; + +class ParseGraphQLController { + constructor(params = {}) { + this.databaseController = params.databaseController || (0, _requiredParameter.default)(`ParseGraphQLController requires a "databaseController" to be instantiated.`); + this.cacheController = params.cacheController; + this.isMounted = !!params.mountGraphQL; + this.configCacheKey = GraphQLConfigKey; + } + + async getGraphQLConfig() { + if (this.isMounted) { + const _cachedConfig = await this._getCachedGraphQLConfig(); + + if (_cachedConfig) { + return _cachedConfig; + } + } + + const results = await this.databaseController.find(GraphQLConfigClassName, { + objectId: GraphQLConfigId + }, { + limit: 1 + }); + let graphQLConfig; + + if (results.length != 1) { + // If there is no config in the database - return empty config. + return {}; + } else { + graphQLConfig = results[0][GraphQLConfigKey]; + } + + if (this.isMounted) { + this._putCachedGraphQLConfig(graphQLConfig); + } + + return graphQLConfig; + } + + async updateGraphQLConfig(graphQLConfig) { + // throws if invalid + this._validateGraphQLConfig(graphQLConfig || (0, _requiredParameter.default)('You must provide a graphQLConfig!')); // Transform in dot notation to make sure it works + + + const update = Object.keys(graphQLConfig).reduce((acc, key) => { + return { + [GraphQLConfigKey]: _objectSpread(_objectSpread({}, acc[GraphQLConfigKey]), {}, { + [key]: graphQLConfig[key] + }) + }; + }, { + [GraphQLConfigKey]: {} + }); + await this.databaseController.update(GraphQLConfigClassName, { + objectId: GraphQLConfigId + }, update, { + upsert: true + }); + + if (this.isMounted) { + this._putCachedGraphQLConfig(graphQLConfig); + } + + return { + response: { + result: true + } + }; + } + + _getCachedGraphQLConfig() { + return this.cacheController.graphQL.get(this.configCacheKey); + } + + _putCachedGraphQLConfig(graphQLConfig) { + return this.cacheController.graphQL.put(this.configCacheKey, graphQLConfig, 60000); + } + + _validateGraphQLConfig(graphQLConfig) { + const errorMessages = []; + + if (!graphQLConfig) { + errorMessages.push('cannot be undefined, null or empty'); + } else if (!isValidSimpleObject(graphQLConfig)) { + errorMessages.push('must be a valid object'); + } else { + const { + enabledForClasses = null, + disabledForClasses = null, + classConfigs = null + } = graphQLConfig, + invalidKeys = _objectWithoutProperties(graphQLConfig, ["enabledForClasses", "disabledForClasses", "classConfigs"]); + + if (Object.keys(invalidKeys).length) { + errorMessages.push(`encountered invalid keys: [${Object.keys(invalidKeys)}]`); + } + + if (enabledForClasses !== null && !isValidStringArray(enabledForClasses)) { + errorMessages.push(`"enabledForClasses" is not a valid array`); + } + + if (disabledForClasses !== null && !isValidStringArray(disabledForClasses)) { + errorMessages.push(`"disabledForClasses" is not a valid array`); + } + + if (classConfigs !== null) { + if (Array.isArray(classConfigs)) { + classConfigs.forEach(classConfig => { + const errorMessage = this._validateClassConfig(classConfig); + + if (errorMessage) { + errorMessages.push(`classConfig:${classConfig.className} is invalid because ${errorMessage}`); + } + }); + } else { + errorMessages.push(`"classConfigs" is not a valid array`); + } + } + } + + if (errorMessages.length) { + throw new Error(`Invalid graphQLConfig: ${errorMessages.join('; ')}`); + } + } + + _validateClassConfig(classConfig) { + if (!isValidSimpleObject(classConfig)) { + return 'it must be a valid object'; + } else { + const { + className, + type = null, + query = null, + mutation = null + } = classConfig, + invalidKeys = _objectWithoutProperties(classConfig, ["className", "type", "query", "mutation"]); + + if (Object.keys(invalidKeys).length) { + return `"invalidKeys" [${Object.keys(invalidKeys)}] should not be present`; + } + + if (typeof className !== 'string' || !className.trim().length) { + // TODO consider checking class exists in schema? + return `"className" must be a valid string`; + } + + if (type !== null) { + if (!isValidSimpleObject(type)) { + return `"type" must be a valid object`; + } + + const { + inputFields = null, + outputFields = null, + constraintFields = null, + sortFields = null + } = type, + invalidKeys = _objectWithoutProperties(type, ["inputFields", "outputFields", "constraintFields", "sortFields"]); + + if (Object.keys(invalidKeys).length) { + return `"type" contains invalid keys, [${Object.keys(invalidKeys)}]`; + } else if (outputFields !== null && !isValidStringArray(outputFields)) { + return `"outputFields" must be a valid string array`; + } else if (constraintFields !== null && !isValidStringArray(constraintFields)) { + return `"constraintFields" must be a valid string array`; + } + + if (sortFields !== null) { + if (Array.isArray(sortFields)) { + let errorMessage; + sortFields.every((sortField, index) => { + if (!isValidSimpleObject(sortField)) { + errorMessage = `"sortField" at index ${index} is not a valid object`; + return false; + } else { + const { + field, + asc, + desc + } = sortField, + invalidKeys = _objectWithoutProperties(sortField, ["field", "asc", "desc"]); + + if (Object.keys(invalidKeys).length) { + errorMessage = `"sortField" at index ${index} contains invalid keys, [${Object.keys(invalidKeys)}]`; + return false; + } else { + if (typeof field !== 'string' || field.trim().length === 0) { + errorMessage = `"sortField" at index ${index} did not provide the "field" as a string`; + return false; + } else if (typeof asc !== 'boolean' || typeof desc !== 'boolean') { + errorMessage = `"sortField" at index ${index} did not provide "asc" or "desc" as booleans`; + return false; + } + } + } + + return true; + }); + + if (errorMessage) { + return errorMessage; + } + } else { + return `"sortFields" must be a valid array.`; + } + } + + if (inputFields !== null) { + if (isValidSimpleObject(inputFields)) { + const { + create = null, + update = null + } = inputFields, + invalidKeys = _objectWithoutProperties(inputFields, ["create", "update"]); + + if (Object.keys(invalidKeys).length) { + return `"inputFields" contains invalid keys: [${Object.keys(invalidKeys)}]`; + } else { + if (update !== null && !isValidStringArray(update)) { + return `"inputFields.update" must be a valid string array`; + } else if (create !== null) { + if (!isValidStringArray(create)) { + return `"inputFields.create" must be a valid string array`; + } else if (className === '_User') { + if (!create.includes('username') || !create.includes('password')) { + return `"inputFields.create" must include required fields, username and password`; + } + } + } + } + } else { + return `"inputFields" must be a valid object`; + } + } + } + + if (query !== null) { + if (isValidSimpleObject(query)) { + const { + find = null, + get = null, + findAlias = null, + getAlias = null + } = query, + invalidKeys = _objectWithoutProperties(query, ["find", "get", "findAlias", "getAlias"]); + + if (Object.keys(invalidKeys).length) { + return `"query" contains invalid keys, [${Object.keys(invalidKeys)}]`; + } else if (find !== null && typeof find !== 'boolean') { + return `"query.find" must be a boolean`; + } else if (get !== null && typeof get !== 'boolean') { + return `"query.get" must be a boolean`; + } else if (findAlias !== null && typeof findAlias !== 'string') { + return `"query.findAlias" must be a string`; + } else if (getAlias !== null && typeof getAlias !== 'string') { + return `"query.getAlias" must be a string`; + } + } else { + return `"query" must be a valid object`; + } + } + + if (mutation !== null) { + if (isValidSimpleObject(mutation)) { + const { + create = null, + update = null, + destroy = null, + createAlias = null, + updateAlias = null, + destroyAlias = null + } = mutation, + invalidKeys = _objectWithoutProperties(mutation, ["create", "update", "destroy", "createAlias", "updateAlias", "destroyAlias"]); + + if (Object.keys(invalidKeys).length) { + return `"mutation" contains invalid keys, [${Object.keys(invalidKeys)}]`; + } + + if (create !== null && typeof create !== 'boolean') { + return `"mutation.create" must be a boolean`; + } + + if (update !== null && typeof update !== 'boolean') { + return `"mutation.update" must be a boolean`; + } + + if (destroy !== null && typeof destroy !== 'boolean') { + return `"mutation.destroy" must be a boolean`; + } + + if (createAlias !== null && typeof createAlias !== 'string') { + return `"mutation.createAlias" must be a string`; + } + + if (updateAlias !== null && typeof updateAlias !== 'string') { + return `"mutation.updateAlias" must be a string`; + } + + if (destroyAlias !== null && typeof destroyAlias !== 'string') { + return `"mutation.destroyAlias" must be a string`; + } + } else { + return `"mutation" must be a valid object`; + } + } + } + } + +} + +const isValidStringArray = function (array) { + return Array.isArray(array) ? !array.some(s => typeof s !== 'string' || s.trim().length < 1) : false; +}; +/** + * Ensures the obj is a simple JSON/{} + * object, i.e. not an array, null, date + * etc. + */ + + +const isValidSimpleObject = function (obj) { + return typeof obj === 'object' && !Array.isArray(obj) && obj !== null && obj instanceof Date !== true && obj instanceof Promise !== true; +}; + +var _default = ParseGraphQLController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkdyYXBoUUxDb25maWdDbGFzc05hbWUiLCJHcmFwaFFMQ29uZmlnSWQiLCJHcmFwaFFMQ29uZmlnS2V5IiwiUGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwiZGF0YWJhc2VDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiaXNNb3VudGVkIiwibW91bnRHcmFwaFFMIiwiY29uZmlnQ2FjaGVLZXkiLCJnZXRHcmFwaFFMQ29uZmlnIiwiX2NhY2hlZENvbmZpZyIsIl9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwicmVzdWx0cyIsImZpbmQiLCJvYmplY3RJZCIsImxpbWl0IiwiZ3JhcGhRTENvbmZpZyIsImxlbmd0aCIsIl9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwidXBkYXRlR3JhcGhRTENvbmZpZyIsIl92YWxpZGF0ZUdyYXBoUUxDb25maWciLCJ1cGRhdGUiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYWNjIiwia2V5IiwidXBzZXJ0IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJncmFwaFFMIiwiZ2V0IiwicHV0IiwiZXJyb3JNZXNzYWdlcyIsInB1c2giLCJpc1ZhbGlkU2ltcGxlT2JqZWN0IiwiZW5hYmxlZEZvckNsYXNzZXMiLCJkaXNhYmxlZEZvckNsYXNzZXMiLCJjbGFzc0NvbmZpZ3MiLCJpbnZhbGlkS2V5cyIsImlzVmFsaWRTdHJpbmdBcnJheSIsIkFycmF5IiwiaXNBcnJheSIsImZvckVhY2giLCJjbGFzc0NvbmZpZyIsImVycm9yTWVzc2FnZSIsIl92YWxpZGF0ZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiRXJyb3IiLCJqb2luIiwidHlwZSIsInF1ZXJ5IiwibXV0YXRpb24iLCJ0cmltIiwiaW5wdXRGaWVsZHMiLCJvdXRwdXRGaWVsZHMiLCJjb25zdHJhaW50RmllbGRzIiwic29ydEZpZWxkcyIsImV2ZXJ5Iiwic29ydEZpZWxkIiwiaW5kZXgiLCJmaWVsZCIsImFzYyIsImRlc2MiLCJjcmVhdGUiLCJpbmNsdWRlcyIsImZpbmRBbGlhcyIsImdldEFsaWFzIiwiZGVzdHJveSIsImNyZWF0ZUFsaWFzIiwidXBkYXRlQWxpYXMiLCJkZXN0cm95QWxpYXMiLCJhcnJheSIsInNvbWUiLCJzIiwib2JqIiwiRGF0ZSIsIlByb21pc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFFQSxNQUFNQSxzQkFBc0IsR0FBRyxnQkFBL0I7O0FBQ0EsTUFBTUMsZUFBZSxHQUFHLEdBQXhCOztBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFFBQXpCOzs7QUFFQSxNQUFNQyxzQkFBTixDQUE2QjtBQU0zQkMsRUFBQUEsV0FBVyxDQUNUQyxNQUdDLEdBQUcsRUFKSyxFQUtUO0FBQ0EsU0FBS0Msa0JBQUwsR0FDRUQsTUFBTSxDQUFDQyxrQkFBUCxJQUNBLGdDQUNHLDRFQURILENBRkY7QUFLQSxTQUFLQyxlQUFMLEdBQXVCRixNQUFNLENBQUNFLGVBQTlCO0FBQ0EsU0FBS0MsU0FBTCxHQUFpQixDQUFDLENBQUNILE1BQU0sQ0FBQ0ksWUFBMUI7QUFDQSxTQUFLQyxjQUFMLEdBQXNCUixnQkFBdEI7QUFDRDs7QUFFRCxRQUFNUyxnQkFBTixHQUFzRDtBQUNwRCxRQUFJLEtBQUtILFNBQVQsRUFBb0I7QUFDbEIsWUFBTUksYUFBYSxHQUFHLE1BQU0sS0FBS0MsdUJBQUwsRUFBNUI7O0FBQ0EsVUFBSUQsYUFBSixFQUFtQjtBQUNqQixlQUFPQSxhQUFQO0FBQ0Q7QUFDRjs7QUFFRCxVQUFNRSxPQUFPLEdBQUcsTUFBTSxLQUFLUixrQkFBTCxDQUF3QlMsSUFBeEIsQ0FDcEJmLHNCQURvQixFQUVwQjtBQUFFZ0IsTUFBQUEsUUFBUSxFQUFFZjtBQUFaLEtBRm9CLEVBR3BCO0FBQUVnQixNQUFBQSxLQUFLLEVBQUU7QUFBVCxLQUhvQixDQUF0QjtBQU1BLFFBQUlDLGFB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QUFhLFFBQWIsSUFBeUJBLENBQUMsQ0FBQ3JCLElBQUYsR0FBU3BDLE1BQVQsR0FBa0IsQ0FBM0QsQ0FERSxHQUVILEtBRko7QUFHRCxDQUpEO0FBS0E7Ozs7Ozs7QUFLQSxNQUFNa0IsbUJBQW1CLEdBQUcsVUFBVXdDLEdBQVYsRUFBd0I7QUFDbEQsU0FDRSxPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUNBLENBQUNsQyxLQUFLLENBQUNDLE9BQU4sQ0FBY2lDLEdBQWQsQ0FERCxJQUVBQSxHQUFHLEtBQUssSUFGUixJQUdBQSxHQUFHLFlBQVlDLElBQWYsS0FBd0IsSUFIeEIsSUFJQUQsR0FBRyxZQUFZRSxPQUFmLEtBQTJCLElBTDdCO0FBT0QsQ0FSRDs7ZUF3RGU1RSxzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuLi8uLi9saWIvcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0IERhdGFiYXNlQ29udHJvbGxlciBmcm9tICcuL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgQ2FjaGVDb250cm9sbGVyIGZyb20gJy4vQ2FjaGVDb250cm9sbGVyJztcblxuY29uc3QgR3JhcGhRTENvbmZpZ0NsYXNzTmFtZSA9ICdfR3JhcGhRTENvbmZpZyc7XG5jb25zdCBHcmFwaFFMQ29uZmlnSWQgPSAnMSc7XG5jb25zdCBHcmFwaFFMQ29uZmlnS2V5ID0gJ2NvbmZpZyc7XG5cbmNsYXNzIFBhcnNlR3JhcGhRTENvbnRyb2xsZXIge1xuICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlcjtcbiAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXI7XG4gIGlzTW91bnRlZDogYm9vbGVhbjtcbiAgY29uZmlnQ2FjaGVLZXk6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwYXJhbXM6IHtcbiAgICAgIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyLFxuICAgICAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXIsXG4gICAgfSA9IHt9XG4gICkge1xuICAgIHRoaXMuZGF0YWJhc2VDb250cm9sbGVyID1cbiAgICAgIHBhcmFtcy5kYXRhYmFzZUNvbnRyb2xsZXIgfHxcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKFxuICAgICAgICBgUGFyc2VHcmFwaFFMQ29udHJvbGxlciByZXF1aXJlcyBhIFwiZGF0YWJhc2VDb250cm9sbGVyXCIgdG8gYmUgaW5zdGFudGlhdGVkLmBcbiAgICAgICk7XG4gICAgdGhpcy5jYWNoZUNvbnRyb2xsZXIgPSBwYXJhbXMuY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMuaXNNb3VudGVkID0gISFwYXJhbXMubW91bnRHcmFwaFFMO1xuICAgIHRoaXMuY29uZmlnQ2FjaGVLZXkgPSBHcmFwaFFMQ29uZmlnS2V5O1xuICB9XG5cbiAgYXN5bmMgZ2V0R3JhcGhRTENvbmZpZygpOiBQcm9taXNlPFBhcnNlR3JhcGhRTENvbmZpZz4ge1xuICAgIGlmICh0aGlzLmlzTW91bnRlZCkge1xuICAgICAgY29uc3QgX2NhY2hlZENvbmZpZyA9IGF3YWl0IHRoaXMuX2dldENhY2hlZEdyYXBoUUxDb25maWcoKTtcbiAgICAgIGlmIChfY2FjaGVkQ29uZmlnKSB7XG4gICAgICAgIHJldHVybiBfY2FjaGVkQ29uZmlnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci5maW5kKFxuICAgICAgR3JhcGhRTENvbmZpZ0NsYXNzTmFtZSxcbiAgICAgIHsgb2JqZWN0SWQ6IEdyYXBoUUxDb25maWdJZCB9LFxuICAgICAgeyBsaW1pdDogMSB9XG4gICAgKTtcblxuICAgIGxldCBncmFwaFFMQ29uZmlnO1xuICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBubyBjb25maWcgaW4gdGhlIGRhdGFiYXNlIC0gcmV0dXJuIGVtcHR5IGNvbmZpZy5cbiAgICAgIHJldHVybiB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ3JhcGhRTENvbmZpZyA9IHJlc3VsdHNbMF1bR3JhcGhRTENvbmZpZ0tleV07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNNb3VudGVkKSB7XG4gICAgICB0aGlzLl9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnKGdyYXBoUUxDb25maWcpO1xuICAgIH1cblxuICAgIHJldHVybiBncmFwaFFMQ29uZmlnO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlR3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpOiBQcm9taXNlPFBhcnNlR3JhcGhRTENvbmZpZz4ge1xuICAgIC8vIHRocm93cyBpZiBpbnZhbGlkXG4gICAgdGhpcy5fdmFsaWRhdGVHcmFwaFFMQ29uZmlnKFxuICAgICAgZ3JhcGhRTENvbmZpZyB8fCByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIGdyYXBoUUxDb25maWchJylcbiAgICApO1xuXG4gICAgLy8gVHJhbnNmb3JtIGluIGRvdCBub3RhdGlvbiB0byBtYWtlIHN1cmUgaXQgd29ya3NcbiAgICBjb25zdCB1cGRhdGUgPSBPYmplY3Qua2V5cyhncmFwaFFMQ29uZmlnKS5yZWR1Y2UoXG4gICAgICAoYWNjLCBrZXkpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBbR3JhcGhRTENvbmZpZ0tleV06IHtcbiAgICAgICAgICAgIC4uLmFjY1tHcmFwaFFMQ29uZmlnS2V5XSxcbiAgICAgICAgICAgIFtrZXldOiBncmFwaFFMQ29uZmlnW2tleV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICB7IFtHcmFwaFFMQ29uZmlnS2V5XToge30gfVxuICAgICk7XG5cbiAgICBhd2FpdCB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci51cGRhdGUoXG4gICAgICBHcmFwaFFMQ29uZmlnQ2xhc3NOYW1lLFxuICAgICAgeyBvYmplY3RJZDogR3JhcGhRTENvbmZpZ0lkIH0sXG4gICAgICB1cGRhdGUsXG4gICAgICB7IHVwc2VydDogdHJ1ZSB9XG4gICAgKTtcblxuICAgIGlmICh0aGlzLmlzTW91bnRlZCkge1xuICAgICAgdGhpcy5fcHV0Q2FjaGVkR3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByZXNwb25zZTogeyByZXN1bHQ6IHRydWUgfSB9O1xuICB9XG5cbiAgX2dldENhY2hlZEdyYXBoUUxDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVDb250cm9sbGVyLmdyYXBoUUwuZ2V0KHRoaXMuY29uZmlnQ2FjaGVLZXkpO1xuICB9XG5cbiAgX3B1dENhY2hlZEdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZzogUGFyc2VHcmFwaFFMQ29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVDb250cm9sbGVyLmdyYXBoUUwucHV0KHRoaXMuY29uZmlnQ2FjaGVLZXksIGdyYXBoUUxDb25maWcsIDYwMDAwKTtcbiAgfVxuXG4gIF92YWxpZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZzogP1BhcnNlR3JhcGhRTENvbmZpZyk6IHZvaWQge1xuICAgIGNvbnN0IGVycm9yTWVzc2FnZXM6IHN0cmluZyA9IFtdO1xuICAgIGlmICghZ3JhcGhRTENvbmZpZykge1xuICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKCdjYW5ub3QgYmUgdW5kZWZpbmVkLCBudWxsIG9yIGVtcHR5Jyk7XG4gICAgfSBlbHNlIGlmICghaXNWYWxpZFNpbXBsZU9iamVjdChncmFwaFFMQ29uZmlnKSkge1xuICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKCdtdXN0IGJlIGEgdmFsaWQgb2JqZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZW5hYmxlZEZvckNsYXNzZXMgPSBudWxsLFxuICAgICAgICBkaXNhYmxlZEZvckNsYXNzZXMgPSBudWxsLFxuICAgICAgICBjbGFzc0NvbmZpZ3MgPSBudWxsLFxuICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgfSA9IGdyYXBoUUxDb25maWc7XG5cbiAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgIGVycm9yTWVzc2FnZXMucHVzaChgZW5jb3VudGVyZWQgaW52YWxpZCBrZXlzOiBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWApO1xuICAgICAgfVxuICAgICAgaWYgKGVuYWJsZWRGb3JDbGFzc2VzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkoZW5hYmxlZEZvckNsYXNzZXMpKSB7XG4gICAgICAgIGVycm9yTWVzc2FnZXMucHVzaChgXCJlbmFibGVkRm9yQ2xhc3Nlc1wiIGlzIG5vdCBhIHZhbGlkIGFycmF5YCk7XG4gICAgICB9XG4gICAgICBpZiAoZGlzYWJsZWRGb3JDbGFzc2VzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkoZGlzYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYFwiZGlzYWJsZWRGb3JDbGFzc2VzXCIgaXMgbm90IGEgdmFsaWQgYXJyYXlgKTtcbiAgICAgIH1cbiAgICAgIGlmIChjbGFzc0NvbmZpZ3MgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2xhc3NDb25maWdzKSkge1xuICAgICAgICAgIGNsYXNzQ29uZmlncy5mb3JFYWNoKGNsYXNzQ29uZmlnID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IHRoaXMuX3ZhbGlkYXRlQ2xhc3NDb25maWcoY2xhc3NDb25maWcpO1xuICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goXG4gICAgICAgICAgICAgICAgYGNsYXNzQ29uZmlnOiR7Y2xhc3NDb25maWcuY2xhc3NOYW1lfSBpcyBpbnZhbGlkIGJlY2F1c2UgJHtlcnJvck1lc3NhZ2V9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVycm9yTWVzc2FnZXMucHVzaChgXCJjbGFzc0NvbmZpZ3NcIiBpcyBub3QgYSB2YWxpZCBhcnJheWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvck1lc3NhZ2VzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGdyYXBoUUxDb25maWc6ICR7ZXJyb3JNZXNzYWdlcy5qb2luKCc7ICcpfWApO1xuICAgIH1cbiAgfVxuXG4gIF92YWxpZGF0ZUNsYXNzQ29uZmlnKGNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWcpOiBzdHJpbmcgfCB2b2lkIHtcbiAgICBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3QoY2xhc3NDb25maWcpKSB7XG4gICAgICByZXR1cm4gJ2l0IG11c3QgYmUgYSB2YWxpZCBvYmplY3QnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgdHlwZSA9IG51bGwsIHF1ZXJ5ID0gbnVsbCwgbXV0YXRpb24gPSBudWxsLCAuLi5pbnZhbGlkS2V5cyB9ID0gY2xhc3NDb25maWc7XG4gICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gYFwiaW52YWxpZEtleXNcIiBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XSBzaG91bGQgbm90IGJlIHByZXNlbnRgO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjbGFzc05hbWUgIT09ICdzdHJpbmcnIHx8ICFjbGFzc05hbWUudHJpbSgpLmxlbmd0aCkge1xuICAgICAgICAvLyBUT0RPIGNvbnNpZGVyIGNoZWNraW5nIGNsYXNzIGV4aXN0cyBpbiBzY2hlbWE/XG4gICAgICAgIHJldHVybiBgXCJjbGFzc05hbWVcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nYDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlICE9PSBudWxsKSB7XG4gICAgICAgIGlmICghaXNWYWxpZFNpbXBsZU9iamVjdCh0eXBlKSkge1xuICAgICAgICAgIHJldHVybiBgXCJ0eXBlXCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGlucHV0RmllbGRzID0gbnVsbCxcbiAgICAgICAgICBvdXRwdXRGaWVsZHMgPSBudWxsLFxuICAgICAgICAgIGNvbnN0cmFpbnRGaWVsZHMgPSBudWxsLFxuICAgICAgICAgIHNvcnRGaWVsZHMgPSBudWxsLFxuICAgICAgICAgIC4uLmludmFsaWRLZXlzXG4gICAgICAgIH0gPSB0eXBlO1xuICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiBgXCJ0eXBlXCIgY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgIH0gZWxzZSBpZiAob3V0cHV0RmllbGRzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkob3V0cHV0RmllbGRzKSkge1xuICAgICAgICAgIHJldHVybiBgXCJvdXRwdXRGaWVsZHNcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgfSBlbHNlIGlmIChjb25zdHJhaW50RmllbGRzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkoY29uc3RyYWludEZpZWxkcykpIHtcbiAgICAgICAgICByZXR1cm4gYFwiY29uc3RyYWludEZpZWxkc1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgYXJyYXlgO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzb3J0RmllbGRzICE9PSBudWxsKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydEZpZWxkcykpIHtcbiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICBzb3J0RmllbGRzLmV2ZXJ5KChzb3J0RmllbGQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNWYWxpZFNpbXBsZU9iamVjdChzb3J0RmllbGQpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGEgdmFsaWQgb2JqZWN0YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBmaWVsZCwgYXNjLCBkZXNjLCAuLi5pbnZhbGlkS2V5cyB9ID0gc29ydEZpZWxkO1xuICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBgXCJzb3J0RmllbGRcIiBhdCBpbmRleCAke2luZGV4fSBjb250YWlucyBpbnZhbGlkIGtleXMsIFske09iamVjdC5rZXlzKFxuICAgICAgICAgICAgICAgICAgICBpbnZhbGlkS2V5c1xuICAgICAgICAgICAgICAgICAgKX1dYDtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmaWVsZCAhPT0gJ3N0cmluZycgfHwgZmllbGQudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBgXCJzb3J0RmllbGRcIiBhdCBpbmRleCAke2luZGV4fSBkaWQgbm90IHByb3ZpZGUgdGhlIFwiZmllbGRcIiBhcyBhIHN0cmluZ2A7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFzYyAhPT0gJ2Jvb2xlYW4nIHx8IHR5cGVvZiBkZXNjICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gZGlkIG5vdCBwcm92aWRlIFwiYXNjXCIgb3IgXCJkZXNjXCIgYXMgYm9vbGVhbnNgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJzb3J0RmllbGRzXCIgbXVzdCBiZSBhIHZhbGlkIGFycmF5LmA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpbnB1dEZpZWxkcyAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChpc1ZhbGlkU2ltcGxlT2JqZWN0KGlucHV0RmllbGRzKSkge1xuICAgICAgICAgICAgY29uc3QgeyBjcmVhdGUgPSBudWxsLCB1cGRhdGUgPSBudWxsLCAuLi5pbnZhbGlkS2V5cyB9ID0gaW5wdXRGaWVsZHM7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICByZXR1cm4gYFwiaW5wdXRGaWVsZHNcIiBjb250YWlucyBpbnZhbGlkIGtleXM6IFske09iamVjdC5rZXlzKGludmFsaWRLZXlzKX1dYDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGUgIT09IG51bGwgJiYgIWlzVmFsaWRTdHJpbmdBcnJheSh1cGRhdGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzLnVwZGF0ZVwiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgYXJyYXlgO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNyZWF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZFN0cmluZ0FycmF5KGNyZWF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgXCJpbnB1dEZpZWxkcy5jcmVhdGVcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgICAgICAgaWYgKCFjcmVhdGUuaW5jbHVkZXMoJ3VzZXJuYW1lJykgfHwgIWNyZWF0ZS5pbmNsdWRlcygncGFzc3dvcmQnKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFwiaW5wdXRGaWVsZHMuY3JlYXRlXCIgbXVzdCBpbmNsdWRlIHJlcXVpcmVkIGZpZWxkcywgdXNlcm5hbWUgYW5kIHBhc3N3b3JkYDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzXCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocXVlcnkgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGlzVmFsaWRTaW1wbGVPYmplY3QocXVlcnkpKSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgZmluZCA9IG51bGwsXG4gICAgICAgICAgICBnZXQgPSBudWxsLFxuICAgICAgICAgICAgZmluZEFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIGdldEFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIC4uLmludmFsaWRLZXlzXG4gICAgICAgICAgfSA9IHF1ZXJ5O1xuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnlcIiBjb250YWlucyBpbnZhbGlkIGtleXMsIFske09iamVjdC5rZXlzKGludmFsaWRLZXlzKX1dYDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGZpbmQgIT09IG51bGwgJiYgdHlwZW9mIGZpbmQgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmZpbmRcIiBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICAgICAgfSBlbHNlIGlmIChnZXQgIT09IG51bGwgJiYgdHlwZW9mIGdldCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnkuZ2V0XCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZmluZEFsaWFzICE9PSBudWxsICYmIHR5cGVvZiBmaW5kQWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnkuZmluZEFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfSBlbHNlIGlmIChnZXRBbGlhcyAhPT0gbnVsbCAmJiB0eXBlb2YgZ2V0QWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnkuZ2V0QWxpYXNcIiBtdXN0IGJlIGEgc3RyaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5XCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtdXRhdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNWYWxpZFNpbXBsZU9iamVjdChtdXRhdGlvbikpIHtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBjcmVhdGUgPSBudWxsLFxuICAgICAgICAgICAgdXBkYXRlID0gbnVsbCxcbiAgICAgICAgICAgIGRlc3Ryb3kgPSBudWxsLFxuICAgICAgICAgICAgY3JlYXRlQWxpYXMgPSBudWxsLFxuICAgICAgICAgICAgdXBkYXRlQWxpYXMgPSBudWxsLFxuICAgICAgICAgICAgZGVzdHJveUFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIC4uLmludmFsaWRLZXlzXG4gICAgICAgICAgfSA9IG11dGF0aW9uO1xuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb25cIiBjb250YWlucyBpbnZhbGlkIGtleXMsIFske09iamVjdC5rZXlzKGludmFsaWRLZXlzKX1dYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNyZWF0ZSAhPT0gbnVsbCAmJiB0eXBlb2YgY3JlYXRlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi5jcmVhdGVcIiBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh1cGRhdGUgIT09IG51bGwgJiYgdHlwZW9mIHVwZGF0ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24udXBkYXRlXCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZGVzdHJveSAhPT0gbnVsbCAmJiB0eXBlb2YgZGVzdHJveSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uZGVzdHJveVwiIG11c3QgYmUgYSBib29sZWFuYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNyZWF0ZUFsaWFzICE9PSBudWxsICYmIHR5cGVvZiBjcmVhdGVBbGlhcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi5jcmVhdGVBbGlhc1wiIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXBkYXRlQWxpYXMgIT09IG51bGwgJiYgdHlwZW9mIHVwZGF0ZUFsaWFzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uLnVwZGF0ZUFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkZXN0cm95QWxpYXMgIT09IG51bGwgJiYgdHlwZW9mIGRlc3Ryb3lBbGlhcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi5kZXN0cm95QWxpYXNcIiBtdXN0IGJlIGEgc3RyaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uXCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuY29uc3QgaXNWYWxpZFN0cmluZ0FycmF5ID0gZnVuY3Rpb24gKGFycmF5KTogYm9vbGVhbiB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFycmF5KVxuICAgID8gIWFycmF5LnNvbWUocyA9PiB0eXBlb2YgcyAhPT0gJ3N0cmluZycgfHwgcy50cmltKCkubGVuZ3RoIDwgMSlcbiAgICA6IGZhbHNlO1xufTtcbi8qKlxuICogRW5zdXJlcyB0aGUgb2JqIGlzIGEgc2ltcGxlIEpTT04ve31cbiAqIG9iamVjdCwgaS5lLiBub3QgYW4gYXJyYXksIG51bGwsIGRhdGVcbiAqIGV0Yy5cbiAqL1xuY29uc3QgaXNWYWxpZFNpbXBsZU9iamVjdCA9IGZ1bmN0aW9uIChvYmopOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJlxuICAgICFBcnJheS5pc0FycmF5KG9iaikgJiZcbiAgICBvYmogIT09IG51bGwgJiZcbiAgICBvYmogaW5zdGFuY2VvZiBEYXRlICE9PSB0cnVlICYmXG4gICAgb2JqIGluc3RhbmNlb2YgUHJvbWlzZSAhPT0gdHJ1ZVxuICApO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBQYXJzZUdyYXBoUUxDb25maWcge1xuICBlbmFibGVkRm9yQ2xhc3Nlcz86IHN0cmluZ1tdO1xuICBkaXNhYmxlZEZvckNsYXNzZXM/OiBzdHJpbmdbXTtcbiAgY2xhc3NDb25maWdzPzogUGFyc2VHcmFwaFFMQ2xhc3NDb25maWdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXJzZUdyYXBoUUxDbGFzc0NvbmZpZyB7XG4gIGNsYXNzTmFtZTogc3RyaW5nO1xuICAvKiBUaGUgYHR5cGVgIG9iamVjdCBjb250YWlucyBvcHRpb25zIGZvciBob3cgdGhlIGNsYXNzIHR5cGVzIGFyZSBnZW5lcmF0ZWQgKi9cbiAgdHlwZTogP3tcbiAgICAvKiBGaWVsZHMgdGhhdCBhcmUgYWxsb3dlZCB3aGVuIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGFuIG9iamVjdC4gKi9cbiAgICBpbnB1dEZpZWxkczogP3tcbiAgICAgIC8qIExlYXZlIGJsYW5rIHRvIGFsbG93IGFsbCBhdmFpbGFibGUgZmllbGRzIGluIHRoZSBzY2hlbWEuICovXG4gICAgICBjcmVhdGU/OiBzdHJpbmdbXSxcbiAgICAgIHVwZGF0ZT86IHN0cmluZ1tdLFxuICAgIH0sXG4gICAgLyogRmllbGRzIG9uIHRoZSBlZGdlcyB0aGF0IGNhbiBiZSByZXNvbHZlZCBmcm9tIGEgcXVlcnksIGkuZS4gdGhlIFJlc3VsdCBUeXBlLiAqL1xuICAgIG91dHB1dEZpZWxkczogPyhzdHJpbmdbXSksXG4gICAgLyogRmllbGRzIGJ5IHdoaWNoIGEgcXVlcnkgY2FuIGJlIGZpbHRlcmVkLCBpLmUuIHRoZSBgd2hlcmVgIG9iamVjdC4gKi9cbiAgICBjb25zdHJhaW50RmllbGRzOiA/KHN0cmluZ1tdKSxcbiAgICAvKiBGaWVsZHMgYnkgd2hpY2ggYSBxdWVyeSBjYW4gYmUgc29ydGVkOyAqL1xuICAgIHNvcnRGaWVsZHM6ID8oe1xuICAgICAgZmllbGQ6IHN0cmluZyxcbiAgICAgIGFzYzogYm9vbGVhbixcbiAgICAgIGRlc2M6IGJvb2xlYW4sXG4gICAgfVtdKSxcbiAgfTtcbiAgLyogVGhlIGBxdWVyeWAgb2JqZWN0IGNvbnRhaW5zIG9wdGlvbnMgZm9yIHdoaWNoIGNsYXNzIHF1ZXJpZXMgYXJlIGdlbmVyYXRlZCAqL1xuICBxdWVyeTogP3tcbiAgICBnZXQ6ID9ib29sZWFuLFxuICAgIGZpbmQ6ID9ib29sZWFuLFxuICAgIGZpbmRBbGlhczogP1N0cmluZyxcbiAgICBnZXRBbGlhczogP1N0cmluZyxcbiAgfTtcbiAgLyogVGhlIGBtdXRhdGlvbmAgb2JqZWN0IGNvbnRhaW5zIG9wdGlvbnMgZm9yIHdoaWNoIGNsYXNzIG11dGF0aW9ucyBhcmUgZ2VuZXJhdGVkICovXG4gIG11dGF0aW9uOiA/e1xuICAgIGNyZWF0ZTogP2Jvb2xlYW4sXG4gICAgdXBkYXRlOiA/Ym9vbGVhbixcbiAgICAvLyBkZWxldGUgaXMgYSByZXNlcnZlZCBrZXkgd29yZCBpbiBqc1xuICAgIGRlc3Ryb3k6ID9ib29sZWFuLFxuICAgIGNyZWF0ZUFsaWFzOiA/U3RyaW5nLFxuICAgIHVwZGF0ZUFsaWFzOiA/U3RyaW5nLFxuICAgIGRlc3Ryb3lBbGlhczogP1N0cmluZyxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VHcmFwaFFMQ29udHJvbGxlcjtcbmV4cG9ydCB7IEdyYXBoUUxDb25maWdDbGFzc05hbWUsIEdyYXBoUUxDb25maWdJZCwgR3JhcGhRTENvbmZpZ0tleSB9O1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/PushController.js b/lib/Controllers/PushController.js new file mode 100644 index 0000000000..dd44dcefc9 --- /dev/null +++ b/lib/Controllers/PushController.js @@ -0,0 +1,257 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushController = void 0; + +var _node = require("parse/node"); + +var _RestQuery = _interopRequireDefault(require("../RestQuery")); + +var _RestWrite = _interopRequireDefault(require("../RestWrite")); + +var _Auth = require("../Auth"); + +var _StatusHandler = require("../StatusHandler"); + +var _utils = require("../Push/utils"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PushController { + sendPush(body = {}, where = {}, config, auth, onPushStatusSaved = () => {}, now = new Date()) { + if (!config.hasPushSupport) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Missing push configuration'); + } // Replace the expiration_time and push_time with a valid Unix epoch milliseconds time + + + body.expiration_time = PushController.getExpirationTime(body); + body.expiration_interval = PushController.getExpirationInterval(body); + + if (body.expiration_time && body.expiration_interval) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Both expiration_time and expiration_interval cannot be set'); + } // Immediate push + + + if (body.expiration_interval && !Object.prototype.hasOwnProperty.call(body, 'push_time')) { + const ttlMs = body.expiration_interval * 1000; + body.expiration_time = new Date(now.valueOf() + ttlMs).valueOf(); + } + + const pushTime = PushController.getPushTime(body); + + if (pushTime && pushTime.date !== 'undefined') { + body['push_time'] = PushController.formatPushTime(pushTime); + } // TODO: If the req can pass the checking, we return immediately instead of waiting + // pushes to be sent. We probably change this behaviour in the future. + + + let badgeUpdate = () => { + return Promise.resolve(); + }; + + if (body.data && body.data.badge) { + const badge = body.data.badge; + let restUpdate = {}; + + if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { + restUpdate = { + badge: { + __op: 'Increment', + amount: 1 + } + }; + } else if (typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount)) { + restUpdate = { + badge: { + __op: 'Increment', + amount: badge.amount + } + }; + } else if (Number(badge)) { + restUpdate = { + badge: badge + }; + } else { + throw "Invalid value for badge, expected number or 'Increment' or {increment: number}"; + } // Force filtering on only valid device tokens + + + const updateWhere = (0, _utils.applyDeviceTokenExists)(where); + + badgeUpdate = () => { + // Build a real RestQuery so we can use it in RestWrite + const restQuery = new _RestQuery.default(config, (0, _Auth.master)(config), '_Installation', updateWhere); + return restQuery.buildRestWhere().then(() => { + const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Installation', restQuery.restWhere, restUpdate); + write.runOptions.many = true; + return write.execute(); + }); + }; + } + + const pushStatus = (0, _StatusHandler.pushStatusHandler)(config); + return Promise.resolve().then(() => { + return pushStatus.setInitial(body, where); + }).then(() => { + onPushStatusSaved(pushStatus.objectId); + return badgeUpdate(); + }).then(() => { + // Update audience lastUsed and timesUsed + if (body.audience_id) { + const audienceId = body.audience_id; + var updateAudience = { + lastUsed: { + __type: 'Date', + iso: new Date().toISOString() + }, + timesUsed: { + __op: 'Increment', + amount: 1 + } + }; + const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Audience', { + objectId: audienceId + }, updateAudience); + write.execute(); + } // Don't wait for the audience update promise to resolve. + + + return Promise.resolve(); + }).then(() => { + if (Object.prototype.hasOwnProperty.call(body, 'push_time') && config.hasPushScheduledSupport) { + return Promise.resolve(); + } + + return config.pushControllerQueue.enqueue(body, where, config, auth, pushStatus); + }).catch(err => { + return pushStatus.fail(err).then(() => { + throw err; + }); + }); + } + /** + * Get expiration time from the request body. + * @param {Object} request A request object + * @returns {Number|undefined} The expiration time if it exists in the request + */ + + + static getExpirationTime(body = {}) { + var hasExpirationTime = Object.prototype.hasOwnProperty.call(body, 'expiration_time'); + + if (!hasExpirationTime) { + return; + } + + var expirationTimeParam = body['expiration_time']; + var expirationTime; + + if (typeof expirationTimeParam === 'number') { + expirationTime = new Date(expirationTimeParam * 1000); + } else if (typeof expirationTimeParam === 'string') { + expirationTime = new Date(expirationTimeParam); + } else { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); + } // Check expirationTime is valid or not, if it is not valid, expirationTime is NaN + + + if (!isFinite(expirationTime)) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); + } + + return expirationTime.valueOf(); + } + + static getExpirationInterval(body = {}) { + const hasExpirationInterval = Object.prototype.hasOwnProperty.call(body, 'expiration_interval'); + + if (!hasExpirationInterval) { + return; + } + + var expirationIntervalParam = body['expiration_interval']; + + if (typeof expirationIntervalParam !== 'number' || expirationIntervalParam <= 0) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, `expiration_interval must be a number greater than 0`); + } + + return expirationIntervalParam; + } + /** + * Get push time from the request body. + * @param {Object} request A request object + * @returns {Number|undefined} The push time if it exists in the request + */ + + + static getPushTime(body = {}) { + var hasPushTime = Object.prototype.hasOwnProperty.call(body, 'push_time'); + + if (!hasPushTime) { + return; + } + + var pushTimeParam = body['push_time']; + var date; + var isLocalTime = true; + + if (typeof pushTimeParam === 'number') { + date = new Date(pushTimeParam * 1000); + } else if (typeof pushTimeParam === 'string') { + isLocalTime = !PushController.pushTimeHasTimezoneComponent(pushTimeParam); + date = new Date(pushTimeParam); + } else { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); + } // Check pushTime is valid or not, if it is not valid, pushTime is NaN + + + if (!isFinite(date)) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); + } + + return { + date, + isLocalTime + }; + } + /** + * Checks if a ISO8601 formatted date contains a timezone component + * @param pushTimeParam {string} + * @returns {boolean} + */ + + + static pushTimeHasTimezoneComponent(pushTimeParam) { + const offsetPattern = /(.+)([+-])\d\d:\d\d$/; + return pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || offsetPattern.test(pushTimeParam) // 2007-04-05T12:30Z + ; // 2007-04-05T12:30.000+02:00, 2007-04-05T12:30.000-02:00 + } + /** + * Converts a date to ISO format in UTC time and strips the timezone if `isLocalTime` is true + * @param date {Date} + * @param isLocalTime {boolean} + * @returns {string} + */ + + + static formatPushTime({ + date, + isLocalTime + }) { + if (isLocalTime) { + // Strip 'Z' + const isoString = date.toISOString(); + return isoString.substring(0, isoString.indexOf('Z')); + } + + return date.toISOString(); + } + +} + +exports.PushController = PushController; +var _default = PushController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QdXNoQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJQdXNoQ29udHJvbGxlciIsInNlbmRQdXNoIiwiYm9keSIsIndoZXJlIiwiY29uZmlnIiwiYXV0aCIsIm9uUHVzaFN0YXR1c1NhdmVkIiwibm93IiwiRGF0ZSIsImhhc1B1c2hTdXBwb3J0IiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGlyYXRpb25fdGltZSIsImdldEV4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsImdldEV4cGlyYXRpb25JbnRlcnZhbCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR0bE1zIiwidmFsdWVPZiIsInB1c2hUaW1lIiwiZ2V0UHVzaFRpbWUiLCJkYXRlIiwiZm9ybWF0UHVzaFRpbWUiLCJiYWRnZVVwZGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZGF0YSIsImJhZGdlIiwicmVzdFVwZGF0ZSIsInRvTG93ZXJDYXNlIiwiX19vcCIsImFtb3VudCIsIk51bWJlciIsInVwZGF0ZVdoZXJlIiwicmVzdFF1ZXJ5IiwiUmVzdFF1ZXJ5IiwiYnVpbGRSZXN0V2hlcmUiLCJ0aGVuIiwid3JpdGUiLCJSZXN0V3JpdGUiLCJyZXN0V2hlcmUiLCJydW5PcHRpb25zIiwibWFueSIsImV4ZWN1dGUiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsIm9iamVjdElkIiwiYXVkaWVuY2VfaWQiLCJhdWRpZW5jZUlkIiwidXBkYXRlQXVkaWVuY2UiLCJsYXN0VXNlZCIsIl9fdHlwZSIsImlzbyIsInRvSVNPU3RyaW5nIiwidGltZXNVc2VkIiwiaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwiZW5xdWV1ZSIsImNhdGNoIiwiZXJyIiwiZmFpbCIsImhhc0V4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvblRpbWVQYXJhbSIsImV4cGlyYXRpb25UaW1lIiwiaXNGaW5pdGUiLCJoYXNFeHBpcmF0aW9uSW50ZXJ2YWwiLCJleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSIsImhhc1B1c2hUaW1lIiwicHVzaFRpbWVQYXJhbSIsImlzTG9jYWxUaW1lIiwicHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudCIsIm9mZnNldFBhdHRlcm4iLCJpbmRleE9mIiwibGVuZ3RoIiwidGVzdCIsImlzb1N0cmluZyIsInN1YnN0cmluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixDQUFxQjtBQUMxQkMsRUFBQUEsUUFBUSxDQUFDQyxJQUFJLEdBQUcsRUFBUixFQUFZQyxLQUFLLEdBQUcsRUFBcEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQ0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFFLENBQWxFLEVBQW9FQyxHQUFHLEdBQUcsSUFBSUMsSUFBSixFQUExRSxFQUFzRjtBQUM1RixRQUFJLENBQUNKLE1BQU0sQ0FBQ0ssY0FBWixFQUE0QjtBQUMxQixZQUFNLElBQUlDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0QsS0FIMkYsQ0FLNUY7OztBQUNBVixJQUFBQSxJQUFJLENBQUNXLGVBQUwsR0FBdUJiLGNBQWMsQ0FBQ2MsaUJBQWYsQ0FBaUNaLElBQWpDLENBQXZCO0FBQ0FBLElBQUFBLElBQUksQ0FBQ2EsbUJBQUwsR0FBMkJmLGNBQWMsQ0FBQ2dCLHFCQUFmLENBQXFDZCxJQUFyQyxDQUEzQjs7QUFDQSxRQUFJQSxJQUFJLENBQUNXLGVBQUwsSUFBd0JYLElBQUksQ0FBQ2EsbUJBQWpDLEVBQXNEO0FBQ3BELFlBQU0sSUFBSUwsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUosNERBRkksQ0FBTjtBQUlELEtBYjJGLENBZTVGOzs7QUFDQSxRQUFJVixJ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QUFDSjtBQUVEOzs7Ozs7OztBQU1BLFNBQU85QyxjQUFQLENBQXNCO0FBQUVELElBQUFBLElBQUY7QUFBUWdELElBQUFBO0FBQVIsR0FBdEIsRUFBbUY7QUFDakYsUUFBSUEsV0FBSixFQUFpQjtBQUNmO0FBQ0EsWUFBTU0sU0FBUyxHQUFHdEQsSUFBSSxDQUFDZ0MsV0FBTCxFQUFsQjtBQUNBLGFBQU9zQixTQUFTLENBQUNDLFNBQVYsQ0FBb0IsQ0FBcEIsRUFBdUJELFNBQVMsQ0FBQ0gsT0FBVixDQUFrQixHQUFsQixDQUF2QixDQUFQO0FBQ0Q7O0FBQ0QsV0FBT25ELElBQUksQ0FBQ2dDLFdBQUwsRUFBUDtBQUNEOztBQW5PeUI7OztlQXNPYnpELGMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFJlc3RRdWVyeSBmcm9tICcuLi9SZXN0UXVlcnknO1xuaW1wb3J0IFJlc3RXcml0ZSBmcm9tICcuLi9SZXN0V3JpdGUnO1xuaW1wb3J0IHsgbWFzdGVyIH0gZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgeyBwdXNoU3RhdHVzSGFuZGxlciB9IGZyb20gJy4uL1N0YXR1c0hhbmRsZXInO1xuaW1wb3J0IHsgYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyB9IGZyb20gJy4uL1B1c2gvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgUHVzaENvbnRyb2xsZXIge1xuICBzZW5kUHVzaChib2R5ID0ge30sIHdoZXJlID0ge30sIGNvbmZpZywgYXV0aCwgb25QdXNoU3RhdHVzU2F2ZWQgPSAoKSA9PiB7fSwgbm93ID0gbmV3IERhdGUoKSkge1xuICAgIGlmICghY29uZmlnLmhhc1B1c2hTdXBwb3J0KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTWlzc2luZyBwdXNoIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBleHBpcmF0aW9uX3RpbWUgYW5kIHB1c2hfdGltZSB3aXRoIGEgdmFsaWQgVW5peCBlcG9jaCBtaWxsaXNlY29uZHMgdGltZVxuICAgIGJvZHkuZXhwaXJhdGlvbl90aW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvblRpbWUoYm9keSk7XG4gICAgYm9keS5leHBpcmF0aW9uX2ludGVydmFsID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkpO1xuICAgIGlmIChib2R5LmV4cGlyYXRpb25fdGltZSAmJiBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnQm90aCBleHBpcmF0aW9uX3RpbWUgYW5kIGV4cGlyYXRpb25faW50ZXJ2YWwgY2Fubm90IGJlIHNldCdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gSW1tZWRpYXRlIHB1c2hcbiAgICBpZiAoYm9keS5leHBpcmF0aW9uX2ludGVydmFsICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpKSB7XG4gICAgICBjb25zdCB0dGxNcyA9IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCAqIDEwMDA7XG4gICAgICBib2R5LmV4cGlyYXRpb25fdGltZSA9IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyB0dGxNcykudmFsdWVPZigpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1c2hUaW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0UHVzaFRpbWUoYm9keSk7XG4gICAgaWYgKHB1c2hUaW1lICYmIHB1c2hUaW1lLmRhdGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5WydwdXNoX3RpbWUnXSA9IFB1c2hDb250cm9sbGVyLmZvcm1hdFB1c2hUaW1lKHB1c2hUaW1lKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBJZiB0aGUgcmVxIGNhbiBwYXNzIHRoZSBjaGVja2luZywgd2UgcmV0dXJuIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZ1xuICAgIC8vIHB1c2hlcyB0byBiZSBzZW50LiBXZSBwcm9iYWJseSBjaGFuZ2UgdGhpcyBiZWhhdmlvdXIgaW4gdGhlIGZ1dHVyZS5cbiAgICBsZXQgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfTtcblxuICAgIGlmIChib2R5LmRhdGEgJiYgYm9keS5kYXRhLmJhZGdlKSB7XG4gICAgICBjb25zdCBiYWRnZSA9IGJvZHkuZGF0YS5iYWRnZTtcbiAgICAgIGxldCByZXN0VXBkYXRlID0ge307XG4gICAgICBpZiAodHlwZW9mIGJhZGdlID09ICdzdHJpbmcnICYmIGJhZGdlLnRvTG93ZXJDYXNlKCkgPT09ICdpbmNyZW1lbnQnKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IDEgfSB9O1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIGJhZGdlID09ICdvYmplY3QnICYmXG4gICAgICAgIHR5cGVvZiBiYWRnZS5fX29wID09ICdzdHJpbmcnICYmXG4gICAgICAgIGJhZGdlLl9fb3AudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50JyAmJlxuICAgICAgICBOdW1iZXIoYmFkZ2UuYW1vdW50KVxuICAgICAgKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGJhZGdlLmFtb3VudCB9IH07XG4gICAgICB9IGVsc2UgaWYgKE51bWJlcihiYWRnZSkpIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IGJhZGdlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBcIkludmFsaWQgdmFsdWUgZm9yIGJhZGdlLCBleHBlY3RlZCBudW1iZXIgb3IgJ0luY3JlbWVudCcgb3Ige2luY3JlbWVudDogbnVtYmVyfVwiO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3JjZSBmaWx0ZXJpbmcgb24gb25seSB2YWxpZCBkZXZpY2UgdG9rZW5zXG4gICAgICBjb25zdCB1cGRhdGVXaGVyZSA9IGFwcGx5RGV2aWNlVG9rZW5FeGlzdHMod2hlcmUpO1xuICAgICAgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICAgIC8vIEJ1aWxkIGEgcmVhbCBSZXN0UXVlcnkgc28gd2UgY2FuIHVzZSBpdCBpbiBSZXN0V3JpdGVcbiAgICAgICAgY29uc3QgcmVzdFF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShjb25maWcsIG1hc3Rlcihjb25maWcpLCAnX0luc3RhbGxhdGlvbicsIHVwZGF0ZVdoZXJlKTtcbiAgICAgICAgcmV0dXJuIHJlc3RRdWVyeS5idWlsZFJlc3RXaGVyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdyaXRlID0gbmV3IFJlc3RXcml0ZShcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIG1hc3Rlcihjb25maWcpLFxuICAgICAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICAgICAgcmVzdFF1ZXJ5LnJlc3RXaGVyZSxcbiAgICAgICAgICAgIHJlc3RVcGRhdGVcbiAgICAgICAgICApO1xuICAgICAgICAgIHdyaXRlLnJ1bk9wdGlvbnMubWFueSA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBwdXNoU3RhdHVzID0gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuc2V0SW5pdGlhbChib2R5LCB3aGVyZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBvblB1c2hTdGF0dXNTYXZlZChwdXNoU3RhdHVzLm9iamVjdElkKTtcbiAgICAgICAgcmV0dXJuIGJhZGdlVXBkYXRlKCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBVcGRhdGUgYXVkaWVuY2UgbGFzdFVzZWQgYW5kIHRpbWVzVXNlZFxuICAgICAgICBpZiAoYm9keS5hdWRpZW5jZV9pZCkge1xuICAgICAgICAgIGNvbnN0IGF1ZGllbmNlSWQgPSBib2R5LmF1ZGllbmNlX2lkO1xuXG4gICAgICAgICAgdmFyIHVwZGF0ZUF1ZGllbmNlID0ge1xuICAgICAgICAgICAgbGFzdFVzZWQ6IHsgX190eXBlOiAnRGF0ZScsIGlzbzogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0sXG4gICAgICAgICAgICB0aW1lc1VzZWQ6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3Qgd3JpdGUgPSBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICAgICAnX0F1ZGllbmNlJyxcbiAgICAgICAgICAgIHsgb2JqZWN0SWQ6IGF1ZGllbmNlSWQgfSxcbiAgICAgICAgICAgIHVwZGF0ZUF1ZGllbmNlXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3cml0ZS5leGVjdXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRG9uJ3Qgd2FpdCBmb3IgdGhlIGF1ZGllbmNlIHVwZGF0ZSBwcm9taXNlIHRvIHJlc29sdmUuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpICYmXG4gICAgICAgICAgY29uZmlnLmhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0XG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uZmlnLnB1c2hDb250cm9sbGVyUXVldWUuZW5xdWV1ZShib2R5LCB3aGVyZSwgY29uZmlnLCBhdXRoLCBwdXNoU3RhdHVzKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuZmFpbChlcnIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwaXJhdGlvbiB0aW1lIGZyb20gdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgQSByZXF1ZXN0IG9iamVjdFxuICAgKiBAcmV0dXJucyB7TnVtYmVyfHVuZGVmaW5lZH0gVGhlIGV4cGlyYXRpb24gdGltZSBpZiBpdCBleGlzdHMgaW4gdGhlIHJlcXVlc3RcbiAgICovXG4gIHN0YXRpYyBnZXRFeHBpcmF0aW9uVGltZShib2R5ID0ge30pIHtcbiAgICB2YXIgaGFzRXhwaXJhdGlvblRpbWUgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ2V4cGlyYXRpb25fdGltZScpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvblRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGV4cGlyYXRpb25UaW1lUGFyYW0gPSBib2R5WydleHBpcmF0aW9uX3RpbWUnXTtcbiAgICB2YXIgZXhwaXJhdGlvblRpbWU7XG4gICAgaWYgKHR5cGVvZiBleHBpcmF0aW9uVGltZVBhcmFtID09PSAnbnVtYmVyJykge1xuICAgICAgZXhwaXJhdGlvblRpbWUgPSBuZXcgRGF0ZShleHBpcmF0aW9uVGltZVBhcmFtICogMTAwMCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwaXJhdGlvblRpbWVQYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGV4cGlyYXRpb25UaW1lID0gbmV3IERhdGUoZXhwaXJhdGlvblRpbWVQYXJhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydleHBpcmF0aW9uX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgZXhwaXJhdGlvblRpbWUgaXMgdmFsaWQgb3Igbm90LCBpZiBpdCBpcyBub3QgdmFsaWQsIGV4cGlyYXRpb25UaW1lIGlzIE5hTlxuICAgIGlmICghaXNGaW5pdGUoZXhwaXJhdGlvblRpbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsnZXhwaXJhdGlvbl90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBleHBpcmF0aW9uVGltZS52YWx1ZU9mKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkgPSB7fSkge1xuICAgIGNvbnN0IGhhc0V4cGlyYXRpb25JbnRlcnZhbCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAnZXhwaXJhdGlvbl9pbnRlcnZhbCcpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvbkludGVydmFsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtID0gYm9keVsnZXhwaXJhdGlvbl9pbnRlcnZhbCddO1xuICAgIGlmICh0eXBlb2YgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gIT09ICdudW1iZXInIHx8IGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBgZXhwaXJhdGlvbl9pbnRlcnZhbCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwdXNoIHRpbWUgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtOdW1iZXJ8dW5kZWZpbmVkfSBUaGUgcHVzaCB0aW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgcmVxdWVzdFxuICAgKi9cbiAgc3RhdGljIGdldFB1c2hUaW1lKGJvZHkgPSB7fSkge1xuICAgIHZhciBoYXNQdXNoVGltZSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJyk7XG4gICAgaWYgKCFoYXNQdXNoVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcHVzaFRpbWVQYXJhbSA9IGJvZHlbJ3B1c2hfdGltZSddO1xuICAgIHZhciBkYXRlO1xuICAgIHZhciBpc0xvY2FsVGltZSA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdudW1iZXInKSB7XG4gICAgICBkYXRlID0gbmV3IERhdGUocHVzaFRpbWVQYXJhbSAqIDEwMDApO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBpc0xvY2FsVGltZSA9ICFQdXNoQ29udHJvbGxlci5wdXNoVGltZUhhc1RpbWV6b25lQ29tcG9uZW50KHB1c2hUaW1lUGFyYW0pO1xuICAgICAgZGF0ZSA9IG5ldyBEYXRlKHB1c2hUaW1lUGFyYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENoZWNrIHB1c2hUaW1lIGlzIHZhbGlkIG9yIG5vdCwgaWYgaXQgaXMgbm90IHZhbGlkLCBwdXNoVGltZSBpcyBOYU5cbiAgICBpZiAoIWlzRmluaXRlKGRhdGUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGUsXG4gICAgICBpc0xvY2FsVGltZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhIElTTzg2MDEgZm9ybWF0dGVkIGRhdGUgY29udGFpbnMgYSB0aW1lem9uZSBjb21wb25lbnRcbiAgICogQHBhcmFtIHB1c2hUaW1lUGFyYW0ge3N0cmluZ31cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgcHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudChwdXNoVGltZVBhcmFtOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBvZmZzZXRQYXR0ZXJuID0gLyguKykoWystXSlcXGRcXGQ6XFxkXFxkJC87XG4gICAgcmV0dXJuIChcbiAgICAgIHB1c2hUaW1lUGFyYW0uaW5kZXhPZignWicpID09PSBwdXNoVGltZVBhcmFtLmxlbmd0aCAtIDEgfHwgb2Zmc2V0UGF0dGVybi50ZXN0KHB1c2hUaW1lUGFyYW0pIC8vIDIwMDctMDQtMDVUMTI6MzBaXG4gICAgKTsgLy8gMjAwNy0wNC0wNVQxMjozMC4wMDArMDI6MDAsIDIwMDctMDQtMDVUMTI6MzAuMDAwLTAyOjAwXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBkYXRlIHRvIElTTyBmb3JtYXQgaW4gVVRDIHRpbWUgYW5kIHN0cmlwcyB0aGUgdGltZXpvbmUgaWYgYGlzTG9jYWxUaW1lYCBpcyB0cnVlXG4gICAqIEBwYXJhbSBkYXRlIHtEYXRlfVxuICAgKiBAcGFyYW0gaXNMb2NhbFRpbWUge2Jvb2xlYW59XG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBzdGF0aWMgZm9ybWF0UHVzaFRpbWUoeyBkYXRlLCBpc0xvY2FsVGltZSB9OiB7IGRhdGU6IERhdGUsIGlzTG9jYWxUaW1lOiBib29sZWFuIH0pIHtcbiAgICBpZiAoaXNMb2NhbFRpbWUpIHtcbiAgICAgIC8vIFN0cmlwICdaJ1xuICAgICAgY29uc3QgaXNvU3RyaW5nID0gZGF0ZS50b0lTT1N0cmluZygpO1xuICAgICAgcmV0dXJuIGlzb1N0cmluZy5zdWJzdHJpbmcoMCwgaXNvU3RyaW5nLmluZGV4T2YoJ1onKSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaENvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/SchemaCache.js b/lib/Controllers/SchemaCache.js new file mode 100644 index 0000000000..ff750893eb --- /dev/null +++ b/lib/Controllers/SchemaCache.js @@ -0,0 +1,75 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _cryptoUtils = require("../cryptoUtils"); + +var _defaults = _interopRequireDefault(require("../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const MAIN_SCHEMA = '__MAIN_SCHEMA'; +const SCHEMA_CACHE_PREFIX = '__SCHEMA'; + +class SchemaCache { + constructor(cacheController, ttl = _defaults.default.schemaCacheTTL, singleCache = false) { + this.ttl = ttl; + + if (typeof ttl == 'string') { + this.ttl = parseInt(ttl); + } + + this.cache = cacheController; + this.prefix = SCHEMA_CACHE_PREFIX; + + if (!singleCache) { + this.prefix += (0, _cryptoUtils.randomString)(20); + } + } + + getAllClasses() { + if (!this.ttl) { + return Promise.resolve(null); + } + + return this.cache.get(this.prefix + MAIN_SCHEMA); + } + + setAllClasses(schema) { + if (!this.ttl) { + return Promise.resolve(null); + } + + return this.cache.put(this.prefix + MAIN_SCHEMA, schema); + } + + getOneSchema(className) { + if (!this.ttl) { + return Promise.resolve(null); + } + + return this.cache.get(this.prefix + MAIN_SCHEMA).then(cachedSchemas => { + cachedSchemas = cachedSchemas || []; + const schema = cachedSchemas.find(cachedSchema => { + return cachedSchema.className === className; + }); + + if (schema) { + return Promise.resolve(schema); + } + + return Promise.resolve(null); + }); + } + + clear() { + return this.cache.del(this.prefix + MAIN_SCHEMA); + } + +} + +exports.default = SchemaCache; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDYWNoZS5qcyJdLCJuYW1lcyI6WyJNQUlOX1NDSEVNQSIsIlNDSEVNQV9DQUNIRV9QUkVGSVgiLCJTY2hlbWFDYWNoZSIsImNvbnN0cnVjdG9yIiwiY2FjaGVDb250cm9sbGVyIiwidHRsIiwiZGVmYXVsdHMiLCJzY2hlbWFDYWNoZVRUTCIsInNpbmdsZUNhY2hlIiwicGFyc2VJbnQiLCJjYWNoZSIsInByZWZpeCIsImdldEFsbENsYXNzZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldCIsInNldEFsbENsYXNzZXMiLCJzY2hlbWEiLCJwdXQiLCJnZXRPbmVTY2hlbWEiLCJjbGFzc05hbWUiLCJ0aGVuIiwiY2FjaGVkU2NoZW1hcyIsImZpbmQiLCJjYWNoZWRTY2hlbWEiLCJjbGVhciIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUdBOztBQUNBOzs7O0FBSkEsTUFBTUEsV0FBVyxHQUFHLGVBQXBCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsVUFBNUI7O0FBS2UsTUFBTUMsV0FBTixDQUFrQjtBQUcvQkMsRUFBQUEsV0FBVyxDQUFDQyxlQUFELEVBQWtCQyxHQUFHLEdBQUdDLGtCQUFTQyxjQUFqQyxFQUFpREMsV0FBVyxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtILEdBQUwsR0FBV0EsR0FBWDs7QUFDQSxRQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFLQSxHQUFMLEdBQVdJLFFBQVEsQ0FBQ0osR0FBRCxDQUFuQjtBQUNEOztBQUNELFNBQUtLLEtBQUwsR0FBYU4sZUFBYjtBQUNBLFNBQUtPLE1BQUwsR0FBY1YsbUJBQWQ7O0FBQ0EsUUFBSSxDQUFDTyxXQUFMLEVBQWtCO0FBQ2hCLFdBQUtHLE1BQUwsSUFBZSwrQkFBYSxFQUFiLENBQWY7QUFDRDtBQUNGOztBQUVEQyxFQUFBQSxhQUFhLEdBQUc7QUFDZCxRQUFJLENBQUMsS0FBS1AsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsQ0FBUDtBQUNEOztBQUVEZ0IsRUFBQUEsYUFBYSxDQUFDQyxNQUFELEVBQVM7QUFDcEIsUUFBSSxDQUFDLEtBQUtaLEdBQVYsRUFBZTtBQUNiLGFBQU9RLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxLQUFLSixLQUFMLENBQVdRLEdBQVgsQ0FBZSxLQUFLUCxNQUFMLEdBQWNYLFdBQTdCLEVBQTBDaUIsTUFBMUMsQ0FBUDtBQUNEOztBQUVERSxFQUFBQSxZQUFZLENBQUNDLFNBQUQsRUFBWTtBQUN0QixRQUFJLENBQUMsS0FBS2YsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsRUFBMENxQixJQUExQyxDQUErQ0MsYUFBYSxJQUFJO0FBQ3JFQSxNQUFBQSxhQUFhLEdBQUdBLGFBQWEsSUFBSSxFQUFqQztBQUNBLFlBQU1MLE1BQU0sR0FBR0ssYUFBYSxDQUFDQyxJQUFkLENBQW1CQyxZQUFZLElBQUk7QUFDaEQsZUFBT0EsWUFBWSxDQUFDSixTQUFiLEtBQTJCQSxTQUFsQztBQUNELE9BRmMsQ0FBZjs7QUFHQSxVQUFJSCxNQUFKLEVBQVk7QUFDVixlQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0JHLE1BQWhCLENBQVA7QUFDRDs7QUFDRCxhQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNELEtBVE0sQ0FBUDtBQVVEOztBQUVEVyxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtmLEtBQUwsQ0FBV2dCLEdBQVgsQ0FBZSxLQUFLZixNQUFMLEdBQWNYLFdBQTdCLENBQVA7QUFDRDs7QUEvQzhCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgTUFJTl9TQ0hFTUEgPSAnX19NQUlOX1NDSEVNQSc7XG5jb25zdCBTQ0hFTUFfQ0FDSEVfUFJFRklYID0gJ19fU0NIRU1BJztcblxuaW1wb3J0IHsgcmFuZG9tU3RyaW5nIH0gZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NoZW1hQ2FjaGUge1xuICBjYWNoZTogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKGNhY2hlQ29udHJvbGxlciwgdHRsID0gZGVmYXVsdHMuc2NoZW1hQ2FjaGVUVEwsIHNpbmdsZUNhY2hlID0gZmFsc2UpIHtcbiAgICB0aGlzLnR0bCA9IHR0bDtcbiAgICBpZiAodHlwZW9mIHR0bCA9PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy50dGwgPSBwYXJzZUludCh0dGwpO1xuICAgIH1cbiAgICB0aGlzLmNhY2hlID0gY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMucHJlZml4ID0gU0NIRU1BX0NBQ0hFX1BSRUZJWDtcbiAgICBpZiAoIXNpbmdsZUNhY2hlKSB7XG4gICAgICB0aGlzLnByZWZpeCArPSByYW5kb21TdHJpbmcoMjApO1xuICAgIH1cbiAgfVxuXG4gIGdldEFsbENsYXNzZXMoKSB7XG4gICAgaWYgKCF0aGlzLnR0bCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRoaXMucHJlZml4ICsgTUFJTl9TQ0hFTUEpO1xuICB9XG5cbiAgc2V0QWxsQ2xhc3NlcyhzY2hlbWEpIHtcbiAgICBpZiAoIXRoaXMudHRsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZS5wdXQodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSwgc2NoZW1hKTtcbiAgfVxuXG4gIGdldE9uZVNjaGVtYShjbGFzc05hbWUpIHtcbiAgICBpZiAoIXRoaXMudHRsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXQodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSkudGhlbihjYWNoZWRTY2hlbWFzID0+IHtcbiAgICAgIGNhY2hlZFNjaGVtYXMgPSBjYWNoZWRTY2hlbWFzIHx8IFtdO1xuICAgICAgY29uc3Qgc2NoZW1hID0gY2FjaGVkU2NoZW1hcy5maW5kKGNhY2hlZFNjaGVtYSA9PiB7XG4gICAgICAgIHJldHVybiBjYWNoZWRTY2hlbWEuY2xhc3NOYW1lID09PSBjbGFzc05hbWU7XG4gICAgICB9KTtcbiAgICAgIGlmIChzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzY2hlbWEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlLmRlbCh0aGlzLnByZWZpeCArIE1BSU5fU0NIRU1BKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Controllers/SchemaController.js b/lib/Controllers/SchemaController.js new file mode 100644 index 0000000000..c7027fd3f3 --- /dev/null +++ b/lib/Controllers/SchemaController.js @@ -0,0 +1,1662 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.classNameIsValid = classNameIsValid; +exports.fieldNameIsValid = fieldNameIsValid; +exports.invalidClassNameMessage = invalidClassNameMessage; +exports.buildMergedSchemaObject = buildMergedSchemaObject; +exports.VolatileClassesSchemas = exports.convertSchemaToAdapterSchema = exports.defaultColumns = exports.systemClasses = exports.load = exports.SchemaController = exports.default = void 0; + +var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); + +var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + +// This class handles schema validation, persistence, and modification. +// +// Each individual Schema object should be immutable. The helpers to +// do things with the Schema just return a new schema when the schema +// is changed. +// +// The canonical place to store this Schema is in the database itself, +// in a _SCHEMA collection. This is not the right way to do it for an +// open source framework, but it's backward compatible, so we're +// keeping it this way for now. +// +// In API-handling code, you should only use the Schema class via the +// DatabaseController. This will let us replace the schema logic for +// different databases. +// TODO: hide all schema logic inside the database adapter. +// -disable-next +const Parse = require('parse/node').Parse; + +const defaultColumns = Object.freeze({ + // Contain the default columns for every parse object type (except _Join collection) + _Default: { + objectId: { + type: 'String' + }, + createdAt: { + type: 'Date' + }, + updatedAt: { + type: 'Date' + }, + ACL: { + type: 'ACL' + } + }, + // The additional default columns for the _User collection (in addition to DefaultCols) + _User: { + username: { + type: 'String' + }, + password: { + type: 'String' + }, + email: { + type: 'String' + }, + emailVerified: { + type: 'Boolean' + }, + authData: { + type: 'Object' + } + }, + // The additional default columns for the _Installation collection (in addition to DefaultCols) + _Installation: { + installationId: { + type: 'String' + }, + deviceToken: { + type: 'String' + }, + channels: { + type: 'Array' + }, + deviceType: { + type: 'String' + }, + pushType: { + type: 'String' + }, + GCMSenderId: { + type: 'String' + }, + timeZone: { + type: 'String' + }, + localeIdentifier: { + type: 'String' + }, + badge: { + type: 'Number' + }, + appVersion: { + type: 'String' + }, + appName: { + type: 'String' + }, + appIdentifier: { + type: 'String' + }, + parseVersion: { + type: 'String' + } + }, + // The additional default columns for the _Role collection (in addition to DefaultCols) + _Role: { + name: { + type: 'String' + }, + users: { + type: 'Relation', + targetClass: '_User' + }, + roles: { + type: 'Relation', + targetClass: '_Role' + } + }, + // The additional default columns for the _Session collection (in addition to DefaultCols) + _Session: { + restricted: { + type: 'Boolean' + }, + user: { + type: 'Pointer', + targetClass: '_User' + }, + installationId: { + type: 'String' + }, + sessionToken: { + type: 'String' + }, + expiresAt: { + type: 'Date' + }, + createdWith: { + type: 'Object' + } + }, + _Product: { + productIdentifier: { + type: 'String' + }, + download: { + type: 'File' + }, + downloadName: { + type: 'String' + }, + icon: { + type: 'File' + }, + order: { + type: 'Number' + }, + title: { + type: 'String' + }, + subtitle: { + type: 'String' + } + }, + _PushStatus: { + pushTime: { + type: 'String' + }, + source: { + type: 'String' + }, + // rest or webui + query: { + type: 'String' + }, + // the stringified JSON query + payload: { + type: 'String' + }, + // the stringified JSON payload, + title: { + type: 'String' + }, + expiry: { + type: 'Number' + }, + expiration_interval: { + type: 'Number' + }, + status: { + type: 'String' + }, + numSent: { + type: 'Number' + }, + numFailed: { + type: 'Number' + }, + pushHash: { + type: 'String' + }, + errorMessage: { + type: 'Object' + }, + sentPerType: { + type: 'Object' + }, + failedPerType: { + type: 'Object' + }, + sentPerUTCOffset: { + type: 'Object' + }, + failedPerUTCOffset: { + type: 'Object' + }, + count: { + type: 'Number' + } // tracks # of batches queued and pending + + }, + _JobStatus: { + jobName: { + type: 'String' + }, + source: { + type: 'String' + }, + status: { + type: 'String' + }, + message: { + type: 'String' + }, + params: { + type: 'Object' + }, + // params received when calling the job + finishedAt: { + type: 'Date' + } + }, + _JobSchedule: { + jobName: { + type: 'String' + }, + description: { + type: 'String' + }, + params: { + type: 'String' + }, + startAfter: { + type: 'String' + }, + daysOfWeek: { + type: 'Array' + }, + timeOfDay: { + type: 'String' + }, + lastRun: { + type: 'Number' + }, + repeatMinutes: { + type: 'Number' + } + }, + _Hooks: { + functionName: { + type: 'String' + }, + className: { + type: 'String' + }, + triggerName: { + type: 'String' + }, + url: { + type: 'String' + } + }, + _GlobalConfig: { + objectId: { + type: 'String' + }, + params: { + type: 'Object' + }, + masterKeyOnly: { + type: 'Object' + } + }, + _GraphQLConfig: { + objectId: { + type: 'String' + }, + config: { + type: 'Object' + } + }, + _Audience: { + objectId: { + type: 'String' + }, + name: { + type: 'String' + }, + query: { + type: 'String' + }, + //storing query as JSON string to prevent "Nested keys should not contain the '$' or '.' characters" error + lastUsed: { + type: 'Date' + }, + timesUsed: { + type: 'Number' + } + }, + _Idempotency: { + reqId: { + type: 'String' + }, + expire: { + type: 'Date' + } + } +}); +exports.defaultColumns = defaultColumns; +const requiredColumns = Object.freeze({ + _Product: ['productIdentifier', 'icon', 'order', 'title', 'subtitle'], + _Role: ['name', 'ACL'] +}); +const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_JobSchedule', '_Audience', '_Idempotency']); +exports.systemClasses = systemClasses; +const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_JobSchedule', '_Audience', '_Idempotency']); // Anything that start with role + +const roleRegex = /^role:.*/; // Anything that starts with userField (allowed for protected fields only) + +const protectedFieldsPointerRegex = /^userField:.*/; // * permission + +const publicRegex = /^\*$/; +const authenticatedRegex = /^authenticated$/; +const requiresAuthenticationRegex = /^requiresAuthentication$/; +const clpPointerRegex = /^pointerFields$/; // regex for validating entities in protectedFields object + +const protectedFieldsRegex = Object.freeze([protectedFieldsPointerRegex, publicRegex, authenticatedRegex, roleRegex]); // clp regex + +const clpFieldsRegex = Object.freeze([clpPointerRegex, publicRegex, requiresAuthenticationRegex, roleRegex]); + +function validatePermissionKey(key, userIdRegExp) { + let matchesSome = false; + + for (const regEx of clpFieldsRegex) { + if (key.match(regEx) !== null) { + matchesSome = true; + break; + } + } // userId depends on startup options so it's dynamic + + + const valid = matchesSome || key.match(userIdRegExp) !== null; + + if (!valid) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); + } +} + +function validateProtectedFieldsKey(key, userIdRegExp) { + let matchesSome = false; + + for (const regEx of protectedFieldsRegex) { + if (key.match(regEx) !== null) { + matchesSome = true; + break; + } + } // userId regex depends on launch options so it's dynamic + + + const valid = matchesSome || key.match(userIdRegExp) !== null; + + if (!valid) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); + } +} + +const CLPValidKeys = Object.freeze(['find', 'count', 'get', 'create', 'update', 'delete', 'addField', 'readUserFields', 'writeUserFields', 'protectedFields']); // validation before setting class-level permissions on collection + +function validateCLP(perms, fields, userIdRegExp) { + if (!perms) { + return; + } + + for (const operationKey in perms) { + if (CLPValidKeys.indexOf(operationKey) == -1) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `${operationKey} is not a valid operation for class level permissions`); + } + + const operation = perms[operationKey]; // proceed with next operationKey + // throws when root fields are of wrong type + + validateCLPjson(operation, operationKey); + + if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { + // validate grouped pointer permissions + // must be an array with field names + for (const fieldName of operation) { + validatePointerPermission(fieldName, fields, operationKey); + } // readUserFields and writerUserFields do not have nesdted fields + // proceed with next operationKey + + + continue; + } // validate protected fields + + + if (operationKey === 'protectedFields') { + for (const entity in operation) { + // throws on unexpected key + validateProtectedFieldsKey(entity, userIdRegExp); + const protectedFields = operation[entity]; + + if (!Array.isArray(protectedFields)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${protectedFields}' is not a valid value for protectedFields[${entity}] - expected an array.`); + } // if the field is in form of array + + + for (const field of protectedFields) { + // do not alloow to protect default fields + if (defaultColumns._Default[field]) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Default field '${field}' can not be protected`); + } // field should exist on collection + + + if (!Object.prototype.hasOwnProperty.call(fields, field)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Field '${field}' in protectedFields:${entity} does not exist`); + } + } + } // proceed with next operationKey + + + continue; + } // validate other fields + // Entity can be: + // "*" - Public, + // "requiresAuthentication" - authenticated users, + // "objectId" - _User id, + // "role:rolename", + // "pointerFields" - array of field names containing pointers to users + + + for (const entity in operation) { + // throws on unexpected key + validatePermissionKey(entity, userIdRegExp); // entity can be either: + // "pointerFields": string[] + + if (entity === 'pointerFields') { + const pointerFields = operation[entity]; + + if (Array.isArray(pointerFields)) { + for (const pointerField of pointerFields) { + validatePointerPermission(pointerField, fields, operation); + } + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${pointerFields}' is not a valid value for ${operationKey}[${entity}] - expected an array.`); + } // proceed with next entity key + + + continue; + } // or [entity]: boolean + + + const permit = operation[entity]; + + if (permit !== true) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${permit}' is not a valid value for class level permissions ${operationKey}:${entity}:${permit}`); + } + } + } +} + +function validateCLPjson(operation, operationKey) { + if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { + if (!Array.isArray(operation)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an array`); + } + } else { + if (typeof operation === 'object' && operation !== null) { + // ok to proceed + return; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an object`); + } + } +} + +function validatePointerPermission(fieldName, fields, operation) { + // Uses collection schema to ensure the field is of type: + // - Pointer<_User> (pointers) + // - Array + // + // It's not possible to enforce type on Array's items in schema + // so we accept any Array field, and later when applying permissions + // only items that are pointers to _User are considered. + if (!(fields[fieldName] && (fields[fieldName].type == 'Pointer' && fields[fieldName].targetClass == '_User' || fields[fieldName].type == 'Array'))) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${fieldName}' is not a valid column for class level pointer permissions ${operation}`); + } +} + +const joinClassRegex = /^_Join:[A-Za-z0-9_]+:[A-Za-z0-9_]+/; +const classAndFieldRegex = /^[A-Za-z][A-Za-z0-9_]*$/; + +function classNameIsValid(className) { + // Valid classes must: + return (// Be one of _User, _Installation, _Role, _Session OR + systemClasses.indexOf(className) > -1 || // Be a join table OR + joinClassRegex.test(className) || // Include only alpha-numeric and underscores, and not start with an underscore or number + fieldNameIsValid(className) + ); +} // Valid fields must be alpha-numeric, and not start with an underscore or number + + +function fieldNameIsValid(fieldName) { + return classAndFieldRegex.test(fieldName); +} // Checks that it's not trying to clobber one of the default fields of the class. + + +function fieldNameIsValidForClass(fieldName, className) { + if (!fieldNameIsValid(fieldName)) { + return false; + } + + if (defaultColumns._Default[fieldName]) { + return false; + } + + if (defaultColumns[className] && defaultColumns[className][fieldName]) { + return false; + } + + return true; +} + +function invalidClassNameMessage(className) { + return 'Invalid classname: ' + className + ', classnames can only have alphanumeric characters and _, and must start with an alpha character '; +} + +const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, 'invalid JSON'); +const validNonRelationOrPointerTypes = ['Number', 'String', 'Boolean', 'Date', 'Object', 'Array', 'GeoPoint', 'File', 'Bytes', 'Polygon']; // Returns an error suitable for throwing if the type is invalid + +const fieldTypeIsInvalid = ({ + type, + targetClass +}) => { + if (['Pointer', 'Relation'].indexOf(type) >= 0) { + if (!targetClass) { + return new Parse.Error(135, `type ${type} needs a class name`); + } else if (typeof targetClass !== 'string') { + return invalidJsonError; + } else if (!classNameIsValid(targetClass)) { + return new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(targetClass)); + } else { + return undefined; + } + } + + if (typeof type !== 'string') { + return invalidJsonError; + } + + if (validNonRelationOrPointerTypes.indexOf(type) < 0) { + return new Parse.Error(Parse.Error.INCORRECT_TYPE, `invalid field type: ${type}`); + } + + return undefined; +}; + +const convertSchemaToAdapterSchema = schema => { + schema = injectDefaultSchema(schema); + delete schema.fields.ACL; + schema.fields._rperm = { + type: 'Array' + }; + schema.fields._wperm = { + type: 'Array' + }; + + if (schema.className === '_User') { + delete schema.fields.password; + schema.fields._hashed_password = { + type: 'String' + }; + } + + return schema; +}; + +exports.convertSchemaToAdapterSchema = convertSchemaToAdapterSchema; + +const convertAdapterSchemaToParseSchema = (_ref) => { + let schema = _extends({}, _ref); + + delete schema.fields._rperm; + delete schema.fields._wperm; + schema.fields.ACL = { + type: 'ACL' + }; + + if (schema.className === '_User') { + delete schema.fields.authData; //Auth data is implicit + + delete schema.fields._hashed_password; + schema.fields.password = { + type: 'String' + }; + } + + if (schema.indexes && Object.keys(schema.indexes).length === 0) { + delete schema.indexes; + } + + return schema; +}; + +class SchemaData { + constructor(allSchemas = [], protectedFields = {}) { + this.__data = {}; + this.__protectedFields = protectedFields; + allSchemas.forEach(schema => { + if (volatileClasses.includes(schema.className)) { + return; + } + + Object.defineProperty(this, schema.className, { + get: () => { + if (!this.__data[schema.className]) { + const data = {}; + data.fields = injectDefaultSchema(schema).fields; + data.classLevelPermissions = (0, _deepcopy.default)(schema.classLevelPermissions); + data.indexes = schema.indexes; + const classProtectedFields = this.__protectedFields[schema.className]; + + if (classProtectedFields) { + for (const key in classProtectedFields) { + const unq = new Set([...(data.classLevelPermissions.protectedFields[key] || []), ...classProtectedFields[key]]); + data.classLevelPermissions.protectedFields[key] = Array.from(unq); + } + } + + this.__data[schema.className] = data; + } + + return this.__data[schema.className]; + } + }); + }); // Inject the in-memory classes + + volatileClasses.forEach(className => { + Object.defineProperty(this, className, { + get: () => { + if (!this.__data[className]) { + const schema = injectDefaultSchema({ + className, + fields: {}, + classLevelPermissions: {} + }); + const data = {}; + data.fields = schema.fields; + data.classLevelPermissions = schema.classLevelPermissions; + data.indexes = schema.indexes; + this.__data[className] = data; + } + + return this.__data[className]; + } + }); + }); + } + +} + +const injectDefaultSchema = ({ + className, + fields, + classLevelPermissions, + indexes +}) => { + const defaultSchema = { + className, + fields: _objectSpread(_objectSpread(_objectSpread({}, defaultColumns._Default), defaultColumns[className] || {}), fields), + classLevelPermissions + }; + + if (indexes && Object.keys(indexes).length !== 0) { + defaultSchema.indexes = indexes; + } + + return defaultSchema; +}; + +const _HooksSchema = { + className: '_Hooks', + fields: defaultColumns._Hooks +}; +const _GlobalConfigSchema = { + className: '_GlobalConfig', + fields: defaultColumns._GlobalConfig +}; +const _GraphQLConfigSchema = { + className: '_GraphQLConfig', + fields: defaultColumns._GraphQLConfig +}; + +const _PushStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_PushStatus', + fields: {}, + classLevelPermissions: {} +})); + +const _JobStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_JobStatus', + fields: {}, + classLevelPermissions: {} +})); + +const _JobScheduleSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_JobSchedule', + fields: {}, + classLevelPermissions: {} +})); + +const _AudienceSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_Audience', + fields: defaultColumns._Audience, + classLevelPermissions: {} +})); + +const _IdempotencySchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_Idempotency', + fields: defaultColumns._Idempotency, + classLevelPermissions: {} +})); + +const VolatileClassesSchemas = [_HooksSchema, _JobStatusSchema, _JobScheduleSchema, _PushStatusSchema, _GlobalConfigSchema, _GraphQLConfigSchema, _AudienceSchema, _IdempotencySchema]; +exports.VolatileClassesSchemas = VolatileClassesSchemas; + +const dbTypeMatchesObjectType = (dbType, objectType) => { + if (dbType.type !== objectType.type) return false; + if (dbType.targetClass !== objectType.targetClass) return false; + if (dbType === objectType.type) return true; + if (dbType.type === objectType.type) return true; + return false; +}; + +const typeToString = type => { + if (typeof type === 'string') { + return type; + } + + if (type.targetClass) { + return `${type.type}<${type.targetClass}>`; + } + + return `${type.type}`; +}; // Stores the entire schema of the app in a weird hybrid format somewhere between +// the mongo format and the Parse format. Soon, this will all be Parse format. + + +class SchemaController { + constructor(databaseAdapter, schemaCache) { + this._dbAdapter = databaseAdapter; + this._cache = schemaCache; + this.schemaData = new SchemaData(); + this.protectedFields = _Config.default.get(Parse.applicationId).protectedFields; + + const customIds = _Config.default.get(Parse.applicationId).allowCustomObjectId; + + const customIdRegEx = /^.{1,}$/u; // 1+ chars + + const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/; + this.userIdRegEx = customIds ? customIdRegEx : autoIdRegEx; + } + + reloadData(options = { + clearCache: false + }) { + if (this.reloadDataPromise && !options.clearCache) { + return this.reloadDataPromise; + } + + this.reloadDataPromise = this.getAllClasses(options).then(allSchemas => { + this.schemaData = new SchemaData(allSchemas, this.protectedFields); + delete this.reloadDataPromise; + }, err => { + this.schemaData = new SchemaData(); + delete this.reloadDataPromise; + throw err; + }).then(() => {}); + return this.reloadDataPromise; + } + + getAllClasses(options = { + clearCache: false + }) { + if (options.clearCache) { + return this.setAllClasses(); + } + + return this._cache.getAllClasses().then(allClasses => { + if (allClasses && allClasses.length) { + return Promise.resolve(allClasses); + } + + return this.setAllClasses(); + }); + } + + setAllClasses() { + return this._dbAdapter.getAllClasses().then(allSchemas => allSchemas.map(injectDefaultSchema)).then(allSchemas => { + /* eslint-disable no-console */ + this._cache.setAllClasses(allSchemas).catch(error => console.error('Error saving schema to cache:', error)); + /* eslint-enable no-console */ + + + return allSchemas; + }); + } + + getOneSchema(className, allowVolatileClasses = false, options = { + clearCache: false + }) { + let promise = Promise.resolve(); + + if (options.clearCache) { + promise = this._cache.clear(); + } + + return promise.then(() => { + if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) { + const data = this.schemaData[className]; + return Promise.resolve({ + className, + fields: data.fields, + classLevelPermissions: data.classLevelPermissions, + indexes: data.indexes + }); + } + + return this._cache.getOneSchema(className).then(cached => { + if (cached && !options.clearCache) { + return Promise.resolve(cached); + } + + return this.setAllClasses().then(allSchemas => { + const oneSchema = allSchemas.find(schema => schema.className === className); + + if (!oneSchema) { + return Promise.reject(undefined); + } + + return oneSchema; + }); + }); + }); + } // Create a new class that includes the three default fields. + // ACL is an implicit column that does not get an entry in the + // _SCHEMAS database. Returns a promise that resolves with the + // created schema, in mongo format. + // on success, and rejects with an error on fail. Ensure you + // have authorization (master key, or client class creation + // enabled) before calling this function. + + + addClassIfNotExists(className, fields = {}, classLevelPermissions, indexes = {}) { + var validationError = this.validateNewClass(className, fields, classLevelPermissions); + + if (validationError) { + if (validationError instanceof Parse.Error) { + return Promise.reject(validationError); + } else if (validationError.code && validationError.error) { + return Promise.reject(new Parse.Error(validationError.code, validationError.error)); + } + + return Promise.reject(validationError); + } + + return this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({ + fields, + classLevelPermissions, + indexes, + className + })).then(convertAdapterSchemaToParseSchema).catch(error => { + if (error && error.code === Parse.Error.DUPLICATE_VALUE) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); + } else { + throw error; + } + }); + } + + updateClass(className, submittedFields, classLevelPermissions, indexes, database) { + return this.getOneSchema(className).then(schema => { + const existingFields = schema.fields; + Object.keys(submittedFields).forEach(name => { + const field = submittedFields[name]; + + if (existingFields[name] && field.__op !== 'Delete') { + throw new Parse.Error(255, `Field ${name} exists, cannot update.`); + } + + if (!existingFields[name] && field.__op === 'Delete') { + throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`); + } + }); + delete existingFields._rperm; + delete existingFields._wperm; + const newSchema = buildMergedSchemaObject(existingFields, submittedFields); + const defaultFields = defaultColumns[className] || defaultColumns._Default; + const fullNewSchema = Object.assign({}, newSchema, defaultFields); + const validationError = this.validateSchemaData(className, newSchema, classLevelPermissions, Object.keys(existingFields)); + + if (validationError) { + throw new Parse.Error(validationError.code, validationError.error); + } // Finally we have checked to make sure the request is valid and we can start deleting fields. + // Do all deletions first, then a single save to _SCHEMA collection to handle all additions. + + + const deletedFields = []; + const insertedFields = []; + Object.keys(submittedFields).forEach(fieldName => { + if (submittedFields[fieldName].__op === 'Delete') { + deletedFields.push(fieldName); + } else { + insertedFields.push(fieldName); + } + }); + let deletePromise = Promise.resolve(); + + if (deletedFields.length > 0) { + deletePromise = this.deleteFields(deletedFields, className, database); + } + + let enforceFields = []; + return deletePromise // Delete Everything + .then(() => this.reloadData({ + clearCache: true + })) // Reload our Schema, so we have all the new values + .then(() => { + const promises = insertedFields.map(fieldName => { + const type = submittedFields[fieldName]; + return this.enforceFieldExists(className, fieldName, type); + }); + return Promise.all(promises); + }).then(results => { + enforceFields = results.filter(result => !!result); + return this.setPermissions(className, classLevelPermissions, newSchema); + }).then(() => this._dbAdapter.setIndexesWithSchemaFormat(className, indexes, schema.indexes, fullNewSchema)).then(() => this.reloadData({ + clearCache: true + })) //TODO: Move this logic into the database adapter + .then(() => { + this.ensureFields(enforceFields); + const schema = this.schemaData[className]; + const reloadedSchema = { + className: className, + fields: schema.fields, + classLevelPermissions: schema.classLevelPermissions + }; + + if (schema.indexes && Object.keys(schema.indexes).length !== 0) { + reloadedSchema.indexes = schema.indexes; + } + + return reloadedSchema; + }); + }).catch(error => { + if (error === undefined) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); + } else { + throw error; + } + }); + } // Returns a promise that resolves successfully to the new schema + // object or fails with a reason. + + + enforceClassExists(className) { + if (this.schemaData[className]) { + return Promise.resolve(this); + } // We don't have this class. Update the schema + + + return this.addClassIfNotExists(className) // The schema update succeeded. Reload the schema + .then(() => this.reloadData({ + clearCache: true + })).catch(() => { + // The schema update failed. This can be okay - it might + // have failed because there's a race condition and a different + // client is making the exact same schema update that we want. + // So just reload the schema. + return this.reloadData({ + clearCache: true + }); + }).then(() => { + // Ensure that the schema now validates + if (this.schemaData[className]) { + return this; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`); + } + }).catch(() => { + // The schema still doesn't validate. Give up + throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate'); + }); + } + + validateNewClass(className, fields = {}, classLevelPermissions) { + if (this.schemaData[className]) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); + } + + if (!classNameIsValid(className)) { + return { + code: Parse.Error.INVALID_CLASS_NAME, + error: invalidClassNameMessage(className) + }; + } + + return this.validateSchemaData(className, fields, classLevelPermissions, []); + } + + validateSchemaData(className, fields, classLevelPermissions, existingFieldNames) { + for (const fieldName in fields) { + if (existingFieldNames.indexOf(fieldName) < 0) { + if (!fieldNameIsValid(fieldName)) { + return { + code: Parse.Error.INVALID_KEY_NAME, + error: 'invalid field name: ' + fieldName + }; + } + + if (!fieldNameIsValidForClass(fieldName, className)) { + return { + code: 136, + error: 'field ' + fieldName + ' cannot be added' + }; + } + + const fieldType = fields[fieldName]; + const error = fieldTypeIsInvalid(fieldType); + if (error) return { + code: error.code, + error: error.message + }; + + if (fieldType.defaultValue !== undefined) { + let defaultValueType = getType(fieldType.defaultValue); + + if (typeof defaultValueType === 'string') { + defaultValueType = { + type: defaultValueType + }; + } else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') { + return { + code: Parse.Error.INCORRECT_TYPE, + error: `The 'default value' option is not applicable for ${typeToString(fieldType)}` + }; + } + + if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) { + return { + code: Parse.Error.INCORRECT_TYPE, + error: `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(fieldType)} but got ${typeToString(defaultValueType)}` + }; + } + } else if (fieldType.required) { + if (typeof fieldType === 'object' && fieldType.type === 'Relation') { + return { + code: Parse.Error.INCORRECT_TYPE, + error: `The 'required' option is not applicable for ${typeToString(fieldType)}` + }; + } + } + } + } + + for (const fieldName in defaultColumns[className]) { + fields[fieldName] = defaultColumns[className][fieldName]; + } + + const geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint'); + + if (geoPoints.length > 1) { + return { + code: Parse.Error.INCORRECT_TYPE, + error: 'currently, only one GeoPoint field may exist in an object. Adding ' + geoPoints[1] + ' when ' + geoPoints[0] + ' already exists.' + }; + } + + validateCLP(classLevelPermissions, fields, this.userIdRegEx); + } // Sets the Class-level permissions for a given className, which must exist. + + + setPermissions(className, perms, newSchema) { + if (typeof perms === 'undefined') { + return Promise.resolve(); + } + + validateCLP(perms, newSchema, this.userIdRegEx); + return this._dbAdapter.setClassLevelPermissions(className, perms); + } // Returns a promise that resolves successfully to the new schema + // object if the provided className-fieldName-type tuple is valid. + // The className must already be validated. + // If 'freeze' is true, refuse to update the schema for this field. + + + enforceFieldExists(className, fieldName, type) { + if (fieldName.indexOf('.') > 0) { + // subdocument key (x.y) => ok if x is of type 'object' + fieldName = fieldName.split('.')[0]; + type = 'Object'; + } + + if (!fieldNameIsValid(fieldName)) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); + } // If someone tries to create a new field with null/undefined as the value, return; + + + if (!type) { + return undefined; + } + + const expectedType = this.getExpectedType(className, fieldName); + + if (typeof type === 'string') { + type = { + type + }; + } + + if (type.defaultValue !== undefined) { + let defaultValueType = getType(type.defaultValue); + + if (typeof defaultValueType === 'string') { + defaultValueType = { + type: defaultValueType + }; + } + + if (!dbTypeMatchesObjectType(type, defaultValueType)) { + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(type)} but got ${typeToString(defaultValueType)}`); + } + } + + if (expectedType) { + if (!dbTypeMatchesObjectType(expectedType, type)) { + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName}; expected ${typeToString(expectedType)} but got ${typeToString(type)}`); + } + + return undefined; + } + + return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).catch(error => { + if (error.code == Parse.Error.INCORRECT_TYPE) { + // Make sure that we throw errors when it is appropriate to do so. + throw error; + } // The update failed. This can be okay - it might have been a race + // condition where another client updated the schema in the same + // way that we wanted to. So, just reload the schema + + + return Promise.resolve(); + }).then(() => { + return { + className, + fieldName, + type + }; + }); + } + + ensureFields(fields) { + for (let i = 0; i < fields.length; i += 1) { + const { + className, + fieldName + } = fields[i]; + let { + type + } = fields[i]; + const expectedType = this.getExpectedType(className, fieldName); + + if (typeof type === 'string') { + type = { + type: type + }; + } + + if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`); + } + } + } // maintain compatibility + + + deleteField(fieldName, className, database) { + return this.deleteFields([fieldName], className, database); + } // Delete fields, and remove that data from all objects. This is intended + // to remove unused fields, if other writers are writing objects that include + // this field, the field may reappear. Returns a Promise that resolves with + // no object on success, or rejects with { code, error } on failure. + // Passing the database and prefix is necessary in order to drop relation collections + // and remove fields from objects. Ideally the database would belong to + // a database adapter and this function would close over it or access it via member. + + + deleteFields(fieldNames, className, database) { + if (!classNameIsValid(className)) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className)); + } + + fieldNames.forEach(fieldName => { + if (!fieldNameIsValid(fieldName)) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`); + } //Don't allow deleting the default fields. + + + if (!fieldNameIsValidForClass(fieldName, className)) { + throw new Parse.Error(136, `field ${fieldName} cannot be changed`); + } + }); + return this.getOneSchema(className, false, { + clearCache: true + }).catch(error => { + if (error === undefined) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); + } else { + throw error; + } + }).then(schema => { + fieldNames.forEach(fieldName => { + if (!schema.fields[fieldName]) { + throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`); + } + }); + + const schemaFields = _objectSpread({}, schema.fields); + + return database.adapter.deleteFields(className, schema, fieldNames).then(() => { + return Promise.all(fieldNames.map(fieldName => { + const field = schemaFields[fieldName]; + + if (field && field.type === 'Relation') { + //For relations, drop the _Join table + return database.adapter.deleteClass(`_Join:${fieldName}:${className}`); + } + + return Promise.resolve(); + })); + }); + }).then(() => this._cache.clear()); + } // Validates an object provided in REST format. + // Returns a promise that resolves to the new schema if this object is + // valid. + + + async validateObject(className, object, query) { + let geocount = 0; + const schema = await this.enforceClassExists(className); + const promises = []; + + for (const fieldName in object) { + if (object[fieldName] === undefined) { + continue; + } + + const expected = getType(object[fieldName]); + + if (expected === 'GeoPoint') { + geocount++; + } + + if (geocount > 1) { + // Make sure all field validation operations run before we return. + // If not - we are continuing to run logic, but already provided response from the server. + return Promise.reject(new Parse.Error(Parse.Error.INCORRECT_TYPE, 'there can only be one geopoint field in a class')); + } + + if (!expected) { + continue; + } + + if (fieldName === 'ACL') { + // Every object has ACL implicitly. + continue; + } + + promises.push(schema.enforceFieldExists(className, fieldName, expected)); + } + + const results = await Promise.all(promises); + const enforceFields = results.filter(result => !!result); + + if (enforceFields.length !== 0) { + await this.reloadData({ + clearCache: true + }); + } + + this.ensureFields(enforceFields); + const promise = Promise.resolve(schema); + return thenValidateRequiredColumns(promise, className, object, query); + } // Validates that all the properties are set for the object + + + validateRequiredColumns(className, object, query) { + const columns = requiredColumns[className]; + + if (!columns || columns.length == 0) { + return Promise.resolve(this); + } + + const missingColumns = columns.filter(function (column) { + if (query && query.objectId) { + if (object[column] && typeof object[column] === 'object') { + // Trying to delete a required column + return object[column].__op == 'Delete'; + } // Not trying to do anything there + + + return false; + } + + return !object[column]; + }); + + if (missingColumns.length > 0) { + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, missingColumns[0] + ' is required.'); + } + + return Promise.resolve(this); + } + + testPermissionsForClassName(className, aclGroup, operation) { + return SchemaController.testPermissions(this.getClassLevelPermissions(className), aclGroup, operation); + } // Tests that the class level permission let pass the operation for a given aclGroup + + + static testPermissions(classPermissions, aclGroup, operation) { + if (!classPermissions || !classPermissions[operation]) { + return true; + } + + const perms = classPermissions[operation]; + + if (perms['*']) { + return true; + } // Check permissions against the aclGroup provided (array of userId/roles) + + + if (aclGroup.some(acl => { + return perms[acl] === true; + })) { + return true; + } + + return false; + } // Validates an operation passes class-level-permissions set in the schema + + + static validatePermission(classPermissions, className, aclGroup, operation, action) { + if (SchemaController.testPermissions(classPermissions, aclGroup, operation)) { + return Promise.resolve(); + } + + if (!classPermissions || !classPermissions[operation]) { + return true; + } + + const perms = classPermissions[operation]; // If only for authenticated users + // make sure we have an aclGroup + + if (perms['requiresAuthentication']) { + // If aclGroup has * (public) + if (!aclGroup || aclGroup.length == 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); + } else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); + } // requiresAuthentication passed, just move forward + // probably would be wise at some point to rename to 'authenticatedUser' + + + return Promise.resolve(); + } // No matching CLP, let's check the Pointer permissions + // And handle those later + + + const permissionField = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; // Reject create when write lockdown + + if (permissionField == 'writeUserFields' && operation == 'create') { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); + } // Process the readUserFields later + + + if (Array.isArray(classPermissions[permissionField]) && classPermissions[permissionField].length > 0) { + return Promise.resolve(); + } + + const pointerFields = classPermissions[operation].pointerFields; + + if (Array.isArray(pointerFields) && pointerFields.length > 0) { + // any op except 'addField as part of create' is ok. + if (operation !== 'addField' || action === 'update') { + // We can allow adding field on update flow only. + return Promise.resolve(); + } + } + + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); + } // Validates an operation passes class-level-permissions set in the schema + + + validatePermission(className, aclGroup, operation, action) { + return SchemaController.validatePermission(this.getClassLevelPermissions(className), className, aclGroup, operation, action); + } + + getClassLevelPermissions(className) { + return this.schemaData[className] && this.schemaData[className].classLevelPermissions; + } // Returns the expected type for a className+key combination + // or undefined if the schema is not set + + + getExpectedType(className, fieldName) { + if (this.schemaData[className]) { + const expectedType = this.schemaData[className].fields[fieldName]; + return expectedType === 'map' ? 'Object' : expectedType; + } + + return undefined; + } // Checks if a given class is in the schema. + + + hasClass(className) { + if (this.schemaData[className]) { + return Promise.resolve(true); + } + + return this.reloadData().then(() => !!this.schemaData[className]); + } + +} // Returns a promise for a new Schema. + + +exports.SchemaController = exports.default = SchemaController; + +const load = (dbAdapter, schemaCache, options) => { + const schema = new SchemaController(dbAdapter, schemaCache); + return schema.reloadData(options).then(() => schema); +}; // Builds a new schema (in schema API response format) out of an +// existing mongo schema + a schemas API put request. This response +// does not include the default fields, as it is intended to be passed +// to mongoSchemaFromFieldsAndClassName. No validation is done here, it +// is done in mongoSchemaFromFieldsAndClassName. + + +exports.load = load; + +function buildMergedSchemaObject(existingFields, putRequest) { + const newSchema = {}; // -disable-next + + const sysSchemaField = Object.keys(defaultColumns).indexOf(existingFields._id) === -1 ? [] : Object.keys(defaultColumns[existingFields._id]); + + for (const oldField in existingFields) { + if (oldField !== '_id' && oldField !== 'ACL' && oldField !== 'updatedAt' && oldField !== 'createdAt' && oldField !== 'objectId') { + if (sysSchemaField.length > 0 && sysSchemaField.indexOf(oldField) !== -1) { + continue; + } + + const fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete'; + + if (!fieldIsDeleted) { + newSchema[oldField] = existingFields[oldField]; + } + } + } + + for (const newField in putRequest) { + if (newField !== 'objectId' && putRequest[newField].__op !== 'Delete') { + if (sysSchemaField.length > 0 && sysSchemaField.indexOf(newField) !== -1) { + continue; + } + + newSchema[newField] = putRequest[newField]; + } + } + + return newSchema; +} // Given a schema promise, construct another schema promise that +// validates this field once the schema loads. + + +function thenValidateRequiredColumns(schemaPromise, className, object, query) { + return schemaPromise.then(schema => { + return schema.validateRequiredColumns(className, object, query); + }); +} // Gets the type from a REST API formatted object, where 'type' is +// extended past javascript types to include the rest of the Parse +// type system. +// The output should be a valid schema value. +// TODO: ensure that this is compatible with the format used in Open DB + + +function getType(obj) { + const type = typeof obj; + + switch (type) { + case 'boolean': + return 'Boolean'; + + case 'string': + return 'String'; + + case 'number': + return 'Number'; + + case 'map': + case 'object': + if (!obj) { + return undefined; + } + + return getObjectType(obj); + + case 'function': + case 'symbol': + case 'undefined': + default: + throw 'bad obj: ' + obj; + } +} // This gets the type for non-JSON types like pointers and files, but +// also gets the appropriate type for $ operators. +// Returns null if the type is unknown. + + +function getObjectType(obj) { + if (obj instanceof Array) { + return 'Array'; + } + + if (obj.__type) { + switch (obj.__type) { + case 'Pointer': + if (obj.className) { + return { + type: 'Pointer', + targetClass: obj.className + }; + } + + break; + + case 'Relation': + if (obj.className) { + return { + type: 'Relation', + targetClass: obj.className + }; + } + + break; + + case 'File': + if (obj.name) { + return 'File'; + } + + break; + + case 'Date': + if (obj.iso) { + return 'Date'; + } + + break; + + case 'GeoPoint': + if (obj.latitude != null && obj.longitude != null) { + return 'GeoPoint'; + } + + break; + + case 'Bytes': + if (obj.base64) { + return 'Bytes'; + } + + break; + + case 'Polygon': + if (obj.coordinates) { + return 'Polygon'; + } + + break; + } + + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, 'This is not a valid ' + obj.__type); + } + + if (obj['$ne']) { + return getObjectType(obj['$ne']); + } + + if (obj.__op) { + switch (obj.__op) { + case 'Increment': + return 'Number'; + + case 'Delete': + return null; + + case 'Add': + case 'AddUnique': + case 'Remove': + return 'Array'; + + case 'AddRelation': + case 'RemoveRelation': + return { + type: 'Relation', + targetClass: obj.objects[0].className + }; + + case 'Batch': + return getObjectType(obj.ops[0]); + + default: + throw 'unexpected op: ' + obj.__op; + } + } + + return 'Object'; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImRlZmF1bHRDb2x1bW5zIiwiT2JqZWN0IiwiZnJlZXplIiwiX0RlZmF1bHQiLCJvYmplY3RJZCIsInR5cGUiLCJjcmVhdGVkQXQiLCJ1cGRhdGVkQXQiLCJBQ0wiLCJfVXNlciIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJlbWFpbCIsImVtYWlsVmVyaWZpZWQiLCJhdXRoRGF0YSIsIl9JbnN0YWxsYXRpb24iLCJpbnN0YWxsYXRpb25JZCIsImRldmljZVRva2VuIiwiY2hhbm5lbHMiLCJkZXZpY2VUeXBlIiwicHVzaFR5cGUiLCJHQ01TZW5kZXJJZCIsInRpbWVab25lIiwibG9jYWxlSWRlbnRpZmllciIsImJhZGdlIiwiYXBwVmVyc2lvbiIsImFwcE5hbWUiLCJhcHBJZGVudGlmaWVyIiwicGFyc2VWZXJzaW9uIiwiX1JvbGUiLCJuYW1lIiwidXNlcnMiLCJ0YXJnZXRDbGFzcyIsInJvbGVzIiwiX1Nlc3Npb24iLCJyZXN0cmljdGVkIiwidXNlciIsInNlc3Npb25Ub2tlbiIsImV4cGlyZXNBdCIsImNyZWF0ZWRXaXRoIiwiX1Byb2R1Y3QiLCJwcm9kdWN0SWRlbnRpZmllciIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwiaWNvbiIsIm9yZGVyIiwidGl0bGUiLCJzdWJ0aXRsZSIsIl9QdXNoU3RhdHVzIiwicHVzaFRpbWUiLCJzb3VyY2UiLCJxdWVyeSIsInBheWxvYWQiLCJleHBpcnkiLCJleHBpcmF0aW9uX2ludGVydmFsIiwic3RhdHVzIiwibnVtU2VudCIsIm51bUZhaWxlZCIsInB1c2hIYXNoIiwiZXJyb3JNZXNzYWdlIiwic2VudFBlclR5cGUiLCJmYWlsZWRQZXJUeXBlIiwic2VudFBlclVUQ09mZnNldCIsImZhaWxlZFBlclVUQ09mZnNldCIsImNvdW50IiwiX0pvYlN0YXR1cyIsImpvYk5hbWUiLCJtZXNzYWdlIiwicGFyYW1zIiwiZmluaXNoZWRBdCIsIl9Kb2JTY2hlZHVsZSIsImRlc2NyaXB0aW9uIiwic3RhcnRBZnRlciIsImRheXNPZldlZWsiLCJ0aW1lT2ZEYXkiLCJsYXN0UnVuIiwicmVwZWF0TWludXRlcyIsIl9Ib29rcyIsImZ1bmN0aW9uTmFtZSIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwidXJsIiwiX0dsb2JhbENvbmZpZyIsIm1hc3RlcktleU9ubHkiLCJfR3JhcGhRTENvbmZpZyIsImNvbmZpZyIsIl9BdWRpZW5jZSIsImxhc3RVc2VkIiwidGltZXNVc2VkIiwiX0lkZW1wb3RlbmN5IiwicmVxSWQiLCJleHBpcmUiLCJyZXF1aXJlZENvbHVtbnMiLCJzeXN0ZW1DbGFzc2VzIiwidm9sYXRpbGVDbGFzc2VzIiwicm9sZVJlZ2V4IiwicHJvdGVjdGVkRmllbGRzUG9pbnRlclJlZ2V4IiwicHVibGljUmVnZXgiLCJhdXRoZW50aWNhdGVkUmVnZXgiLCJyZXF1aXJlc0F1dGhlbnRpY2F0aW9uUmVnZXgiLCJjbHBQb2ludGVyUmVnZXgiLCJwcm90ZWN0ZWRGaWVsZHNSZWdleCIsImNscEZpZWxkc1JlZ2V4IiwidmFsaWRhdGVQZXJtaXNzaW9uS2V5Iiwia2V5IiwidXNlcklkUmVnRXhwIiwibWF0Y2hlc1NvbWUiLCJyZWdFeCIsIm1hdGNoIiwidmFsaWQiLCJFcnJvciIsIklOVkFMSURfSlNPTiIsInZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5IiwiQ0xQVmFsaWRLZXlzIiwidmFsaWRhdGVDTFAiLCJwZXJtcyIsImZpZWxkcyIsIm9wZXJhdGlvbktleSIsImluZGV4T2YiLCJvcGVyYXRpb24iLCJ2YWxpZGF0ZUNMUGpzb24iLCJmaWVsZE5hbWUiLCJ2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uIiwiZW50aXR5IiwicHJvdGVjdGVkRmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwiZmllbGQiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJwb2ludGVyRmllbGRzIiwicG9pbnRlckZpZWxkIiwicGVybWl0Iiwiam9pbkNsYXNzUmVnZXgiLCJjbGFzc0FuZEZpZWxkUmVnZXgiLCJjbGFzc05hbWVJc1ZhbGlkIiwidGVzdCIsImZpZWxkTmFtZUlzVmFsaWQiLCJmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MiLCJpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZSIsImludmFsaWRKc29uRXJyb3IiLCJ2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMiLCJmaWVsZFR5cGVJc0ludmFsaWQiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJ1bmRlZmluZWQiLCJJTkNPUlJFQ1RfVFlQRSIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJzY2hlbWEiLCJpbmplY3REZWZhdWx0U2NoZW1hIiwiX3JwZXJtIiwiX3dwZXJtIiwiX2hhc2hlZF9wYXNzd29yZCIsImNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSIsImluZGV4ZXMiLCJrZXlzIiwibGVuZ3RoIiwiU2NoZW1hRGF0YSIsImNvbnN0cnVjdG9yIiwiYWxsU2NoZW1hcyIsIl9fZGF0YSIsIl9fcHJvdGVjdGVkRmllbGRzIiwiZm9yRWFjaCIsImluY2x1ZGVzIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJkYXRhIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiY2xhc3NQcm90ZWN0ZWRGaWVsZHMiLCJ1bnEiLCJTZXQiLCJmcm9tIiwiZGVmYXVsdFNjaGVtYSIsIl9Ib29rc1NjaGVtYSIsIl9HbG9iYWxDb25maWdTY2hlbWEiLCJfR3JhcGhRTENvbmZpZ1NjaGVtYSIsIl9QdXNoU3RhdHVzU2NoZW1hIiwiX0pvYlN0YXR1c1NjaGVtYSIsIl9Kb2JTY2hlZHVsZVNjaGVtYSIsIl9BdWRpZW5jZVNjaGVtYSIsIl9JZGVtcG90ZW5jeVNjaGVtYSIsIlZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMiLCJkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZSIsImRiVHlwZSIsIm9iamVjdFR5cGUiLCJ0eXBlVG9TdHJpbmciLCJTY2hlbWFDb250cm9sbGVyIiwiZGF0YWJhc2VBZGFwdGVyIiwic2NoZW1hQ2FjaGUiLCJfZGJBZGFwdGVyIiwiX2NhY2hlIiwic2NoZW1hRGF0YSIsIkNvbmZpZyIsImFwcGxpY2F0aW9uSWQiLCJjdXN0b21JZHMiLCJhbGxvd0N1c3RvbU9iamVjdElkIiwiY3VzdG9tSWRSZWdFeCIsImF1dG9JZFJlZ0V4IiwidXNlcklkUmVnRXgiLCJyZWxvYWREYXRhIiwib3B0aW9ucyIsImNsZWFyQ2FjaGUiLCJyZWxvYWREYXRhUHJvbWlzZSIsImdldEFsbENsYXNzZXMiLCJ0aGVuIiwiZXJyIiwic2V0QWxsQ2xhc3NlcyIsImFsbENsYXNzZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1hcCIsImNhdGNoIiwiZXJyb3IiLCJjb25zb2xlIiwiZ2V0T25lU2NoZW1hIiwiYWxsb3dWb2xhdGlsZUNsYXNzZXMiLCJwcm9taXNlIiwiY2xlYXIiLCJjYWNoZWQiLCJvbmVTY2hlbWEiLCJmaW5kIiwicmVqZWN0IiwiYWRkQ2xhc3NJZk5vdEV4aXN0cyIsInZhbGlkYXRpb25FcnJvciIsInZhbGlkYXRlTmV3Q2xhc3MiLCJjb2RlIiwiY3JlYXRlQ2xhc3MiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1cGRhdGVDbGFzcyIsInN1Ym1pdHRlZEZpZWxkcyIsImRhdGFiYXNlIiwiZXhpc3RpbmdGaWVsZHMiLCJfX29wIiwibmV3U2NoZW1hIiwiYnVpbGRNZXJnZWRTY2hlbWFPYmplY3QiLCJkZWZhdWx0RmllbGRzIiwiZnVsbE5ld1NjaGVtYSIsImFzc2lnbiIsInZhbGlkYXRlU2NoZW1hRGF0YSIsImRlbGV0ZWRGaWVsZHMiLCJpbnNlcnRlZEZpZWxkcyIsInB1c2giLCJkZWxldGVQcm9taXNlIiwiZGVsZXRlRmllbGRzIiwiZW5mb3JjZUZpZWxkcyIsInByb21pc2VzIiwiZW5mb3JjZUZpZWxkRXhpc3RzIiwiYWxsIiwicmVzdWx0cyIsImZpbHRlciIsInJlc3VsdCIsInNldFBlcm1pc3Npb25zIiwic2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQiLCJlbnN1cmVGaWVsZHMiLCJyZWxvYWRlZFNjaGVtYSIsImVuZm9yY2VDbGFzc0V4aXN0cyIsImV4aXN0aW5nRmllbGROYW1lcyIsIklOVkFMSURfS0VZX05BTUUiLCJmaWVsZFR5cGUiLCJkZWZhdWx0VmFsdWUiLCJkZWZhdWx0VmFsdWVUeXBlIiwiZ2V0VHlwZSIsInJlcXVpcmVkIiwiZ2VvUG9pbnRzIiwic2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwic3BsaXQiLCJleHBlY3RlZFR5cGUiLCJnZXRFeHBlY3RlZFR5cGUiLCJhZGRGaWVsZElmTm90RXhpc3RzIiwiaSIsImRlbGV0ZUZpZWxkIiwiZmllbGROYW1lcyIsInNjaGVtYUZpZWxkcyIsImFkYXB0ZXIiLCJkZWxldGVDbGFzcyIsInZhbGlkYXRlT2JqZWN0Iiwib2JqZWN0IiwiZ2VvY291bnQiLCJleHBlY3RlZCIsInRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyIsInZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zIiwiY29sdW1ucyIsIm1pc3NpbmdDb2x1bW5zIiwiY29sdW1uIiwidGVzdFBlcm1pc3Npb25zRm9yQ2xhc3NOYW1lIiwiYWNsR3JvdXAiLCJ0ZXN0UGVybWlzc2lvbnMiLCJnZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJjbGFzc1Blcm1pc3Npb25zIiwic29tZSIsImFjbCIsInZhbGlkYXRlUGVybWlzc2lvbiIsImFjdGlvbiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJwZXJtaXNzaW9uRmllbGQiLCJPUEVSQVRJT05fRk9SQklEREVOIiwiaGFzQ2xhc3MiLCJsb2FkIiwiZGJBZGFwdGVyIiwicHV0UmVxdWVzdCIsInN5c1NjaGVtYUZpZWxkIiwiX2lkIiwib2xkRmllbGQiLCJmaWVsZElzRGVsZXRlZCIsIm5ld0ZpZWxkIiwic2NoZW1hUHJvbWlzZSIsIm9iaiIsImdldE9iamVjdFR5cGUiLCJfX3R5cGUiLCJpc28iLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsImJhc2U2NCIsImNvb3JkaW5hdGVzIiwib2JqZWN0cyIsIm9wcyJd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NEMseUJBQXlCZ0ssR0FBRyxDQUFDRSxNQUF6RSxDQUFOO0FBQ0Q7O0FBQ0QsTUFBSUYsR0FBRyxDQUFDLEtBQUQsQ0FBUCxFQUFnQjtBQUNkLFdBQU9DLGFBQWEsQ0FBQ0QsR0FBRyxDQUFDLEtBQUQsQ0FBSixDQUFwQjtBQUNEOztBQUNELE1BQUlBLEdBQUcsQ0FBQzFFLElBQVIsRUFBYztBQUNaLFlBQVEwRSxHQUFHLENBQUMxRSxJQUFaO0FBQ0UsV0FBSyxXQUFMO0FBQ0UsZUFBTyxRQUFQOztBQUNGLFdBQUssUUFBTDtBQUNFLGVBQU8sSUFBUDs7QUFDRixXQUFLLEtBQUw7QUFDQSxXQUFLLFdBQUw7QUFDQSxXQUFLLFFBQUw7QUFDRSxlQUFPLE9BQVA7O0FBQ0YsV0FBSyxhQUFMO0FBQ0EsV0FBSyxnQkFBTDtBQUNFLGVBQU87QUFDTG5PLFVBQUFBLElBQUksRUFBRSxVQUREO0FBRUwyQixVQUFBQSxXQUFXLEVBQUVrUixHQUFHLENBQUNRLE9BQUosQ0FBWSxDQUFaLEVBQWUzTztBQUZ2QixTQUFQOztBQUlGLFdBQUssT0FBTDtBQUNFLGVBQU9vTyxhQUFhLENBQUNELEdBQUcsQ0FBQ1MsR0FBSixDQUFRLENBQVIsQ0FBRCxDQUFwQjs7QUFDRjtBQUNFLGNBQU0sb0JBQW9CVCxHQUFHLENBQUMxRSxJQUE5QjtBQWxCSjtBQW9CRDs7QUFDRCxTQUFPLFFBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBUaGlzIGNsYXNzIGhhbmRsZXMgc2NoZW1hIHZhbGlkYXRpb24sIHBlcnNpc3RlbmNlLCBhbmQgbW9kaWZpY2F0aW9uLlxuLy9cbi8vIEVhY2ggaW5kaXZpZHVhbCBTY2hlbWEgb2JqZWN0IHNob3VsZCBiZSBpbW11dGFibGUuIFRoZSBoZWxwZXJzIHRvXG4vLyBkbyB0aGluZ3Mgd2l0aCB0aGUgU2NoZW1hIGp1c3QgcmV0dXJuIGEgbmV3IHNjaGVtYSB3aGVuIHRoZSBzY2hlbWFcbi8vIGlzIGNoYW5nZWQuXG4vL1xuLy8gVGhlIGNhbm9uaWNhbCBwbGFjZSB0byBzdG9yZSB0aGlzIFNjaGVtYSBpcyBpbiB0aGUgZGF0YWJhc2UgaXRzZWxmLFxuLy8gaW4gYSBfU0NIRU1BIGNvbGxlY3Rpb24uIFRoaXMgaXMgbm90IHRoZSByaWdodCB3YXkgdG8gZG8gaXQgZm9yIGFuXG4vLyBvcGVuIHNvdXJjZSBmcmFtZXdvcmssIGJ1dCBpdCdzIGJhY2t3YXJkIGNvbXBhdGlibGUsIHNvIHdlJ3JlXG4vLyBrZWVwaW5nIGl0IHRoaXMgd2F5IGZvciBub3cuXG4vL1xuLy8gSW4gQVBJLWhhbmRsaW5nIGNvZGUsIHlvdSBzaG91bGQgb25seSB1c2UgdGhlIFNjaGVtYSBjbGFzcyB2aWEgdGhlXG4vLyBEYXRhYmFzZUNvbnRyb2xsZXIuIFRoaXMgd2lsbCBsZXQgdXMgcmVwbGFjZSB0aGUgc2NoZW1hIGxvZ2ljIGZvclxuLy8gZGlmZmVyZW50IGRhdGFiYXNlcy5cbi8vIFRPRE86IGhpZGUgYWxsIHNjaGVtYSBsb2dpYyBpbnNpZGUgdGhlIGRhdGFiYXNlIGFkYXB0ZXIuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9TdG9yYWdlL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgZGVlcGNvcHkgZnJvbSAnZGVlcGNvcHknO1xuaW1wb3J0IHR5cGUge1xuICBTY2hlbWEsXG4gIFNjaGVtYUZpZWxkcyxcbiAgQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICBTY2hlbWFGaWVsZCxcbiAgTG9hZFNjaGVtYU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkZWZhdWx0Q29sdW1uczogeyBbc3RyaW5nXTogU2NoZW1hRmllbGRzIH0gPSBPYmplY3QuZnJlZXplKHtcbiAgLy8gQ29udGFpbiB0aGUgZGVmYXVsdCBjb2x1bW5zIGZvciBldmVyeSBwYXJzZSBvYmplY3QgdHlwZSAoZXhjZXB0IF9Kb2luIGNvbGxlY3Rpb24pXG4gIF9EZWZhdWx0OiB7XG4gICAgb2JqZWN0SWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBjcmVhdGVkQXQ6IHsgdHlwZTogJ0RhdGUnIH0sXG4gICAgdXBkYXRlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIEFDTDogeyB0eXBlOiAnQUNMJyB9LFxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfVXNlciBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1VzZXI6IHtcbiAgICB1c2VybmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhc3N3b3JkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZW1haWw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBlbWFpbFZlcmlmaWVkOiB7IHR5cGU6ICdCb29sZWFuJyB9LFxuICAgIGF1dGhEYXRhOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9JbnN0YWxsYXRpb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9JbnN0YWxsYXRpb246IHtcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRldmljZVRva2VuOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2hhbm5lbHM6IHsgdHlwZTogJ0FycmF5JyB9LFxuICAgIGRldmljZVR5cGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwdXNoVHlwZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIEdDTVNlbmRlcklkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdGltZVpvbmU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBsb2NhbGVJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYmFkZ2U6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBhcHBWZXJzaW9uOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYXBwTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGFwcElkZW50aWZpZXI6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJzZVZlcnNpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1JvbGUgY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9Sb2xlOiB7XG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHVzZXJzOiB7IHR5cGU6ICdSZWxhdGlvbicsIHRhcmdldENsYXNzOiAnX1VzZXInIH0sXG4gICAgcm9sZXM6IHsgdHlwZTogJ1JlbGF0aW9uJywgdGFyZ2V0Q2xhc3M6ICdfUm9sZScgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1Nlc3Npb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9TZXNzaW9uOiB7XG4gICAgcmVzdHJpY3RlZDogeyB0eXBlOiAnQm9vbGVhbicgfSxcbiAgICB1c2VyOiB7IHR5cGU6ICdQb2ludGVyJywgdGFyZ2V0Q2xhc3M6ICdfVXNlcicgfSxcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNlc3Npb25Ub2tlbjogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZXNBdDogeyB0eXBlOiAnRGF0ZScgfSxcbiAgICBjcmVhdGVkV2l0aDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfUHJvZHVjdDoge1xuICAgIHByb2R1Y3RJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZG93bmxvYWQ6IHsgdHlwZTogJ0ZpbGUnIH0sXG4gICAgZG93bmxvYWROYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgaWNvbjogeyB0eXBlOiAnRmlsZScgfSxcbiAgICBvcmRlcjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHRpdGxlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3VidGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX1B1c2hTdGF0dXM6IHtcbiAgICBwdXNoVGltZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNvdXJjZTogeyB0eXBlOiAnU3RyaW5nJyB9LCAvLyByZXN0IG9yIHdlYnVpXG4gICAgcXVlcnk6IHsgdHlwZTogJ1N0cmluZycgfSwgLy8gdGhlIHN0cmluZ2lmaWVkIEpTT04gcXVlcnlcbiAgICBwYXlsb2FkOiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vIHRoZSBzdHJpbmdpZmllZCBKU09OIHBheWxvYWQsXG4gICAgdGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBleHBpcnk6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBleHBpcmF0aW9uX2ludGVydmFsOiB7IHR5cGU6ICdOdW1iZXInIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbnVtU2VudDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIG51bUZhaWxlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHB1c2hIYXNoOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZXJyb3JNZXNzYWdlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclR5cGU6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgICBmYWlsZWRQZXJUeXBlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGZhaWxlZFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGNvdW50OiB7IHR5cGU6ICdOdW1iZXInIH0sIC8vIHRyYWNrcyAjIG9mIGJhdGNoZXMgcXVldWVkIGFuZCBwZW5kaW5nXG4gIH0sXG4gIF9Kb2JTdGF0dXM6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc291cmNlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbWVzc2FnZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhcmFtczogeyB0eXBlOiAnT2JqZWN0JyB9LCAvLyBwYXJhbXMgcmVjZWl2ZWQgd2hlbiBjYWxsaW5nIHRoZSBqb2JcbiAgICBmaW5pc2hlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICB9LFxuICBfSm9iU2NoZWR1bGU6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGVzY3JpcHRpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJhbXM6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBzdGFydEFmdGVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGF5c09mV2VlazogeyB0eXBlOiAnQXJyYXknIH0sXG4gICAgdGltZU9mRGF5OiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbGFzdFJ1bjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHJlcGVhdE1pbnV0ZXM6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgfSxcbiAgX0hvb2tzOiB7XG4gICAgZnVuY3Rpb25OYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2xhc3NOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdHJpZ2dlck5hbWU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICB1cmw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX0dsb2JhbENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgcGFyYW1zOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgbWFzdGVyS2V5T25seTogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfR3JhcGhRTENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY29uZmlnOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIF9BdWRpZW5jZToge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHF1ZXJ5OiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vc3RvcmluZyBxdWVyeSBhcyBKU09OIHN0cmluZyB0byBwcmV2ZW50IFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIiBlcnJvclxuICAgIGxhc3RVc2VkOiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIHRpbWVzVXNlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICB9LFxuICBfSWRlbXBvdGVuY3k6IHtcbiAgICByZXFJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZTogeyB0eXBlOiAnRGF0ZScgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3QuZnJlZXplKHtcbiAgX1Byb2R1Y3Q6IFsncHJvZHVjdElkZW50aWZpZXInLCAnaWNvbicsICdvcmRlcicsICd0aXRsZScsICdzdWJ0aXRsZSddLFxuICBfUm9sZTogWyduYW1lJywgJ0FDTCddLFxufSk7XG5cbmNvbnN0IHN5c3RlbUNsYXNzZXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ19Vc2VyJyxcbiAgJ19JbnN0YWxsYXRpb24nLFxuICAnX1JvbGUnLFxuICAnX1Nlc3Npb24nLFxuICAnX1Byb2R1Y3QnLFxuICAnX1B1c2hTdGF0dXMnLFxuICAnX0pvYlN0YXR1cycsXG4gICdfSm9iU2NoZWR1bGUnLFxuICAnX0F1ZGllbmNlJyxcbiAgJ19JZGVtcG90ZW5jeScsXG5dKTtcblxuY29uc3Qgdm9sYXRpbGVDbGFzc2VzID0gT2JqZWN0LmZyZWV6ZShbXG4gICdfSm9iU3RhdHVzJyxcbiAgJ19QdXNoU3RhdHVzJyxcbiAgJ19Ib29rcycsXG4gICdfR2xvYmFsQ29uZmlnJyxcbiAgJ19HcmFwaFFMQ29uZmlnJyxcbiAgJ19Kb2JTY2hlZHVsZScsXG4gICdfQXVkaWVuY2UnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl0pO1xuXG4vLyBBbnl0aGluZyB0aGF0IHN0YXJ0IHdpdGggcm9sZVxuY29uc3Qgcm9sZVJlZ2V4ID0gL15yb2xlOi4qLztcbi8vIEFueXRoaW5nIHRoYXQgc3RhcnRzIHdpdGggdXNlckZpZWxkIChhbGxvd2VkIGZvciBwcm90ZWN0ZWQgZmllbGRzIG9ubHkpXG5jb25zdCBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXggPSAvXnVzZXJGaWVsZDouKi87XG4vLyAqIHBlcm1pc3Npb25cbmNvbnN0IHB1YmxpY1JlZ2V4ID0gL15cXCokLztcblxuY29uc3QgYXV0aGVudGljYXRlZFJlZ2V4ID0gL15hdXRoZW50aWNhdGVkJC87XG5cbmNvbnN0IHJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCA9IC9ecmVxdWlyZXNBdXRoZW50aWNhdGlvbiQvO1xuXG5jb25zdCBjbHBQb2ludGVyUmVnZXggPSAvXnBvaW50ZXJGaWVsZHMkLztcblxuLy8gcmVnZXggZm9yIHZhbGlkYXRpbmcgZW50aXRpZXMgaW4gcHJvdGVjdGVkRmllbGRzIG9iamVjdFxuY29uc3QgcHJvdGVjdGVkRmllbGRzUmVnZXggPSBPYmplY3QuZnJlZXplKFtcbiAgcHJvdGVjdGVkRmllbGRzUG9pbnRlclJlZ2V4LFxuICBwdWJsaWNSZWdleCxcbiAgYXV0aGVudGljYXRlZFJlZ2V4LFxuICByb2xlUmVnZXgsXG5dKTtcblxuLy8gY2xwIHJlZ2V4XG5jb25zdCBjbHBGaWVsZHNSZWdleCA9IE9iamVjdC5mcmVlemUoW1xuICBjbHBQb2ludGVyUmVnZXgsXG4gIHB1YmxpY1JlZ2V4LFxuICByZXF1aXJlc0F1dGhlbnRpY2F0aW9uUmVnZXgsXG4gIHJvbGVSZWdleCxcbl0pO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVBlcm1pc3Npb25LZXkoa2V5LCB1c2VySWRSZWdFeHApIHtcbiAgbGV0IG1hdGNoZXNTb21lID0gZmFsc2U7XG4gIGZvciAoY29uc3QgcmVnRXggb2YgY2xwRmllbGRzUmVnZXgpIHtcbiAgICBpZiAoa2V5Lm1hdGNoKHJlZ0V4KSAhPT0gbnVsbCkge1xuICAgICAgbWF0Y2hlc1NvbWUgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLy8gdXNlcklkIGRlcGVuZHMgb24gc3RhcnR1cCBvcHRpb25zIHNvIGl0J3MgZHluYW1pY1xuICBjb25zdCB2YWxpZCA9IG1hdGNoZXNTb21lIHx8IGtleS5tYXRjaCh1c2VySWRSZWdFeHApICE9PSBudWxsO1xuICBpZiAoIXZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3RlY3RlZEZpZWxkc0tleShrZXksIHVzZXJJZFJlZ0V4cCkge1xuICBsZXQgbWF0Y2hlc1NvbWUgPSBmYWxzZTtcbiAgZm9yIChjb25zdCByZWdFeCBvZiBwcm90ZWN0ZWRGaWVsZHNSZWdleCkge1xuICAgIGlmIChrZXkubWF0Y2gocmVnRXgpICE9PSBudWxsKSB7XG4gICAgICBtYXRjaGVzU29tZSA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyB1c2VySWQgcmVnZXggZGVwZW5kcyBvbiBsYXVuY2ggb3B0aW9ucyBzbyBpdCdzIGR5bmFtaWNcbiAgY29uc3QgdmFsaWQgPSBtYXRjaGVzU29tZSB8fCBrZXkubWF0Y2godXNlcklkUmVnRXhwKSAhPT0gbnVsbDtcbiAgaWYgKCF2YWxpZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgIGAnJHtrZXl9JyBpcyBub3QgYSB2YWxpZCBrZXkgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zYFxuICAgICk7XG4gIH1cbn1cblxuY29uc3QgQ0xQVmFsaWRLZXlzID0gT2JqZWN0LmZyZWV6ZShbXG4gICdmaW5kJyxcbiAgJ2NvdW50JyxcbiAgJ2dldCcsXG4gICdjcmVhdGUnLFxuICAndXBkYXRlJyxcbiAgJ2RlbGV0ZScsXG4gICdhZGRGaWVsZCcsXG4gICdyZWFkVXNlckZpZWxkcycsXG4gICd3cml0ZVVzZXJGaWVsZHMnLFxuICAncHJvdGVjdGVkRmllbGRzJyxcbl0pO1xuXG4vLyB2YWxpZGF0aW9uIGJlZm9yZSBzZXR0aW5nIGNsYXNzLWxldmVsIHBlcm1pc3Npb25zIG9uIGNvbGxlY3Rpb25cbmZ1bmN0aW9uIHZhbGlkYXRlQ0xQKHBlcm1zOiBDbGFzc0xldmVsUGVybWlzc2lvbnMsIGZpZWxkczogU2NoZW1hRmllbGRzLCB1c2VySWRSZWdFeHA6IFJlZ0V4cCkge1xuICBpZiAoIXBlcm1zKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAoY29uc3Qgb3BlcmF0aW9uS2V5IGluIHBlcm1zKSB7XG4gICAgaWYgKENMUFZhbGlkS2V5cy5pbmRleE9mKG9wZXJhdGlvbktleSkgPT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJHtvcGVyYXRpb25LZXl9IGlzIG5vdCBhIHZhbGlkIG9wZXJhdGlvbiBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IHBlcm1zW29wZXJhdGlvbktleV07XG4gICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgb3BlcmF0aW9uS2V5XG5cbiAgICAvLyB0aHJvd3Mgd2hlbiByb290IGZpZWxkcyBhcmUgb2Ygd3JvbmcgdHlwZVxuICAgIHZhbGlkYXRlQ0xQanNvbihvcGVyYXRpb24sIG9wZXJhdGlvbktleSk7XG5cbiAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbktleSA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICAgIC8vIHZhbGlkYXRlIGdyb3VwZWQgcG9pbnRlciBwZXJtaXNzaW9uc1xuICAgICAgLy8gbXVzdCBiZSBhbiBhcnJheSB3aXRoIGZpZWxkIG5hbWVzXG4gICAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBvZiBvcGVyYXRpb24pIHtcbiAgICAgICAgdmFsaWRhdGVQb2ludGVyUGVybWlzc2lvbihmaWVsZE5hbWUsIGZpZWxkcywgb3BlcmF0aW9uS2V5KTtcbiAgICAgIH1cbiAgICAgIC8vIHJlYWRVc2VyRmllbGRzIGFuZCB3cml0ZXJVc2VyRmllbGRzIGRvIG5vdCBoYXZlIG5lc2R0ZWQgZmllbGRzXG4gICAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIHByb3RlY3RlZCBmaWVsZHNcbiAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAncHJvdGVjdGVkRmllbGRzJykge1xuICAgICAgZm9yIChjb25zdCBlbnRpdHkgaW4gb3BlcmF0aW9uKSB7XG4gICAgICAgIC8vIHRocm93cyBvbiB1bmV4cGVjdGVkIGtleVxuICAgICAgICB2YWxpZGF0ZVByb3RlY3RlZEZpZWxkc0tleShlbnRpdHksIHVzZXJJZFJlZ0V4cCk7XG5cbiAgICAgICAgY29uc3QgcHJvdGVjdGVkRmllbGRzID0gb3BlcmF0aW9uW2VudGl0eV07XG5cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHByb3RlY3RlZEZpZWxkcykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7cHJvdGVjdGVkRmllbGRzfScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHByb3RlY3RlZEZpZWxkc1ske2VudGl0eX1dIC0gZXhwZWN0ZWQgYW4gYXJyYXkuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGUgZmllbGQgaXMgaW4gZm9ybSBvZiBhcnJheVxuICAgICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgIC8vIGRvIG5vdCBhbGxvb3cgdG8gcHJvdGVjdCBkZWZhdWx0IGZpZWxkc1xuICAgICAgICAgIGlmIChkZWZhdWx0Q29sdW1ucy5fRGVmYXVsdFtmaWVsZF0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICBgRGVmYXVsdCBmaWVsZCAnJHtmaWVsZH0nIGNhbiBub3QgYmUgcHJvdGVjdGVkYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZmllbGQgc2hvdWxkIGV4aXN0IG9uIGNvbGxlY3Rpb25cbiAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmaWVsZHMsIGZpZWxkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIGBGaWVsZCAnJHtmaWVsZH0nIGluIHByb3RlY3RlZEZpZWxkczoke2VudGl0eX0gZG9lcyBub3QgZXhpc3RgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgb3BlcmF0aW9uS2V5XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBvdGhlciBmaWVsZHNcbiAgICAvLyBFbnRpdHkgY2FuIGJlOlxuICAgIC8vIFwiKlwiIC0gUHVibGljLFxuICAgIC8vIFwicmVxdWlyZXNBdXRoZW50aWNhdGlvblwiIC0gYXV0aGVudGljYXRlZCB1c2VycyxcbiAgICAvLyBcIm9iamVjdElkXCIgLSBfVXNlciBpZCxcbiAgICAvLyBcInJvbGU6cm9sZW5hbWVcIixcbiAgICAvLyBcInBvaW50ZXJGaWVsZHNcIiAtIGFycmF5IG9mIGZpZWxkIG5hbWVzIGNvbnRhaW5pbmcgcG9pbnRlcnMgdG8gdXNlcnNcbiAgICBmb3IgKGNvbnN0IGVudGl0eSBpbiBvcGVyYXRpb24pIHtcbiAgICAgIC8vIHRocm93cyBvbiB1bmV4cGVjdGVkIGtleVxuICAgICAgdmFsaWRhdGVQZXJtaXNzaW9uS2V5KGVudGl0eSwgdXNlcklkUmVnRXhwKTtcblxuICAgICAgLy8gZW50aXR5IGNhbiBiZSBlaXRoZXI6XG4gICAgICAvLyBcInBvaW50ZXJGaWVsZHNcIjogc3RyaW5nW11cbiAgICAgIGlmIChlbnRpdHkgPT09ICdwb2ludGVyRmllbGRzJykge1xuICAgICAgICBjb25zdCBwb2ludGVyRmllbGRzID0gb3BlcmF0aW9uW2VudGl0eV07XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnRlckZpZWxkcykpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHBvaW50ZXJGaWVsZCBvZiBwb2ludGVyRmllbGRzKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKHBvaW50ZXJGaWVsZCwgZmllbGRzLCBvcGVyYXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7cG9pbnRlckZpZWxkc30nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciAke29wZXJhdGlvbktleX1bJHtlbnRpdHl9XSAtIGV4cGVjdGVkIGFuIGFycmF5LmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb2NlZWQgd2l0aCBuZXh0IGVudGl0eSBrZXlcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIG9yIFtlbnRpdHldOiBib29sZWFuXG4gICAgICBjb25zdCBwZXJtaXQgPSBvcGVyYXRpb25bZW50aXR5XTtcblxuICAgICAgaWYgKHBlcm1pdCAhPT0gdHJ1ZSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGAnJHtwZXJtaXR9JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9OiR7ZW50aXR5fToke3Blcm1pdH1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ0xQanNvbihvcGVyYXRpb246IGFueSwgb3BlcmF0aW9uS2V5OiBzdHJpbmcpIHtcbiAgaWYgKG9wZXJhdGlvbktleSA9PT0gJ3JlYWRVc2VyRmllbGRzJyB8fCBvcGVyYXRpb25LZXkgPT09ICd3cml0ZVVzZXJGaWVsZHMnKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wZXJhdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJyR7b3BlcmF0aW9ufScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zICR7b3BlcmF0aW9uS2V5fSAtIG11c3QgYmUgYW4gYXJyYXlgXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIG9wZXJhdGlvbiA9PT0gJ29iamVjdCcgJiYgb3BlcmF0aW9uICE9PSBudWxsKSB7XG4gICAgICAvLyBvayB0byBwcm9jZWVkXG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJyR7b3BlcmF0aW9ufScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zICR7b3BlcmF0aW9uS2V5fSAtIG11c3QgYmUgYW4gb2JqZWN0YFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVQb2ludGVyUGVybWlzc2lvbihmaWVsZE5hbWU6IHN0cmluZywgZmllbGRzOiBPYmplY3QsIG9wZXJhdGlvbjogc3RyaW5nKSB7XG4gIC8vIFVzZXMgY29sbGVjdGlvbiBzY2hlbWEgdG8gZW5zdXJlIHRoZSBmaWVsZCBpcyBvZiB0eXBlOlxuICAvLyAtIFBvaW50ZXI8X1VzZXI+IChwb2ludGVycylcbiAgLy8gLSBBcnJheVxuICAvL1xuICAvLyAgICBJdCdzIG5vdCBwb3NzaWJsZSB0byBlbmZvcmNlIHR5cGUgb24gQXJyYXkncyBpdGVtcyBpbiBzY2hlbWFcbiAgLy8gIHNvIHdlIGFjY2VwdCBhbnkgQXJyYXkgZmllbGQsIGFuZCBsYXRlciB3aGVuIGFwcGx5aW5nIHBlcm1pc3Npb25zXG4gIC8vICBvbmx5IGl0ZW1zIHRoYXQgYXJlIHBvaW50ZXJzIHRvIF9Vc2VyIGFyZSBjb25zaWRlcmVkLlxuICBpZiAoXG4gICAgIShcbiAgICAgIGZpZWxkc1tmaWVsZE5hbWVdICYmXG4gICAgICAoKGZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT0gJ1BvaW50ZXInICYmIGZpZWxkc1tmaWVsZE5hbWVdLnRhcmdldENsYXNzID09ICdfVXNlcicpIHx8XG4gICAgICAgIGZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT0gJ0FycmF5JylcbiAgICApXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgIGAnJHtmaWVsZE5hbWV9JyBpcyBub3QgYSB2YWxpZCBjb2x1bW4gZm9yIGNsYXNzIGxldmVsIHBvaW50ZXIgcGVybWlzc2lvbnMgJHtvcGVyYXRpb259YFxuICAgICk7XG4gIH1cbn1cblxuY29uc3Qgam9pbkNsYXNzUmVnZXggPSAvXl9Kb2luOltBLVphLXowLTlfXSs6W0EtWmEtejAtOV9dKy87XG5jb25zdCBjbGFzc0FuZEZpZWxkUmVnZXggPSAvXltBLVphLXpdW0EtWmEtejAtOV9dKiQvO1xuZnVuY3Rpb24gY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAvLyBWYWxpZCBjbGFzc2VzIG11c3Q6XG4gIHJldHVybiAoXG4gICAgLy8gQmUgb25lIG9mIF9Vc2VyLCBfSW5zdGFsbGF0aW9uLCBfUm9sZSwgX1Nlc3Npb24gT1JcbiAgICBzeXN0ZW1DbGFzc2VzLmluZGV4T2YoY2xhc3NOYW1lKSA+IC0xIHx8XG4gICAgLy8gQmUgYSBqb2luIHRhYmxlIE9SXG4gICAgam9pbkNsYXNzUmVnZXgudGVzdChjbGFzc05hbWUpIHx8XG4gICAgLy8gSW5jbHVkZSBvbmx5IGFscGhhLW51bWVyaWMgYW5kIHVuZGVyc2NvcmVzLCBhbmQgbm90IHN0YXJ0IHdpdGggYW4gdW5kZXJzY29yZSBvciBudW1iZXJcbiAgICBmaWVsZE5hbWVJc1ZhbGlkKGNsYXNzTmFtZSlcbiAgKTtcbn1cblxuLy8gVmFsaWQgZmllbGRzIG11c3QgYmUgYWxwaGEtbnVtZXJpYywgYW5kIG5vdCBzdGFydCB3aXRoIGFuIHVuZGVyc2NvcmUgb3IgbnVtYmVyXG5mdW5jdGlvbiBmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBjbGFzc0FuZEZpZWxkUmVnZXgudGVzdChmaWVsZE5hbWUpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBpdCdzIG5vdCB0cnlpbmcgdG8gY2xvYmJlciBvbmUgb2YgdGhlIGRlZmF1bHQgZmllbGRzIG9mIHRoZSBjbGFzcy5cbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWU6IHN0cmluZywgY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0W2ZpZWxkTmFtZV0pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gJiYgZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXVtmaWVsZE5hbWVdKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiAoXG4gICAgJ0ludmFsaWQgY2xhc3NuYW1lOiAnICtcbiAgICBjbGFzc05hbWUgK1xuICAgICcsIGNsYXNzbmFtZXMgY2FuIG9ubHkgaGF2ZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgXywgYW5kIG11c3Qgc3RhcnQgd2l0aCBhbiBhbHBoYSBjaGFyYWN0ZXIgJ1xuICApO1xufVxuXG5jb25zdCBpbnZhbGlkSnNvbkVycm9yID0gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2ludmFsaWQgSlNPTicpO1xuY29uc3QgdmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzID0gW1xuICAnTnVtYmVyJyxcbiAgJ1N0cmluZycsXG4gICdCb29sZWFuJyxcbiAgJ0RhdGUnLFxuICAnT2JqZWN0JyxcbiAgJ0FycmF5JyxcbiAgJ0dlb1BvaW50JyxcbiAgJ0ZpbGUnLFxuICAnQnl0ZXMnLFxuICAnUG9seWdvbicsXG5dO1xuLy8gUmV0dXJucyBhbiBlcnJvciBzdWl0YWJsZSBmb3IgdGhyb3dpbmcgaWYgdGhlIHR5cGUgaXMgaW52YWxpZFxuY29uc3QgZmllbGRUeXBlSXNJbnZhbGlkID0gKHsgdHlwZSwgdGFyZ2V0Q2xhc3MgfSkgPT4ge1xuICBpZiAoWydQb2ludGVyJywgJ1JlbGF0aW9uJ10uaW5kZXhPZih0eXBlKSA+PSAwKSB7XG4gICAgaWYgKCF0YXJnZXRDbGFzcykge1xuICAgICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcigxMzUsIGB0eXBlICR7dHlwZX0gbmVlZHMgYSBjbGFzcyBuYW1lYCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGFyZ2V0Q2xhc3MgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gaW52YWxpZEpzb25FcnJvcjtcbiAgICB9IGVsc2UgaWYgKCFjbGFzc05hbWVJc1ZhbGlkKHRhcmdldENsYXNzKSkge1xuICAgICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsIGludmFsaWRDbGFzc05hbWVNZXNzYWdlKHRhcmdldENsYXNzKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gaW52YWxpZEpzb25FcnJvcjtcbiAgfVxuICBpZiAodmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzLmluZGV4T2YodHlwZSkgPCAwKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSwgYGludmFsaWQgZmllbGQgdHlwZTogJHt0eXBlfWApO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG5jb25zdCBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hID0gKHNjaGVtYTogYW55KSA9PiB7XG4gIHNjaGVtYSA9IGluamVjdERlZmF1bHRTY2hlbWEoc2NoZW1hKTtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuQUNMO1xuICBzY2hlbWEuZmllbGRzLl9ycGVybSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuICBzY2hlbWEuZmllbGRzLl93cGVybSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuXG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMucGFzc3dvcmQ7XG4gICAgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbmNvbnN0IGNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSA9ICh7IC4uLnNjaGVtYSB9KSA9PiB7XG4gIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9ycGVybTtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3dwZXJtO1xuXG4gIHNjaGVtYS5maWVsZHMuQUNMID0geyB0eXBlOiAnQUNMJyB9O1xuXG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuYXV0aERhdGE7IC8vQXV0aCBkYXRhIGlzIGltcGxpY2l0XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgICBzY2hlbWEuZmllbGRzLnBhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICB9XG5cbiAgaWYgKHNjaGVtYS5pbmRleGVzICYmIE9iamVjdC5rZXlzKHNjaGVtYS5pbmRleGVzKS5sZW5ndGggPT09IDApIHtcbiAgICBkZWxldGUgc2NoZW1hLmluZGV4ZXM7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY2xhc3MgU2NoZW1hRGF0YSB7XG4gIF9fZGF0YTogYW55O1xuICBfX3Byb3RlY3RlZEZpZWxkczogYW55O1xuICBjb25zdHJ1Y3RvcihhbGxTY2hlbWFzID0gW10sIHByb3RlY3RlZEZpZWxkcyA9IHt9KSB7XG4gICAgdGhpcy5fX2RhdGEgPSB7fTtcbiAgICB0aGlzLl9fcHJvdGVjdGVkRmllbGRzID0gcHJvdGVjdGVkRmllbGRzO1xuICAgIGFsbFNjaGVtYXMuZm9yRWFjaChzY2hlbWEgPT4ge1xuICAgICAgaWYgKHZvbGF0aWxlQ2xhc3Nlcy5pbmNsdWRlcyhzY2hlbWEuY2xhc3NOYW1lKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgc2NoZW1hLmNsYXNzTmFtZSwge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuX19kYXRhW3NjaGVtYS5jbGFzc05hbWVdKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgICAgICBkYXRhLmZpZWxkcyA9IGluamVjdERlZmF1bHRTY2hlbWEoc2NoZW1hKS5maWVsZHM7XG4gICAgICAgICAgICBkYXRhLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyA9IGRlZXBjb3B5KHNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMpO1xuICAgICAgICAgICAgZGF0YS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG5cbiAgICAgICAgICAgIGNvbnN0IGNsYXNzUHJvdGVjdGVkRmllbGRzID0gdGhpcy5fX3Byb3RlY3RlZEZpZWxkc1tzY2hlbWEuY2xhc3NOYW1lXTtcbiAgICAgICAgICAgIGlmIChjbGFzc1Byb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjbGFzc1Byb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVucSA9IG5ldyBTZXQoW1xuICAgICAgICAgICAgICAgICAgLi4uKGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLnByb3RlY3RlZEZpZWxkc1trZXldIHx8IFtdKSxcbiAgICAgICAgICAgICAgICAgIC4uLmNsYXNzUHJvdGVjdGVkRmllbGRzW2tleV0sXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMucHJvdGVjdGVkRmllbGRzW2tleV0gPSBBcnJheS5mcm9tKHVucSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV0gPSBkYXRhO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV07XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEluamVjdCB0aGUgaW4tbWVtb3J5IGNsYXNzZXNcbiAgICB2b2xhdGlsZUNsYXNzZXMuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGNsYXNzTmFtZSwge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuX19kYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGZpZWxkczoge30sXG4gICAgICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgICAgIGRhdGEuZmllbGRzID0gc2NoZW1hLmZpZWxkcztcbiAgICAgICAgICAgIGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICAgICAgICAgIGRhdGEuaW5kZXhlcyA9IHNjaGVtYS5pbmRleGVzO1xuICAgICAgICAgICAgdGhpcy5fX2RhdGFbY2xhc3NOYW1lXSA9IGRhdGE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLl9fZGF0YVtjbGFzc05hbWVdO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxuY29uc3QgaW5qZWN0RGVmYXVsdFNjaGVtYSA9ICh7IGNsYXNzTmFtZSwgZmllbGRzLCBjbGFzc0xldmVsUGVybWlzc2lvbnMsIGluZGV4ZXMgfTogU2NoZW1hKSA9PiB7XG4gIGNvbnN0IGRlZmF1bHRTY2hlbWE6IFNjaGVtYSA9IHtcbiAgICBjbGFzc05hbWUsXG4gICAgZmllbGRzOiB7XG4gICAgICAuLi5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgIC4uLihkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdIHx8IHt9KSxcbiAgICAgIC4uLmZpZWxkcyxcbiAgICB9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgfTtcbiAgaWYgKGluZGV4ZXMgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoICE9PSAwKSB7XG4gICAgZGVmYXVsdFNjaGVtYS5pbmRleGVzID0gaW5kZXhlcztcbiAgfVxuICByZXR1cm4gZGVmYXVsdFNjaGVtYTtcbn07XG5cbmNvbnN0IF9Ib29rc1NjaGVtYSA9IHsgY2xhc3NOYW1lOiAnX0hvb2tzJywgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fSG9va3MgfTtcbmNvbnN0IF9HbG9iYWxDb25maWdTY2hlbWEgPSB7XG4gIGNsYXNzTmFtZTogJ19HbG9iYWxDb25maWcnLFxuICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9HbG9iYWxDb25maWcsXG59O1xuY29uc3QgX0dyYXBoUUxDb25maWdTY2hlbWEgPSB7XG4gIGNsYXNzTmFtZTogJ19HcmFwaFFMQ29uZmlnJyxcbiAgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fR3JhcGhRTENvbmZpZyxcbn07XG5jb25zdCBfUHVzaFN0YXR1c1NjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19QdXNoU3RhdHVzJyxcbiAgICBmaWVsZHM6IHt9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgX0pvYlN0YXR1c1NjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19Kb2JTdGF0dXMnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSm9iU2NoZWR1bGVTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfSm9iU2NoZWR1bGUnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfQXVkaWVuY2VTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfQXVkaWVuY2UnLFxuICAgIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0F1ZGllbmNlLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgX0lkZW1wb3RlbmN5U2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX0lkZW1wb3RlbmN5JyxcbiAgICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9JZGVtcG90ZW5jeSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMgPSBbXG4gIF9Ib29rc1NjaGVtYSxcbiAgX0pvYlN0YXR1c1NjaGVtYSxcbiAgX0pvYlNjaGVkdWxlU2NoZW1hLFxuICBfUHVzaFN0YXR1c1NjaGVtYSxcbiAgX0dsb2JhbENvbmZpZ1NjaGVtYSxcbiAgX0dyYXBoUUxDb25maWdTY2hlbWEsXG4gIF9BdWRpZW5jZVNjaGVtYSxcbiAgX0lkZW1wb3RlbmN5U2NoZW1hLFxuXTtcblxuY29uc3QgZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUgPSAoZGJUeXBlOiBTY2hlbWFGaWVsZCB8IHN0cmluZywgb2JqZWN0VHlwZTogU2NoZW1hRmllbGQpID0+IHtcbiAgaWYgKGRiVHlwZS50eXBlICE9PSBvYmplY3RUeXBlLnR5cGUpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRiVHlwZS50YXJnZXRDbGFzcyAhPT0gb2JqZWN0VHlwZS50YXJnZXRDbGFzcykgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGJUeXBlID09PSBvYmplY3RUeXBlLnR5cGUpIHJldHVybiB0cnVlO1xuICBpZiAoZGJUeXBlLnR5cGUgPT09IG9iamVjdFR5cGUudHlwZSkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IHR5cGVUb1N0cmluZyA9ICh0eXBlOiBTY2hlbWFGaWVsZCB8IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuICBpZiAodHlwZS50YXJnZXRDbGFzcykge1xuICAgIHJldHVybiBgJHt0eXBlLnR5cGV9PCR7dHlwZS50YXJnZXRDbGFzc30+YDtcbiAgfVxuICByZXR1cm4gYCR7dHlwZS50eXBlfWA7XG59O1xuXG4vLyBTdG9yZXMgdGhlIGVudGlyZSBzY2hlbWEgb2YgdGhlIGFwcCBpbiBhIHdlaXJkIGh5YnJpZCBmb3JtYXQgc29tZXdoZXJlIGJldHdlZW5cbi8vIHRoZSBtb25nbyBmb3JtYXQgYW5kIHRoZSBQYXJzZSBmb3JtYXQuIFNvb24sIHRoaXMgd2lsbCBhbGwgYmUgUGFyc2UgZm9ybWF0LlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NoZW1hQ29udHJvbGxlciB7XG4gIF9kYkFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyO1xuICBzY2hlbWFEYXRhOiB7IFtzdHJpbmddOiBTY2hlbWEgfTtcbiAgX2NhY2hlOiBhbnk7XG4gIHJlbG9hZERhdGFQcm9taXNlOiA/UHJvbWlzZTxhbnk+O1xuICBwcm90ZWN0ZWRGaWVsZHM6IGFueTtcbiAgdXNlcklkUmVnRXg6IFJlZ0V4cDtcblxuICBjb25zdHJ1Y3RvcihkYXRhYmFzZUFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5fZGJBZGFwdGVyID0gZGF0YWJhc2VBZGFwdGVyO1xuICAgIHRoaXMuX2NhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoKTtcbiAgICB0aGlzLnByb3RlY3RlZEZpZWxkcyA9IENvbmZpZy5nZXQoUGFyc2UuYXBwbGljYXRpb25JZCkucHJvdGVjdGVkRmllbGRzO1xuXG4gICAgY29uc3QgY3VzdG9tSWRzID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKS5hbGxvd0N1c3RvbU9iamVjdElkO1xuXG4gICAgY29uc3QgY3VzdG9tSWRSZWdFeCA9IC9eLnsxLH0kL3U7IC8vIDErIGNoYXJzXG4gICAgY29uc3QgYXV0b0lkUmVnRXggPSAvXlthLXpBLVowLTldezEsfSQvO1xuXG4gICAgdGhpcy51c2VySWRSZWdFeCA9IGN1c3RvbUlkcyA/IGN1c3RvbUlkUmVnRXggOiBhdXRvSWRSZWdFeDtcbiAgfVxuXG4gIHJlbG9hZERhdGEob3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGlmICh0aGlzLnJlbG9hZERhdGFQcm9taXNlICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgIH1cbiAgICB0aGlzLnJlbG9hZERhdGFQcm9taXNlID0gdGhpcy5nZXRBbGxDbGFzc2VzKG9wdGlvbnMpXG4gICAgICAudGhlbihcbiAgICAgICAgYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoYWxsU2NoZW1hcywgdGhpcy5wcm90ZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHRoaXMuc2NoZW1hRGF0YSA9IG5ldyBTY2hlbWFEYXRhKCk7XG4gICAgICAgICAgZGVsZXRlIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB7fSk7XG4gICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gIH1cblxuICBnZXRBbGxDbGFzc2VzKG9wdGlvbnM6IExvYWRTY2hlbWFPcHRpb25zID0geyBjbGVhckNhY2hlOiBmYWxzZSB9KTogUHJvbWlzZTxBcnJheTxTY2hlbWE+PiB7XG4gICAgaWYgKG9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY2FjaGUuZ2V0QWxsQ2xhc3NlcygpLnRoZW4oYWxsQ2xhc3NlcyA9PiB7XG4gICAgICBpZiAoYWxsQ2xhc3NlcyAmJiBhbGxDbGFzc2VzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGFsbENsYXNzZXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0QWxsQ2xhc3NlcygpOiBQcm9taXNlPEFycmF5PFNjaGVtYT4+IHtcbiAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyXG4gICAgICAuZ2V0QWxsQ2xhc3NlcygpXG4gICAgICAudGhlbihhbGxTY2hlbWFzID0+IGFsbFNjaGVtYXMubWFwKGluamVjdERlZmF1bHRTY2hlbWEpKVxuICAgICAgLnRoZW4oYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgdGhpcy5fY2FjaGVcbiAgICAgICAgICAuc2V0QWxsQ2xhc3NlcyhhbGxTY2hlbWFzKVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiBjb25zb2xlLmVycm9yKCdFcnJvciBzYXZpbmcgc2NoZW1hIHRvIGNhY2hlOicsIGVycm9yKSk7XG4gICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuICAgICAgICByZXR1cm4gYWxsU2NoZW1hcztcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0T25lU2NoZW1hKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGFsbG93Vm9sYXRpbGVDbGFzc2VzOiBib29sZWFuID0gZmFsc2UsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWE+IHtcbiAgICBsZXQgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLl9jYWNoZS5jbGVhcigpO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChhbGxvd1ZvbGF0aWxlQ2xhc3NlcyAmJiB2b2xhdGlsZUNsYXNzZXMuaW5kZXhPZihjbGFzc05hbWUpID4gLTEpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGRzOiBkYXRhLmZpZWxkcyxcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgIGluZGV4ZXM6IGRhdGEuaW5kZXhlcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGUuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSkudGhlbihjYWNoZWQgPT4ge1xuICAgICAgICBpZiAoY2FjaGVkICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpLnRoZW4oYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgICAgY29uc3Qgb25lU2NoZW1hID0gYWxsU2NoZW1hcy5maW5kKHNjaGVtYSA9PiBzY2hlbWEuY2xhc3NOYW1lID09PSBjbGFzc05hbWUpO1xuICAgICAgICAgIGlmICghb25lU2NoZW1hKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodW5kZWZpbmVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG9uZVNjaGVtYTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIG5ldyBjbGFzcyB0aGF0IGluY2x1ZGVzIHRoZSB0aHJlZSBkZWZhdWx0IGZpZWxkcy5cbiAgLy8gQUNMIGlzIGFuIGltcGxpY2l0IGNvbHVtbiB0aGF0IGRvZXMgbm90IGdldCBhbiBlbnRyeSBpbiB0aGVcbiAgLy8gX1NDSEVNQVMgZGF0YWJhc2UuIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGVcbiAgLy8gY3JlYXRlZCBzY2hlbWEsIGluIG1vbmdvIGZvcm1hdC5cbiAgLy8gb24gc3VjY2VzcywgYW5kIHJlamVjdHMgd2l0aCBhbiBlcnJvciBvbiBmYWlsLiBFbnN1cmUgeW91XG4gIC8vIGhhdmUgYXV0aG9yaXphdGlvbiAobWFzdGVyIGtleSwgb3IgY2xpZW50IGNsYXNzIGNyZWF0aW9uXG4gIC8vIGVuYWJsZWQpIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gIGFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBTY2hlbWFGaWVsZHMgPSB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueSxcbiAgICBpbmRleGVzOiBhbnkgPSB7fVxuICApOiBQcm9taXNlPHZvaWQgfCBTY2hlbWE+IHtcbiAgICB2YXIgdmFsaWRhdGlvbkVycm9yID0gdGhpcy52YWxpZGF0ZU5ld0NsYXNzKGNsYXNzTmFtZSwgZmllbGRzLCBjbGFzc0xldmVsUGVybWlzc2lvbnMpO1xuICAgIGlmICh2YWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIH0gZWxzZSBpZiAodmFsaWRhdGlvbkVycm9yLmNvZGUgJiYgdmFsaWRhdGlvbkVycm9yLmVycm9yKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgUGFyc2UuRXJyb3IodmFsaWRhdGlvbkVycm9yLmNvZGUsIHZhbGlkYXRpb25FcnJvci5lcnJvcikpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHZhbGlkYXRpb25FcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmNyZWF0ZUNsYXNzKFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoe1xuICAgICAgICAgIGZpZWxkcyxcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgaW5kZXhlcyxcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAudGhlbihjb252ZXJ0QWRhcHRlclNjaGVtYVRvUGFyc2VTY2hlbWEpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGVDbGFzcyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzdWJtaXR0ZWRGaWVsZHM6IFNjaGVtYUZpZWxkcyxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueSxcbiAgICBpbmRleGVzOiBhbnksXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlclxuICApIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdGaWVsZHMgPSBzY2hlbWEuZmllbGRzO1xuICAgICAgICBPYmplY3Qua2V5cyhzdWJtaXR0ZWRGaWVsZHMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBzdWJtaXR0ZWRGaWVsZHNbbmFtZV07XG4gICAgICAgICAgaWYgKGV4aXN0aW5nRmllbGRzW25hbWVdICYmIGZpZWxkLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMjU1LCBgRmllbGQgJHtuYW1lfSBleGlzdHMsIGNhbm5vdCB1cGRhdGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZXhpc3RpbmdGaWVsZHNbbmFtZV0gJiYgZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nRmllbGRzLl9ycGVybTtcbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nRmllbGRzLl93cGVybTtcbiAgICAgICAgY29uc3QgbmV3U2NoZW1hID0gYnVpbGRNZXJnZWRTY2hlbWFPYmplY3QoZXhpc3RpbmdGaWVsZHMsIHN1Ym1pdHRlZEZpZWxkcyk7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRGaWVsZHMgPSBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdIHx8IGRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0O1xuICAgICAgICBjb25zdCBmdWxsTmV3U2NoZW1hID0gT2JqZWN0LmFzc2lnbih7fSwgbmV3U2NoZW1hLCBkZWZhdWx0RmllbGRzKTtcbiAgICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9yID0gdGhpcy52YWxpZGF0ZVNjaGVtYURhdGEoXG4gICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgIG5ld1NjaGVtYSxcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgT2JqZWN0LmtleXMoZXhpc3RpbmdGaWVsZHMpXG4gICAgICAgICk7XG4gICAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IodmFsaWRhdGlvbkVycm9yLmNvZGUsIHZhbGlkYXRpb25FcnJvci5lcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5hbGx5IHdlIGhhdmUgY2hlY2tlZCB0byBtYWtlIHN1cmUgdGhlIHJlcXVlc3QgaXMgdmFsaWQgYW5kIHdlIGNhbiBzdGFydCBkZWxldGluZyBmaWVsZHMuXG4gICAgICAgIC8vIERvIGFsbCBkZWxldGlvbnMgZmlyc3QsIHRoZW4gYSBzaW5nbGUgc2F2ZSB0byBfU0NIRU1BIGNvbGxlY3Rpb24gdG8gaGFuZGxlIGFsbCBhZGRpdGlvbnMuXG4gICAgICAgIGNvbnN0IGRlbGV0ZWRGaWVsZHM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGNvbnN0IGluc2VydGVkRmllbGRzID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgIGlmIChzdWJtaXR0ZWRGaWVsZHNbZmllbGROYW1lXS5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICAgICAgZGVsZXRlZEZpZWxkcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc2VydGVkRmllbGRzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGxldCBkZWxldGVQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIGlmIChkZWxldGVkRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBkZWxldGVQcm9taXNlID0gdGhpcy5kZWxldGVGaWVsZHMoZGVsZXRlZEZpZWxkcywgY2xhc3NOYW1lLCBkYXRhYmFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVuZm9yY2VGaWVsZHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBkZWxldGVQcm9taXNlIC8vIERlbGV0ZSBFdmVyeXRoaW5nXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pKSAvLyBSZWxvYWQgb3VyIFNjaGVtYSwgc28gd2UgaGF2ZSBhbGwgdGhlIG5ldyB2YWx1ZXNcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBpbnNlcnRlZEZpZWxkcy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0eXBlID0gc3VibWl0dGVkRmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5mb3JjZUZpZWxkRXhpc3RzKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgICAgIGVuZm9yY2VGaWVsZHMgPSByZXN1bHRzLmZpbHRlcihyZXN1bHQgPT4gISFyZXN1bHQpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRQZXJtaXNzaW9ucyhjbGFzc05hbWUsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbmV3U2NoZW1hKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PlxuICAgICAgICAgICAgICB0aGlzLl9kYkFkYXB0ZXIuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4ZXMsXG4gICAgICAgICAgICAgICAgc2NoZW1hLmluZGV4ZXMsXG4gICAgICAgICAgICAgICAgZnVsbE5ld1NjaGVtYVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pKVxuICAgICAgICAgICAgLy9UT0RPOiBNb3ZlIHRoaXMgbG9naWMgaW50byB0aGUgZGF0YWJhc2UgYWRhcHRlclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmVuc3VyZUZpZWxkcyhlbmZvcmNlRmllbGRzKTtcbiAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgICAgICAgICAgIGNvbnN0IHJlbG9hZGVkU2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgZmllbGRzOiBzY2hlbWEuZmllbGRzLFxuICAgICAgICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgaWYgKHNjaGVtYS5pbmRleGVzICYmIE9iamVjdC5rZXlzKHNjaGVtYS5pbmRleGVzKS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgICAgICByZWxvYWRlZFNjaGVtYS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlbG9hZGVkU2NoZW1hO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSxcbiAgICAgICAgICAgIGBDbGFzcyAke2NsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3QuYFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgdG8gdGhlIG5ldyBzY2hlbWFcbiAgLy8gb2JqZWN0IG9yIGZhaWxzIHdpdGggYSByZWFzb24uXG4gIGVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8U2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG4gICAgLy8gV2UgZG9uJ3QgaGF2ZSB0aGlzIGNsYXNzLiBVcGRhdGUgdGhlIHNjaGVtYVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmFkZENsYXNzSWZOb3RFeGlzdHMoY2xhc3NOYW1lKVxuICAgICAgICAvLyBUaGUgc2NoZW1hIHVwZGF0ZSBzdWNjZWVkZWQuIFJlbG9hZCB0aGUgc2NoZW1hXG4gICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHRcbiAgICAgICAgICAvLyBoYXZlIGZhaWxlZCBiZWNhdXNlIHRoZXJlJ3MgYSByYWNlIGNvbmRpdGlvbiBhbmQgYSBkaWZmZXJlbnRcbiAgICAgICAgICAvLyBjbGllbnQgaXMgbWFraW5nIHRoZSBleGFjdCBzYW1lIHNjaGVtYSB1cGRhdGUgdGhhdCB3ZSB3YW50LlxuICAgICAgICAgIC8vIFNvIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWEuXG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc2NoZW1hIG5vdyB2YWxpZGF0ZXNcbiAgICAgICAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgRmFpbGVkIHRvIGFkZCAke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBzdGlsbCBkb2Vzbid0IHZhbGlkYXRlLiBHaXZlIHVwXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ3NjaGVtYSBjbGFzcyBuYW1lIGRvZXMgbm90IHJldmFsaWRhdGUnKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVOZXdDbGFzcyhjbGFzc05hbWU6IHN0cmluZywgZmllbGRzOiBTY2hlbWFGaWVsZHMgPSB7fSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBhbnkpOiBhbnkge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gKTtcbiAgICB9XG4gICAgaWYgKCFjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSxcbiAgICAgICAgZXJyb3I6IGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZSksXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVNjaGVtYURhdGEoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgW10pO1xuICB9XG5cbiAgdmFsaWRhdGVTY2hlbWFEYXRhKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGZpZWxkczogU2NoZW1hRmllbGRzLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgIGV4aXN0aW5nRmllbGROYW1lczogQXJyYXk8c3RyaW5nPlxuICApIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBmaWVsZHMpIHtcbiAgICAgIGlmIChleGlzdGluZ0ZpZWxkTmFtZXMuaW5kZXhPZihmaWVsZE5hbWUpIDwgMCkge1xuICAgICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICAgZXJyb3I6ICdpbnZhbGlkIGZpZWxkIG5hbWU6ICcgKyBmaWVsZE5hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29kZTogMTM2LFxuICAgICAgICAgICAgZXJyb3I6ICdmaWVsZCAnICsgZmllbGROYW1lICsgJyBjYW5ub3QgYmUgYWRkZWQnLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmllbGRUeXBlID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAgIGNvbnN0IGVycm9yID0gZmllbGRUeXBlSXNJbnZhbGlkKGZpZWxkVHlwZSk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuIHsgY29kZTogZXJyb3IuY29kZSwgZXJyb3I6IGVycm9yLm1lc3NhZ2UgfTtcbiAgICAgICAgaWYgKGZpZWxkVHlwZS5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxldCBkZWZhdWx0VmFsdWVUeXBlID0gZ2V0VHlwZShmaWVsZFR5cGUuZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgICBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmYXVsdFZhbHVlVHlwZSA9PT0gJ29iamVjdCcgJiYgZmllbGRUeXBlLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICBlcnJvcjogYFRoZSAnZGVmYXVsdCB2YWx1ZScgb3B0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciAke3R5cGVUb1N0cmluZyhmaWVsZFR5cGUpfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKGZpZWxkVHlwZSwgZGVmYXVsdFZhbHVlVHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICBlcnJvcjogYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfSBkZWZhdWx0IHZhbHVlOyBleHBlY3RlZCAke3R5cGVUb1N0cmluZyhcbiAgICAgICAgICAgICAgICBmaWVsZFR5cGVcbiAgICAgICAgICAgICAgKX0gYnV0IGdvdCAke3R5cGVUb1N0cmluZyhkZWZhdWx0VmFsdWVUeXBlKX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGRUeXBlLnJlcXVpcmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFR5cGUgPT09ICdvYmplY3QnICYmIGZpZWxkVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBUaGUgJ3JlcXVpcmVkJyBvcHRpb24gaXMgbm90IGFwcGxpY2FibGUgZm9yICR7dHlwZVRvU3RyaW5nKGZpZWxkVHlwZSl9YCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXSkge1xuICAgICAgZmllbGRzW2ZpZWxkTmFtZV0gPSBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdW2ZpZWxkTmFtZV07XG4gICAgfVxuXG4gICAgY29uc3QgZ2VvUG9pbnRzID0gT2JqZWN0LmtleXMoZmllbGRzKS5maWx0ZXIoXG4gICAgICBrZXkgPT4gZmllbGRzW2tleV0gJiYgZmllbGRzW2tleV0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICk7XG4gICAgaWYgKGdlb1BvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgZXJyb3I6XG4gICAgICAgICAgJ2N1cnJlbnRseSwgb25seSBvbmUgR2VvUG9pbnQgZmllbGQgbWF5IGV4aXN0IGluIGFuIG9iamVjdC4gQWRkaW5nICcgK1xuICAgICAgICAgIGdlb1BvaW50c1sxXSArXG4gICAgICAgICAgJyB3aGVuICcgK1xuICAgICAgICAgIGdlb1BvaW50c1swXSArXG4gICAgICAgICAgJyBhbHJlYWR5IGV4aXN0cy4nLFxuICAgICAgfTtcbiAgICB9XG4gICAgdmFsaWRhdGVDTFAoY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBmaWVsZHMsIHRoaXMudXNlcklkUmVnRXgpO1xuICB9XG5cbiAgLy8gU2V0cyB0aGUgQ2xhc3MtbGV2ZWwgcGVybWlzc2lvbnMgZm9yIGEgZ2l2ZW4gY2xhc3NOYW1lLCB3aGljaCBtdXN0IGV4aXN0LlxuICBzZXRQZXJtaXNzaW9ucyhjbGFzc05hbWU6IHN0cmluZywgcGVybXM6IGFueSwgbmV3U2NoZW1hOiBTY2hlbWFGaWVsZHMpIHtcbiAgICBpZiAodHlwZW9mIHBlcm1zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICB2YWxpZGF0ZUNMUChwZXJtcywgbmV3U2NoZW1hLCB0aGlzLnVzZXJJZFJlZ0V4KTtcbiAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyLnNldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUsIHBlcm1zKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgc3VjY2Vzc2Z1bGx5IHRvIHRoZSBuZXcgc2NoZW1hXG4gIC8vIG9iamVjdCBpZiB0aGUgcHJvdmlkZWQgY2xhc3NOYW1lLWZpZWxkTmFtZS10eXBlIHR1cGxlIGlzIHZhbGlkLlxuICAvLyBUaGUgY2xhc3NOYW1lIG11c3QgYWxyZWFkeSBiZSB2YWxpZGF0ZWQuXG4gIC8vIElmICdmcmVlemUnIGlzIHRydWUsIHJlZnVzZSB0byB1cGRhdGUgdGhlIHNjaGVtYSBmb3IgdGhpcyBmaWVsZC5cbiAgZW5mb3JjZUZpZWxkRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nIHwgU2NoZW1hRmllbGQpIHtcbiAgICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA+IDApIHtcbiAgICAgIC8vIHN1YmRvY3VtZW50IGtleSAoeC55KSA9PiBvayBpZiB4IGlzIG9mIHR5cGUgJ29iamVjdCdcbiAgICAgIGZpZWxkTmFtZSA9IGZpZWxkTmFtZS5zcGxpdCgnLicpWzBdO1xuICAgICAgdHlwZSA9ICdPYmplY3QnO1xuICAgIH1cbiAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfS5gKTtcbiAgICB9XG5cbiAgICAvLyBJZiBzb21lb25lIHRyaWVzIHRvIGNyZWF0ZSBhIG5ldyBmaWVsZCB3aXRoIG51bGwvdW5kZWZpbmVkIGFzIHRoZSB2YWx1ZSwgcmV0dXJuO1xuICAgIGlmICghdHlwZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgdHlwZSA9ICh7IHR5cGUgfTogU2NoZW1hRmllbGQpO1xuICAgIH1cblxuICAgIGlmICh0eXBlLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBsZXQgZGVmYXVsdFZhbHVlVHlwZSA9IGdldFR5cGUodHlwZS5kZWZhdWx0VmFsdWUpO1xuICAgICAgaWYgKHR5cGVvZiBkZWZhdWx0VmFsdWVUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICB9XG4gICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKHR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICBgc2NoZW1hIG1pc21hdGNoIGZvciAke2NsYXNzTmFtZX0uJHtmaWVsZE5hbWV9IGRlZmF1bHQgdmFsdWU7IGV4cGVjdGVkICR7dHlwZVRvU3RyaW5nKFxuICAgICAgICAgICAgdHlwZVxuICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcoZGVmYXVsdFZhbHVlVHlwZSl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleHBlY3RlZFR5cGUpIHtcbiAgICAgIGlmICghZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUoZXhwZWN0ZWRUeXBlLCB0eXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICBleHBlY3RlZFR5cGVcbiAgICAgICAgICApfSBidXQgZ290ICR7dHlwZVRvU3RyaW5nKHR5cGUpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSkge1xuICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHdlIHRocm93IGVycm9ycyB3aGVuIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGRvIHNvLlxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHQgaGF2ZSBiZWVuIGEgcmFjZVxuICAgICAgICAvLyBjb25kaXRpb24gd2hlcmUgYW5vdGhlciBjbGllbnQgdXBkYXRlZCB0aGUgc2NoZW1hIGluIHRoZSBzYW1lXG4gICAgICAgIC8vIHdheSB0aGF0IHdlIHdhbnRlZCB0by4gU28sIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIGVuc3VyZUZpZWxkcyhmaWVsZHM6IGFueSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH0gPSBmaWVsZHNbaV07XG4gICAgICBsZXQgeyB0eXBlIH0gPSBmaWVsZHNbaV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHR5cGUgPSB7IHR5cGU6IHR5cGUgfTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWRUeXBlIHx8ICFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBDb3VsZCBub3QgYWRkIGZpZWxkICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG1haW50YWluIGNvbXBhdGliaWxpdHlcbiAgZGVsZXRlRmllbGQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nLCBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlRmllbGRzKFtmaWVsZE5hbWVdLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgfVxuXG4gIC8vIERlbGV0ZSBmaWVsZHMsIGFuZCByZW1vdmUgdGhhdCBkYXRhIGZyb20gYWxsIG9iamVjdHMuIFRoaXMgaXMgaW50ZW5kZWRcbiAgLy8gdG8gcmVtb3ZlIHVudXNlZCBmaWVsZHMsIGlmIG90aGVyIHdyaXRlcnMgYXJlIHdyaXRpbmcgb2JqZWN0cyB0aGF0IGluY2x1ZGVcbiAgLy8gdGhpcyBmaWVsZCwgdGhlIGZpZWxkIG1heSByZWFwcGVhci4gUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoXG4gIC8vIG5vIG9iamVjdCBvbiBzdWNjZXNzLCBvciByZWplY3RzIHdpdGggeyBjb2RlLCBlcnJvciB9IG9uIGZhaWx1cmUuXG4gIC8vIFBhc3NpbmcgdGhlIGRhdGFiYXNlIGFuZCBwcmVmaXggaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGRyb3AgcmVsYXRpb24gY29sbGVjdGlvbnNcbiAgLy8gYW5kIHJlbW92ZSBmaWVsZHMgZnJvbSBvYmplY3RzLiBJZGVhbGx5IHRoZSBkYXRhYmFzZSB3b3VsZCBiZWxvbmcgdG9cbiAgLy8gYSBkYXRhYmFzZSBhZGFwdGVyIGFuZCB0aGlzIGZ1bmN0aW9uIHdvdWxkIGNsb3NlIG92ZXIgaXQgb3IgYWNjZXNzIGl0IHZpYSBtZW1iZXIuXG4gIGRlbGV0ZUZpZWxkcyhmaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+LCBjbGFzc05hbWU6IHN0cmluZywgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIGlmICghY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWUpKTtcbiAgICB9XG5cbiAgICBmaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCBgaW52YWxpZCBmaWVsZCBuYW1lOiAke2ZpZWxkTmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIC8vRG9uJ3QgYWxsb3cgZGVsZXRpbmcgdGhlIGRlZmF1bHQgZmllbGRzLlxuICAgICAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MoZmllbGROYW1lLCBjbGFzc05hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxMzYsIGBmaWVsZCAke2ZpZWxkTmFtZX0gY2Fubm90IGJlIGNoYW5nZWRgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIGZhbHNlLCB7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICAgIGZpZWxkTmFtZXMuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgIGlmICghc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMjU1LCBgRmllbGQgJHtmaWVsZE5hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2NoZW1hRmllbGRzID0geyAuLi5zY2hlbWEuZmllbGRzIH07XG4gICAgICAgIHJldHVybiBkYXRhYmFzZS5hZGFwdGVyLmRlbGV0ZUZpZWxkcyhjbGFzc05hbWUsIHNjaGVtYSwgZmllbGROYW1lcykudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICAgICAgZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZmllbGQgPSBzY2hlbWFGaWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgICAgICAgICAvL0ZvciByZWxhdGlvbnMsIGRyb3AgdGhlIF9Kb2luIHRhYmxlXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlQ2xhc3MoYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX2NhY2hlLmNsZWFyKCkpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9iamVjdCBwcm92aWRlZCBpbiBSRVNUIGZvcm1hdC5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYSBpZiB0aGlzIG9iamVjdCBpc1xuICAvLyB2YWxpZC5cbiAgYXN5bmMgdmFsaWRhdGVPYmplY3QoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdDogYW55LCBxdWVyeTogYW55KSB7XG4gICAgbGV0IGdlb2NvdW50ID0gMDtcbiAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLmVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWUpO1xuICAgIGNvbnN0IHByb21pc2VzID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBnZXRUeXBlKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgIGlmIChleHBlY3RlZCA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBnZW9jb3VudCsrO1xuICAgICAgfVxuICAgICAgaWYgKGdlb2NvdW50ID4gMSkge1xuICAgICAgICAvLyBNYWtlIHN1cmUgYWxsIGZpZWxkIHZhbGlkYXRpb24gb3BlcmF0aW9ucyBydW4gYmVmb3JlIHdlIHJldHVybi5cbiAgICAgICAgLy8gSWYgbm90IC0gd2UgYXJlIGNvbnRpbnVpbmcgdG8gcnVuIGxvZ2ljLCBidXQgYWxyZWFkeSBwcm92aWRlZCByZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICd0aGVyZSBjYW4gb25seSBiZSBvbmUgZ2VvcG9pbnQgZmllbGQgaW4gYSBjbGFzcydcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIWV4cGVjdGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgLy8gRXZlcnkgb2JqZWN0IGhhcyBBQ0wgaW1wbGljaXRseS5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBwcm9taXNlcy5wdXNoKHNjaGVtYS5lbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIGV4cGVjdGVkKSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgY29uc3QgZW5mb3JjZUZpZWxkcyA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiAhIXJlc3VsdCk7XG5cbiAgICBpZiAoZW5mb3JjZUZpZWxkcy5sZW5ndGggIT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgfVxuICAgIHRoaXMuZW5zdXJlRmllbGRzKGVuZm9yY2VGaWVsZHMpO1xuXG4gICAgY29uc3QgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShzY2hlbWEpO1xuICAgIHJldHVybiB0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMocHJvbWlzZSwgY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGF0IGFsbCB0aGUgcHJvcGVydGllcyBhcmUgc2V0IGZvciB0aGUgb2JqZWN0XG4gIHZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zKGNsYXNzTmFtZTogc3RyaW5nLCBvYmplY3Q6IGFueSwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGNvbHVtbnMgPSByZXF1aXJlZENvbHVtbnNbY2xhc3NOYW1lXTtcbiAgICBpZiAoIWNvbHVtbnMgfHwgY29sdW1ucy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBtaXNzaW5nQ29sdW1ucyA9IGNvbHVtbnMuZmlsdGVyKGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgIGlmIChxdWVyeSAmJiBxdWVyeS5vYmplY3RJZCkge1xuICAgICAgICBpZiAob2JqZWN0W2NvbHVtbl0gJiYgdHlwZW9mIG9iamVjdFtjb2x1bW5dID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIC8vIFRyeWluZyB0byBkZWxldGUgYSByZXF1aXJlZCBjb2x1bW5cbiAgICAgICAgICByZXR1cm4gb2JqZWN0W2NvbHVtbl0uX19vcCA9PSAnRGVsZXRlJztcbiAgICAgICAgfVxuICAgICAgICAvLyBOb3QgdHJ5aW5nIHRvIGRvIGFueXRoaW5nIHRoZXJlXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAhb2JqZWN0W2NvbHVtbl07XG4gICAgfSk7XG5cbiAgICBpZiAobWlzc2luZ0NvbHVtbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBtaXNzaW5nQ29sdW1uc1swXSArICcgaXMgcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XG4gIH1cblxuICB0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUoY2xhc3NOYW1lOiBzdHJpbmcsIGFjbEdyb3VwOiBzdHJpbmdbXSwgb3BlcmF0aW9uOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gU2NoZW1hQ29udHJvbGxlci50ZXN0UGVybWlzc2lvbnMoXG4gICAgICB0aGlzLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpLFxuICAgICAgYWNsR3JvdXAsXG4gICAgICBvcGVyYXRpb25cbiAgICApO1xuICB9XG5cbiAgLy8gVGVzdHMgdGhhdCB0aGUgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbiBsZXQgcGFzcyB0aGUgb3BlcmF0aW9uIGZvciBhIGdpdmVuIGFjbEdyb3VwXG4gIHN0YXRpYyB0ZXN0UGVybWlzc2lvbnMoY2xhc3NQZXJtaXNzaW9uczogP2FueSwgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghY2xhc3NQZXJtaXNzaW9ucyB8fCAhY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl07XG4gICAgaWYgKHBlcm1zWycqJ10pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDaGVjayBwZXJtaXNzaW9ucyBhZ2FpbnN0IHRoZSBhY2xHcm91cCBwcm92aWRlZCAoYXJyYXkgb2YgdXNlcklkL3JvbGVzKVxuICAgIGlmIChcbiAgICAgIGFjbEdyb3VwLnNvbWUoYWNsID0+IHtcbiAgICAgICAgcmV0dXJuIHBlcm1zW2FjbF0gPT09IHRydWU7XG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyBhbiBvcGVyYXRpb24gcGFzc2VzIGNsYXNzLWxldmVsLXBlcm1pc3Npb25zIHNldCBpbiB0aGUgc2NoZW1hXG4gIHN0YXRpYyB2YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgY2xhc3NQZXJtaXNzaW9uczogP2FueSxcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBhY2xHcm91cDogc3RyaW5nW10sXG4gICAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gICAgYWN0aW9uPzogc3RyaW5nXG4gICkge1xuICAgIGlmIChTY2hlbWFDb250cm9sbGVyLnRlc3RQZXJtaXNzaW9ucyhjbGFzc1Blcm1pc3Npb25zLCBhY2xHcm91cCwgb3BlcmF0aW9uKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICghY2xhc3NQZXJtaXNzaW9ucyB8fCAhY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl07XG4gICAgLy8gSWYgb25seSBmb3IgYXV0aGVudGljYXRlZCB1c2Vyc1xuICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIGFjbEdyb3VwXG4gICAgaWYgKHBlcm1zWydyZXF1aXJlc0F1dGhlbnRpY2F0aW9uJ10pIHtcbiAgICAgIC8vIElmIGFjbEdyb3VwIGhhcyAqIChwdWJsaWMpXG4gICAgICBpZiAoIWFjbEdyb3VwIHx8IGFjbEdyb3VwLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdQZXJtaXNzaW9uIGRlbmllZCwgdXNlciBuZWVkcyB0byBiZSBhdXRoZW50aWNhdGVkLidcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoYWNsR3JvdXAuaW5kZXhPZignKicpID4gLTEgJiYgYWNsR3JvdXAubGVuZ3RoID09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1Blcm1pc3Npb24gZGVuaWVkLCB1c2VyIG5lZWRzIHRvIGJlIGF1dGhlbnRpY2F0ZWQuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gcmVxdWlyZXNBdXRoZW50aWNhdGlvbiBwYXNzZWQsIGp1c3QgbW92ZSBmb3J3YXJkXG4gICAgICAvLyBwcm9iYWJseSB3b3VsZCBiZSB3aXNlIGF0IHNvbWUgcG9pbnQgdG8gcmVuYW1lIHRvICdhdXRoZW50aWNhdGVkVXNlcidcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvLyBObyBtYXRjaGluZyBDTFAsIGxldCdzIGNoZWNrIHRoZSBQb2ludGVyIHBlcm1pc3Npb25zXG4gICAgLy8gQW5kIGhhbmRsZSB0aG9zZSBsYXRlclxuICAgIGNvbnN0IHBlcm1pc3Npb25GaWVsZCA9XG4gICAgICBbJ2dldCcsICdmaW5kJywgJ2NvdW50J10uaW5kZXhPZihvcGVyYXRpb24pID4gLTEgPyAncmVhZFVzZXJGaWVsZHMnIDogJ3dyaXRlVXNlckZpZWxkcyc7XG5cbiAgICAvLyBSZWplY3QgY3JlYXRlIHdoZW4gd3JpdGUgbG9ja2Rvd25cbiAgICBpZiAocGVybWlzc2lvbkZpZWxkID09ICd3cml0ZVVzZXJGaWVsZHMnICYmIG9wZXJhdGlvbiA9PSAnY3JlYXRlJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBgUGVybWlzc2lvbiBkZW5pZWQgZm9yIGFjdGlvbiAke29wZXJhdGlvbn0gb24gY2xhc3MgJHtjbGFzc05hbWV9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyB0aGUgcmVhZFVzZXJGaWVsZHMgbGF0ZXJcbiAgICBpZiAoXG4gICAgICBBcnJheS5pc0FycmF5KGNsYXNzUGVybWlzc2lvbnNbcGVybWlzc2lvbkZpZWxkXSkgJiZcbiAgICAgIGNsYXNzUGVybWlzc2lvbnNbcGVybWlzc2lvbkZpZWxkXS5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgcG9pbnRlckZpZWxkcyA9IGNsYXNzUGVybWlzc2lvbnNbb3BlcmF0aW9uXS5wb2ludGVyRmllbGRzO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHBvaW50ZXJGaWVsZHMpICYmIHBvaW50ZXJGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gYW55IG9wIGV4Y2VwdCAnYWRkRmllbGQgYXMgcGFydCBvZiBjcmVhdGUnIGlzIG9rLlxuICAgICAgaWYgKG9wZXJhdGlvbiAhPT0gJ2FkZEZpZWxkJyB8fCBhY3Rpb24gPT09ICd1cGRhdGUnKSB7XG4gICAgICAgIC8vIFdlIGNhbiBhbGxvdyBhZGRpbmcgZmllbGQgb24gdXBkYXRlIGZsb3cgb25seS5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICBgUGVybWlzc2lvbiBkZW5pZWQgZm9yIGFjdGlvbiAke29wZXJhdGlvbn0gb24gY2xhc3MgJHtjbGFzc05hbWV9LmBcbiAgICApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9wZXJhdGlvbiBwYXNzZXMgY2xhc3MtbGV2ZWwtcGVybWlzc2lvbnMgc2V0IGluIHRoZSBzY2hlbWFcbiAgdmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZTogc3RyaW5nLCBhY2xHcm91cDogc3RyaW5nW10sIG9wZXJhdGlvbjogc3RyaW5nLCBhY3Rpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gU2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgICB0aGlzLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgYWNsR3JvdXAsXG4gICAgICBvcGVyYXRpb24sXG4gICAgICBhY3Rpb25cbiAgICApO1xuICB9XG5cbiAgZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0gJiYgdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0uY2xhc3NMZXZlbFBlcm1pc3Npb25zO1xuICB9XG5cbiAgLy8gUmV0dXJucyB0aGUgZXhwZWN0ZWQgdHlwZSBmb3IgYSBjbGFzc05hbWUra2V5IGNvbWJpbmF0aW9uXG4gIC8vIG9yIHVuZGVmaW5lZCBpZiB0aGUgc2NoZW1hIGlzIG5vdCBzZXRcbiAgZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZyk6ID8oU2NoZW1hRmllbGQgfCBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgcmV0dXJuIGV4cGVjdGVkVHlwZSA9PT0gJ21hcCcgPyAnT2JqZWN0JyA6IGV4cGVjdGVkVHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIENoZWNrcyBpZiBhIGdpdmVuIGNsYXNzIGlzIGluIHRoZSBzY2hlbWEuXG4gIGhhc0NsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhKCkudGhlbigoKSA9PiAhIXRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBuZXcgU2NoZW1hLlxuY29uc3QgbG9hZCA9IChcbiAgZGJBZGFwdGVyOiBTdG9yYWdlQWRhcHRlcixcbiAgc2NoZW1hQ2FjaGU6IGFueSxcbiAgb3B0aW9uczogYW55XG4pOiBQcm9taXNlPFNjaGVtYUNvbnRyb2xsZXI+ID0+IHtcbiAgY29uc3Qgc2NoZW1hID0gbmV3IFNjaGVtYUNvbnRyb2xsZXIoZGJBZGFwdGVyLCBzY2hlbWFDYWNoZSk7XG4gIHJldHVybiBzY2hlbWEucmVsb2FkRGF0YShvcHRpb25zKS50aGVuKCgpID0+IHNjaGVtYSk7XG59O1xuXG4vLyBCdWlsZHMgYSBuZXcgc2NoZW1hIChpbiBzY2hlbWEgQVBJIHJlc3BvbnNlIGZvcm1hdCkgb3V0IG9mIGFuXG4vLyBleGlzdGluZyBtb25nbyBzY2hlbWEgKyBhIHNjaGVtYXMgQVBJIHB1dCByZXF1ZXN0LiBUaGlzIHJlc3BvbnNlXG4vLyBkb2VzIG5vdCBpbmNsdWRlIHRoZSBkZWZhdWx0IGZpZWxkcywgYXMgaXQgaXMgaW50ZW5kZWQgdG8gYmUgcGFzc2VkXG4vLyB0byBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWUuIE5vIHZhbGlkYXRpb24gaXMgZG9uZSBoZXJlLCBpdFxuLy8gaXMgZG9uZSBpbiBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWUuXG5mdW5jdGlvbiBidWlsZE1lcmdlZFNjaGVtYU9iamVjdChleGlzdGluZ0ZpZWxkczogU2NoZW1hRmllbGRzLCBwdXRSZXF1ZXN0OiBhbnkpOiBTY2hlbWFGaWVsZHMge1xuICBjb25zdCBuZXdTY2hlbWEgPSB7fTtcbiAgLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG4gIGNvbnN0IHN5c1NjaGVtYUZpZWxkID1cbiAgICBPYmplY3Qua2V5cyhkZWZhdWx0Q29sdW1ucykuaW5kZXhPZihleGlzdGluZ0ZpZWxkcy5faWQpID09PSAtMVxuICAgICAgPyBbXVxuICAgICAgOiBPYmplY3Qua2V5cyhkZWZhdWx0Q29sdW1uc1tleGlzdGluZ0ZpZWxkcy5faWRdKTtcbiAgZm9yIChjb25zdCBvbGRGaWVsZCBpbiBleGlzdGluZ0ZpZWxkcykge1xuICAgIGlmIChcbiAgICAgIG9sZEZpZWxkICE9PSAnX2lkJyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdBQ0wnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ3VwZGF0ZWRBdCcgJiZcbiAgICAgIG9sZEZpZWxkICE9PSAnY3JlYXRlZEF0JyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdvYmplY3RJZCdcbiAgICApIHtcbiAgICAgIGlmIChzeXNTY2hlbWFGaWVsZC5sZW5ndGggPiAwICYmIHN5c1NjaGVtYUZpZWxkLmluZGV4T2Yob2xkRmllbGQpICE9PSAtMSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpZWxkSXNEZWxldGVkID0gcHV0UmVxdWVzdFtvbGRGaWVsZF0gJiYgcHV0UmVxdWVzdFtvbGRGaWVsZF0uX19vcCA9PT0gJ0RlbGV0ZSc7XG4gICAgICBpZiAoIWZpZWxkSXNEZWxldGVkKSB7XG4gICAgICAgIG5ld1NjaGVtYVtvbGRGaWVsZF0gPSBleGlzdGluZ0ZpZWxkc1tvbGRGaWVsZF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgbmV3RmllbGQgaW4gcHV0UmVxdWVzdCkge1xuICAgIGlmIChuZXdGaWVsZCAhPT0gJ29iamVjdElkJyAmJiBwdXRSZXF1ZXN0W25ld0ZpZWxkXS5fX29wICE9PSAnRGVsZXRlJykge1xuICAgICAgaWYgKHN5c1NjaGVtYUZpZWxkLmxlbmd0aCA+IDAgJiYgc3lzU2NoZW1hRmllbGQuaW5kZXhPZihuZXdGaWVsZCkgIT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbmV3U2NoZW1hW25ld0ZpZWxkXSA9IHB1dFJlcXVlc3RbbmV3RmllbGRdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3U2NoZW1hO1xufVxuXG4vLyBHaXZlbiBhIHNjaGVtYSBwcm9taXNlLCBjb25zdHJ1Y3QgYW5vdGhlciBzY2hlbWEgcHJvbWlzZSB0aGF0XG4vLyB2YWxpZGF0ZXMgdGhpcyBmaWVsZCBvbmNlIHRoZSBzY2hlbWEgbG9hZHMuXG5mdW5jdGlvbiB0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoc2NoZW1hUHJvbWlzZSwgY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KSB7XG4gIHJldHVybiBzY2hlbWFQcm9taXNlLnRoZW4oc2NoZW1hID0+IHtcbiAgICByZXR1cm4gc2NoZW1hLnZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zKGNsYXNzTmFtZSwgb2JqZWN0LCBxdWVyeSk7XG4gIH0pO1xufVxuXG4vLyBHZXRzIHRoZSB0eXBlIGZyb20gYSBSRVNUIEFQSSBmb3JtYXR0ZWQgb2JqZWN0LCB3aGVyZSAndHlwZScgaXNcbi8vIGV4dGVuZGVkIHBhc3QgamF2YXNjcmlwdCB0eXBlcyB0byBpbmNsdWRlIHRoZSByZXN0IG9mIHRoZSBQYXJzZVxuLy8gdHlwZSBzeXN0ZW0uXG4vLyBUaGUgb3V0cHV0IHNob3VsZCBiZSBhIHZhbGlkIHNjaGVtYSB2YWx1ZS5cbi8vIFRPRE86IGVuc3VyZSB0aGF0IHRoaXMgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBmb3JtYXQgdXNlZCBpbiBPcGVuIERCXG5mdW5jdGlvbiBnZXRUeXBlKG9iajogYW55KTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICBjb25zdCB0eXBlID0gdHlwZW9mIG9iajtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICByZXR1cm4gJ0Jvb2xlYW4nO1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICByZXR1cm4gJ1N0cmluZyc7XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIHJldHVybiAnTnVtYmVyJztcbiAgICBjYXNlICdtYXAnOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoIW9iaikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGdldE9iamVjdFR5cGUob2JqKTtcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyAnYmFkIG9iajogJyArIG9iajtcbiAgfVxufVxuXG4vLyBUaGlzIGdldHMgdGhlIHR5cGUgZm9yIG5vbi1KU09OIHR5cGVzIGxpa2UgcG9pbnRlcnMgYW5kIGZpbGVzLCBidXRcbi8vIGFsc28gZ2V0cyB0aGUgYXBwcm9wcmlhdGUgdHlwZSBmb3IgJCBvcGVyYXRvcnMuXG4vLyBSZXR1cm5zIG51bGwgaWYgdGhlIHR5cGUgaXMgdW5rbm93bi5cbmZ1bmN0aW9uIGdldE9iamVjdFR5cGUob2JqKTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICByZXR1cm4gJ0FycmF5JztcbiAgfVxuICBpZiAob2JqLl9fdHlwZSkge1xuICAgIHN3aXRjaCAob2JqLl9fdHlwZSkge1xuICAgICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICAgIGlmIChvYmouY2xhc3NOYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICAgIHRhcmdldENsYXNzOiBvYmouY2xhc3NOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdSZWxhdGlvbic6XG4gICAgICAgIGlmIChvYmouY2xhc3NOYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICAgICAgICB0YXJnZXRDbGFzczogb2JqLmNsYXNzTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRmlsZSc6XG4gICAgICAgIGlmIChvYmoubmFtZSkge1xuICAgICAgICAgIHJldHVybiAnRmlsZSc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdEYXRlJzpcbiAgICAgICAgaWYgKG9iai5pc28pIHtcbiAgICAgICAgICByZXR1cm4gJ0RhdGUnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgICBpZiAob2JqLmxhdGl0dWRlICE9IG51bGwgJiYgb2JqLmxvbmdpdHVkZSAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuICdHZW9Qb2ludCc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdCeXRlcyc6XG4gICAgICAgIGlmIChvYmouYmFzZTY0KSB7XG4gICAgICAgICAgcmV0dXJuICdCeXRlcyc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgICAgaWYgKG9iai5jb29yZGluYXRlcykge1xuICAgICAgICAgIHJldHVybiAnUG9seWdvbic7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSwgJ1RoaXMgaXMgbm90IGEgdmFsaWQgJyArIG9iai5fX3R5cGUpO1xuICB9XG4gIGlmIChvYmpbJyRuZSddKSB7XG4gICAgcmV0dXJuIGdldE9iamVjdFR5cGUob2JqWyckbmUnXSk7XG4gIH1cbiAgaWYgKG9iai5fX29wKSB7XG4gICAgc3dpdGNoIChvYmouX19vcCkge1xuICAgICAgY2FzZSAnSW5jcmVtZW50JzpcbiAgICAgICAgcmV0dXJuICdOdW1iZXInO1xuICAgICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICBjYXNlICdBZGQnOlxuICAgICAgY2FzZSAnQWRkVW5pcXVlJzpcbiAgICAgIGNhc2UgJ1JlbW92ZSc6XG4gICAgICAgIHJldHVybiAnQXJyYXknO1xuICAgICAgY2FzZSAnQWRkUmVsYXRpb24nOlxuICAgICAgY2FzZSAnUmVtb3ZlUmVsYXRpb24nOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICAgICAgdGFyZ2V0Q2xhc3M6IG9iai5vYmplY3RzWzBdLmNsYXNzTmFtZSxcbiAgICAgICAgfTtcbiAgICAgIGNhc2UgJ0JhdGNoJzpcbiAgICAgICAgcmV0dXJuIGdldE9iamVjdFR5cGUob2JqLm9wc1swXSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyAndW5leHBlY3RlZCBvcDogJyArIG9iai5fX29wO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJ09iamVjdCc7XG59XG5cbmV4cG9ydCB7XG4gIGxvYWQsXG4gIGNsYXNzTmFtZUlzVmFsaWQsXG4gIGZpZWxkTmFtZUlzVmFsaWQsXG4gIGludmFsaWRDbGFzc05hbWVNZXNzYWdlLFxuICBidWlsZE1lcmdlZFNjaGVtYU9iamVjdCxcbiAgc3lzdGVtQ2xhc3NlcyxcbiAgZGVmYXVsdENvbHVtbnMsXG4gIGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEsXG4gIFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMsXG4gIFNjaGVtYUNvbnRyb2xsZXIsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/UserController.js b/lib/Controllers/UserController.js new file mode 100644 index 0000000000..75b067b3f9 --- /dev/null +++ b/lib/Controllers/UserController.js @@ -0,0 +1,318 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.UserController = void 0; + +var _cryptoUtils = require("../cryptoUtils"); + +var _triggers = require("../triggers"); + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var RestQuery = require('../RestQuery'); + +var Auth = require('../Auth'); + +class UserController extends _AdaptableController.default { + constructor(adapter, appId, options = {}) { + super(adapter, appId, options); + } + + validateAdapter(adapter) { + // Allow no adapter + if (!adapter && !this.shouldVerifyEmails) { + return; + } + + super.validateAdapter(adapter); + } + + expectedAdapterType() { + return _MailAdapter.default; + } + + get shouldVerifyEmails() { + return this.options.verifyUserEmails; + } + + setEmailVerifyToken(user) { + if (this.shouldVerifyEmails) { + user._email_verify_token = (0, _cryptoUtils.randomString)(25); + user.emailVerified = false; + + if (this.config.emailVerifyTokenValidityDuration) { + user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt()); + } + } + } + + verifyEmail(username, token) { + if (!this.shouldVerifyEmails) { + // Trying to verify email when not enabled + // TODO: Better error here. + throw undefined; + } + + const query = { + username: username, + _email_verify_token: token + }; + const updateFields = { + emailVerified: true, + _email_verify_token: { + __op: 'Delete' + } + }; // if the email verify token needs to be validated then + // add additional query params and additional fields that need to be updated + + if (this.config.emailVerifyTokenValidityDuration) { + query.emailVerified = false; + query._email_verify_token_expires_at = { + $gt: _node.default._encode(new Date()) + }; + updateFields._email_verify_token_expires_at = { + __op: 'Delete' + }; + } + + const masterAuth = Auth.master(this.config); + var findUserForEmailVerification = new RestQuery(this.config, Auth.master(this.config), '_User', { + username: username + }); + return findUserForEmailVerification.execute().then(result => { + if (result.results.length && result.results[0].emailVerified) { + return Promise.resolve(result.results.length[0]); + } else if (result.results.length) { + query.objectId = result.results[0].objectId; + } + + return _rest.default.update(this.config, masterAuth, '_User', query, updateFields); + }); + } + + checkResetTokenValidity(username, token) { + return this.config.database.find('_User', { + username: username, + _perishable_token: token + }, { + limit: 1 + }).then(results => { + if (results.length != 1) { + throw 'Failed to reset password: username / email / token is invalid'; + } + + if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { + let expiresDate = results[0]._perishable_token_expires_at; + + if (expiresDate && expiresDate.__type == 'Date') { + expiresDate = new Date(expiresDate.iso); + } + + if (expiresDate < new Date()) throw 'The password reset link has expired'; + } + + return results[0]; + }); + } + + getUserIfNeeded(user) { + if (user.username && user.email) { + return Promise.resolve(user); + } + + var where = {}; + + if (user.username) { + where.username = user.username; + } + + if (user.email) { + where.email = user.email; + } + + var query = new RestQuery(this.config, Auth.master(this.config), '_User', where); + return query.execute().then(function (result) { + if (result.results.length != 1) { + throw undefined; + } + + return result.results[0]; + }); + } + + sendVerificationEmail(user) { + if (!this.shouldVerifyEmails) { + return; + } + + const token = encodeURIComponent(user._email_verify_token); // We may need to fetch the user in case of update email + + this.getUserIfNeeded(user).then(user => { + const username = encodeURIComponent(user.username); + const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config); + const options = { + appName: this.config.appName, + link: link, + user: (0, _triggers.inflate)('_User', user) + }; + + if (this.adapter.sendVerificationEmail) { + this.adapter.sendVerificationEmail(options); + } else { + this.adapter.sendMail(this.defaultVerificationEmail(options)); + } + }); + } + /** + * Regenerates the given user's email verification token + * + * @param user + * @returns {*} + */ + + + regenerateEmailVerifyToken(user) { + this.setEmailVerifyToken(user); + return this.config.database.update('_User', { + username: user.username + }, user); + } + + resendVerificationEmail(username) { + return this.getUserIfNeeded({ + username: username + }).then(aUser => { + if (!aUser || aUser.emailVerified) { + throw undefined; + } + + return this.regenerateEmailVerifyToken(aUser).then(() => { + this.sendVerificationEmail(aUser); + }); + }); + } + + setPasswordResetToken(email) { + const token = { + _perishable_token: (0, _cryptoUtils.randomString)(25) + }; + + if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { + token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt()); + } + + return this.config.database.update('_User', { + $or: [{ + email + }, { + username: email, + email: { + $exists: false + } + }] + }, token, {}, true); + } + + sendPasswordResetEmail(email) { + if (!this.adapter) { + throw 'Trying to send a reset password but no adapter is set'; // TODO: No adapter? + } + + return this.setPasswordResetToken(email).then(user => { + const token = encodeURIComponent(user._perishable_token); + const username = encodeURIComponent(user.username); + const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config); + const options = { + appName: this.config.appName, + link: link, + user: (0, _triggers.inflate)('_User', user) + }; + + if (this.adapter.sendPasswordResetEmail) { + this.adapter.sendPasswordResetEmail(options); + } else { + this.adapter.sendMail(this.defaultResetPasswordEmail(options)); + } + + return Promise.resolve(user); + }); + } + + updatePassword(username, token, password) { + return this.checkResetTokenValidity(username, token).then(user => updateUserPassword(user.objectId, password, this.config)).catch(error => { + if (error && error.message) { + // in case of Parse.Error, fail with the error message only + return Promise.reject(error.message); + } else { + return Promise.reject(error); + } + }); + } + + defaultVerificationEmail({ + link, + user, + appName + }) { + const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link; + const to = user.get('email'); + const subject = 'Please verify your e-mail for ' + appName; + return { + text, + to, + subject + }; + } + + defaultResetPasswordEmail({ + link, + user, + appName + }) { + const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link; + const to = user.get('email') || user.get('username'); + const subject = 'Password Reset for ' + appName; + return { + text, + to, + subject + }; + } + +} // Mark this private + + +exports.UserController = UserController; + +function updateUserPassword(userId, password, config) { + return _rest.default.update(config, Auth.master(config), '_User', { + objectId: userId + }, { + password: password + }); +} + +function buildEmailLink(destination, username, token, config) { + const usernameAndToken = `token=${token}&username=${username}`; + + if (config.parseFrameURL) { + const destinationWithoutHost = destination.replace(config.publicServerURL, ''); + return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`; + } else { + return `${destination}?${usernameAndToken}`; + } +} + +var _default = UserController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Vc2VyQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJSZXN0UXVlcnkiLCJyZXF1aXJlIiwiQXV0aCIsIlVzZXJDb250cm9sbGVyIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsInNob3VsZFZlcmlmeUVtYWlscyIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJNYWlsQWRhcHRlciIsInZlcmlmeVVzZXJFbWFpbHMiLCJzZXRFbWFpbFZlcmlmeVRva2VuIiwidXNlciIsIl9lbWFpbF92ZXJpZnlfdG9rZW4iLCJlbWFpbFZlcmlmaWVkIiwiY29uZmlnIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJQYXJzZSIsIl9lbmNvZGUiLCJnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQiLCJ2ZXJpZnlFbWFpbCIsInVzZXJuYW1lIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFzdGVyQXV0aCIsIm1hc3RlciIsImZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24iLCJleGVjdXRlIiwidGhlbiIsInJlc3VsdCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm9iamVjdElkIiwicmVzdCIsInVwZGF0ZSIsImNoZWNrUmVzZXRUb2tlblZhbGlkaXR5IiwiZGF0YWJhc2UiLCJmaW5kIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJsaW1pdCIsInBhc3N3b3JkUG9saWN5IiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJleHBpcmVzRGF0ZSIsIl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQiLCJfX3R5cGUiLCJpc28iLCJnZXRVc2VySWZOZWVkZWQiLCJlbWFpbCIsIndoZXJlIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwibGluayIsImJ1aWxkRW1haWxMaW5rIiwidmVyaWZ5RW1haWxVUkwiLCJhcHBOYW1lIiwic2VuZE1haWwiLCJkZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwiLCJyZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbiIsInJlc2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiYVVzZXIiLCJzZXRQYXNzd29yZFJlc2V0VG9rZW4iLCJnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCIsIiRvciIsIiRleGlzdHMiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwicmVxdWVzdFJlc2V0UGFzc3dvcmRVUkwiLCJkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsIiwidXBkYXRlUGFzc3dvcmQiLCJwYXNzd29yZCIsInVwZGF0ZVVzZXJQYXNzd29yZCIsImNhdGNoIiwiZXJyb3IiLCJtZXNzYWdlIiwicmVqZWN0IiwidGV4dCIsImdldCIsInRvIiwic3ViamVjdCIsInVzZXJJZCIsImRlc3RpbmF0aW9uIiwidXNlcm5hbWVBbmRUb2tlbiIsInBhcnNlRnJhbWVVUkwiLCJkZXN0aW5hdGlvbldpdGhvdXRIb3N0IiwicmVwbGFjZSIsInB1YmxpY1NlcnZlclVSTCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsSUFBSUEsU0FBUyxHQUFHQyxPQUFPLENBQUMsY0FBRCxDQUF2Qjs7QUFDQSxJQUFJQyxJQUFJLEdBQUdELE9BQU8sQ0FBQyxTQUFELENBQWxCOztBQUVPLE1BQU1FLGNBQU4sU0FBNkJDLDRCQUE3QixDQUFpRDtBQUN0REMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQU8sR0FBRyxFQUEzQixFQUErQjtBQUN4QyxVQUFNRixPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0Q7O0FB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LENBb1F4RDs7Ozs7QUFDQSxTQUFTUixrQkFBVCxDQUE0QlMsTUFBNUIsRUFBb0NWLFFBQXBDLEVBQThDN0QsTUFBOUMsRUFBc0Q7QUFDcEQsU0FBTzBCLGNBQUtDLE1BQUwsQ0FDTDNCLE1BREssRUFFTGhCLElBQUksQ0FBQ2dDLE1BQUwsQ0FBWWhCLE1BQVosQ0FGSyxFQUdMLE9BSEssRUFJTDtBQUFFeUIsSUFBQUEsUUFBUSxFQUFFOEM7QUFBWixHQUpLLEVBS0w7QUFDRVYsSUFBQUEsUUFBUSxFQUFFQTtBQURaLEdBTEssQ0FBUDtBQVNEOztBQUVELFNBQVNoQixjQUFULENBQXdCMkIsV0FBeEIsRUFBcUNqRSxRQUFyQyxFQUErQ0MsS0FBL0MsRUFBc0RSLE1BQXRELEVBQThEO0FBQzVELFFBQU15RSxnQkFBZ0IsR0FBSSxTQUFRakUsS0FBTSxhQUFZRCxRQUFTLEVBQTdEOztBQUVBLE1BQUlQLE1BQU0sQ0FBQzBFLGFBQVgsRUFBMEI7QUFDeEIsVUFBTUMsc0JBQXNCLEdBQUdILFdBQVcsQ0FBQ0ksT0FBWixDQUFvQjVFLE1BQU0sQ0FBQzZFLGVBQTNCLEVBQTRDLEVBQTVDLENBQS9CO0FBRUEsV0FBUSxHQUFFN0UsTUFBTSxDQUFDMEUsYUFBYyxTQUFRL0Isa0JBQWtCLENBQ3ZEZ0Msc0JBRHVELENBRXZELElBQUdGLGdCQUFpQixFQUZ0QjtBQUdELEdBTkQsTUFNTztBQUNMLFdBQVEsR0FBRUQsV0FBWSxJQUFHQyxnQkFBaUIsRUFBMUM7QUFDRDtBQUNGOztlQUVjeEYsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gJy4uL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGluZmxhdGUgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IE1haWxBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0VtYWlsL01haWxBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG52YXIgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi4vUmVzdFF1ZXJ5Jyk7XG52YXIgQXV0aCA9IHJlcXVpcmUoJy4uL0F1dGgnKTtcblxuZXhwb3J0IGNsYXNzIFVzZXJDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyk7XG4gIH1cblxuICB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcikge1xuICAgIC8vIEFsbG93IG5vIGFkYXB0ZXJcbiAgICBpZiAoIWFkYXB0ZXIgJiYgIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN1cGVyLnZhbGlkYXRlQWRhcHRlcihhZGFwdGVyKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIE1haWxBZGFwdGVyO1xuICB9XG5cbiAgZ2V0IHNob3VsZFZlcmlmeUVtYWlscygpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZlcmlmeVVzZXJFbWFpbHM7XG4gIH1cblxuICBzZXRFbWFpbFZlcmlmeVRva2VuKHVzZXIpIHtcbiAgICBpZiAodGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbiA9IHJhbmRvbVN0cmluZygyNSk7XG4gICAgICB1c2VyLmVtYWlsVmVyaWZpZWQgPSBmYWxzZTtcblxuICAgICAgaWYgKHRoaXMuY29uZmlnLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICAgIHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0gUGFyc2UuX2VuY29kZShcbiAgICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQoKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZlcmlmeUVtYWlsKHVzZXJuYW1lLCB0b2tlbikge1xuICAgIGlmICghdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIC8vIFRyeWluZyB0byB2ZXJpZnkgZW1haWwgd2hlbiBub3QgZW5hYmxlZFxuICAgICAgLy8gVE9ETzogQmV0dGVyIGVycm9yIGhlcmUuXG4gICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgcXVlcnkgPSB7IHVzZXJuYW1lOiB1c2VybmFtZSwgX2VtYWlsX3ZlcmlmeV90b2tlbjogdG9rZW4gfTtcbiAgICBjb25zdCB1cGRhdGVGaWVsZHMgPSB7XG4gICAgICBlbWFpbFZlcmlmaWVkOiB0cnVlLFxuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgIH07XG5cbiAgICAvLyBpZiB0aGUgZW1haWwgdmVyaWZ5IHRva2VuIG5lZWRzIHRvIGJlIHZhbGlkYXRlZCB0aGVuXG4gICAgLy8gYWRkIGFkZGl0aW9uYWwgcXVlcnkgcGFyYW1zIGFuZCBhZGRpdGlvbmFsIGZpZWxkcyB0aGF0IG5lZWQgdG8gYmUgdXBkYXRlZFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcXVlcnkuZW1haWxWZXJpZmllZCA9IGZhbHNlO1xuICAgICAgcXVlcnkuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0geyAkZ3Q6IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSkgfTtcblxuICAgICAgdXBkYXRlRmllbGRzLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHsgX19vcDogJ0RlbGV0ZScgfTtcbiAgICB9XG4gICAgY29uc3QgbWFzdGVyQXV0aCA9IEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKTtcbiAgICB2YXIgZmluZFVzZXJGb3JFbWFpbFZlcmlmaWNhdGlvbiA9IG5ldyBSZXN0UXVlcnkoXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSxcbiAgICAgICdfVXNlcicsXG4gICAgICB7IHVzZXJuYW1lOiB1c2VybmFtZSB9XG4gICAgKTtcbiAgICByZXR1cm4gZmluZFVzZXJGb3JFbWFpbFZlcmlmaWNhdGlvbi5leGVjdXRlKCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5yZXN1bHRzLmxlbmd0aCAmJiByZXN1bHQucmVzdWx0c1swXS5lbWFpbFZlcmlmaWVkKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0LnJlc3VsdHMubGVuZ3RoWzBdKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXJ5Lm9iamVjdElkID0gcmVzdWx0LnJlc3VsdHNbMF0ub2JqZWN0SWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdC51cGRhdGUodGhpcy5jb25maWcsIG1hc3RlckF1dGgsICdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICAgIH0pO1xuICB9XG5cbiAgY2hlY2tSZXNldFRva2VuVmFsaWRpdHkodXNlcm5hbWUsIHRva2VuKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJuYW1lOiB1c2VybmFtZSxcbiAgICAgICAgICBfcGVyaXNoYWJsZV90b2tlbjogdG9rZW4sXG4gICAgICAgIH0sXG4gICAgICAgIHsgbGltaXQ6IDEgfVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhyb3cgJ0ZhaWxlZCB0byByZXNldCBwYXNzd29yZDogdXNlcm5hbWUgLyBlbWFpbCAvIHRva2VuIGlzIGludmFsaWQnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICAgICAgbGV0IGV4cGlyZXNEYXRlID0gcmVzdWx0c1swXS5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0O1xuICAgICAgICAgIGlmIChleHBpcmVzRGF0ZSAmJiBleHBpcmVzRGF0ZS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgICBleHBpcmVzRGF0ZSA9IG5ldyBEYXRlKGV4cGlyZXNEYXRlLmlzbyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChleHBpcmVzRGF0ZSA8IG5ldyBEYXRlKCkpIHRocm93ICdUaGUgcGFzc3dvcmQgcmVzZXQgbGluayBoYXMgZXhwaXJlZCc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0c1swXTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklmTmVlZGVkKHVzZXIpIHtcbiAgICBpZiAodXNlci51c2VybmFtZSAmJiB1c2VyLmVtYWlsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICAgIH1cbiAgICB2YXIgd2hlcmUgPSB7fTtcbiAgICBpZiAodXNlci51c2VybmFtZSkge1xuICAgICAgd2hlcmUudXNlcm5hbWUgPSB1c2VyLnVzZXJuYW1lO1xuICAgIH1cbiAgICBpZiAodXNlci5lbWFpbCkge1xuICAgICAgd2hlcmUuZW1haWwgPSB1c2VyLmVtYWlsO1xuICAgIH1cblxuICAgIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSwgJ19Vc2VyJywgd2hlcmUpO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdC5yZXN1bHRzWzBdO1xuICAgIH0pO1xuICB9XG5cbiAgc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXIpIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRva2VuID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbik7XG4gICAgLy8gV2UgbWF5IG5lZWQgdG8gZmV0Y2ggdGhlIHVzZXIgaW4gY2FzZSBvZiB1cGRhdGUgZW1haWxcbiAgICB0aGlzLmdldFVzZXJJZk5lZWRlZCh1c2VyKS50aGVuKHVzZXIgPT4ge1xuICAgICAgY29uc3QgdXNlcm5hbWUgPSBlbmNvZGVVUklDb21wb25lbnQodXNlci51c2VybmFtZSk7XG5cbiAgICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy52ZXJpZnlFbWFpbFVSTCwgdXNlcm5hbWUsIHRva2VuLCB0aGlzLmNvbmZpZyk7XG4gICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICBhcHBOYW1lOiB0aGlzLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBsaW5rOiBsaW5rLFxuICAgICAgICB1c2VyOiBpbmZsYXRlKCdfVXNlcicsIHVzZXIpLFxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLmFkYXB0ZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwob3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFkYXB0ZXIuc2VuZE1haWwodGhpcy5kZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwob3B0aW9ucykpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2VuZXJhdGVzIHRoZSBnaXZlbiB1c2VyJ3MgZW1haWwgdmVyaWZpY2F0aW9uIHRva2VuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgcmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4odXNlcikge1xuICAgIHRoaXMuc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSwgdXNlcik7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkge1xuICAgIHJldHVybiB0aGlzLmdldFVzZXJJZk5lZWRlZCh7IHVzZXJuYW1lOiB1c2VybmFtZSB9KS50aGVuKGFVc2VyID0+IHtcbiAgICAgIGlmICghYVVzZXIgfHwgYVVzZXIuZW1haWxWZXJpZmllZCkge1xuICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbihhVXNlcikudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKGFVc2VyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0UGFzc3dvcmRSZXNldFRva2VuKGVtYWlsKSB7XG4gICAgY29uc3QgdG9rZW4gPSB7IF9wZXJpc2hhYmxlX3Rva2VuOiByYW5kb21TdHJpbmcoMjUpIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHRva2VuLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAnX1VzZXInLFxuICAgICAgeyAkb3I6IFt7IGVtYWlsIH0sIHsgdXNlcm5hbWU6IGVtYWlsLCBlbWFpbDogeyAkZXhpc3RzOiBmYWxzZSB9IH1dIH0sXG4gICAgICB0b2tlbixcbiAgICAgIHt9LFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBzZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdUcnlpbmcgdG8gc2VuZCBhIHJlc2V0IHBhc3N3b3JkIGJ1dCBubyBhZGFwdGVyIGlzIHNldCc7XG4gICAgICAvLyAgVE9ETzogTm8gYWRhcHRlcj9cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zZXRQYXNzd29yZFJlc2V0VG9rZW4oZW1haWwpLnRoZW4odXNlciA9PiB7XG4gICAgICBjb25zdCB0b2tlbiA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLl9wZXJpc2hhYmxlX3Rva2VuKTtcbiAgICAgIGNvbnN0IHVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIudXNlcm5hbWUpO1xuXG4gICAgICBjb25zdCBsaW5rID0gYnVpbGRFbWFpbExpbmsoXG4gICAgICAgIHRoaXMuY29uZmlnLnJlcXVlc3RSZXNldFBhc3N3b3JkVVJMLFxuICAgICAgICB1c2VybmFtZSxcbiAgICAgICAgdG9rZW4sXG4gICAgICAgIHRoaXMuY29uZmlnXG4gICAgICApO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgYXBwTmFtZTogdGhpcy5jb25maWcuYXBwTmFtZSxcbiAgICAgICAgbGluazogbGluayxcbiAgICAgICAgdXNlcjogaW5mbGF0ZSgnX1VzZXInLCB1c2VyKSxcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCkge1xuICAgICAgICB0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRSZXNldFBhc3N3b3JkRW1haWwob3B0aW9ucykpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlUGFzc3dvcmQodXNlcm5hbWUsIHRva2VuLCBwYXNzd29yZCkge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUmVzZXRUb2tlblZhbGlkaXR5KHVzZXJuYW1lLCB0b2tlbilcbiAgICAgIC50aGVuKHVzZXIgPT4gdXBkYXRlVXNlclBhc3N3b3JkKHVzZXIub2JqZWN0SWQsIHBhc3N3b3JkLCB0aGlzLmNvbmZpZykpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgIC8vIGluIGNhc2Ugb2YgUGFyc2UuRXJyb3IsIGZhaWwgd2l0aCB0aGUgZXJyb3IgbWVzc2FnZSBvbmx5XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgZGVmYXVsdFZlcmlmaWNhdGlvbkVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IGFyZSBiZWluZyBhc2tlZCB0byBjb25maXJtIHRoZSBlLW1haWwgYWRkcmVzcyAnICtcbiAgICAgIHVzZXIuZ2V0KCdlbWFpbCcpICtcbiAgICAgICcgd2l0aCAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgJ1xcblxcbicgK1xuICAgICAgJycgK1xuICAgICAgJ0NsaWNrIGhlcmUgdG8gY29uZmlybSBpdDpcXG4nICtcbiAgICAgIGxpbms7XG4gICAgY29uc3QgdG8gPSB1c2VyLmdldCgnZW1haWwnKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1BsZWFzZSB2ZXJpZnkgeW91ciBlLW1haWwgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cblxuICBkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IHJlcXVlc3RlZCB0byByZXNldCB5b3VyIHBhc3N3b3JkIGZvciAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgKHVzZXIuZ2V0KCd1c2VybmFtZScpID8gXCIgKHlvdXIgdXNlcm5hbWUgaXMgJ1wiICsgdXNlci5nZXQoJ3VzZXJuYW1lJykgKyBcIicpXCIgOiAnJykgK1xuICAgICAgJy5cXG5cXG4nICtcbiAgICAgICcnICtcbiAgICAgICdDbGljayBoZXJlIHRvIHJlc2V0IGl0OlxcbicgK1xuICAgICAgbGluaztcbiAgICBjb25zdCB0byA9IHVzZXIuZ2V0KCdlbWFpbCcpIHx8IHVzZXIuZ2V0KCd1c2VybmFtZScpO1xuICAgIGNvbnN0IHN1YmplY3QgPSAnUGFzc3dvcmQgUmVzZXQgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cbn1cblxuLy8gTWFyayB0aGlzIHByaXZhdGVcbmZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VySWQsIHBhc3N3b3JkLCBjb25maWcpIHtcbiAgcmV0dXJuIHJlc3QudXBkYXRlKFxuICAgIGNvbmZpZyxcbiAgICBBdXRoLm1hc3Rlcihjb25maWcpLFxuICAgICdfVXNlcicsXG4gICAgeyBvYmplY3RJZDogdXNlcklkIH0sXG4gICAge1xuICAgICAgcGFzc3dvcmQ6IHBhc3N3b3JkLFxuICAgIH1cbiAgKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRFbWFpbExpbmsoZGVzdGluYXRpb24sIHVzZXJuYW1lLCB0b2tlbiwgY29uZmlnKSB7XG4gIGNvbnN0IHVzZXJuYW1lQW5kVG9rZW4gPSBgdG9rZW49JHt0b2tlbn0mdXNlcm5hbWU9JHt1c2VybmFtZX1gO1xuXG4gIGlmIChjb25maWcucGFyc2VGcmFtZVVSTCkge1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uV2l0aG91dEhvc3QgPSBkZXN0aW5hdGlvbi5yZXBsYWNlKGNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwsICcnKTtcblxuICAgIHJldHVybiBgJHtjb25maWcucGFyc2VGcmFtZVVSTH0/bGluaz0ke2VuY29kZVVSSUNvbXBvbmVudChcbiAgICAgIGRlc3RpbmF0aW9uV2l0aG91dEhvc3RcbiAgICApfSYke3VzZXJuYW1lQW5kVG9rZW59YDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYCR7ZGVzdGluYXRpb259PyR7dXNlcm5hbWVBbmRUb2tlbn1gO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/index.js b/lib/Controllers/index.js new file mode 100644 index 0000000000..e3ace5883c --- /dev/null +++ b/lib/Controllers/index.js @@ -0,0 +1,312 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getControllers = getControllers; +exports.getLoggerController = getLoggerController; +exports.getFilesController = getFilesController; +exports.getUserController = getUserController; +exports.getCacheController = getCacheController; +exports.getParseGraphQLController = getParseGraphQLController; +exports.getAnalyticsController = getAnalyticsController; +exports.getLiveQueryController = getLiveQueryController; +exports.getDatabaseController = getDatabaseController; +exports.getHooksController = getHooksController; +exports.getPushController = getPushController; +exports.getAuthDataManager = getAuthDataManager; +exports.getDatabaseAdapter = getDatabaseAdapter; + +var _Auth = _interopRequireDefault(require("../Adapters/Auth")); + +var _Options = require("../Options"); + +var _AdapterLoader = require("../Adapters/AdapterLoader"); + +var _defaults = _interopRequireDefault(require("../defaults")); + +var _url = _interopRequireDefault(require("url")); + +var _LoggerController = require("./LoggerController"); + +var _FilesController = require("./FilesController"); + +var _HooksController = require("./HooksController"); + +var _UserController = require("./UserController"); + +var _CacheController = require("./CacheController"); + +var _LiveQueryController = require("./LiveQueryController"); + +var _AnalyticsController = require("./AnalyticsController"); + +var _PushController = require("./PushController"); + +var _PushQueue = require("../Push/PushQueue"); + +var _PushWorker = require("../Push/PushWorker"); + +var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); + +var _SchemaCache = _interopRequireDefault(require("./SchemaCache")); + +var _GridFSBucketAdapter = require("../Adapters/Files/GridFSBucketAdapter"); + +var _WinstonLoggerAdapter = require("../Adapters/Logger/WinstonLoggerAdapter"); + +var _InMemoryCacheAdapter = require("../Adapters/Cache/InMemoryCacheAdapter"); + +var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); + +var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); + +var _PostgresStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Postgres/PostgresStorageAdapter")); + +var _pushAdapter = _interopRequireDefault(require("@parse/push-adapter")); + +var _ParseGraphQLController = _interopRequireDefault(require("./ParseGraphQLController")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function getControllers(options) { + const loggerController = getLoggerController(options); + const filesController = getFilesController(options); + const userController = getUserController(options); + const { + pushController, + hasPushScheduledSupport, + hasPushSupport, + pushControllerQueue, + pushWorker + } = getPushController(options); + const cacheController = getCacheController(options); + const analyticsController = getAnalyticsController(options); + const liveQueryController = getLiveQueryController(options); + const databaseController = getDatabaseController(options, cacheController); + const hooksController = getHooksController(options, databaseController); + const authDataManager = getAuthDataManager(options); + const parseGraphQLController = getParseGraphQLController(options, { + databaseController, + cacheController + }); + return { + loggerController, + filesController, + userController, + pushController, + hasPushScheduledSupport, + hasPushSupport, + pushWorker, + pushControllerQueue, + analyticsController, + cacheController, + parseGraphQLController, + liveQueryController, + databaseController, + hooksController, + authDataManager + }; +} + +function getLoggerController(options) { + const { + appId, + jsonLogs, + logsFolder, + verbose, + logLevel, + maxLogFiles, + silent, + loggerAdapter + } = options; + const loggerOptions = { + jsonLogs, + logsFolder, + verbose, + logLevel, + silent, + maxLogFiles + }; + const loggerControllerAdapter = (0, _AdapterLoader.loadAdapter)(loggerAdapter, _WinstonLoggerAdapter.WinstonLoggerAdapter, loggerOptions); + return new _LoggerController.LoggerController(loggerControllerAdapter, appId, loggerOptions); +} + +function getFilesController(options) { + const { + appId, + databaseURI, + filesAdapter, + databaseAdapter, + preserveFileName, + fileKey + } = options; + + if (!filesAdapter && databaseAdapter) { + throw 'When using an explicit database adapter, you must also use an explicit filesAdapter.'; + } + + const filesControllerAdapter = (0, _AdapterLoader.loadAdapter)(filesAdapter, () => { + return new _GridFSBucketAdapter.GridFSBucketAdapter(databaseURI, {}, fileKey); + }); + return new _FilesController.FilesController(filesControllerAdapter, appId, { + preserveFileName + }); +} + +function getUserController(options) { + const { + appId, + emailAdapter, + verifyUserEmails + } = options; + const emailControllerAdapter = (0, _AdapterLoader.loadAdapter)(emailAdapter); + return new _UserController.UserController(emailControllerAdapter, appId, { + verifyUserEmails + }); +} + +function getCacheController(options) { + const { + appId, + cacheAdapter, + cacheTTL, + cacheMaxSize + } = options; + const cacheControllerAdapter = (0, _AdapterLoader.loadAdapter)(cacheAdapter, _InMemoryCacheAdapter.InMemoryCacheAdapter, { + appId: appId, + ttl: cacheTTL, + maxSize: cacheMaxSize + }); + return new _CacheController.CacheController(cacheControllerAdapter, appId); +} + +function getParseGraphQLController(options, controllerDeps) { + return new _ParseGraphQLController.default(_objectSpread({ + mountGraphQL: options.mountGraphQL + }, controllerDeps)); +} + +function getAnalyticsController(options) { + const { + analyticsAdapter + } = options; + const analyticsControllerAdapter = (0, _AdapterLoader.loadAdapter)(analyticsAdapter, _AnalyticsAdapter.AnalyticsAdapter); + return new _AnalyticsController.AnalyticsController(analyticsControllerAdapter); +} + +function getLiveQueryController(options) { + return new _LiveQueryController.LiveQueryController(options.liveQuery); +} + +function getDatabaseController(options, cacheController) { + const { + databaseURI, + databaseOptions, + collectionPrefix, + schemaCacheTTL, + enableSingleSchemaCache + } = options; + let { + databaseAdapter + } = options; + + if ((databaseOptions || databaseURI && databaseURI !== _defaults.default.databaseURI || collectionPrefix !== _defaults.default.collectionPrefix) && databaseAdapter) { + throw 'You cannot specify both a databaseAdapter and a databaseURI/databaseOptions/collectionPrefix.'; + } else if (!databaseAdapter) { + databaseAdapter = getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions); + } else { + databaseAdapter = (0, _AdapterLoader.loadAdapter)(databaseAdapter); + } + + return new _DatabaseController.default(databaseAdapter, new _SchemaCache.default(cacheController, schemaCacheTTL, enableSingleSchemaCache)); +} + +function getHooksController(options, databaseController) { + const { + appId, + webhookKey + } = options; + return new _HooksController.HooksController(appId, databaseController, webhookKey); +} + +function getPushController(options) { + const { + scheduledPush, + push + } = options; + const pushOptions = Object.assign({}, push); + const pushQueueOptions = pushOptions.queueOptions || {}; + + if (pushOptions.queueOptions) { + delete pushOptions.queueOptions; + } // Pass the push options too as it works with the default + + + const pushAdapter = (0, _AdapterLoader.loadAdapter)(pushOptions && pushOptions.adapter, _pushAdapter.default, pushOptions); // We pass the options and the base class for the adatper, + // Note that passing an instance would work too + + const pushController = new _PushController.PushController(); + const hasPushSupport = !!(pushAdapter && push); + const hasPushScheduledSupport = hasPushSupport && scheduledPush === true; + const { + disablePushWorker + } = pushQueueOptions; + const pushControllerQueue = new _PushQueue.PushQueue(pushQueueOptions); + let pushWorker; + + if (!disablePushWorker) { + pushWorker = new _PushWorker.PushWorker(pushAdapter, pushQueueOptions); + } + + return { + pushController, + hasPushSupport, + hasPushScheduledSupport, + pushControllerQueue, + pushWorker + }; +} + +function getAuthDataManager(options) { + const { + auth, + enableAnonymousUsers + } = options; + return (0, _Auth.default)(auth, enableAnonymousUsers); +} + +function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions) { + let protocol; + + try { + const parsedURI = _url.default.parse(databaseURI); + + protocol = parsedURI.protocol ? parsedURI.protocol.toLowerCase() : null; + } catch (e) { + /* */ + } + + switch (protocol) { + case 'postgres:': + return new _PostgresStorageAdapter.default({ + uri: databaseURI, + collectionPrefix, + databaseOptions + }); + + default: + return new _MongoStorageAdapter.default({ + uri: databaseURI, + collectionPrefix, + mongoOptions: databaseOptions + }); + } +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9pbmRleC5qcyJdLCJuYW1lcyI6WyJnZXRDb250cm9sbGVycyIsIm9wdGlvbnMiLCJsb2dnZXJDb250cm9sbGVyIiwiZ2V0TG9nZ2VyQ29udHJvbGxlciIsImZpbGVzQ29udHJvbGxlciIsImdldEZpbGVzQ29udHJvbGxlciIsInVzZXJDb250cm9sbGVyIiwiZ2V0VXNlckNvbnRyb2xsZXIiLCJwdXNoQ29udHJvbGxlciIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwiaGFzUHVzaFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwicHVzaFdvcmtlciIsImdldFB1c2hDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiZ2V0Q2FjaGVDb250cm9sbGVyIiwiYW5hbHl0aWNzQ29udHJvbGxlciIsImdldEFuYWx5dGljc0NvbnRyb2xsZXIiLCJsaXZlUXVlcnlDb250cm9sbGVyIiwiZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImdldERhdGFiYXNlQ29udHJvbGxlciIsImhvb2tzQ29udHJvbGxlciIsImdldEhvb2tzQ29udHJvbGxlciIsImF1dGhEYXRhTWFuYWdlciIsImdldEF1dGhEYXRhTWFuYWdlciIsInBhcnNlR3JhcGhRTENvbnRyb2xsZXIiLCJnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwiYXBwSWQiLCJqc29uTG9ncyIsImxvZ3NGb2xkZXIiLCJ2ZXJib3NlIiwibG9nTGV2ZWwiLCJtYXhMb2dGaWxlcyIsInNpbGVudCIsImxvZ2dlckFkYXB0ZXIiLCJsb2dnZXJPcHRpb25zIiwibG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIiLCJXaW5zdG9uTG9nZ2VyQWRhcHRlciIsIkxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZVVSSSIsImZpbGVzQWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInByZXNlcnZlRmlsZU5hbWUiLCJmaWxlS2V5IiwiZmlsZXNDb250cm9sbGVyQWRhcHRlciIsIkdyaWRGU0J1Y2tldEFkYXB0ZXIiLCJGaWxlc0NvbnRyb2xsZXIiLCJlbWFpbEFkYXB0ZXIiLCJ2ZXJpZnlVc2VyRW1haWxzIiwiZW1haWxDb250cm9sbGVyQWRhcHRlciIsIlVzZXJDb250cm9sbGVyIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVUVEwiLCJjYWNoZU1heFNpemUiLCJjYWNoZUNvbnRyb2xsZXJBZGFwdGVyIiwiSW5NZW1vcnlDYWNoZUFkYXB0ZXIiLCJ0dGwiLCJtYXhTaXplIiwiQ2FjaGVDb250cm9sbGVyIiwiY29udHJvbGxlckRlcHMiLCJQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibW91bnRHcmFwaFFMIiwiYW5hbHl0aWNzQWRhcHRlciIsImFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyIiwiQW5hbHl0aWNzQWRhcHRlciIsIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJMaXZlUXVlcnlDb250cm9sbGVyIiwibGl2ZVF1ZXJ5IiwiZGF0YWJhc2VPcHRpb25zIiwiY29sbGVjdGlvblByZWZpeCIsInNjaGVtYUNhY2hlVFRMIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkZWZhdWx0cyIsImdldERhdGFiYXNlQWRhcHRlciIsIkRhdGFiYXNlQ29udHJvbGxlciIsIlNjaGVtYUNhY2hlIiwid2ViaG9va0tleSIsIkhvb2tzQ29udHJvbGxlciIsInNjaGVkdWxlZFB1c2giLCJwdXNoIiwicHVzaE9wdGlvbnMiLCJPYmplY3QiLCJhc3NpZ24iLCJwdXNoUXVldWVPcHRpb25zIiwicXVldWVPcHRpb25zIiwicHVzaEFkYXB0ZXIiLCJhZGFwdGVyIiwiUGFyc2VQdXNoQWRhcHRlciIsIlB1c2hDb250cm9sbGVyIiwiZGlzYWJsZVB1c2hXb3JrZXIiLCJQdXNoUXVldWUiLCJQdXNoV29ya2VyIiwiYXV0aCIsImVuYWJsZUFub255bW91c1VzZXJzIiwicHJvdG9jb2wiLCJwYXJzZWRVUkkiLCJ1cmwiLCJwYXJzZSIsInRvTG93ZXJDYXNlIiwiZSIsIlBvc3RncmVzU3Rv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QUEsR0FBRyxFQUFFOUQsV0FEMkI7QUFFaEM4QixRQUFBQSxnQkFGZ0M7QUFHaENELFFBQUFBO0FBSGdDLE9BQTNCLENBQVA7O0FBS0Y7QUFDRSxhQUFPLElBQUlrQyw0QkFBSixDQUF3QjtBQUM3QkQsUUFBQUEsR0FBRyxFQUFFOUQsV0FEd0I7QUFFN0I4QixRQUFBQSxnQkFGNkI7QUFHN0JrQyxRQUFBQSxZQUFZLEVBQUVuQztBQUhlLE9BQXhCLENBQVA7QUFSSjtBQWNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF1dGhEYXRhTWFuYWdlciBmcm9tICcuLi9BZGFwdGVycy9BdXRoJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4uL09wdGlvbnMnO1xuaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi9kZWZhdWx0cyc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG4vLyBDb250cm9sbGVyc1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vTG9nZ2VyQ29udHJvbGxlcic7XG5pbXBvcnQgeyBGaWxlc0NvbnRyb2xsZXIgfSBmcm9tICcuL0ZpbGVzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBIb29rc0NvbnRyb2xsZXIgfSBmcm9tICcuL0hvb2tzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBVc2VyQ29udHJvbGxlciB9IGZyb20gJy4vVXNlckNvbnRyb2xsZXInO1xuaW1wb3J0IHsgQ2FjaGVDb250cm9sbGVyIH0gZnJvbSAnLi9DYWNoZUNvbnRyb2xsZXInO1xuaW1wb3J0IHsgTGl2ZVF1ZXJ5Q29udHJvbGxlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5Q29udHJvbGxlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NDb250cm9sbGVyIH0gZnJvbSAnLi9BbmFseXRpY3NDb250cm9sbGVyJztcbmltcG9ydCB7IFB1c2hDb250cm9sbGVyIH0gZnJvbSAnLi9QdXNoQ29udHJvbGxlcic7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuLi9QdXNoL1B1c2hRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoV29ya2VyIH0gZnJvbSAnLi4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IFNjaGVtYUNhY2hlIGZyb20gJy4vU2NoZW1hQ2FjaGUnO1xuXG4vLyBBZGFwdGVyc1xuaW1wb3J0IHsgR3JpZEZTQnVja2V0QWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0ZpbGVzL0dyaWRGU0J1Y2tldEFkYXB0ZXInO1xuaW1wb3J0IHsgV2luc3RvbkxvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgSW5NZW1vcnlDYWNoZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvUG9zdGdyZXMvUG9zdGdyZXNTdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgUGFyc2VQdXNoQWRhcHRlciBmcm9tICdAcGFyc2UvcHVzaC1hZGFwdGVyJztcbmltcG9ydCBQYXJzZUdyYXBoUUxDb250cm9sbGVyIGZyb20gJy4vUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250cm9sbGVycyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlciA9IGdldExvZ2dlckNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGZpbGVzQ29udHJvbGxlciA9IGdldEZpbGVzQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSBnZXRVc2VyQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3Qge1xuICAgIHB1c2hDb250cm9sbGVyLFxuICAgIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0LFxuICAgIGhhc1B1c2hTdXBwb3J0LFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgcHVzaFdvcmtlcixcbiAgfSA9IGdldFB1c2hDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBjYWNoZUNvbnRyb2xsZXIgPSBnZXRDYWNoZUNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGFuYWx5dGljc0NvbnRyb2xsZXIgPSBnZXRBbmFseXRpY3NDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBsaXZlUXVlcnlDb250cm9sbGVyID0gZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgZGF0YWJhc2VDb250cm9sbGVyID0gZ2V0RGF0YWJhc2VDb250cm9sbGVyKG9wdGlvbnMsIGNhY2hlQ29udHJvbGxlcik7XG4gIGNvbnN0IGhvb2tzQ29udHJvbGxlciA9IGdldEhvb2tzQ29udHJvbGxlcihvcHRpb25zLCBkYXRhYmFzZUNvbnRyb2xsZXIpO1xuICBjb25zdCBhdXRoRGF0YU1hbmFnZXIgPSBnZXRBdXRoRGF0YU1hbmFnZXIob3B0aW9ucyk7XG4gIGNvbnN0IHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKG9wdGlvbnMsIHtcbiAgICBkYXRhYmFzZUNvbnRyb2xsZXIsXG4gICAgY2FjaGVDb250cm9sbGVyLFxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZXJDb250cm9sbGVyLFxuICAgIGZpbGVzQ29udHJvbGxlcixcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBwdXNoQ29udHJvbGxlcixcbiAgICBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICBoYXNQdXNoU3VwcG9ydCxcbiAgICBwdXNoV29ya2VyLFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgYW5hbHl0aWNzQ29udHJvbGxlcixcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICBsaXZlUXVlcnlDb250cm9sbGVyLFxuICAgIGRhdGFiYXNlQ29udHJvbGxlcixcbiAgICBob29rc0NvbnRyb2xsZXIsXG4gICAgYXV0aERhdGFNYW5hZ2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VyQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBMb2dnZXJDb250cm9sbGVyIHtcbiAgY29uc3Qge1xuICAgIGFwcElkLFxuICAgIGpzb25Mb2dzLFxuICAgIGxvZ3NGb2xkZXIsXG4gICAgdmVyYm9zZSxcbiAgICBsb2dMZXZlbCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgICBzaWxlbnQsXG4gICAgbG9nZ2VyQWRhcHRlcixcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxvZ2dlck9wdGlvbnMgPSB7XG4gICAganNvbkxvZ3MsXG4gICAgbG9nc0ZvbGRlcixcbiAgICB2ZXJib3NlLFxuICAgIGxvZ0xldmVsLFxuICAgIHNpbGVudCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgfTtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihsb2dnZXJBZGFwdGVyLCBXaW5zdG9uTG9nZ2VyQWRhcHRlciwgbG9nZ2VyT3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihsb2dnZXJDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIGxvZ2dlck9wdGlvbnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZXNDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IEZpbGVzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGRhdGFiYXNlVVJJLCBmaWxlc0FkYXB0ZXIsIGRhdGFiYXNlQWRhcHRlciwgcHJlc2VydmVGaWxlTmFtZSwgZmlsZUtleSB9ID0gb3B0aW9ucztcbiAgaWYgKCFmaWxlc0FkYXB0ZXIgJiYgZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgdGhyb3cgJ1doZW4gdXNpbmcgYW4gZXhwbGljaXQgZGF0YWJhc2UgYWRhcHRlciwgeW91IG11c3QgYWxzbyB1c2UgYW4gZXhwbGljaXQgZmlsZXNBZGFwdGVyLic7XG4gIH1cbiAgY29uc3QgZmlsZXNDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGZpbGVzQWRhcHRlciwgKCkgPT4ge1xuICAgIHJldHVybiBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihkYXRhYmFzZVVSSSwge30sIGZpbGVLZXkpO1xuICB9KTtcbiAgcmV0dXJuIG5ldyBGaWxlc0NvbnRyb2xsZXIoZmlsZXNDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIHtcbiAgICBwcmVzZXJ2ZUZpbGVOYW1lLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IFVzZXJDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgZW1haWxBZGFwdGVyLCB2ZXJpZnlVc2VyRW1haWxzIH0gPSBvcHRpb25zO1xuICBjb25zdCBlbWFpbENvbnRyb2xsZXJBZGFwdGVyID0gbG9hZEFkYXB0ZXIoZW1haWxBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBVc2VyQ29udHJvbGxlcihlbWFpbENvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCwge1xuICAgIHZlcmlmeVVzZXJFbWFpbHMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2FjaGVDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IENhY2hlQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGNhY2hlQWRhcHRlciwgY2FjaGVUVEwsIGNhY2hlTWF4U2l6ZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgY2FjaGVDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGNhY2hlQWRhcHRlciwgSW5NZW1vcnlDYWNoZUFkYXB0ZXIsIHtcbiAgICBhcHBJZDogYXBwSWQsXG4gICAgdHRsOiBjYWNoZVRUTCxcbiAgICBtYXhTaXplOiBjYWNoZU1heFNpemUsXG4gIH0pO1xuICByZXR1cm4gbmV3IENhY2hlQ29udHJvbGxlcihjYWNoZUNvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKFxuICBvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsXG4gIGNvbnRyb2xsZXJEZXBzXG4pOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyIHtcbiAgcmV0dXJuIG5ldyBQYXJzZUdyYXBoUUxDb250cm9sbGVyKHtcbiAgICBtb3VudEdyYXBoUUw6IG9wdGlvbnMubW91bnRHcmFwaFFMLFxuICAgIC4uLmNvbnRyb2xsZXJEZXBzLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFuYWx5dGljc0NvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogQW5hbHl0aWNzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYW5hbHl0aWNzQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihhbmFseXRpY3NBZGFwdGVyLCBBbmFseXRpY3NBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBBbmFseXRpY3NDb250cm9sbGVyKGFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExpdmVRdWVyeUNvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogTGl2ZVF1ZXJ5Q29udHJvbGxlciB7XG4gIHJldHVybiBuZXcgTGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zLmxpdmVRdWVyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhYmFzZUNvbnRyb2xsZXIoXG4gIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyxcbiAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXJcbik6IERhdGFiYXNlQ29udHJvbGxlciB7XG4gIGNvbnN0IHtcbiAgICBkYXRhYmFzZVVSSSxcbiAgICBkYXRhYmFzZU9wdGlvbnMsXG4gICAgY29sbGVjdGlvblByZWZpeCxcbiAgICBzY2hlbWFDYWNoZVRUTCxcbiAgICBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSxcbiAgfSA9IG9wdGlvbnM7XG4gIGxldCB7IGRhdGFiYXNlQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgaWYgKFxuICAgIChkYXRhYmFzZU9wdGlvbnMgfHxcbiAgICAgIChkYXRhYmFzZVVSSSAmJiBkYXRhYmFzZVVSSSAhPT0gZGVmYXVsdHMuZGF0YWJhc2VVUkkpIHx8XG4gICAgICBjb2xsZWN0aW9uUHJlZml4ICE9PSBkZWZhdWx0cy5jb2xsZWN0aW9uUHJlZml4KSAmJlxuICAgIGRhdGFiYXNlQWRhcHRlclxuICApIHtcbiAgICB0aHJvdyAnWW91IGNhbm5vdCBzcGVjaWZ5IGJvdGggYSBkYXRhYmFzZUFkYXB0ZXIgYW5kIGEgZGF0YWJhc2VVUkkvZGF0YWJhc2VPcHRpb25zL2NvbGxlY3Rpb25QcmVmaXguJztcbiAgfSBlbHNlIGlmICghZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgZGF0YWJhc2VBZGFwdGVyID0gZ2V0RGF0YWJhc2VBZGFwdGVyKGRhdGFiYXNlVVJJLCBjb2xsZWN0aW9uUHJlZml4LCBkYXRhYmFzZU9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIGRhdGFiYXNlQWRhcHRlciA9IGxvYWRBZGFwdGVyKGRhdGFiYXNlQWRhcHRlcik7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRhYmFzZUNvbnRyb2xsZXIoXG4gICAgZGF0YWJhc2VBZGFwdGVyLFxuICAgIG5ldyBTY2hlbWFDYWNoZShjYWNoZUNvbnRyb2xsZXIsIHNjaGVtYUNhY2hlVFRMLCBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tzQ29udHJvbGxlcihcbiAgb3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zLFxuICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlclxuKTogSG9va3NDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgd2ViaG9va0tleSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBIb29rc0NvbnRyb2xsZXIoYXBwSWQsIGRhdGFiYXNlQ29udHJvbGxlciwgd2ViaG9va0tleSk7XG59XG5cbmludGVyZmFjZSBQdXNoQ29udHJvbGxpbmcge1xuICBwdXNoQ29udHJvbGxlcjogUHVzaENvbnRyb2xsZXI7XG4gIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0OiBib29sZWFuO1xuICBwdXNoQ29udHJvbGxlclF1ZXVlOiBQdXNoUXVldWU7XG4gIHB1c2hXb3JrZXI6IFB1c2hXb3JrZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQdXNoQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBQdXNoQ29udHJvbGxpbmcge1xuICBjb25zdCB7IHNjaGVkdWxlZFB1c2gsIHB1c2ggfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgcHVzaE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBwdXNoKTtcbiAgY29uc3QgcHVzaFF1ZXVlT3B0aW9ucyA9IHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucyB8fCB7fTtcbiAgaWYgKHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucykge1xuICAgIGRlbGV0ZSBwdXNoT3B0aW9ucy5xdWV1ZU9wdGlvbnM7XG4gIH1cblxuICAvLyBQYXNzIHRoZSBwdXNoIG9wdGlvbnMgdG9vIGFzIGl0IHdvcmtzIHdpdGggdGhlIGRlZmF1bHRcbiAgY29uc3QgcHVzaEFkYXB0ZXIgPSBsb2FkQWRhcHRlcihcbiAgICBwdXNoT3B0aW9ucyAmJiBwdXNoT3B0aW9ucy5hZGFwdGVyLFxuICAgIFBhcnNlUHVzaEFkYXB0ZXIsXG4gICAgcHVzaE9wdGlvbnNcbiAgKTtcbiAgLy8gV2UgcGFzcyB0aGUgb3B0aW9ucyBhbmQgdGhlIGJhc2UgY2xhc3MgZm9yIHRoZSBhZGF0cGVyLFxuICAvLyBOb3RlIHRoYXQgcGFzc2luZyBhbiBpbnN0YW5jZSB3b3VsZCB3b3JrIHRvb1xuICBjb25zdCBwdXNoQ29udHJvbGxlciA9IG5ldyBQdXNoQ29udHJvbGxlcigpO1xuICBjb25zdCBoYXNQdXNoU3VwcG9ydCA9ICEhKHB1c2hBZGFwdGVyICYmIHB1c2gpO1xuICBjb25zdCBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCA9IGhhc1B1c2hTdXBwb3J0ICYmIHNjaGVkdWxlZFB1c2ggPT09IHRydWU7XG5cbiAgY29uc3QgeyBkaXNhYmxlUHVzaFdvcmtlciB9ID0gcHVzaFF1ZXVlT3B0aW9ucztcblxuICBjb25zdCBwdXNoQ29udHJvbGxlclF1ZXVlID0gbmV3IFB1c2hRdWV1ZShwdXNoUXVldWVPcHRpb25zKTtcbiAgbGV0IHB1c2hXb3JrZXI7XG4gIGlmICghZGlzYWJsZVB1c2hXb3JrZXIpIHtcbiAgICBwdXNoV29ya2VyID0gbmV3IFB1c2hXb3JrZXIocHVzaEFkYXB0ZXIsIHB1c2hRdWV1ZU9wdGlvbnMpO1xuICB9XG4gIHJldHVybiB7XG4gICAgcHVzaENvbnRyb2xsZXIsXG4gICAgaGFzUHVzaFN1cHBvcnQsXG4gICAgaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQsXG4gICAgcHVzaENvbnRyb2xsZXJRdWV1ZSxcbiAgICBwdXNoV29ya2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0aERhdGFNYW5hZ2VyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCB7IGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzIH0gPSBvcHRpb25zO1xuICByZXR1cm4gYXV0aERhdGFNYW5hZ2VyKGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERhdGFiYXNlQWRhcHRlcihkYXRhYmFzZVVSSSwgY29sbGVjdGlvblByZWZpeCwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBwcm90b2NvbDtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWRVUkkgPSB1cmwucGFyc2UoZGF0YWJhc2VVUkkpO1xuICAgIHByb3RvY29sID0gcGFyc2VkVVJJLnByb3RvY29sID8gcGFyc2VkVVJJLnByb3RvY29sLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICBzd2l0Y2ggKHByb3RvY29sKSB7XG4gICAgY2FzZSAncG9zdGdyZXM6JzpcbiAgICAgIHJldHVybiBuZXcgUG9zdGdyZXNTdG9yYWdlQWRhcHRlcih7XG4gICAgICAgIHVyaTogZGF0YWJhc2VVUkksXG4gICAgICAgIGNvbGxlY3Rpb25QcmVmaXgsXG4gICAgICAgIGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbmV3IE1vbmdvU3RvcmFnZUFkYXB0ZXIoe1xuICAgICAgICB1cmk6IGRhdGFiYXNlVVJJLFxuICAgICAgICBjb2xsZWN0aW9uUHJlZml4LFxuICAgICAgICBtb25nb09wdGlvbnM6IGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/types.js b/lib/Controllers/types.js new file mode 100644 index 0000000000..4310b4ffac --- /dev/null +++ b/lib/Controllers/types.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLSchema.js b/lib/GraphQL/ParseGraphQLSchema.js new file mode 100644 index 0000000000..254e6f3989 --- /dev/null +++ b/lib/GraphQL/ParseGraphQLSchema.js @@ -0,0 +1,446 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseGraphQLSchema = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphql = require("graphql"); + +var _stitch = require("@graphql-tools/stitch"); + +var _utils = require("@graphql-tools/utils"); + +var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./loaders/defaultGraphQLTypes")); + +var parseClassTypes = _interopRequireWildcard(require("./loaders/parseClassTypes")); + +var parseClassQueries = _interopRequireWildcard(require("./loaders/parseClassQueries")); + +var parseClassMutations = _interopRequireWildcard(require("./loaders/parseClassMutations")); + +var defaultGraphQLQueries = _interopRequireWildcard(require("./loaders/defaultGraphQLQueries")); + +var defaultGraphQLMutations = _interopRequireWildcard(require("./loaders/defaultGraphQLMutations")); + +var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); + +var _DatabaseController = _interopRequireDefault(require("../Controllers/DatabaseController")); + +var _parseGraphQLUtils = require("./parseGraphQLUtils"); + +var schemaDirectives = _interopRequireWildcard(require("./loaders/schemaDirectives")); + +var schemaTypes = _interopRequireWildcard(require("./loaders/schemaTypes")); + +var _triggers = require("../triggers"); + +var defaultRelaySchema = _interopRequireWildcard(require("./loaders/defaultRelaySchema")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const RESERVED_GRAPHQL_TYPE_NAMES = ['String', 'Boolean', 'Int', 'Float', 'ID', 'ArrayResult', 'Query', 'Mutation', 'Subscription', 'CreateFileInput', 'CreateFilePayload', 'Viewer', 'SignUpInput', 'SignUpPayload', 'LogInInput', 'LogInPayload', 'LogOutInput', 'LogOutPayload', 'CloudCodeFunction', 'CallCloudCodeInput', 'CallCloudCodePayload', 'CreateClassInput', 'CreateClassPayload', 'UpdateClassInput', 'UpdateClassPayload', 'DeleteClassInput', 'DeleteClassPayload', 'PageInfo']; +const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes']; +const RESERVED_GRAPHQL_MUTATION_NAMES = ['signUp', 'logIn', 'logOut', 'createFile', 'callCloudCode', 'createClass', 'updateClass', 'deleteClass']; + +class ParseGraphQLSchema { + constructor(params = {}) { + this.parseGraphQLController = params.parseGraphQLController || (0, _requiredParameter.default)('You must provide a parseGraphQLController instance!'); + this.databaseController = params.databaseController || (0, _requiredParameter.default)('You must provide a databaseController instance!'); + this.log = params.log || (0, _requiredParameter.default)('You must provide a log instance!'); + this.graphQLCustomTypeDefs = params.graphQLCustomTypeDefs; + this.appId = params.appId || (0, _requiredParameter.default)('You must provide the appId!'); + } + + async load() { + const { + parseGraphQLConfig + } = await this._initializeSchemaAndConfig(); + const parseClasses = await this._getClassesForSchema(parseGraphQLConfig); + const parseClassesString = JSON.stringify(parseClasses); + const functionNames = await this._getFunctionNames(); + const functionNamesString = JSON.stringify(functionNames); + + if (this.graphQLSchema && !this._hasSchemaInputChanged({ + parseClasses, + parseClassesString, + parseGraphQLConfig, + functionNamesString + })) { + return this.graphQLSchema; + } + + this.parseClasses = parseClasses; + this.parseClassesString = parseClassesString; + this.parseGraphQLConfig = parseGraphQLConfig; + this.functionNames = functionNames; + this.functionNamesString = functionNamesString; + this.parseClassTypes = {}; + this.viewerType = null; + this.graphQLAutoSchema = null; + this.graphQLSchema = null; + this.graphQLTypes = []; + this.graphQLQueries = {}; + this.graphQLMutations = {}; + this.graphQLSubscriptions = {}; + this.graphQLSchemaDirectivesDefinitions = null; + this.graphQLSchemaDirectives = {}; + this.relayNodeInterface = null; + defaultGraphQLTypes.load(this); + defaultRelaySchema.load(this); + schemaTypes.load(this); + + this._getParseClassesWithConfig(parseClasses, parseGraphQLConfig).forEach(([parseClass, parseClassConfig]) => { + parseClassTypes.load(this, parseClass, parseClassConfig); + parseClassQueries.load(this, parseClass, parseClassConfig); + parseClassMutations.load(this, parseClass, parseClassConfig); + }); + + defaultGraphQLTypes.loadArrayResult(this, parseClasses); + defaultGraphQLQueries.load(this); + defaultGraphQLMutations.load(this); + let graphQLQuery = undefined; + + if (Object.keys(this.graphQLQueries).length > 0) { + graphQLQuery = new _graphql.GraphQLObjectType({ + name: 'Query', + description: 'Query is the top level type for queries.', + fields: this.graphQLQueries + }); + this.addGraphQLType(graphQLQuery, true, true); + } + + let graphQLMutation = undefined; + + if (Object.keys(this.graphQLMutations).length > 0) { + graphQLMutation = new _graphql.GraphQLObjectType({ + name: 'Mutation', + description: 'Mutation is the top level type for mutations.', + fields: this.graphQLMutations + }); + this.addGraphQLType(graphQLMutation, true, true); + } + + let graphQLSubscription = undefined; + + if (Object.keys(this.graphQLSubscriptions).length > 0) { + graphQLSubscription = new _graphql.GraphQLObjectType({ + name: 'Subscription', + description: 'Subscription is the top level type for subscriptions.', + fields: this.graphQLSubscriptions + }); + this.addGraphQLType(graphQLSubscription, true, true); + } + + this.graphQLAutoSchema = new _graphql.GraphQLSchema({ + types: this.graphQLTypes, + query: graphQLQuery, + mutation: graphQLMutation, + subscription: graphQLSubscription + }); + + if (this.graphQLCustomTypeDefs) { + schemaDirectives.load(this); + + if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') { + const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs.getTypeMap(); + + const findAndReplaceLastType = (parent, key) => { + if (parent[key].name) { + if (this.graphQLAutoSchema.getType(parent[key].name) && this.graphQLAutoSchema.getType(parent[key].name) !== parent[key]) { + // To avoid unresolved field on overloaded schema + // replace the final type with the auto schema one + parent[key] = this.graphQLAutoSchema.getType(parent[key].name); + } + } else { + if (parent[key].ofType) { + findAndReplaceLastType(parent[key], 'ofType'); + } + } + }; + + Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { + if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { + return; + } + + const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); + + if (!autoGraphQLSchemaType) { + this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name] = customGraphQLSchemaType; + } + }); + Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { + if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { + return; + } + + const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); + + if (autoGraphQLSchemaType && typeof customGraphQLSchemaType.getFields === 'function') { + Object.values(customGraphQLSchemaType.getFields()).forEach(field => { + findAndReplaceLastType(field, 'type'); + }); + autoGraphQLSchemaType._fields = _objectSpread(_objectSpread({}, autoGraphQLSchemaType.getFields()), customGraphQLSchemaType.getFields()); + } + }); + this.graphQLSchema = (0, _stitch.stitchSchemas)({ + schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema], + mergeDirectives: true + }); + } else if (typeof this.graphQLCustomTypeDefs === 'function') { + this.graphQLSchema = await this.graphQLCustomTypeDefs({ + directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions, + autoSchema: this.graphQLAutoSchema, + stitchSchemas: _stitch.stitchSchemas + }); + } else { + this.graphQLSchema = (0, _stitch.stitchSchemas)({ + schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema, this.graphQLCustomTypeDefs], + mergeDirectives: true + }); + } + + const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap(); + Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => { + const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName]; + + if (typeof graphQLSchemaType.getFields === 'function' && this.graphQLCustomTypeDefs.definitions) { + const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(definition => definition.name.value === graphQLSchemaTypeName); + + if (graphQLCustomTypeDef) { + const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields(); + Object.keys(graphQLSchemaTypeFieldMap).forEach(graphQLSchemaTypeFieldName => { + const graphQLSchemaTypeField = graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName]; + + if (!graphQLSchemaTypeField.astNode) { + const astNode = graphQLCustomTypeDef.fields.find(field => field.name.value === graphQLSchemaTypeFieldName); + + if (astNode) { + graphQLSchemaTypeField.astNode = astNode; + } + } + }); + } + } + }); + + _utils.SchemaDirectiveVisitor.visitSchemaDirectives(this.graphQLSchema, this.graphQLSchemaDirectives); + } else { + this.graphQLSchema = this.graphQLAutoSchema; + } + + return this.graphQLSchema; + } + + addGraphQLType(type, throwError = false, ignoreReserved = false, ignoreConnection = false) { + if (!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name) || this.graphQLTypes.find(existingType => existingType.name === type.name) || !ignoreConnection && type.name.endsWith('Connection')) { + const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`; + + if (throwError) { + throw new Error(message); + } + + this.log.warn(message); + return undefined; + } + + this.graphQLTypes.push(type); + return type; + } + + addGraphQLQuery(fieldName, field, throwError = false, ignoreReserved = false) { + if (!ignoreReserved && RESERVED_GRAPHQL_QUERY_NAMES.includes(fieldName) || this.graphQLQueries[fieldName]) { + const message = `Query ${fieldName} could not be added to the auto schema because it collided with an existing field.`; + + if (throwError) { + throw new Error(message); + } + + this.log.warn(message); + return undefined; + } + + this.graphQLQueries[fieldName] = field; + return field; + } + + addGraphQLMutation(fieldName, field, throwError = false, ignoreReserved = false) { + if (!ignoreReserved && RESERVED_GRAPHQL_MUTATION_NAMES.includes(fieldName) || this.graphQLMutations[fieldName]) { + const message = `Mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`; + + if (throwError) { + throw new Error(message); + } + + this.log.warn(message); + return undefined; + } + + this.graphQLMutations[fieldName] = field; + return field; + } + + handleError(error) { + if (error instanceof _node.default.Error) { + this.log.error('Parse error: ', error); + } else { + this.log.error('Uncaught internal server error.', error, error.stack); + } + + throw (0, _parseGraphQLUtils.toGraphQLError)(error); + } + + async _initializeSchemaAndConfig() { + const [schemaController, parseGraphQLConfig] = await Promise.all([this.databaseController.loadSchema(), this.parseGraphQLController.getGraphQLConfig()]); + this.schemaController = schemaController; + return { + parseGraphQLConfig + }; + } + /** + * Gets all classes found by the `schemaController` + * minus those filtered out by the app's parseGraphQLConfig. + */ + + + async _getClassesForSchema(parseGraphQLConfig) { + const { + enabledForClasses, + disabledForClasses + } = parseGraphQLConfig; + const allClasses = await this.schemaController.getAllClasses(); + + if (Array.isArray(enabledForClasses) || Array.isArray(disabledForClasses)) { + let includedClasses = allClasses; + + if (enabledForClasses) { + includedClasses = allClasses.filter(clazz => { + return enabledForClasses.includes(clazz.className); + }); + } + + if (disabledForClasses) { + // Classes included in `enabledForClasses` that + // are also present in `disabledForClasses` will + // still be filtered out + includedClasses = includedClasses.filter(clazz => { + return !disabledForClasses.includes(clazz.className); + }); + } + + this.isUsersClassDisabled = !includedClasses.some(clazz => { + return clazz.className === '_User'; + }); + return includedClasses; + } else { + return allClasses; + } + } + /** + * This method returns a list of tuples + * that provide the parseClass along with + * its parseClassConfig where provided. + */ + + + _getParseClassesWithConfig(parseClasses, parseGraphQLConfig) { + const { + classConfigs + } = parseGraphQLConfig; // Make sures that the default classes and classes that + // starts with capitalized letter will be generated first. + + const sortClasses = (a, b) => { + a = a.className; + b = b.className; + + if (a[0] === '_') { + if (b[0] !== '_') { + return -1; + } + } + + if (b[0] === '_') { + if (a[0] !== '_') { + return 1; + } + } + + if (a === b) { + return 0; + } else if (a < b) { + return -1; + } else { + return 1; + } + }; + + return parseClasses.sort(sortClasses).map(parseClass => { + let parseClassConfig; + + if (classConfigs) { + parseClassConfig = classConfigs.find(c => c.className === parseClass.className); + } + + return [parseClass, parseClassConfig]; + }); + } + + async _getFunctionNames() { + return await (0, _triggers.getFunctionNames)(this.appId).filter(functionName => { + if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(functionName)) { + return true; + } else { + this.log.warn(`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`); + return false; + } + }); + } + /** + * Checks for changes to the parseClasses + * objects (i.e. database schema) or to + * the parseGraphQLConfig object. If no + * changes are found, return true; + */ + + + _hasSchemaInputChanged(params) { + const { + parseClasses, + parseClassesString, + parseGraphQLConfig, + functionNamesString + } = params; + + if (JSON.stringify(this.parseGraphQLConfig) === JSON.stringify(parseGraphQLConfig) && this.functionNamesString === functionNamesString) { + if (this.parseClasses === parseClasses) { + return false; + } + + if (this.parseClassesString === parseClassesString) { + this.parseClasses = parseClasses; + return false; + } + } + + return true; + } + +} + +exports.ParseGraphQLSchema = ParseGraphQLSchema; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMiLCJSRVNFUlZFRF9HUkFQSFFMX1FVRVJZX05BTUVTIiwiUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyIsIlBhcnNlR3JhcGhRTFNjaGVtYSIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwicGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImxvZyIsImdyYXBoUUxDdXN0b21UeXBlRGVmcyIsImFwcElkIiwibG9hZCIsInBhcnNlR3JhcGhRTENvbmZpZyIsIl9pbml0aWFsaXplU2NoZW1hQW5kQ29uZmlnIiwicGFyc2VDbGFzc2VzIiwiX2dldENsYXNzZXNGb3JTY2hlbWEiLCJwYXJzZUNsYXNzZXNTdHJpbmciLCJKU09OIiwic3RyaW5naWZ5IiwiZnVuY3Rpb25OYW1lcyIsIl9nZXRGdW5jdGlvbk5hbWVzIiwiZnVuY3Rpb25OYW1lc1N0cmluZyIsImdyYXBoUUxTY2hlbWEiLCJfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkIiwicGFyc2VDbGFzc1R5cGVzIiwidmlld2VyVHlwZSIsImdyYXBoUUxBdXRvU2NoZW1hIiwiZ3JhcGhRTFR5cGVzIiwiZ3JhcGhRTFF1ZXJpZXMiLCJncmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFN1YnNjcmlwdGlvbnMiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXMiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiZGVmYXVsdFJlbGF5U2NoZW1hIiwic2NoZW1hVHlwZXMiLCJfZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyIsImZvckVhY2giLCJwYXJzZUNsYXNzIiwicGFyc2VDbGFzc0NvbmZpZyIsInBhcnNlQ2xhc3NRdWVyaWVzIiwicGFyc2VDbGFzc011dGF0aW9ucyIsImxvYWRBcnJheVJlc3VsdCIsImRlZmF1bHRHcmFwaFFMUXVlcmllcyIsImRlZmF1bHRHcmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFF1ZXJ5IiwidW5kZWZpbmVkIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsIkdyYXBoUUxPYmplY3RUeXBlIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiZmllbGRzIiwiYWRkR3JhcGhRTFR5cGUiLCJncmFwaFFMTXV0YXRpb24iLCJncmFwaFFMU3Vic2NyaXB0aW9uIiwiR3JhcGhRTFNjaGVtYSIsInR5cGVzIiwicXVlcnkiLCJtdXRhdGlvbiIsInN1YnNjcmlwdGlvbiIsInNjaGVtYURpcmVjdGl2ZXMiLCJnZXRUeXBlTWFwIiwiY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJmaW5kQW5kUmVwbGFjZUxhc3RUeXBlIiwicGFyZW50Iiwia2V5IiwiZ2V0VHlwZSIsIm9mVHlwZSIsInZhbHVlcyIsImN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlIiwic3RhcnRzV2l0aCIsImF1dG9HcmFwaFFMU2NoZW1hVHlwZSIsIl90eXBlTWFwIiwiZ2V0RmllbGRzIiwiZmllbGQiLCJfZmllbGRzIiwic2NoZW1hcyIsIm1lcmdlRGlyZWN0aXZlcyIsImRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYSIsImF1dG9TY2hlbWEiLCJzdGl0Y2hTY2hlbWFzIiwiZ3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJncmFwaFFMU2NoZW1hVHlwZU5hbWUiLCJncmFwaFFMU2NoZW1hVHlwZSIsImRlZmluaXRpb25zIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWYiLCJmaW5kIiwiZGVmaW5pdGlvbiIsInZhbHVlIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE1hcCIsImdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCIsImFzdE5vZGUiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRTY2hlbWFEaXJlY3RpdmVzIiwidHlwZSIsInRocm93RXJyb3IiLCJpZ25vcmVSZXNlcnZlZCIsImlnbm9yZUNvbm5lY3Rpb24iLCJpbmNsdWRlcyIsImV4aXN0aW5nVHlwZSIsImVuZHNXaXRoIiwibWVzc2FnZSIsIkVycm9yIiwid2FybiIsInB1c2giLCJhZGRHcmFwaFFMUXVlcnkiLCJmaWVsZE5hbWUiLCJhZGRHcmFwaFFMTXV0YXRpb24iLCJoYW5kbGVFcnJvciIsImVycm9yIiwiUGFyc2UiLCJzdGFjayIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwiYWxsIiwibG9hZFNjaGVtYSIsImdldEdyYXBoUUxDb25maWciLCJlbmFibGVkRm9yQ2xhc3NlcyIsImRpc2FibGVkRm9yQ2xhc3NlcyIsImFsbENsYXNzZXMiLCJnZXRBbGxDbGFzc2VzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZWRDbGFzc2VzIiwiZmlsdGVyIiwiY2xhenoiLCJjbGFzc05hbWUiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNvbWUiLCJjbGFzc0NvbmZpZ3MiLCJzb3J0Q2xhc3NlcyIsImEiLCJiIiwic29ydCIsIm1hcCIsImMiLCJmdW5jdGlvbk5hbWUiLCJ0ZXN0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsMkJBQTJCLEdBQUcsQ0FDbEMsUUFEa0MsRUFFbEMsU0FGa0MsRUFHbEMsS0FIa0MsRUFJbEMsT0FKa0MsRUFLbEMsSUFMa0MsRUFNbEMsYUFOa0MsRUFPbEMsT0FQa0MsRUFRbEMsVUFSa0MsRUFTbEMsY0FUa0MsRUFVbEMsaUJBVmtDLEVBV2xDLG1CQVhrQyxFQVlsQyxRQVprQyxFQWFsQyxhQWJrQyxFQWNsQyxlQWRrQyxFQWVsQyxZQWZrQyxFQWdCbEMsY0FoQmtDLEVBaUJsQyxhQWpCa0MsRUFrQmxDLGVBbEJrQyxF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LENBQUNsQixNQUFELEVBS1Y7QUFDVixVQUFNO0FBQUVTLE1BQUFBLFlBQUY7QUFBZ0JFLE1BQUFBLGtCQUFoQjtBQUFvQ0osTUFBQUEsa0JBQXBDO0FBQXdEUyxNQUFBQTtBQUF4RCxRQUFnRmhCLE1BQXRGOztBQUVBLFFBQ0VZLElBQUksQ0FBQ0MsU0FBTCxDQUFlLEtBQUtOLGtCQUFwQixNQUE0Q0ssSUFBSSxDQUFDQyxTQUFMLENBQWVOLGtCQUFmLENBQTVDLElBQ0EsS0FBS1MsbUJBQUwsS0FBNkJBLG1CQUYvQixFQUdFO0FBQ0EsVUFBSSxLQUFLUCxZQUFMLEtBQXNCQSxZQUExQixFQUF3QztBQUN0QyxlQUFPLEtBQVA7QUFDRDs7QUFFRCxVQUFJLEtBQUtFLGtCQUFMLEtBQTRCQSxrQkFBaEMsRUFBb0Q7QUFDbEQsYUFBS0YsWUFBTCxHQUFvQkEsWUFBcEI7QUFDQSxlQUFPLEtBQVA7QUFDRDtBQUNGOztBQUVELFdBQU8sSUFBUDtBQUNEOztBQXRhc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMU2NoZW1hLCBHcmFwaFFMT2JqZWN0VHlwZSwgRG9jdW1lbnROb2RlLCBHcmFwaFFMTmFtZWRUeXBlIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBzdGl0Y2hTY2hlbWFzIH0gZnJvbSAnQGdyYXBocWwtdG9vbHMvc3RpdGNoJztcbmltcG9ydCB7IFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IgfSBmcm9tICdAZ3JhcGhxbC10b29scy91dGlscyc7XG5pbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzVHlwZXMgZnJvbSAnLi9sb2FkZXJzL3BhcnNlQ2xhc3NUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzUXVlcmllcyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMnO1xuaW1wb3J0ICogYXMgcGFyc2VDbGFzc011dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMgZnJvbSAnLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0b0dyYXBoUUxFcnJvciB9IGZyb20gJy4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuaW1wb3J0ICogYXMgc2NoZW1hRGlyZWN0aXZlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFUeXBlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hVHlwZXMnO1xuaW1wb3J0IHsgZ2V0RnVuY3Rpb25OYW1lcyB9IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRSZWxheVNjaGVtYSBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hJztcblxuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9UWVBFX05BTUVTID0gW1xuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnSW50JyxcbiAgJ0Zsb2F0JyxcbiAgJ0lEJyxcbiAgJ0FycmF5UmVzdWx0JyxcbiAgJ1F1ZXJ5JyxcbiAgJ011dGF0aW9uJyxcbiAgJ1N1YnNjcmlwdGlvbicsXG4gICdDcmVhdGVGaWxlSW5wdXQnLFxuICAnQ3JlYXRlRmlsZVBheWxvYWQnLFxuICAnVmlld2VyJyxcbiAgJ1NpZ25VcElucHV0JyxcbiAgJ1NpZ25VcFBheWxvYWQnLFxuICAnTG9nSW5JbnB1dCcsXG4gICdMb2dJblBheWxvYWQnLFxuICAnTG9nT3V0SW5wdXQnLFxuICAnTG9nT3V0UGF5bG9hZCcsXG4gICdDbG91ZENvZGVGdW5jdGlvbicsXG4gICdDYWxsQ2xvdWRDb2RlSW5wdXQnLFxuICAnQ2FsbENsb3VkQ29kZVBheWxvYWQnLFxuICAnQ3JlYXRlQ2xhc3NJbnB1dCcsXG4gICdDcmVhdGVDbGFzc1BheWxvYWQnLFxuICAnVXBkYXRlQ2xhc3NJbnB1dCcsXG4gICdVcGRhdGVDbGFzc1BheWxvYWQnLFxuICAnRGVsZXRlQ2xhc3NJbnB1dCcsXG4gICdEZWxldGVDbGFzc1BheWxvYWQnLFxuICAnUGFnZUluZm8nLFxuXTtcbmNvbnN0IFJFU0VSVkVEX0dSQVBIUUxfUVVFUllfTkFNRVMgPSBbJ2hlYWx0aCcsICd2aWV3ZXInLCAnY2xhc3MnLCAnY2xhc3NlcyddO1xuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyA9IFtcbiAgJ3NpZ25VcCcsXG4gICdsb2dJbicsXG4gICdsb2dPdXQnLFxuICAnY3JlYXRlRmlsZScsXG4gICdjYWxsQ2xvdWRDb2RlJyxcbiAgJ2NyZWF0ZUNsYXNzJyxcbiAgJ3VwZGF0ZUNsYXNzJyxcbiAgJ2RlbGV0ZUNsYXNzJyxcbl07XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNjaGVtYSB7XG4gIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZztcbiAgbG9nOiBhbnk7XG4gIGFwcElkOiBzdHJpbmc7XG4gIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwYXJhbXM6IHtcbiAgICAgIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyLFxuICAgICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcjogUGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICAgIGxvZzogYW55LFxuICAgICAgYXBwSWQ6IHN0cmluZyxcbiAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKSxcbiAgICB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyID1cbiAgICAgIHBhcmFtcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyIHx8XG4gICAgICByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIgPVxuICAgICAgcGFyYW1zLmRhdGFiYXNlQ29udHJvbGxlciB8fFxuICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBkYXRhYmFzZUNvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5sb2cgPSBwYXJhbXMubG9nIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgbG9nIGluc3RhbmNlIScpO1xuICAgIHRoaXMuZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gcGFyYW1zLmdyYXBoUUxDdXN0b21UeXBlRGVmcztcbiAgICB0aGlzLmFwcElkID0gcGFyYW1zLmFwcElkIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIHRoZSBhcHBJZCEnKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgY29uc3QgeyBwYXJzZUdyYXBoUUxDb25maWcgfSA9IGF3YWl0IHRoaXMuX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKTtcbiAgICBjb25zdCBwYXJzZUNsYXNzZXMgPSBhd2FpdCB0aGlzLl9nZXRDbGFzc2VzRm9yU2NoZW1hKHBhcnNlR3JhcGhRTENvbmZpZyk7XG4gICAgY29uc3QgcGFyc2VDbGFzc2VzU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkocGFyc2VDbGFzc2VzKTtcbiAgICBjb25zdCBmdW5jdGlvbk5hbWVzID0gYXdhaXQgdGhpcy5fZ2V0RnVuY3Rpb25OYW1lcygpO1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZXNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShmdW5jdGlvbk5hbWVzKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSAmJlxuICAgICAgIXRoaXMuX2hhc1NjaGVtYUlucHV0Q2hhbmdlZCh7XG4gICAgICAgIHBhcnNlQ2xhc3NlcyxcbiAgICAgICAgcGFyc2VDbGFzc2VzU3RyaW5nLFxuICAgICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgICAgIGZ1bmN0aW9uTmFtZXNTdHJpbmcsXG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgICB9XG5cbiAgICB0aGlzLnBhcnNlQ2xhc3NlcyA9IHBhcnNlQ2xhc3NlcztcbiAgICB0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9IHBhcnNlQ2xhc3Nlc1N0cmluZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbmZpZyA9IHBhcnNlR3JhcGhRTENvbmZpZztcbiAgICB0aGlzLmZ1bmN0aW9uTmFtZXMgPSBmdW5jdGlvbk5hbWVzO1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lc1N0cmluZyA9IGZ1bmN0aW9uTmFtZXNTdHJpbmc7XG4gICAgdGhpcy5wYXJzZUNsYXNzVHlwZXMgPSB7fTtcbiAgICB0aGlzLnZpZXdlclR5cGUgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMVHlwZXMgPSBbXTtcbiAgICB0aGlzLmdyYXBoUUxRdWVyaWVzID0ge307XG4gICAgdGhpcy5ncmFwaFFMTXV0YXRpb25zID0ge307XG4gICAgdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyA9IHt9O1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNEZWZpbml0aW9ucyA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyA9IHt9O1xuICAgIHRoaXMucmVsYXlOb2RlSW50ZXJmYWNlID0gbnVsbDtcblxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0UmVsYXlTY2hlbWEubG9hZCh0aGlzKTtcbiAgICBzY2hlbWFUeXBlcy5sb2FkKHRoaXMpO1xuXG4gICAgdGhpcy5fZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyhwYXJzZUNsYXNzZXMsIHBhcnNlR3JhcGhRTENvbmZpZykuZm9yRWFjaChcbiAgICAgIChbcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZ10pID0+IHtcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NRdWVyaWVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NNdXRhdGlvbnMubG9hZCh0aGlzLCBwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5sb2FkQXJyYXlSZXN1bHQodGhpcywgcGFyc2VDbGFzc2VzKTtcbiAgICBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucy5sb2FkKHRoaXMpO1xuXG4gICAgbGV0IGdyYXBoUUxRdWVyeSA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMUXVlcmllcykubGVuZ3RoID4gMCkge1xuICAgICAgZ3JhcGhRTFF1ZXJ5ID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICAgICAgbmFtZTogJ1F1ZXJ5JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdRdWVyeSBpcyB0aGUgdG9wIGxldmVsIHR5cGUgZm9yIHF1ZXJpZXMuJyxcbiAgICAgICAgZmllbGRzOiB0aGlzLmdyYXBoUUxRdWVyaWVzLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxRdWVyeSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxNdXRhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMTXV0YXRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBncmFwaFFMTXV0YXRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnTXV0YXRpb24nLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ011dGF0aW9uIGlzIHRoZSB0b3AgbGV2ZWwgdHlwZSBmb3IgbXV0YXRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMTXV0YXRpb25zLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZ3JhcGhRTFN1YnNjcmlwdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGdyYXBoUUxTdWJzY3JpcHRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnU3Vic2NyaXB0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdTdWJzY3JpcHRpb24gaXMgdGhlIHRvcCBsZXZlbCB0eXBlIGZvciBzdWJzY3JpcHRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRHcmFwaFFMVHlwZShncmFwaFFMU3Vic2NyaXB0aW9uLCB0cnVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hID0gbmV3IEdyYXBoUUxTY2hlbWEoe1xuICAgICAgdHlwZXM6IHRoaXMuZ3JhcGhRTFR5cGVzLFxuICAgICAgcXVlcnk6IGdyYXBoUUxRdWVyeSxcbiAgICAgIG11dGF0aW9uOiBncmFwaFFMTXV0YXRpb24sXG4gICAgICBzdWJzY3JpcHRpb246IGdyYXBoUUxTdWJzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMpIHtcbiAgICAgIHNjaGVtYURpcmVjdGl2ZXMubG9hZCh0aGlzKTtcblxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5nZXRUeXBlTWFwID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlTWFwID0gdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZ2V0VHlwZU1hcCgpO1xuICAgICAgICBjb25zdCBmaW5kQW5kUmVwbGFjZUxhc3RUeXBlID0gKHBhcmVudCwga2V5KSA9PiB7XG4gICAgICAgICAgaWYgKHBhcmVudFtrZXldLm5hbWUpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpICYmXG4gICAgICAgICAgICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEuZ2V0VHlwZShwYXJlbnRba2V5XS5uYW1lKSAhPT0gcGFyZW50W2tleV1cbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAvLyBUbyBhdm9pZCB1bnJlc29sdmVkIGZpZWxkIG9uIG92ZXJsb2FkZWQgc2NoZW1hXG4gICAgICAgICAgICAgIC8vIHJlcGxhY2UgdGhlIGZpbmFsIHR5cGUgd2l0aCB0aGUgYXV0byBzY2hlbWEgb25lXG4gICAgICAgICAgICAgIHBhcmVudFtrZXldID0gdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocGFyZW50W2tleV0ub2ZUeXBlKSB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUocGFyZW50W2tleV0sICdvZlR5cGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIWF1dG9HcmFwaFFMU2NoZW1hVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5fdHlwZU1hcFtjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXSA9IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChhdXRvR3JhcGhRTFNjaGVtYVR5cGUgJiYgdHlwZW9mIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyhjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5nZXRGaWVsZHMoKSkuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUoZmllbGQsICd0eXBlJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF1dG9HcmFwaFFMU2NoZW1hVHlwZS5fZmllbGRzID0ge1xuICAgICAgICAgICAgICAuLi5hdXRvR3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCksXG4gICAgICAgICAgICAgIC4uLmN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcygpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLCB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5ncmFwaFFMU2NoZW1hID0gYXdhaXQgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMoe1xuICAgICAgICAgIGRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYTogdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLFxuICAgICAgICAgIGF1dG9TY2hlbWE6IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEsXG4gICAgICAgICAgc3RpdGNoU2NoZW1hcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzRGVmaW5pdGlvbnMsXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLFxuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZU1hcCA9IHRoaXMuZ3JhcGhRTFNjaGVtYS5nZXRUeXBlTWFwKCk7XG4gICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZU1hcCkuZm9yRWFjaChncmFwaFFMU2NoZW1hVHlwZU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZSA9IGdyYXBoUUxTY2hlbWFUeXBlTWFwW2dyYXBoUUxTY2hlbWFUeXBlTmFtZV07XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZGVmaW5pdGlvbnNcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZ3JhcGhRTEN1c3RvbVR5cGVEZWYgPSB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5kZWZpbml0aW9ucy5maW5kKFxuICAgICAgICAgICAgZGVmaW5pdGlvbiA9PiBkZWZpbml0aW9uLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlTmFtZVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGdyYXBoUUxDdXN0b21UeXBlRGVmKSB7XG4gICAgICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwID0gZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCk7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwKS5mb3JFYWNoKGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCA9IGdyYXBoUUxTY2hlbWFUeXBlRmllbGRNYXBbZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoIWdyYXBoUUxTY2hlbWFUeXBlRmllbGQuYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzdE5vZGUgPSBncmFwaFFMQ3VzdG9tVHlwZURlZi5maWVsZHMuZmluZChcbiAgICAgICAgICAgICAgICAgIGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZC5hc3ROb2RlID0gYXN0Tm9kZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IudmlzaXRTY2hlbWFEaXJlY3RpdmVzKFxuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEsXG4gICAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgfVxuXG4gIGFkZEdyYXBoUUxUeXBlKHR5cGUsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSwgaWdub3JlQ29ubmVjdGlvbiA9IGZhbHNlKSB7XG4gICAgaWYgKFxuICAgICAgKCFpZ25vcmVSZXNlcnZlZCAmJiBSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMuaW5jbHVkZXModHlwZS5uYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTFR5cGVzLmZpbmQoZXhpc3RpbmdUeXBlID0+IGV4aXN0aW5nVHlwZS5uYW1lID09PSB0eXBlLm5hbWUpIHx8XG4gICAgICAoIWlnbm9yZUNvbm5lY3Rpb24gJiYgdHlwZS5uYW1lLmVuZHNXaXRoKCdDb25uZWN0aW9uJykpXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFR5cGUgJHt0eXBlLm5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBpdCBjb2xsaWRlZCB3aXRoIGFuIGV4aXN0aW5nIHR5cGUuYDtcbiAgICAgIGlmICh0aHJvd0Vycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLndhcm4obWVzc2FnZSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLmdyYXBoUUxUeXBlcy5wdXNoKHR5cGUpO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgYWRkR3JhcGhRTFF1ZXJ5KGZpZWxkTmFtZSwgZmllbGQsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSkge1xuICAgIGlmIChcbiAgICAgICghaWdub3JlUmVzZXJ2ZWQgJiYgUkVTRVJWRURfR1JBUEhRTF9RVUVSWV9OQU1FUy5pbmNsdWRlcyhmaWVsZE5hbWUpKSB8fFxuICAgICAgdGhpcy5ncmFwaFFMUXVlcmllc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFF1ZXJ5ICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTFF1ZXJpZXNbZmllbGROYW1lXSA9IGZpZWxkO1xuICAgIHJldHVybiBmaWVsZDtcbiAgfVxuXG4gIGFkZEdyYXBoUUxNdXRhdGlvbihmaWVsZE5hbWUsIGZpZWxkLCB0aHJvd0Vycm9yID0gZmFsc2UsIGlnbm9yZVJlc2VydmVkID0gZmFsc2UpIHtcbiAgICBpZiAoXG4gICAgICAoIWlnbm9yZVJlc2VydmVkICYmIFJFU0VSVkVEX0dSQVBIUUxfTVVUQVRJT05fTkFNRVMuaW5jbHVkZXMoZmllbGROYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYE11dGF0aW9uICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdID0gZmllbGQ7XG4gICAgcmV0dXJuIGZpZWxkO1xuICB9XG5cbiAgaGFuZGxlRXJyb3IoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoJ1BhcnNlIGVycm9yOiAnLCBlcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKCdVbmNhdWdodCBpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJywgZXJyb3IsIGVycm9yLnN0YWNrKTtcbiAgICB9XG4gICAgdGhyb3cgdG9HcmFwaFFMRXJyb3IoZXJyb3IpO1xuICB9XG5cbiAgYXN5bmMgX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKSB7XG4gICAgY29uc3QgW3NjaGVtYUNvbnRyb2xsZXIsIHBhcnNlR3JhcGhRTENvbmZpZ10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci5sb2FkU2NoZW1hKCksXG4gICAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIuZ2V0R3JhcGhRTENvbmZpZygpLFxuICAgIF0pO1xuXG4gICAgdGhpcy5zY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB7XG4gICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFsbCBjbGFzc2VzIGZvdW5kIGJ5IHRoZSBgc2NoZW1hQ29udHJvbGxlcmBcbiAgICogbWludXMgdGhvc2UgZmlsdGVyZWQgb3V0IGJ5IHRoZSBhcHAncyBwYXJzZUdyYXBoUUxDb25maWcuXG4gICAqL1xuICBhc3luYyBfZ2V0Q2xhc3Nlc0ZvclNjaGVtYShwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZykge1xuICAgIGNvbnN0IHsgZW5hYmxlZEZvckNsYXNzZXMsIGRpc2FibGVkRm9yQ2xhc3NlcyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuICAgIGNvbnN0IGFsbENsYXNzZXMgPSBhd2FpdCB0aGlzLnNjaGVtYUNvbnRyb2xsZXIuZ2V0QWxsQ2xhc3NlcygpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZW5hYmxlZEZvckNsYXNzZXMpIHx8IEFycmF5LmlzQXJyYXkoZGlzYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgbGV0IGluY2x1ZGVkQ2xhc3NlcyA9IGFsbENsYXNzZXM7XG4gICAgICBpZiAoZW5hYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgaW5jbHVkZWRDbGFzc2VzID0gYWxsQ2xhc3Nlcy5maWx0ZXIoY2xhenogPT4ge1xuICAgICAgICAgIHJldHVybiBlbmFibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChkaXNhYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgLy8gQ2xhc3NlcyBpbmNsdWRlZCBpbiBgZW5hYmxlZEZvckNsYXNzZXNgIHRoYXRcbiAgICAgICAgLy8gYXJlIGFsc28gcHJlc2VudCBpbiBgZGlzYWJsZWRGb3JDbGFzc2VzYCB3aWxsXG4gICAgICAgIC8vIHN0aWxsIGJlIGZpbHRlcmVkIG91dFxuICAgICAgICBpbmNsdWRlZENsYXNzZXMgPSBpbmNsdWRlZENsYXNzZXMuZmlsdGVyKGNsYXp6ID0+IHtcbiAgICAgICAgICByZXR1cm4gIWRpc2FibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc1VzZXJzQ2xhc3NEaXNhYmxlZCA9ICFpbmNsdWRlZENsYXNzZXMuc29tZShjbGF6eiA9PiB7XG4gICAgICAgIHJldHVybiBjbGF6ei5jbGFzc05hbWUgPT09ICdfVXNlcic7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGluY2x1ZGVkQ2xhc3NlcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFsbENsYXNzZXM7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBsaXN0IG9mIHR1cGxlc1xuICAgKiB0aGF0IHByb3ZpZGUgdGhlIHBhcnNlQ2xhc3MgYWxvbmcgd2l0aFxuICAgKiBpdHMgcGFyc2VDbGFzc0NvbmZpZyB3aGVyZSBwcm92aWRlZC5cbiAgICovXG4gIF9nZXRQYXJzZUNsYXNzZXNXaXRoQ29uZmlnKHBhcnNlQ2xhc3NlcywgcGFyc2VHcmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpIHtcbiAgICBjb25zdCB7IGNsYXNzQ29uZmlncyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuXG4gICAgLy8gTWFrZSBzdXJlcyB0aGF0IHRoZSBkZWZhdWx0IGNsYXNzZXMgYW5kIGNsYXNzZXMgdGhhdFxuICAgIC8vIHN0YXJ0cyB3aXRoIGNhcGl0YWxpemVkIGxldHRlciB3aWxsIGJlIGdlbmVyYXRlZCBmaXJzdC5cbiAgICBjb25zdCBzb3J0Q2xhc3NlcyA9IChhLCBiKSA9PiB7XG4gICAgICBhID0gYS5jbGFzc05hbWU7XG4gICAgICBiID0gYi5jbGFzc05hbWU7XG4gICAgICBpZiAoYVswXSA9PT0gJ18nKSB7XG4gICAgICAgIGlmIChiWzBdICE9PSAnXycpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChiWzBdID09PSAnXycpIHtcbiAgICAgICAgaWYgKGFbMF0gIT09ICdfJykge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0gZWxzZSBpZiAoYSA8IGIpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBwYXJzZUNsYXNzZXMuc29ydChzb3J0Q2xhc3NlcykubWFwKHBhcnNlQ2xhc3MgPT4ge1xuICAgICAgbGV0IHBhcnNlQ2xhc3NDb25maWc7XG4gICAgICBpZiAoY2xhc3NDb25maWdzKSB7XG4gICAgICAgIHBhcnNlQ2xhc3NDb25maWcgPSBjbGFzc0NvbmZpZ3MuZmluZChjID0+IGMuY2xhc3NOYW1lID09PSBwYXJzZUNsYXNzLmNsYXNzTmFtZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW3BhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWddO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgX2dldEZ1bmN0aW9uTmFtZXMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IGdldEZ1bmN0aW9uTmFtZXModGhpcy5hcHBJZCkuZmlsdGVyKGZ1bmN0aW9uTmFtZSA9PiB7XG4gICAgICBpZiAoL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8udGVzdChmdW5jdGlvbk5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2cud2FybihcbiAgICAgICAgICBgRnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBHcmFwaFFMIG5hbWVzIG11c3QgbWF0Y2ggL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8uYFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBjaGFuZ2VzIHRvIHRoZSBwYXJzZUNsYXNzZXNcbiAgICogb2JqZWN0cyAoaS5lLiBkYXRhYmFzZSBzY2hlbWEpIG9yIHRvXG4gICAqIHRoZSBwYXJzZUdyYXBoUUxDb25maWcgb2JqZWN0LiBJZiBub1xuICAgKiBjaGFuZ2VzIGFyZSBmb3VuZCwgcmV0dXJuIHRydWU7XG4gICAqL1xuICBfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkKHBhcmFtczoge1xuICAgIHBhcnNlQ2xhc3NlczogYW55LFxuICAgIHBhcnNlQ2xhc3Nlc1N0cmluZzogc3RyaW5nLFxuICAgIHBhcnNlR3JhcGhRTENvbmZpZzogP1BhcnNlR3JhcGhRTENvbmZpZyxcbiAgICBmdW5jdGlvbk5hbWVzU3RyaW5nOiBzdHJpbmcsXG4gIH0pOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHBhcnNlQ2xhc3NlcywgcGFyc2VDbGFzc2VzU3RyaW5nLCBwYXJzZUdyYXBoUUxDb25maWcsIGZ1bmN0aW9uTmFtZXNTdHJpbmcgfSA9IHBhcmFtcztcblxuICAgIGlmIChcbiAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyc2VHcmFwaFFMQ29uZmlnKSA9PT0gSlNPTi5zdHJpbmdpZnkocGFyc2VHcmFwaFFMQ29uZmlnKSAmJlxuICAgICAgdGhpcy5mdW5jdGlvbk5hbWVzU3RyaW5nID09PSBmdW5jdGlvbk5hbWVzU3RyaW5nXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5wYXJzZUNsYXNzZXMgPT09IHBhcnNlQ2xhc3Nlcykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9PT0gcGFyc2VDbGFzc2VzU3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGFyc2VDbGFzc2VzID0gcGFyc2VDbGFzc2VzO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLServer.js b/lib/GraphQL/ParseGraphQLServer.js new file mode 100644 index 0000000000..3025e6ae74 --- /dev/null +++ b/lib/GraphQL/ParseGraphQLServer.js @@ -0,0 +1,140 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseGraphQLServer = void 0; + +var _cors = _interopRequireDefault(require("cors")); + +var _bodyParser = _interopRequireDefault(require("body-parser")); + +var _graphqlUpload = require("graphql-upload"); + +var _expressApollo = require("apollo-server-express/dist/expressApollo"); + +var _graphqlPlaygroundHtml = require("@apollographql/graphql-playground-html"); + +var _graphql = require("graphql"); + +var _subscriptionsTransportWs = require("subscriptions-transport-ws"); + +var _middlewares = require("../middlewares"); + +var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); + +var _logger = _interopRequireDefault(require("../logger")); + +var _ParseGraphQLSchema = require("./ParseGraphQLSchema"); + +var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseGraphQLServer { + constructor(parseServer, config) { + this.parseServer = parseServer || (0, _requiredParameter.default)('You must provide a parseServer instance!'); + + if (!config || !config.graphQLPath) { + (0, _requiredParameter.default)('You must provide a config.graphQLPath!'); + } + + this.config = config; + this.parseGraphQLController = this.parseServer.config.parseGraphQLController; + this.log = this.parseServer.config && this.parseServer.config.loggerController || _logger.default; + this.parseGraphQLSchema = new _ParseGraphQLSchema.ParseGraphQLSchema({ + parseGraphQLController: this.parseGraphQLController, + databaseController: this.parseServer.config.databaseController, + log: this.log, + graphQLCustomTypeDefs: this.config.graphQLCustomTypeDefs, + appId: this.parseServer.config.appId + }); + } + + async _getGraphQLOptions(req) { + try { + return { + schema: await this.parseGraphQLSchema.load(), + context: { + info: req.info, + config: req.config, + auth: req.auth + }, + formatError: error => { + // Allow to console.log here to debug + return error; + } + }; + } catch (e) { + this.log.error(e.stack || typeof e.toString === 'function' && e.toString() || e); + throw e; + } + } + + _transformMaxUploadSizeToBytes(maxUploadSize) { + const unitMap = { + kb: 1, + mb: 2, + gb: 3 + }; + return Number(maxUploadSize.slice(0, -2)) * Math.pow(1024, unitMap[maxUploadSize.slice(-2).toLowerCase()]); + } + + applyGraphQL(app) { + if (!app || !app.use) { + (0, _requiredParameter.default)('You must provide an Express.js app instance!'); + } + + app.use(this.config.graphQLPath, (0, _graphqlUpload.graphqlUploadExpress)({ + maxFileSize: this._transformMaxUploadSizeToBytes(this.parseServer.config.maxUploadSize || '20mb') + })); + app.use(this.config.graphQLPath, (0, _cors.default)()); + app.use(this.config.graphQLPath, _bodyParser.default.json()); + app.use(this.config.graphQLPath, _middlewares.handleParseHeaders); + app.use(this.config.graphQLPath, _middlewares.handleParseErrors); + app.use(this.config.graphQLPath, (0, _expressApollo.graphqlExpress)(async req => await this._getGraphQLOptions(req))); + } + + applyPlayground(app) { + if (!app || !app.get) { + (0, _requiredParameter.default)('You must provide an Express.js app instance!'); + } + + app.get(this.config.playgroundPath || (0, _requiredParameter.default)('You must provide a config.playgroundPath to applyPlayground!'), (_req, res) => { + res.setHeader('Content-Type', 'text/html'); + res.write((0, _graphqlPlaygroundHtml.renderPlaygroundPage)({ + endpoint: this.config.graphQLPath, + version: '1.7.25', + subscriptionEndpoint: this.config.subscriptionsPath, + headers: { + 'X-Parse-Application-Id': this.parseServer.config.appId, + 'X-Parse-Master-Key': this.parseServer.config.masterKey + } + })); + res.end(); + }); + } + + createSubscriptions(server) { + _subscriptionsTransportWs.SubscriptionServer.create({ + execute: _graphql.execute, + subscribe: _graphql.subscribe, + onOperation: async (_message, params, webSocket) => Object.assign({}, params, await this._getGraphQLOptions(webSocket.upgradeReq)) + }, { + server, + path: this.config.subscriptionsPath || (0, _requiredParameter.default)('You must provide a config.subscriptionsPath to createSubscriptions!') + }); + } + + setGraphQLConfig(graphQLConfig) { + return this.parseGraphQLController.updateGraphQLConfig(graphQLConfig); + } + +} + +exports.ParseGraphQLServer = ParseGraphQLServer; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlci5qcyJdLCJuYW1lcyI6WyJQYXJzZUdyYXBoUUxTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInBhcnNlU2VydmVyIiwiY29uZmlnIiwiZ3JhcGhRTFBhdGgiLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImRlZmF1bHRMb2dnZXIiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJQYXJzZUdyYXBoUUxTY2hlbWEiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJncmFwaFFMQ3VzdG9tVHlwZURlZnMiLCJhcHBJZCIsIl9nZXRHcmFwaFFMT3B0aW9ucyIsInJlcSIsInNjaGVtYSIsImxvYWQiLCJjb250ZXh0IiwiaW5mbyIsImF1dGgiLCJmb3JtYXRFcnJvciIsImVycm9yIiwiZSIsInN0YWNrIiwidG9TdHJpbmciLCJfdHJhbnNmb3JtTWF4VXBsb2FkU2l6ZVRvQnl0ZXMiLCJtYXhVcGxvYWRTaXplIiwidW5pdE1hcCIsImtiIiwibWIiLCJnYiIsIk51bWJlciIsInNsaWNlIiwiTWF0aCIsInBvdyIsInRvTG93ZXJDYXNlIiwiYXBwbHlHcmFwaFFMIiwiYXBwIiwidXNlIiwibWF4RmlsZVNpemUiLCJib2R5UGFyc2VyIiwianNvbiIsImhhbmRsZVBhcnNlSGVhZGVycyIsImhhbmRsZVBhcnNlRXJyb3JzIiwiYXBwbHlQbGF5Z3JvdW5kIiwiZ2V0IiwicGxheWdyb3VuZFBhdGgiLCJfcmVxIiwicmVzIiwic2V0SGVhZGVyIiwid3JpdGUiLCJlbmRwb2ludCIsInZlcnNpb24iLCJzdWJzY3JpcHRpb25FbmRwb2ludCIsInN1YnNjcmlwdGlvbnNQYXRoIiwiaGVhZGVycyIsIm1hc3RlcktleSIsImVuZCIsImNyZWF0ZVN1YnNjcmlwdGlvbnMiLCJzZXJ2ZXIiLCJTdWJzY3JpcHRpb25TZXJ2ZXIiLCJjcmVhdGUiLCJleGVjdXRlIiwic3Vic2NyaWJlIiwib25PcGVyYXRpb24iLCJfbWVzc2FnZSIsInBhcmFtcyIsIndlYlNvY2tldCIsIk9iamVjdCIsImFzc2lnbiIsInVwZ3JhZGVSZXEiLCJwYXRoIiwic2V0R3JhcGhRTENvbmZpZyIsImdyYXBoUUxDb25maWciLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsa0JBQU4sQ0FBeUI7QUFHdkJDLEVBQUFBLFdBQVcsQ0FBQ0MsV0FBRCxFQUFjQyxNQUFkLEVBQXNCO0FBQy9CLFNBQUtELFdBQUwsR0FBbUJBLFdBQVcsSUFBSSxnQ0FBa0IsMENBQWxCLENBQWxDOztBQUNBLFFBQUksQ0FBQ0MsTUFBRCxJQUFXLENBQUNBLE1BQU0sQ0FBQ0MsV0FBdkIsRUFBb0M7QUFDbEMsc0NBQWtCLHdDQUFsQjtBQUNEOztBQUNELFNBQUtELE1BQUwsR0FBY0EsTUFBZDtBQUNBLFNBQUtFLHNCQUFMLEdBQThCLEtBQUtILFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdCRSxzQkFBdEQ7QUFDQSxTQUFLQyxHQUFMLEdBQ0csS0FBS0osV0FBTCxDQUFpQkMsTUFBakIsSUFBMkIsS0FBS0QsV0FBTCxDQUFpQkMsTUFBakIsQ0FBd0JJLGdCQUFwRCxJQUF5RUMsZUFEM0U7QUFFQSxTQUFLQyxrQkFBTCxHQUEwQixJQUFJQyxzQ0FBSixDQUF1QjtBQUMvQ0wsTUFBQUEsc0JBQXNCLEVBQUUsS0FBS0Esc0JBRGtCO0FBRS9DTSxNQUFBQSxrQkFBa0IsRUFBRSxLQUFLVCxXQUFMLENBQWlCQyxNQUFqQixDQUF3QlEsa0JBRkc7QUFHL0NMLE1BQUFBLEdBQUcsRUFBRSxLQUFLQSxHQUhxQztBQUkvQ00sTUFBQUEscUJBQXFCLEVBQUUsS0FBS1QsTUFBTCxDQUFZUyxxQkFKWTtBQUsvQ0MsTUFBQUEsS0FBSyxFQUFFLEtBQUtYLFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdC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QixDQUFnREQsYUFBaEQsQ0FBUDtBQUNEOztBQXpIc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29yc01pZGRsZXdhcmUgZnJvbSAnY29ycyc7XG5pbXBvcnQgYm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQgeyBncmFwaHFsVXBsb2FkRXhwcmVzcyB9IGZyb20gJ2dyYXBocWwtdXBsb2FkJztcbmltcG9ydCB7IGdyYXBocWxFeHByZXNzIH0gZnJvbSAnYXBvbGxvLXNlcnZlci1leHByZXNzL2Rpc3QvZXhwcmVzc0Fwb2xsbyc7XG5pbXBvcnQgeyByZW5kZXJQbGF5Z3JvdW5kUGFnZSB9IGZyb20gJ0BhcG9sbG9ncmFwaHFsL2dyYXBocWwtcGxheWdyb3VuZC1odG1sJztcbmltcG9ydCB7IGV4ZWN1dGUsIHN1YnNjcmliZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uU2VydmVyIH0gZnJvbSAnc3Vic2NyaXB0aW9ucy10cmFuc3BvcnQtd3MnO1xuaW1wb3J0IHsgaGFuZGxlUGFyc2VFcnJvcnMsIGhhbmRsZVBhcnNlSGVhZGVycyB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuLi9yZXF1aXJlZFBhcmFtZXRlcic7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH0gZnJvbSAnLi9QYXJzZUdyYXBoUUxTY2hlbWEnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNlcnZlciB7XG4gIHBhcnNlR3JhcGhRTENvbnRyb2xsZXI6IFBhcnNlR3JhcGhRTENvbnRyb2xsZXI7XG5cbiAgY29uc3RydWN0b3IocGFyc2VTZXJ2ZXIsIGNvbmZpZykge1xuICAgIHRoaXMucGFyc2VTZXJ2ZXIgPSBwYXJzZVNlcnZlciB8fCByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlU2VydmVyIGluc3RhbmNlIScpO1xuICAgIGlmICghY29uZmlnIHx8ICFjb25maWcuZ3JhcGhRTFBhdGgpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgY29uZmlnLmdyYXBoUUxQYXRoIScpO1xuICAgIH1cbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICAgIHRoaXMubG9nID1cbiAgICAgICh0aGlzLnBhcnNlU2VydmVyLmNvbmZpZyAmJiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB8fCBkZWZhdWx0TG9nZ2VyO1xuICAgIHRoaXMucGFyc2VHcmFwaFFMU2NoZW1hID0gbmV3IFBhcnNlR3JhcGhRTFNjaGVtYSh7XG4gICAgICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIsXG4gICAgICBkYXRhYmFzZUNvbnRyb2xsZXI6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLmRhdGFiYXNlQ29udHJvbGxlcixcbiAgICAgIGxvZzogdGhpcy5sb2csXG4gICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnM6IHRoaXMuY29uZmlnLmdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIGFwcElkOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIF9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2NoZW1hOiBhd2FpdCB0aGlzLnBhcnNlR3JhcGhRTFNjaGVtYS5sb2FkKCksXG4gICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICBpbmZvOiByZXEuaW5mbyxcbiAgICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgICAgYXV0aDogcmVxLmF1dGgsXG4gICAgICAgIH0sXG4gICAgICAgIGZvcm1hdEVycm9yOiBlcnJvciA9PiB7XG4gICAgICAgICAgLy8gQWxsb3cgdG8gY29uc29sZS5sb2cgaGVyZSB0byBkZWJ1Z1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoZS5zdGFjayB8fCAodHlwZW9mIGUudG9TdHJpbmcgPT09ICdmdW5jdGlvbicgJiYgZS50b1N0cmluZygpKSB8fCBlKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKG1heFVwbG9hZFNpemUpIHtcbiAgICBjb25zdCB1bml0TWFwID0ge1xuICAgICAga2I6IDEsXG4gICAgICBtYjogMixcbiAgICAgIGdiOiAzLFxuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgTnVtYmVyKG1heFVwbG9hZFNpemUuc2xpY2UoMCwgLTIpKSAqXG4gICAgICBNYXRoLnBvdygxMDI0LCB1bml0TWFwW21heFVwbG9hZFNpemUuc2xpY2UoLTIpLnRvTG93ZXJDYXNlKCldKVxuICAgICk7XG4gIH1cblxuICBhcHBseUdyYXBoUUwoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC51c2UpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cblxuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxVcGxvYWRFeHByZXNzKHtcbiAgICAgICAgbWF4RmlsZVNpemU6IHRoaXMuX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKFxuICAgICAgICAgIHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1heFVwbG9hZFNpemUgfHwgJzIwbWInXG4gICAgICAgICksXG4gICAgICB9KVxuICAgICk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgY29yc01pZGRsZXdhcmUoKSk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgYm9keVBhcnNlci5qc29uKCkpO1xuICAgIGFwcC51c2UodGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsIGhhbmRsZVBhcnNlSGVhZGVycyk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgaGFuZGxlUGFyc2VFcnJvcnMpO1xuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxFeHByZXNzKGFzeW5jIHJlcSA9PiBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpKVxuICAgICk7XG4gIH1cblxuICBhcHBseVBsYXlncm91bmQoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC5nZXQpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cbiAgICBhcHAuZ2V0KFxuICAgICAgdGhpcy5jb25maWcucGxheWdyb3VuZFBhdGggfHxcbiAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcucGxheWdyb3VuZFBhdGggdG8gYXBwbHlQbGF5Z3JvdW5kIScpLFxuICAgICAgKF9yZXEsIHJlcykgPT4ge1xuICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgIHJlcy53cml0ZShcbiAgICAgICAgICByZW5kZXJQbGF5Z3JvdW5kUGFnZSh7XG4gICAgICAgICAgICBlbmRwb2ludDogdGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS43LjI1JyxcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbkVuZHBvaW50OiB0aGlzLmNvbmZpZy5zdWJzY3JpcHRpb25zUGF0aCxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtTWFzdGVyLUtleSc6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1hc3RlcktleSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBjcmVhdGVTdWJzY3JpcHRpb25zKHNlcnZlcikge1xuICAgIFN1YnNjcmlwdGlvblNlcnZlci5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIGV4ZWN1dGUsXG4gICAgICAgIHN1YnNjcmliZSxcbiAgICAgICAgb25PcGVyYXRpb246IGFzeW5jIChfbWVzc2FnZSwgcGFyYW1zLCB3ZWJTb2NrZXQpID0+XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgcGFyYW1zLCBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyh3ZWJTb2NrZXQudXBncmFkZVJlcSkpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBwYXRoOlxuICAgICAgICAgIHRoaXMuY29uZmlnLnN1YnNjcmlwdGlvbnNQYXRoIHx8XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcuc3Vic2NyaXB0aW9uc1BhdGggdG8gY3JlYXRlU3Vic2NyaXB0aW9ucyEnKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgc2V0R3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpOiBQcm9taXNlIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZyk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsMutations.js b/lib/GraphQL/helpers/objectsMutations.js new file mode 100644 index 0000000000..4d10d2fb4a --- /dev/null +++ b/lib/GraphQL/helpers/objectsMutations.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.deleteObject = exports.updateObject = exports.createObject = void 0; + +var _rest = _interopRequireDefault(require("../../rest")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const createObject = async (className, fields, config, auth, info) => { + if (!fields) { + fields = {}; + } + + return (await _rest.default.create(config, auth, className, fields, info.clientSDK, info.context)).response; +}; + +exports.createObject = createObject; + +const updateObject = async (className, objectId, fields, config, auth, info) => { + if (!fields) { + fields = {}; + } + + return (await _rest.default.update(config, auth, className, { + objectId + }, fields, info.clientSDK, info.context)).response; +}; + +exports.updateObject = updateObject; + +const deleteObject = async (className, objectId, config, auth, info) => { + await _rest.default.del(config, auth, className, objectId, info.context); + return true; +}; + +exports.deleteObject = deleteObject; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJjcmVhdGVPYmplY3QiLCJjbGFzc05hbWUiLCJmaWVsZHMiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInJlc3QiLCJjcmVhdGUiLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzcG9uc2UiLCJ1cGRhdGVPYmplY3QiLCJvYmplY3RJZCIsInVwZGF0ZSIsImRlbGV0ZU9iamVjdCIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsTUFBTUEsWUFBWSxHQUFHLE9BQU9DLFNBQVAsRUFBa0JDLE1BQWxCLEVBQTBCQyxNQUExQixFQUFrQ0MsSUFBbEMsRUFBd0NDLElBQXhDLEtBQWlEO0FBQ3BFLE1BQUksQ0FBQ0gsTUFBTCxFQUFhO0FBQ1hBLElBQUFBLE1BQU0sR0FBRyxFQUFUO0FBQ0Q7O0FBRUQsU0FBTyxDQUNMLE1BQU1JLGNBQUtDLE1BQUwsQ0FDSkosTUFESSxFQUVKQyxJQUZJLEVBR0pILFNBSEksRUFJSkMsTUFKSSxFQUtKRyxJQUFJLENBQUNHLFNBTEQsRUFNSkgsSUFBSSxDQUFDSSxPQU5ELENBREQsRUFTTEMsUUFURjtBQVVELENBZkQ7Ozs7QUFpQkEsTUFBTUMsWUFBWSxHQUFHLE9BQ25CVixTQURtQixFQUVuQlcsUUFGbUIsRUFHbkJWLE1BSG1CLEVBSW5CQyxNQUptQixFQUtuQkMsSUFMbUIsRUFNbkJDLElBTm1CLEtBT2hCO0FBQ0gsTUFBSSxDQUFDSCxNQUFMLEVBQWE7QUFDWEEsSUFBQUEsTUFBTSxHQUFHLEVBQVQ7QUFDRDs7QUFFRCxTQUFPLENBQ0wsTUFBTUksY0FBS08sTUFBTCxDQUNKVixNQURJLEVBRUpDLElBRkksRUFHSkgsU0FISSxFQUlKO0FBQUVXLElBQUFBO0FBQUYsR0FKSSxFQUtKVixNQUxJLEVBTUpHLElBQUksQ0FBQ0csU0FORCxFQU9KSCxJQUFJLENBQUNJLE9BUEQsQ0FERCxFQVVMQyxRQVZGO0FBV0QsQ0F2QkQ7Ozs7QUF5QkEsTUFBTUksWUFBWSxHQUFHLE9BQU9iLFNBQVAsRUFBa0JXLFFBQWxCLEVBQTRCVCxNQUE1QixFQUFvQ0MsSUFBcEMsRUFBMENDLElBQTFDLEtBQW1EO0FBQ3RFLFFBQU1DLGNBQUtTLEdBQUwsQ0FBU1osTUFBVCxFQUFpQkMsSUFBakIsRUFBdUJILFNBQXZCLEVBQWtDVyxRQUFsQyxFQUE0Q1AsSUFBSSxDQUFDSSxPQUFqRCxDQUFOO0FBQ0EsU0FBTyxJQUFQO0FBQ0QsQ0FIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuXG5jb25zdCBjcmVhdGVPYmplY3QgPSBhc3luYyAoY2xhc3NOYW1lLCBmaWVsZHMsIGNvbmZpZywgYXV0aCwgaW5mbykgPT4ge1xuICBpZiAoIWZpZWxkcykge1xuICAgIGZpZWxkcyA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICBhd2FpdCByZXN0LmNyZWF0ZShcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBmaWVsZHMsXG4gICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgIGluZm8uY29udGV4dFxuICAgIClcbiAgKS5yZXNwb25zZTtcbn07XG5cbmNvbnN0IHVwZGF0ZU9iamVjdCA9IGFzeW5jIChcbiAgY2xhc3NOYW1lLFxuICBvYmplY3RJZCxcbiAgZmllbGRzLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm9cbikgPT4ge1xuICBpZiAoIWZpZWxkcykge1xuICAgIGZpZWxkcyA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICBhd2FpdCByZXN0LnVwZGF0ZShcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB7IG9iamVjdElkIH0sXG4gICAgICBmaWVsZHMsXG4gICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgIGluZm8uY29udGV4dFxuICAgIClcbiAgKS5yZXNwb25zZTtcbn07XG5cbmNvbnN0IGRlbGV0ZU9iamVjdCA9IGFzeW5jIChjbGFzc05hbWUsIG9iamVjdElkLCBjb25maWcsIGF1dGgsIGluZm8pID0+IHtcbiAgYXdhaXQgcmVzdC5kZWwoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCBpbmZvLmNvbnRleHQpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmV4cG9ydCB7IGNyZWF0ZU9iamVjdCwgdXBkYXRlT2JqZWN0LCBkZWxldGVPYmplY3QgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsQueries.js b/lib/GraphQL/helpers/objectsQueries.js new file mode 100644 index 0000000000..b62de58245 --- /dev/null +++ b/lib/GraphQL/helpers/objectsQueries.js @@ -0,0 +1,307 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.needToGetAllKeys = exports.calculateSkipAndLimit = exports.findObjects = exports.getObject = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphqlRelay = require("graphql-relay"); + +var _rest = _interopRequireDefault(require("../../rest")); + +var _query = require("../transformers/query"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Eslint/Prettier conflict + +/* eslint-disable*/ +const needToGetAllKeys = (fields, keys, parseClasses) => keys ? keys.split(',').some(keyName => { + const key = keyName.split('.'); + + if (fields[key[0]]) { + if (fields[key[0]].type === 'Pointer') { + const subClass = parseClasses.find(({ + className: parseClassName + }) => fields[key[0]].targetClass === parseClassName); + + if (subClass && subClass.fields[key[1]]) { + // Current sub key is not custom + return false; + } + } else if (!key[1] || fields[key[0]].type === 'Array' || fields[key[0]].type === 'Object') { + // current key is not custom + return false; + } + } // Key not found into Parse Schema so it's custom + + + return true; +}) : true; +/* eslint-enable*/ + + +exports.needToGetAllKeys = needToGetAllKeys; + +const getObject = async (className, objectId, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses) => { + const options = {}; + + try { + if (!needToGetAllKeys(parseClasses.find(({ + className: parseClassName + }) => className === parseClassName).fields, keys, parseClasses)) { + options.keys = keys; + } + } catch (e) { + console.log(e); + } + + if (include) { + options.include = include; + + if (includeReadPreference) { + options.includeReadPreference = includeReadPreference; + } + } + + if (readPreference) { + options.readPreference = readPreference; + } + + const response = await _rest.default.get(config, auth, className, objectId, options, info.clientSDK, info.context); + + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + const object = response.results[0]; + + if (className === '_User') { + delete object.sessionToken; + } + + return object; +}; + +exports.getObject = getObject; + +const findObjects = async (className, where, order, skipInput, first, after, last, before, keys, include, includeAll, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseClasses) => { + if (!where) { + where = {}; + } + + (0, _query.transformQueryInputToParse)(where, className, parseClasses); + const skipAndLimitCalculation = calculateSkipAndLimit(skipInput, first, after, last, before, config.maxLimit); + let { + skip + } = skipAndLimitCalculation; + const { + limit, + needToPreCount + } = skipAndLimitCalculation; + let preCount = undefined; + + if (needToPreCount) { + const preCountOptions = { + limit: 0, + count: true + }; + + if (readPreference) { + preCountOptions.readPreference = readPreference; + } + + if (Object.keys(where).length > 0 && subqueryReadPreference) { + preCountOptions.subqueryReadPreference = subqueryReadPreference; + } + + preCount = (await _rest.default.find(config, auth, className, where, preCountOptions, info.clientSDK, info.context)).count; + + if ((skip || 0) + limit < preCount) { + skip = preCount - limit; + } + } + + const options = {}; + + if (selectedFields.find(field => field.startsWith('edges.') || field.startsWith('pageInfo.'))) { + if (limit || limit === 0) { + options.limit = limit; + } else { + options.limit = 100; + } + + if (options.limit !== 0) { + if (order) { + options.order = order; + } + + if (skip) { + options.skip = skip; + } + + if (config.maxLimit && options.limit > config.maxLimit) { + // Silently replace the limit on the query with the max configured + options.limit = config.maxLimit; + } + + if (!needToGetAllKeys(parseClasses.find(({ + className: parseClassName + }) => className === parseClassName).fields, keys, parseClasses)) { + options.keys = keys; + } + + if (includeAll === true) { + options.includeAll = includeAll; + } + + if (!options.includeAll && include) { + options.include = include; + } + + if ((options.includeAll || options.include) && includeReadPreference) { + options.includeReadPreference = includeReadPreference; + } + } + } else { + options.limit = 0; + } + + if ((selectedFields.includes('count') || selectedFields.includes('pageInfo.hasPreviousPage') || selectedFields.includes('pageInfo.hasNextPage')) && !needToPreCount) { + options.count = true; + } + + if (readPreference) { + options.readPreference = readPreference; + } + + if (Object.keys(where).length > 0 && subqueryReadPreference) { + options.subqueryReadPreference = subqueryReadPreference; + } + + let results, count; + + if (options.count || !options.limit || options.limit && options.limit > 0) { + const findResult = await _rest.default.find(config, auth, className, where, options, info.clientSDK, info.context); + results = findResult.results; + count = findResult.count; + } + + let edges = null; + let pageInfo = null; + + if (results) { + edges = results.map((result, index) => ({ + cursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + index), + node: result + })); + pageInfo = { + hasPreviousPage: (preCount && preCount > 0 || count && count > 0) && skip !== undefined && skip > 0, + startCursor: (0, _graphqlRelay.offsetToCursor)(skip || 0), + endCursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + (results.length || 1) - 1), + hasNextPage: (preCount || count) > (skip || 0) + results.length + }; + } + + return { + edges, + pageInfo, + count: preCount || count + }; +}; + +exports.findObjects = findObjects; + +const calculateSkipAndLimit = (skipInput, first, after, last, before, maxLimit) => { + let skip = undefined; + let limit = undefined; + let needToPreCount = false; // Validates the skip input + + if (skipInput || skipInput === 0) { + if (skipInput < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Skip should be a positive number'); + } + + skip = skipInput; + } // Validates the after param + + + if (after) { + after = (0, _graphqlRelay.cursorToOffset)(after); + + if (!after && after !== 0 || after < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'After is not a valid cursor'); + } // If skip and after are passed, a new skip is calculated by adding them + + + skip = (skip || 0) + (after + 1); + } // Validates the first param + + + if (first || first === 0) { + if (first < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'First should be a positive number'); + } // The first param is translated to the limit param of the Parse legacy API + + + limit = first; + } // Validates the before param + + + if (before || before === 0) { + // This method converts the cursor to the index of the object + before = (0, _graphqlRelay.cursorToOffset)(before); + + if (!before && before !== 0 || before < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Before is not a valid cursor'); + } + + if ((skip || 0) >= before) { + // If the before index is less then the skip, no objects will be returned + limit = 0; + } else if (!limit && limit !== 0 || (skip || 0) + limit > before) { + // If there is no limit set, the limit is calculated. Or, if the limit (plus skip) is bigger than the before index, the new limit is set. + limit = before - (skip || 0); + } + } // Validates the last param + + + if (last || last === 0) { + if (last < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Last should be a positive number'); + } + + if (last > maxLimit) { + // Last can't be bigger than Parse server maxLimit config. + last = maxLimit; + } + + if (limit || limit === 0) { + // If there is a previous limit set, it may be adjusted + if (last < limit) { + // if last is less than the current limit + skip = (skip || 0) + (limit - last); // The skip is adjusted + + limit = last; // the limit is adjusted + } + } else if (last === 0) { + // No objects will be returned + limit = 0; + } else { + // No previous limit set, the limit will be equal to last and pre count is needed. + limit = last; + needToPreCount = true; + } + } + + return { + skip, + limit, + needToPreCount + }; +}; + +exports.calculateSkipAndLimit = calculateSkipAndLimit; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMuanMiXSwibmFtZXMiOlsibmVlZFRvR2V0QWxsS2V5cyIsImZpZWxkcyIsImtleXMiLCJwYXJzZUNsYXNzZXMiLCJzcGxpdCIsInNvbWUiLCJrZXlOYW1lIiwia2V5IiwidHlwZSIsInN1YkNsYXNzIiwiZmluZCIsImNsYXNzTmFtZSIsInBhcnNlQ2xhc3NOYW1lIiwidGFyZ2V0Q2xhc3MiLCJnZXRPYmplY3QiLCJvYmplY3RJZCIsImluY2x1ZGUiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwib3B0aW9ucyIsImUiLCJjb25zb2xlIiwibG9nIiwicmVzcG9uc2UiLCJyZXN0IiwiZ2V0IiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIm9iamVjdCIsInNlc3Npb25Ub2tlbiIsImZpbmRPYmplY3RzIiwid2hlcmUiLCJvcmRlciIsInNraXBJbnB1dCIsImZpcnN0IiwiYWZ0ZXIiLCJsYXN0IiwiYmVmb3JlIiwiaW5jbHVkZUFsbCIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJzZWxlY3RlZEZpZWxkcyIsInNraXBBbmRMaW1pdENhbGN1bGF0aW9uIiwiY2FsY3VsYXRlU2tpcEFuZExpbWl0IiwibWF4TGltaXQiLCJza2lwIiwibGltaXQiLCJuZWVkVG9QcmVDb3VudCIsInByZUNvdW50IiwidW5kZWZpbmVkIiwicHJlQ291bnRPcHRpb25zIiwiY291bnQiLCJPYmplY3QiLCJmaWVsZCIsInN0YXJ0c1dpdGgiLCJpbmNsdWRlcyIsImZpbmRSZXN1bHQiLCJlZGdlcyIsInBhZ2VJbmZvIiwibWFwIiwicmVzdWx0IiwiaW5kZXgiLCJjdXJzb3IiLCJub2RlIiwiaGFzUHJldmlvdXNQYWdlIiwic3RhcnRDdXJzb3IiLCJl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Q0YsS0FQRCxNQU9PLElBQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ3JCO0FBQ0FTLE1BQUFBLEtBQUssR0FBRyxDQUFSO0FBQ0QsS0FITSxNQUdBO0FBQ0w7QUFDQUEsTUFBQUEsS0FBSyxHQUFHVCxJQUFSO0FBQ0FVLE1BQUFBLGNBQWMsR0FBRyxJQUFqQjtBQUNEO0FBQ0Y7O0FBQ0QsU0FBTztBQUNMRixJQUFBQSxJQURLO0FBRUxDLElBQUFBLEtBRks7QUFHTEMsSUFBQUE7QUFISyxHQUFQO0FBS0QsQ0F6R0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBvZmZzZXRUb0N1cnNvciwgY3Vyc29yVG9PZmZzZXQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuaW1wb3J0IHsgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvcXVlcnknO1xuXG4vLyBFc2xpbnQvUHJldHRpZXIgY29uZmxpY3Rcbi8qIGVzbGludC1kaXNhYmxlKi9cbmNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSAoZmllbGRzLCBrZXlzLCBwYXJzZUNsYXNzZXMpID0+XG4gIGtleXNcbiAgICA/IGtleXMuc3BsaXQoJywnKS5zb21lKGtleU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlOYW1lLnNwbGl0KCcuJyk7XG4gICAgICAgIGlmIChmaWVsZHNba2V5WzBdXSkge1xuICAgICAgICAgIGlmIChmaWVsZHNba2V5WzBdXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1YkNsYXNzID0gcGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgICAgICAgICAgICh7IGNsYXNzTmFtZTogcGFyc2VDbGFzc05hbWUgfSkgPT5cbiAgICAgICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50YXJnZXRDbGFzcyA9PT0gcGFyc2VDbGFzc05hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoc3ViQ2xhc3MgJiYgc3ViQ2xhc3MuZmllbGRzW2tleVsxXV0pIHtcbiAgICAgICAgICAgICAgLy8gQ3VycmVudCBzdWIga2V5IGlzIG5vdCBjdXN0b21cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAha2V5WzFdIHx8XG4gICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50eXBlID09PSAnQXJyYXknIHx8XG4gICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50eXBlID09PSAnT2JqZWN0J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gY3VycmVudCBrZXkgaXMgbm90IGN1c3RvbVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBLZXkgbm90IGZvdW5kIGludG8gUGFyc2UgU2NoZW1hIHNvIGl0J3MgY3VzdG9tXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSlcbiAgICA6IHRydWU7XG4vKiBlc2xpbnQtZW5hYmxlKi9cblxuY29uc3QgZ2V0T2JqZWN0ID0gYXN5bmMgKFxuICBjbGFzc05hbWUsXG4gIG9iamVjdElkLFxuICBrZXlzLFxuICBpbmNsdWRlLFxuICByZWFkUHJlZmVyZW5jZSxcbiAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm8sXG4gIHBhcnNlQ2xhc3Nlc1xuKSA9PiB7XG4gIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgdHJ5IHtcbiAgICBpZiAoXG4gICAgICAhbmVlZFRvR2V0QWxsS2V5cyhcbiAgICAgICAgcGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgICAgICAgKHsgY2xhc3NOYW1lOiBwYXJzZUNsYXNzTmFtZSB9KSA9PiBjbGFzc05hbWUgPT09IHBhcnNlQ2xhc3NOYW1lXG4gICAgICAgICkuZmllbGRzLFxuICAgICAgICBrZXlzLFxuICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgIClcbiAgICApIHtcbiAgICAgIG9wdGlvbnMua2V5cyA9IGtleXM7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5sb2coZSk7XG4gIH1cbiAgaWYgKGluY2x1ZGUpIHtcbiAgICBvcHRpb25zLmluY2x1ZGUgPSBpbmNsdWRlO1xuICAgIGlmIChpbmNsdWRlUmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgfVxuICBpZiAocmVhZFByZWZlcmVuY2UpIHtcbiAgICBvcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlc3QuZ2V0KFxuICAgIGNvbmZpZyxcbiAgICBhdXRoLFxuICAgIGNsYXNzTmFtZSxcbiAgICBvYmplY3RJZCxcbiAgICBvcHRpb25zLFxuICAgIGluZm8uY2xpZW50U0RLLFxuICAgIGluZm8uY29udGV4dFxuICApO1xuXG4gIGlmICghcmVzcG9uc2UucmVzdWx0cyB8fCByZXNwb25zZS5yZXN1bHRzLmxlbmd0aCA9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICB9XG5cbiAgY29uc3Qgb2JqZWN0ID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCBmaW5kT2JqZWN0cyA9IGFzeW5jIChcbiAgY2xhc3NOYW1lLFxuICB3aGVyZSxcbiAgb3JkZXIsXG4gIHNraXBJbnB1dCxcbiAgZmlyc3QsXG4gIGFmdGVyLFxuICBsYXN0LFxuICBiZWZvcmUsXG4gIGtleXMsXG4gIGluY2x1ZGUsXG4gIGluY2x1ZGVBbGwsXG4gIHJlYWRQcmVmZXJlbmNlLFxuICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgaW5mbyxcbiAgc2VsZWN0ZWRGaWVsZHMsXG4gIHBhcnNlQ2xhc3Nlc1xuKSA9PiB7XG4gIGlmICghd2hlcmUpIHtcbiAgICB3aGVyZSA9IHt9O1xuICB9XG4gIHRyYW5zZm9ybVF1ZXJ5SW5wdXRUb1BhcnNlKHdoZXJlLCBjbGFzc05hbWUsIHBhcnNlQ2xhc3Nlcyk7XG4gIGNvbnN0IHNraXBBbmRMaW1pdENhbGN1bGF0aW9uID0gY2FsY3VsYXRlU2tpcEFuZExpbWl0KFxuICAgIHNraXBJbnB1dCxcbiAgICBmaXJzdCxcbiAgICBhZnRlcixcbiAgICBsYXN0LFxuICAgIGJlZm9yZSxcbiAgICBjb25maWcubWF4TGltaXRcbiAgKTtcbiAgbGV0IHsgc2tpcCB9ID0gc2tpcEFuZExpbWl0Q2FsY3VsYXRpb247XG4gIGNvbnN0IHsgbGltaXQsIG5lZWRUb1ByZUNvdW50IH0gPSBza2lwQW5kTGltaXRDYWxjdWxhdGlvbjtcbiAgbGV0IHByZUNvdW50ID0gdW5kZWZpbmVkO1xuICBpZiAobmVlZFRvUHJlQ291bnQpIHtcbiAgICBjb25zdCBwcmVDb3VudE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMCxcbiAgICAgIGNvdW50OiB0cnVlLFxuICAgIH07XG4gICAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBwcmVDb3VudE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5rZXlzKHdoZXJlKS5sZW5ndGggPiAwICYmIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHByZUNvdW50T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgcHJlQ291bnQgPSAoXG4gICAgICBhd2FpdCByZXN0LmZpbmQoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICB3aGVyZSxcbiAgICAgICAgcHJlQ291bnRPcHRpb25zLFxuICAgICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgICAgaW5mby5jb250ZXh0XG4gICAgICApXG4gICAgKS5jb3VudDtcbiAgICBpZiAoKHNraXAgfHwgMCkgKyBsaW1pdCA8IHByZUNvdW50KSB7XG4gICAgICBza2lwID0gcHJlQ291bnQgLSBsaW1pdDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0ge307XG5cbiAgaWYgKFxuICAgIHNlbGVjdGVkRmllbGRzLmZpbmQoXG4gICAgICBmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKCdlZGdlcy4nKSB8fCBmaWVsZC5zdGFydHNXaXRoKCdwYWdlSW5mby4nKVxuICAgIClcbiAgKSB7XG4gICAgaWYgKGxpbWl0IHx8IGxpbWl0ID09PSAwKSB7XG4gICAgICBvcHRpb25zLmxpbWl0ID0gbGltaXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSAxMDA7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxpbWl0ICE9PSAwKSB7XG4gICAgICBpZiAob3JkZXIpIHtcbiAgICAgICAgb3B0aW9ucy5vcmRlciA9IG9yZGVyO1xuICAgICAgfVxuICAgICAgaWYgKHNraXApIHtcbiAgICAgICAgb3B0aW9ucy5za2lwID0gc2tpcDtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcubWF4TGltaXQgJiYgb3B0aW9ucy5saW1pdCA+IGNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgICAvLyBTaWxlbnRseSByZXBsYWNlIHRoZSBsaW1pdCBvbiB0aGUgcXVlcnkgd2l0aCB0aGUgbWF4IGNvbmZpZ3VyZWRcbiAgICAgICAgb3B0aW9ucy5saW1pdCA9IGNvbmZpZy5tYXhMaW1pdDtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIW5lZWRUb0dldEFsbEtleXMoXG4gICAgICAgICAgcGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgICAgICAgICAoeyBjbGFzc05hbWU6IHBhcnNlQ2xhc3NOYW1lIH0pID0+IGNsYXNzTmFtZSA9PT0gcGFyc2VDbGFzc05hbWVcbiAgICAgICAgICApLmZpZWxkcyxcbiAgICAgICAgICBrZXlzLFxuICAgICAgICAgIHBhcnNlQ2xhc3Nlc1xuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgb3B0aW9ucy5rZXlzID0ga2V5cztcbiAgICAgIH1cbiAgICAgIGlmIChpbmNsdWRlQWxsID09PSB0cnVlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IGluY2x1ZGVBbGw7XG4gICAgICB9XG4gICAgICBpZiAoIW9wdGlvbnMuaW5jbHVkZUFsbCAmJiBpbmNsdWRlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZSA9IGluY2x1ZGU7XG4gICAgICB9XG4gICAgICBpZiAoKG9wdGlvbnMuaW5jbHVkZUFsbCB8fCBvcHRpb25zLmluY2x1ZGUpICYmIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgb3B0aW9ucy5saW1pdCA9IDA7XG4gIH1cblxuICBpZiAoXG4gICAgKHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdjb3VudCcpIHx8XG4gICAgICBzZWxlY3RlZEZpZWxkcy5pbmNsdWRlcygncGFnZUluZm8uaGFzUHJldmlvdXNQYWdlJykgfHxcbiAgICAgIHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdwYWdlSW5mby5oYXNOZXh0UGFnZScpKSAmJlxuICAgICFuZWVkVG9QcmVDb3VudFxuICApIHtcbiAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChyZWFkUHJlZmVyZW5jZSkge1xuICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZWFkUHJlZmVyZW5jZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMod2hlcmUpLmxlbmd0aCA+IDAgJiYgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBsZXQgcmVzdWx0cywgY291bnQ7XG4gIGlmIChvcHRpb25zLmNvdW50IHx8ICFvcHRpb25zLmxpbWl0IHx8IChvcHRpb25zLmxpbWl0ICYmIG9wdGlvbnMubGltaXQgPiAwKSkge1xuICAgIGNvbnN0IGZpbmRSZXN1bHQgPSBhd2FpdCByZXN0LmZpbmQoXG4gICAgICBjb25maWcsXG4gICAgICBhdXRoLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgd2hlcmUsXG4gICAgICBvcHRpb25zLFxuICAgICAgaW5mby5jbGllbnRTREssXG4gICAgICBpbmZvLmNvbnRleHRcbiAgICApO1xuICAgIHJlc3VsdHMgPSBmaW5kUmVzdWx0LnJlc3VsdHM7XG4gICAgY291bnQgPSBmaW5kUmVzdWx0LmNvdW50O1xuICB9XG5cbiAgbGV0IGVkZ2VzID0gbnVsbDtcbiAgbGV0IHBhZ2VJbmZvID0gbnVsbDtcbiAgaWYgKHJlc3VsdHMpIHtcbiAgICBlZGdlcyA9IHJlc3VsdHMubWFwKChyZXN1bHQsIGluZGV4KSA9PiAoe1xuICAgICAgY3Vyc29yOiBvZmZzZXRUb0N1cnNvcigoc2tpcCB8fCAwKSArIGluZGV4KSxcbiAgICAgIG5vZGU6IHJlc3VsdCxcbiAgICB9KSk7XG5cbiAgICBwYWdlSW5mbyA9IHtcbiAgICAgIGhhc1ByZXZpb3VzUGFnZTpcbiAgICAgICAgKChwcmVDb3VudCAmJiBwcmVDb3VudCA+IDApIHx8IChjb3VudCAmJiBjb3VudCA+IDApKSAmJlxuICAgICAgICBza2lwICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgc2tpcCA+IDAsXG4gICAgICBzdGFydEN1cnNvcjogb2Zmc2V0VG9DdXJzb3Ioc2tpcCB8fCAwKSxcbiAgICAgIGVuZEN1cnNvcjogb2Zmc2V0VG9DdXJzb3IoKHNraXAgfHwgMCkgKyAocmVzdWx0cy5sZW5ndGggfHwgMSkgLSAxKSxcbiAgICAgIGhhc05leHRQYWdlOiAocHJlQ291bnQgfHwgY291bnQpID4gKHNraXAgfHwgMCkgKyByZXN1bHRzLmxlbmd0aCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlZGdlcyxcbiAgICBwYWdlSW5mbyxcbiAgICBjb3VudDogcHJlQ291bnQgfHwgY291bnQsXG4gIH07XG59O1xuXG5jb25zdCBjYWxjdWxhdGVTa2lwQW5kTGltaXQgPSAoXG4gIHNraXBJbnB1dCxcbiAgZmlyc3QsXG4gIGFmdGVyLFxuICBsYXN0LFxuICBiZWZvcmUsXG4gIG1heExpbWl0XG4pID0+IHtcbiAgbGV0IHNraXAgPSB1bmRlZmluZWQ7XG4gIGxldCBsaW1pdCA9IHVuZGVmaW5lZDtcbiAgbGV0IG5lZWRUb1ByZUNvdW50ID0gZmFsc2U7XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBza2lwIGlucHV0XG4gIGlmIChza2lwSW5wdXQgfHwgc2tpcElucHV0ID09PSAwKSB7XG4gICAgaWYgKHNraXBJbnB1dCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgJ1NraXAgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyJ1xuICAgICAgKTtcbiAgICB9XG4gICAgc2tpcCA9IHNraXBJbnB1dDtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgYWZ0ZXIgcGFyYW1cbiAgaWYgKGFmdGVyKSB7XG4gICAgYWZ0ZXIgPSBjdXJzb3JUb09mZnNldChhZnRlcik7XG4gICAgaWYgKCghYWZ0ZXIgJiYgYWZ0ZXIgIT09IDApIHx8IGFmdGVyIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnQWZ0ZXIgaXMgbm90IGEgdmFsaWQgY3Vyc29yJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJZiBza2lwIGFuZCBhZnRlciBhcmUgcGFzc2VkLCBhIG5ldyBza2lwIGlzIGNhbGN1bGF0ZWQgYnkgYWRkaW5nIHRoZW1cbiAgICBza2lwID0gKHNraXAgfHwgMCkgKyAoYWZ0ZXIgKyAxKTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgZmlyc3QgcGFyYW1cbiAgaWYgKGZpcnN0IHx8IGZpcnN0ID09PSAwKSB7XG4gICAgaWYgKGZpcnN0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnRmlyc3Qgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgZmlyc3QgcGFyYW0gaXMgdHJhbnNsYXRlZCB0byB0aGUgbGltaXQgcGFyYW0gb2YgdGhlIFBhcnNlIGxlZ2FjeSBBUElcbiAgICBsaW1pdCA9IGZpcnN0O1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBiZWZvcmUgcGFyYW1cbiAgaWYgKGJlZm9yZSB8fCBiZWZvcmUgPT09IDApIHtcbiAgICAvLyBUaGlzIG1ldGhvZCBjb252ZXJ0cyB0aGUgY3Vyc29yIHRvIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0XG4gICAgYmVmb3JlID0gY3Vyc29yVG9PZmZzZXQoYmVmb3JlKTtcbiAgICBpZiAoKCFiZWZvcmUgJiYgYmVmb3JlICE9PSAwKSB8fCBiZWZvcmUgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICdCZWZvcmUgaXMgbm90IGEgdmFsaWQgY3Vyc29yJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoKHNraXAgfHwgMCkgPj0gYmVmb3JlKSB7XG4gICAgICAvLyBJZiB0aGUgYmVmb3JlIGluZGV4IGlzIGxlc3MgdGhlbiB0aGUgc2tpcCwgbm8gb2JqZWN0cyB3aWxsIGJlIHJldHVybmVkXG4gICAgICBsaW1pdCA9IDA7XG4gICAgfSBlbHNlIGlmICgoIWxpbWl0ICYmIGxpbWl0ICE9PSAwKSB8fCAoc2tpcCB8fCAwKSArIGxpbWl0ID4gYmVmb3JlKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBubyBsaW1pdCBzZXQsIHRoZSBsaW1pdCBpcyBjYWxjdWxhdGVkLiBPciwgaWYgdGhlIGxpbWl0IChwbHVzIHNraXApIGlzIGJpZ2dlciB0aGFuIHRoZSBiZWZvcmUgaW5kZXgsIHRoZSBuZXcgbGltaXQgaXMgc2V0LlxuICAgICAgbGltaXQgPSBiZWZvcmUgLSAoc2tpcCB8fCAwKTtcbiAgICB9XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgdGhlIGxhc3QgcGFyYW1cbiAgaWYgKGxhc3QgfHwgbGFzdCA9PT0gMCkge1xuICAgIGlmIChsYXN0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnTGFzdCBzaG91bGQgYmUgYSBwb3NpdGl2ZSBudW1iZXInXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChsYXN0ID4gbWF4TGltaXQpIHtcbiAgICAgIC8vIExhc3QgY2FuJ3QgYmUgYmlnZ2VyIHRoYW4gUGFyc2Ugc2VydmVyIG1heExpbWl0IGNvbmZpZy5cbiAgICAgIGxhc3QgPSBtYXhMaW1pdDtcbiAgICB9XG5cbiAgICBpZiAobGltaXQgfHwgbGltaXQgPT09IDApIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgcHJldmlvdXMgbGltaXQgc2V0LCBpdCBtYXkgYmUgYWRqdXN0ZWRcbiAgICAgIGlmIChsYXN0IDwgbGltaXQpIHtcbiAgICAgICAgLy8gaWYgbGFzdCBpcyBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgbGltaXRcbiAgICAgICAgc2tpcCA9IChza2lwIHx8IDApICsgKGxpbWl0IC0gbGFzdCk7IC8vIFRoZSBza2lwIGlzIGFkanVzdGVkXG4gICAgICAgIGxpbWl0ID0gbGFzdDsgLy8gdGhlIGxpbWl0IGlzIGFkanVzdGVkXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAwKSB7XG4gICAgICAvLyBObyBvYmplY3RzIHdpbGwgYmUgcmV0dXJuZWRcbiAgICAgIGxpbWl0ID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gcHJldmlvdXMgbGltaXQgc2V0LCB0aGUgbGltaXQgd2lsbCBiZSBlcXVhbCB0byBsYXN0IGFuZCBwcmUgY291bnQgaXMgbmVlZGVkLlxuICAgICAgbGltaXQgPSBsYXN0O1xuICAgICAgbmVlZFRvUHJlQ291bnQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIHNraXAsXG4gICAgbGltaXQsXG4gICAgbmVlZFRvUHJlQ291bnQsXG4gIH07XG59O1xuXG5leHBvcnQgeyBnZXRPYmplY3QsIGZpbmRPYmplY3RzLCBjYWxjdWxhdGVTa2lwQW5kTGltaXQsIG5lZWRUb0dldEFsbEtleXMgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLMutations.js b/lib/GraphQL/loaders/defaultGraphQLMutations.js new file mode 100644 index 0000000000..afe32cc4fb --- /dev/null +++ b/lib/GraphQL/loaders/defaultGraphQLMutations.js @@ -0,0 +1,28 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var filesMutations = _interopRequireWildcard(require("./filesMutations")); + +var usersMutations = _interopRequireWildcard(require("./usersMutations")); + +var functionsMutations = _interopRequireWildcard(require("./functionsMutations")); + +var schemaMutations = _interopRequireWildcard(require("./schemaMutations")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const load = parseGraphQLSchema => { + filesMutations.load(parseGraphQLSchema); + usersMutations.load(parseGraphQLSchema); + functionsMutations.load(parseGraphQLSchema); + schemaMutations.load(parseGraphQLSchema); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImZpbGVzTXV0YXRpb25zIiwidXNlcnNNdXRhdGlvbnMiLCJmdW5jdGlvbnNNdXRhdGlvbnMiLCJzY2hlbWFNdXRhdGlvbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0MsRUFBQUEsY0FBYyxDQUFDRixJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUUsRUFBQUEsY0FBYyxDQUFDSCxJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUcsRUFBQUEsa0JBQWtCLENBQUNKLElBQW5CLENBQXdCQyxrQkFBeEI7QUFDQUksRUFBQUEsZUFBZSxDQUFDTCxJQUFoQixDQUFxQkMsa0JBQXJCO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZpbGVzTXV0YXRpb25zIGZyb20gJy4vZmlsZXNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgdXNlcnNNdXRhdGlvbnMgZnJvbSAnLi91c2Vyc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBmdW5jdGlvbnNNdXRhdGlvbnMgZnJvbSAnLi9mdW5jdGlvbnNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgc2NoZW1hTXV0YXRpb25zIGZyb20gJy4vc2NoZW1hTXV0YXRpb25zJztcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGZpbGVzTXV0YXRpb25zLmxvYWQocGFyc2VHcmFwaFFMU2NoZW1hKTtcbiAgdXNlcnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBmdW5jdGlvbnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBzY2hlbWFNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLQueries.js b/lib/GraphQL/loaders/defaultGraphQLQueries.js new file mode 100644 index 0000000000..b8935f3ab1 --- /dev/null +++ b/lib/GraphQL/loaders/defaultGraphQLQueries.js @@ -0,0 +1,29 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var usersQueries = _interopRequireWildcard(require("./usersQueries")); + +var schemaQueries = _interopRequireWildcard(require("./schemaQueries")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLQuery('health', { + description: 'The health query can be used to check if the server is up and running.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean), + resolve: () => true + }, true, true); + usersQueries.load(parseGraphQLSchema); + schemaQueries.load(parseGraphQLSchema); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkdyYXBoUUxCb29sZWFuIiwicmVzb2x2ZSIsInVzZXJzUXVlcmllcyIsInNjaGVtYVF1ZXJpZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0EsRUFBQUEsa0JBQWtCLENBQUNDLGVBQW5CLENBQ0UsUUFERixFQUVFO0FBQ0VDLElBQUFBLFdBQVcsRUFDVCx3RUFGSjtBQUdFQyxJQUFBQSxJQUFJLEVBQUUsSUFBSUMsdUJBQUosQ0FBbUJDLHVCQUFuQixDQUhSO0FBSUVDLElBQUFBLE9BQU8sRUFBRSxNQUFNO0FBSmpCLEdBRkYsRUFRRSxJQVJGLEVBU0UsSUFURjtBQVlBQyxFQUFBQSxZQUFZLENBQUNSLElBQWIsQ0FBa0JDLGtCQUFsQjtBQUNBUSxFQUFBQSxhQUFhLENBQUNULElBQWQsQ0FBbUJDLGtCQUFuQjtBQUNELENBZkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCwgR3JhcGhRTEJvb2xlYW4gfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCAqIGFzIHVzZXJzUXVlcmllcyBmcm9tICcuL3VzZXJzUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFRdWVyaWVzIGZyb20gJy4vc2NoZW1hUXVlcmllcyc7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdoZWFsdGgnLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGhlYWx0aCBxdWVyeSBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiB0aGUgc2VydmVyIGlzIHVwIGFuZCBydW5uaW5nLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgcmVzb2x2ZTogKCkgPT4gdHJ1ZSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIHVzZXJzUXVlcmllcy5sb2FkKHBhcnNlR3JhcGhRTFNjaGVtYSk7XG4gIHNjaGVtYVF1ZXJpZXMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLTypes.js b/lib/GraphQL/loaders/defaultGraphQLTypes.js new file mode 100644 index 0000000000..913aa114ce --- /dev/null +++ b/lib/GraphQL/loaders/defaultGraphQLTypes.js @@ -0,0 +1,1271 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadArrayResult = exports.load = exports.PUBLIC_ACL = exports.ROLE_ACL = exports.USER_ACL = exports.ACL = exports.PUBLIC_ACL_INPUT = exports.ROLE_ACL_INPUT = exports.USER_ACL_INPUT = exports.ACL_INPUT = exports.ELEMENT = exports.ARRAY_RESULT = exports.POLYGON_WHERE_INPUT = exports.GEO_POINT_WHERE_INPUT = exports.FILE_WHERE_INPUT = exports.BYTES_WHERE_INPUT = exports.DATE_WHERE_INPUT = exports.OBJECT_WHERE_INPUT = exports.KEY_VALUE_INPUT = exports.ARRAY_WHERE_INPUT = exports.BOOLEAN_WHERE_INPUT = exports.NUMBER_WHERE_INPUT = exports.STRING_WHERE_INPUT = exports.ID_WHERE_INPUT = exports.notInQueryKey = exports.inQueryKey = exports.options = exports.matchesRegex = exports.exists = exports.notIn = exports.inOp = exports.greaterThanOrEqualTo = exports.greaterThan = exports.lessThanOrEqualTo = exports.lessThan = exports.notEqualTo = exports.equalTo = exports.GEO_INTERSECTS_INPUT = exports.GEO_WITHIN_INPUT = exports.CENTER_SPHERE_INPUT = exports.WITHIN_INPUT = exports.BOX_INPUT = exports.TEXT_INPUT = exports.SEARCH_INPUT = exports.COUNT_ATT = exports.LIMIT_ATT = exports.SKIP_ATT = exports.WHERE_ATT = exports.READ_OPTIONS_ATT = exports.READ_OPTIONS_INPUT = exports.SUBQUERY_READ_PREFERENCE_ATT = exports.INCLUDE_READ_PREFERENCE_ATT = exports.READ_PREFERENCE_ATT = exports.READ_PREFERENCE = exports.SESSION_TOKEN_ATT = exports.PARSE_OBJECT = exports.PARSE_OBJECT_FIELDS = exports.UPDATE_RESULT_FIELDS = exports.CREATE_RESULT_FIELDS = exports.INPUT_FIELDS = exports.CREATED_AT_ATT = exports.UPDATED_AT_ATT = exports.OBJECT_ID_ATT = exports.GLOBAL_OR_OBJECT_ID_ATT = exports.CLASS_NAME_ATT = exports.OBJECT_ID = exports.POLYGON = exports.POLYGON_INPUT = exports.GEO_POINT = exports.GEO_POINT_INPUT = exports.GEO_POINT_FIELDS = exports.FILE_INPUT = exports.FILE_INFO = exports.FILE = exports.SELECT_INPUT = exports.SUBQUERY_INPUT = exports.parseFileValue = exports.BYTES = exports.DATE = exports.serializeDateIso = exports.parseDateIsoValue = exports.OBJECT = exports.ANY = exports.parseObjectFields = exports.parseListValues = exports.parseValue = exports.parseBooleanValue = exports.parseFloatValue = exports.parseIntValue = exports.parseStringValue = exports.TypeValidationError = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _links = require("@graphql-tools/links"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +class TypeValidationError extends Error { + constructor(value, type) { + super(`${value} is not a valid ${type}`); + } + +} + +exports.TypeValidationError = TypeValidationError; + +const parseStringValue = value => { + if (typeof value === 'string') { + return value; + } + + throw new TypeValidationError(value, 'String'); +}; + +exports.parseStringValue = parseStringValue; + +const parseIntValue = value => { + if (typeof value === 'string') { + const int = Number(value); + + if (Number.isInteger(int)) { + return int; + } + } + + throw new TypeValidationError(value, 'Int'); +}; + +exports.parseIntValue = parseIntValue; + +const parseFloatValue = value => { + if (typeof value === 'string') { + const float = Number(value); + + if (!isNaN(float)) { + return float; + } + } + + throw new TypeValidationError(value, 'Float'); +}; + +exports.parseFloatValue = parseFloatValue; + +const parseBooleanValue = value => { + if (typeof value === 'boolean') { + return value; + } + + throw new TypeValidationError(value, 'Boolean'); +}; + +exports.parseBooleanValue = parseBooleanValue; + +const parseValue = value => { + switch (value.kind) { + case _graphql.Kind.STRING: + return parseStringValue(value.value); + + case _graphql.Kind.INT: + return parseIntValue(value.value); + + case _graphql.Kind.FLOAT: + return parseFloatValue(value.value); + + case _graphql.Kind.BOOLEAN: + return parseBooleanValue(value.value); + + case _graphql.Kind.LIST: + return parseListValues(value.values); + + case _graphql.Kind.OBJECT: + return parseObjectFields(value.fields); + + default: + return value.value; + } +}; + +exports.parseValue = parseValue; + +const parseListValues = values => { + if (Array.isArray(values)) { + return values.map(value => parseValue(value)); + } + + throw new TypeValidationError(values, 'List'); +}; + +exports.parseListValues = parseListValues; + +const parseObjectFields = fields => { + if (Array.isArray(fields)) { + return fields.reduce((object, field) => _objectSpread(_objectSpread({}, object), {}, { + [field.name.value]: parseValue(field.value) + }), {}); + } + + throw new TypeValidationError(fields, 'Object'); +}; + +exports.parseObjectFields = parseObjectFields; +const ANY = new _graphql.GraphQLScalarType({ + name: 'Any', + description: 'The Any scalar type is used in operations and types that involve any type of value.', + parseValue: value => value, + serialize: value => value, + parseLiteral: ast => parseValue(ast) +}); +exports.ANY = ANY; +const OBJECT = new _graphql.GraphQLScalarType({ + name: 'Object', + description: 'The Object scalar type is used in operations and types that involve objects.', + + parseValue(value) { + if (typeof value === 'object') { + return value; + } + + throw new TypeValidationError(value, 'Object'); + }, + + serialize(value) { + if (typeof value === 'object') { + return value; + } + + throw new TypeValidationError(value, 'Object'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.OBJECT) { + return parseObjectFields(ast.fields); + } + + throw new TypeValidationError(ast.kind, 'Object'); + } + +}); +exports.OBJECT = OBJECT; + +const parseDateIsoValue = value => { + if (typeof value === 'string') { + const date = new Date(value); + + if (!isNaN(date)) { + return date; + } + } else if (value instanceof Date) { + return value; + } + + throw new TypeValidationError(value, 'Date'); +}; + +exports.parseDateIsoValue = parseDateIsoValue; + +const serializeDateIso = value => { + if (typeof value === 'string') { + return value; + } + + if (value instanceof Date) { + return value.toISOString(); + } + + throw new TypeValidationError(value, 'Date'); +}; + +exports.serializeDateIso = serializeDateIso; + +const parseDateIsoLiteral = ast => { + if (ast.kind === _graphql.Kind.STRING) { + return parseDateIsoValue(ast.value); + } + + throw new TypeValidationError(ast.kind, 'Date'); +}; + +const DATE = new _graphql.GraphQLScalarType({ + name: 'Date', + description: 'The Date scalar type is used in operations and types that involve dates.', + + parseValue(value) { + if (typeof value === 'string' || value instanceof Date) { + return { + __type: 'Date', + iso: parseDateIsoValue(value) + }; + } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { + return { + __type: value.__type, + iso: parseDateIsoValue(value.iso) + }; + } + + throw new TypeValidationError(value, 'Date'); + }, + + serialize(value) { + if (typeof value === 'string' || value instanceof Date) { + return serializeDateIso(value); + } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { + return serializeDateIso(value.iso); + } + + throw new TypeValidationError(value, 'Date'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.STRING) { + return { + __type: 'Date', + iso: parseDateIsoLiteral(ast) + }; + } else if (ast.kind === _graphql.Kind.OBJECT) { + const __type = ast.fields.find(field => field.name.value === '__type'); + + const iso = ast.fields.find(field => field.name.value === 'iso'); + + if (__type && __type.value && __type.value.value === 'Date' && iso) { + return { + __type: __type.value.value, + iso: parseDateIsoLiteral(iso.value) + }; + } + } + + throw new TypeValidationError(ast.kind, 'Date'); + } + +}); +exports.DATE = DATE; +const BYTES = new _graphql.GraphQLScalarType({ + name: 'Bytes', + description: 'The Bytes scalar type is used in operations and types that involve base 64 binary data.', + + parseValue(value) { + if (typeof value === 'string') { + return { + __type: 'Bytes', + base64: value + }; + } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { + return value; + } + + throw new TypeValidationError(value, 'Bytes'); + }, + + serialize(value) { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { + return value.base64; + } + + throw new TypeValidationError(value, 'Bytes'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.STRING) { + return { + __type: 'Bytes', + base64: ast.value + }; + } else if (ast.kind === _graphql.Kind.OBJECT) { + const __type = ast.fields.find(field => field.name.value === '__type'); + + const base64 = ast.fields.find(field => field.name.value === 'base64'); + + if (__type && __type.value && __type.value.value === 'Bytes' && base64 && base64.value && typeof base64.value.value === 'string') { + return { + __type: __type.value.value, + base64: base64.value.value + }; + } + } + + throw new TypeValidationError(ast.kind, 'Bytes'); + } + +}); +exports.BYTES = BYTES; + +const parseFileValue = value => { + if (typeof value === 'string') { + return { + __type: 'File', + name: value + }; + } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { + return value; + } + + throw new TypeValidationError(value, 'File'); +}; + +exports.parseFileValue = parseFileValue; +const FILE = new _graphql.GraphQLScalarType({ + name: 'File', + description: 'The File scalar type is used in operations and types that involve files.', + parseValue: parseFileValue, + serialize: value => { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { + return value.name; + } + + throw new TypeValidationError(value, 'File'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.STRING) { + return parseFileValue(ast.value); + } else if (ast.kind === _graphql.Kind.OBJECT) { + const __type = ast.fields.find(field => field.name.value === '__type'); + + const name = ast.fields.find(field => field.name.value === 'name'); + const url = ast.fields.find(field => field.name.value === 'url'); + + if (__type && __type.value && name && name.value) { + return parseFileValue({ + __type: __type.value.value, + name: name.value.value, + url: url && url.value ? url.value.value : undefined + }); + } + } + + throw new TypeValidationError(ast.kind, 'File'); + } + +}); +exports.FILE = FILE; +const FILE_INFO = new _graphql.GraphQLObjectType({ + name: 'FileInfo', + description: 'The FileInfo object type is used to return the information about files.', + fields: { + name: { + description: 'This is the file name.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + url: { + description: 'This is the url in which the file can be downloaded.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + } +}); +exports.FILE_INFO = FILE_INFO; +const FILE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'FileInput', + fields: { + file: { + description: 'A File Scalar can be an url or a FileInfo object. If this field is set to null the file will be unlinked.', + type: FILE + }, + upload: { + description: 'Use this field if you want to create a new file.', + type: _links.GraphQLUpload + }, + unlink: { + description: 'Use this field if you want to unlink the file (the file will not be deleted on cloud storage)', + type: _graphql.GraphQLBoolean + } + } +}); +exports.FILE_INPUT = FILE_INPUT; +const GEO_POINT_FIELDS = { + latitude: { + description: 'This is the latitude.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) + }, + longitude: { + description: 'This is the longitude.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) + } +}; +exports.GEO_POINT_FIELDS = GEO_POINT_FIELDS; +const GEO_POINT_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoPointInput', + description: 'The GeoPointInput type is used in operations that involve inputting fields of type geo point.', + fields: GEO_POINT_FIELDS +}); +exports.GEO_POINT_INPUT = GEO_POINT_INPUT; +const GEO_POINT = new _graphql.GraphQLObjectType({ + name: 'GeoPoint', + description: 'The GeoPoint object type is used to return the information about geo point fields.', + fields: GEO_POINT_FIELDS +}); +exports.GEO_POINT = GEO_POINT; +const POLYGON_INPUT = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT_INPUT)); +exports.POLYGON_INPUT = POLYGON_INPUT; +const POLYGON = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT)); +exports.POLYGON = POLYGON; +const USER_ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'UserACLInput', + description: 'Allow to manage users in ACL.', + fields: { + userId: { + description: 'ID of the targetted User.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) + }, + read: { + description: 'Allow the user to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow the user to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.USER_ACL_INPUT = USER_ACL_INPUT; +const ROLE_ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'RoleACLInput', + description: 'Allow to manage roles in ACL.', + fields: { + roleName: { + description: 'Name of the targetted Role.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + read: { + description: 'Allow users who are members of the role to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow users who are members of the role to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.ROLE_ACL_INPUT = ROLE_ACL_INPUT; +const PUBLIC_ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'PublicACLInput', + description: 'Allow to manage public rights.', + fields: { + read: { + description: 'Allow anyone to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow anyone to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.PUBLIC_ACL_INPUT = PUBLIC_ACL_INPUT; +const ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ACLInput', + description: 'Allow to manage access rights. If not provided object will be publicly readable and writable', + fields: { + users: { + description: 'Access control list for users.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL_INPUT)) + }, + roles: { + description: 'Access control list for roles.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL_INPUT)) + }, + public: { + description: 'Public access control list.', + type: PUBLIC_ACL_INPUT + } + } +}); +exports.ACL_INPUT = ACL_INPUT; +const USER_ACL = new _graphql.GraphQLObjectType({ + name: 'UserACL', + description: 'Allow to manage users in ACL. If read and write are null the users have read and write rights.', + fields: { + userId: { + description: 'ID of the targetted User.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) + }, + read: { + description: 'Allow the user to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow the user to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.USER_ACL = USER_ACL; +const ROLE_ACL = new _graphql.GraphQLObjectType({ + name: 'RoleACL', + description: 'Allow to manage roles in ACL. If read and write are null the role have read and write rights.', + fields: { + roleName: { + description: 'Name of the targetted Role.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) + }, + read: { + description: 'Allow users who are members of the role to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow users who are members of the role to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.ROLE_ACL = ROLE_ACL; +const PUBLIC_ACL = new _graphql.GraphQLObjectType({ + name: 'PublicACL', + description: 'Allow to manage public rights.', + fields: { + read: { + description: 'Allow anyone to read the current object.', + type: _graphql.GraphQLBoolean + }, + write: { + description: 'Allow anyone to write on the current object.', + type: _graphql.GraphQLBoolean + } + } +}); +exports.PUBLIC_ACL = PUBLIC_ACL; +const ACL = new _graphql.GraphQLObjectType({ + name: 'ACL', + description: 'Current access control list of the current object.', + fields: { + users: { + description: 'Access control list for users.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL)), + + resolve(p) { + const users = []; + Object.keys(p).forEach(rule => { + if (rule !== '*' && rule.indexOf('role:') !== 0) { + users.push({ + userId: (0, _graphqlRelay.toGlobalId)('_User', rule), + read: p[rule].read ? true : false, + write: p[rule].write ? true : false + }); + } + }); + return users.length ? users : null; + } + + }, + roles: { + description: 'Access control list for roles.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL)), + + resolve(p) { + const roles = []; + Object.keys(p).forEach(rule => { + if (rule.indexOf('role:') === 0) { + roles.push({ + roleName: rule.replace('role:', ''), + read: p[rule].read ? true : false, + write: p[rule].write ? true : false + }); + } + }); + return roles.length ? roles : null; + } + + }, + public: { + description: 'Public access control list.', + type: PUBLIC_ACL, + + resolve(p) { + /* eslint-disable */ + return p['*'] ? { + read: p['*'].read ? true : false, + write: p['*'].write ? true : false + } : null; + } + + } + } +}); +exports.ACL = ACL; +const OBJECT_ID = new _graphql.GraphQLNonNull(_graphql.GraphQLID); +exports.OBJECT_ID = OBJECT_ID; +const CLASS_NAME_ATT = { + description: 'This is the class name of the object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.CLASS_NAME_ATT = CLASS_NAME_ATT; +const GLOBAL_OR_OBJECT_ID_ATT = { + description: 'This is the object id. You can use either the global or the object id.', + type: OBJECT_ID +}; +exports.GLOBAL_OR_OBJECT_ID_ATT = GLOBAL_OR_OBJECT_ID_ATT; +const OBJECT_ID_ATT = { + description: 'This is the object id.', + type: OBJECT_ID +}; +exports.OBJECT_ID_ATT = OBJECT_ID_ATT; +const CREATED_AT_ATT = { + description: 'This is the date in which the object was created.', + type: new _graphql.GraphQLNonNull(DATE) +}; +exports.CREATED_AT_ATT = CREATED_AT_ATT; +const UPDATED_AT_ATT = { + description: 'This is the date in which the object was las updated.', + type: new _graphql.GraphQLNonNull(DATE) +}; +exports.UPDATED_AT_ATT = UPDATED_AT_ATT; +const INPUT_FIELDS = { + ACL: { + type: ACL + } +}; +exports.INPUT_FIELDS = INPUT_FIELDS; +const CREATE_RESULT_FIELDS = { + objectId: OBJECT_ID_ATT, + createdAt: CREATED_AT_ATT +}; +exports.CREATE_RESULT_FIELDS = CREATE_RESULT_FIELDS; +const UPDATE_RESULT_FIELDS = { + updatedAt: UPDATED_AT_ATT +}; +exports.UPDATE_RESULT_FIELDS = UPDATE_RESULT_FIELDS; + +const PARSE_OBJECT_FIELDS = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, CREATE_RESULT_FIELDS), UPDATE_RESULT_FIELDS), INPUT_FIELDS), {}, { + ACL: { + type: new _graphql.GraphQLNonNull(ACL), + resolve: ({ + ACL + }) => ACL ? ACL : { + '*': { + read: true, + write: true + } + } + } +}); + +exports.PARSE_OBJECT_FIELDS = PARSE_OBJECT_FIELDS; +const PARSE_OBJECT = new _graphql.GraphQLInterfaceType({ + name: 'ParseObject', + description: 'The ParseObject interface type is used as a base type for the auto generated object types.', + fields: PARSE_OBJECT_FIELDS +}); +exports.PARSE_OBJECT = PARSE_OBJECT; +const SESSION_TOKEN_ATT = { + description: 'The current user session token.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.SESSION_TOKEN_ATT = SESSION_TOKEN_ATT; +const READ_PREFERENCE = new _graphql.GraphQLEnumType({ + name: 'ReadPreference', + description: 'The ReadPreference enum type is used in queries in order to select in which database replica the operation must run.', + values: { + PRIMARY: { + value: 'PRIMARY' + }, + PRIMARY_PREFERRED: { + value: 'PRIMARY_PREFERRED' + }, + SECONDARY: { + value: 'SECONDARY' + }, + SECONDARY_PREFERRED: { + value: 'SECONDARY_PREFERRED' + }, + NEAREST: { + value: 'NEAREST' + } + } +}); +exports.READ_PREFERENCE = READ_PREFERENCE; +const READ_PREFERENCE_ATT = { + description: 'The read preference for the main query to be executed.', + type: READ_PREFERENCE +}; +exports.READ_PREFERENCE_ATT = READ_PREFERENCE_ATT; +const INCLUDE_READ_PREFERENCE_ATT = { + description: 'The read preference for the queries to be executed to include fields.', + type: READ_PREFERENCE +}; +exports.INCLUDE_READ_PREFERENCE_ATT = INCLUDE_READ_PREFERENCE_ATT; +const SUBQUERY_READ_PREFERENCE_ATT = { + description: 'The read preference for the subqueries that may be required.', + type: READ_PREFERENCE +}; +exports.SUBQUERY_READ_PREFERENCE_ATT = SUBQUERY_READ_PREFERENCE_ATT; +const READ_OPTIONS_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ReadOptionsInput', + description: 'The ReadOptionsInputt type is used in queries in order to set the read preferences.', + fields: { + readPreference: READ_PREFERENCE_ATT, + includeReadPreference: INCLUDE_READ_PREFERENCE_ATT, + subqueryReadPreference: SUBQUERY_READ_PREFERENCE_ATT + } +}); +exports.READ_OPTIONS_INPUT = READ_OPTIONS_INPUT; +const READ_OPTIONS_ATT = { + description: 'The read options for the query to be executed.', + type: READ_OPTIONS_INPUT +}; +exports.READ_OPTIONS_ATT = READ_OPTIONS_ATT; +const WHERE_ATT = { + description: 'These are the conditions that the objects need to match in order to be found', + type: OBJECT +}; +exports.WHERE_ATT = WHERE_ATT; +const SKIP_ATT = { + description: 'This is the number of objects that must be skipped to return.', + type: _graphql.GraphQLInt +}; +exports.SKIP_ATT = SKIP_ATT; +const LIMIT_ATT = { + description: 'This is the limit number of objects that must be returned.', + type: _graphql.GraphQLInt +}; +exports.LIMIT_ATT = LIMIT_ATT; +const COUNT_ATT = { + description: 'This is the total matched objecs count that is returned when the count flag is set.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLInt) +}; +exports.COUNT_ATT = COUNT_ATT; +const SEARCH_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SearchInput', + description: 'The SearchInput type is used to specifiy a search operation on a full text search.', + fields: { + term: { + description: 'This is the term to be searched.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + language: { + description: 'This is the language to tetermine the list of stop words and the rules for tokenizer.', + type: _graphql.GraphQLString + }, + caseSensitive: { + description: 'This is the flag to enable or disable case sensitive search.', + type: _graphql.GraphQLBoolean + }, + diacriticSensitive: { + description: 'This is the flag to enable or disable diacritic sensitive search.', + type: _graphql.GraphQLBoolean + } + } +}); +exports.SEARCH_INPUT = SEARCH_INPUT; +const TEXT_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'TextInput', + description: 'The TextInput type is used to specify a text operation on a constraint.', + fields: { + search: { + description: 'This is the search to be executed.', + type: new _graphql.GraphQLNonNull(SEARCH_INPUT) + } + } +}); +exports.TEXT_INPUT = TEXT_INPUT; +const BOX_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'BoxInput', + description: 'The BoxInput type is used to specifiy a box operation on a within geo query.', + fields: { + bottomLeft: { + description: 'This is the bottom left coordinates of the box.', + type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) + }, + upperRight: { + description: 'This is the upper right coordinates of the box.', + type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) + } + } +}); +exports.BOX_INPUT = BOX_INPUT; +const WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'WithinInput', + description: 'The WithinInput type is used to specify a within operation on a constraint.', + fields: { + box: { + description: 'This is the box to be specified.', + type: new _graphql.GraphQLNonNull(BOX_INPUT) + } + } +}); +exports.WITHIN_INPUT = WITHIN_INPUT; +const CENTER_SPHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'CenterSphereInput', + description: 'The CenterSphereInput type is used to specifiy a centerSphere operation on a geoWithin query.', + fields: { + center: { + description: 'This is the center of the sphere.', + type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) + }, + distance: { + description: 'This is the radius of the sphere.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) + } + } +}); +exports.CENTER_SPHERE_INPUT = CENTER_SPHERE_INPUT; +const GEO_WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoWithinInput', + description: 'The GeoWithinInput type is used to specify a geoWithin operation on a constraint.', + fields: { + polygon: { + description: 'This is the polygon to be specified.', + type: POLYGON_INPUT + }, + centerSphere: { + description: 'This is the sphere to be specified.', + type: CENTER_SPHERE_INPUT + } + } +}); +exports.GEO_WITHIN_INPUT = GEO_WITHIN_INPUT; +const GEO_INTERSECTS_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoIntersectsInput', + description: 'The GeoIntersectsInput type is used to specify a geoIntersects operation on a constraint.', + fields: { + point: { + description: 'This is the point to be specified.', + type: GEO_POINT_INPUT + } + } +}); +exports.GEO_INTERSECTS_INPUT = GEO_INTERSECTS_INPUT; + +const equalTo = type => ({ + description: 'This is the equalTo operator to specify a constraint to select the objects where the value of a field equals to a specified value.', + type +}); + +exports.equalTo = equalTo; + +const notEqualTo = type => ({ + description: 'This is the notEqualTo operator to specify a constraint to select the objects where the value of a field do not equal to a specified value.', + type +}); + +exports.notEqualTo = notEqualTo; + +const lessThan = type => ({ + description: 'This is the lessThan operator to specify a constraint to select the objects where the value of a field is less than a specified value.', + type +}); + +exports.lessThan = lessThan; + +const lessThanOrEqualTo = type => ({ + description: 'This is the lessThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is less than or equal to a specified value.', + type +}); + +exports.lessThanOrEqualTo = lessThanOrEqualTo; + +const greaterThan = type => ({ + description: 'This is the greaterThan operator to specify a constraint to select the objects where the value of a field is greater than a specified value.', + type +}); + +exports.greaterThan = greaterThan; + +const greaterThanOrEqualTo = type => ({ + description: 'This is the greaterThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is greater than or equal to a specified value.', + type +}); + +exports.greaterThanOrEqualTo = greaterThanOrEqualTo; + +const inOp = type => ({ + description: 'This is the in operator to specify a constraint to select the objects where the value of a field equals any value in the specified array.', + type: new _graphql.GraphQLList(type) +}); + +exports.inOp = inOp; + +const notIn = type => ({ + description: 'This is the notIn operator to specify a constraint to select the objects where the value of a field do not equal any value in the specified array.', + type: new _graphql.GraphQLList(type) +}); + +exports.notIn = notIn; +const exists = { + description: 'This is the exists operator to specify a constraint to select the objects where a field exists (or do not exist).', + type: _graphql.GraphQLBoolean +}; +exports.exists = exists; +const matchesRegex = { + description: 'This is the matchesRegex operator to specify a constraint to select the objects where the value of a field matches a specified regular expression.', + type: _graphql.GraphQLString +}; +exports.matchesRegex = matchesRegex; +const options = { + description: 'This is the options operator to specify optional flags (such as "i" and "m") to be added to a matchesRegex operation in the same set of constraints.', + type: _graphql.GraphQLString +}; +exports.options = options; +const SUBQUERY_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SubqueryInput', + description: 'The SubqueryInput type is used to specify a sub query to another class.', + fields: { + className: CLASS_NAME_ATT, + where: Object.assign({}, WHERE_ATT, { + type: new _graphql.GraphQLNonNull(WHERE_ATT.type) + }) + } +}); +exports.SUBQUERY_INPUT = SUBQUERY_INPUT; +const SELECT_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SelectInput', + description: 'The SelectInput type is used to specify an inQueryKey or a notInQueryKey operation on a constraint.', + fields: { + query: { + description: 'This is the subquery to be executed.', + type: new _graphql.GraphQLNonNull(SUBQUERY_INPUT) + }, + key: { + description: 'This is the key in the result of the subquery that must match (not match) the field.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + } +}); +exports.SELECT_INPUT = SELECT_INPUT; +const inQueryKey = { + description: 'This is the inQueryKey operator to specify a constraint to select the objects where a field equals to a key in the result of a different query.', + type: SELECT_INPUT +}; +exports.inQueryKey = inQueryKey; +const notInQueryKey = { + description: 'This is the notInQueryKey operator to specify a constraint to select the objects where a field do not equal to a key in the result of a different query.', + type: SELECT_INPUT +}; +exports.notInQueryKey = notInQueryKey; +const ID_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'IdWhereInput', + description: 'The IdWhereInput input type is used in operations that involve filtering objects by an id.', + fields: { + equalTo: equalTo(_graphql.GraphQLID), + notEqualTo: notEqualTo(_graphql.GraphQLID), + lessThan: lessThan(_graphql.GraphQLID), + lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLID), + greaterThan: greaterThan(_graphql.GraphQLID), + greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLID), + in: inOp(_graphql.GraphQLID), + notIn: notIn(_graphql.GraphQLID), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.ID_WHERE_INPUT = ID_WHERE_INPUT; +const STRING_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'StringWhereInput', + description: 'The StringWhereInput input type is used in operations that involve filtering objects by a field of type String.', + fields: { + equalTo: equalTo(_graphql.GraphQLString), + notEqualTo: notEqualTo(_graphql.GraphQLString), + lessThan: lessThan(_graphql.GraphQLString), + lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLString), + greaterThan: greaterThan(_graphql.GraphQLString), + greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLString), + in: inOp(_graphql.GraphQLString), + notIn: notIn(_graphql.GraphQLString), + exists, + matchesRegex, + options, + text: { + description: 'This is the $text operator to specify a full text search constraint.', + type: TEXT_INPUT + }, + inQueryKey, + notInQueryKey + } +}); +exports.STRING_WHERE_INPUT = STRING_WHERE_INPUT; +const NUMBER_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'NumberWhereInput', + description: 'The NumberWhereInput input type is used in operations that involve filtering objects by a field of type Number.', + fields: { + equalTo: equalTo(_graphql.GraphQLFloat), + notEqualTo: notEqualTo(_graphql.GraphQLFloat), + lessThan: lessThan(_graphql.GraphQLFloat), + lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLFloat), + greaterThan: greaterThan(_graphql.GraphQLFloat), + greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLFloat), + in: inOp(_graphql.GraphQLFloat), + notIn: notIn(_graphql.GraphQLFloat), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.NUMBER_WHERE_INPUT = NUMBER_WHERE_INPUT; +const BOOLEAN_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'BooleanWhereInput', + description: 'The BooleanWhereInput input type is used in operations that involve filtering objects by a field of type Boolean.', + fields: { + equalTo: equalTo(_graphql.GraphQLBoolean), + notEqualTo: notEqualTo(_graphql.GraphQLBoolean), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.BOOLEAN_WHERE_INPUT = BOOLEAN_WHERE_INPUT; +const ARRAY_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ArrayWhereInput', + description: 'The ArrayWhereInput input type is used in operations that involve filtering objects by a field of type Array.', + fields: { + equalTo: equalTo(ANY), + notEqualTo: notEqualTo(ANY), + lessThan: lessThan(ANY), + lessThanOrEqualTo: lessThanOrEqualTo(ANY), + greaterThan: greaterThan(ANY), + greaterThanOrEqualTo: greaterThanOrEqualTo(ANY), + in: inOp(ANY), + notIn: notIn(ANY), + exists, + containedBy: { + description: 'This is the containedBy operator to specify a constraint to select the objects where the values of an array field is contained by another specified array.', + type: new _graphql.GraphQLList(ANY) + }, + contains: { + description: 'This is the contains operator to specify a constraint to select the objects where the values of an array field contain all elements of another specified array.', + type: new _graphql.GraphQLList(ANY) + }, + inQueryKey, + notInQueryKey + } +}); +exports.ARRAY_WHERE_INPUT = ARRAY_WHERE_INPUT; +const KEY_VALUE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'KeyValueInput', + description: 'An entry from an object, i.e., a pair of key and value.', + fields: { + key: { + description: 'The key used to retrieve the value of this entry.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + value: { + description: 'The value of the entry. Could be any type of scalar data.', + type: new _graphql.GraphQLNonNull(ANY) + } + } +}); +exports.KEY_VALUE_INPUT = KEY_VALUE_INPUT; +const OBJECT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ObjectWhereInput', + description: 'The ObjectWhereInput input type is used in operations that involve filtering result by a field of type Object.', + fields: { + equalTo: equalTo(KEY_VALUE_INPUT), + notEqualTo: notEqualTo(KEY_VALUE_INPUT), + in: inOp(KEY_VALUE_INPUT), + notIn: notIn(KEY_VALUE_INPUT), + lessThan: lessThan(KEY_VALUE_INPUT), + lessThanOrEqualTo: lessThanOrEqualTo(KEY_VALUE_INPUT), + greaterThan: greaterThan(KEY_VALUE_INPUT), + greaterThanOrEqualTo: greaterThanOrEqualTo(KEY_VALUE_INPUT), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.OBJECT_WHERE_INPUT = OBJECT_WHERE_INPUT; +const DATE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'DateWhereInput', + description: 'The DateWhereInput input type is used in operations that involve filtering objects by a field of type Date.', + fields: { + equalTo: equalTo(DATE), + notEqualTo: notEqualTo(DATE), + lessThan: lessThan(DATE), + lessThanOrEqualTo: lessThanOrEqualTo(DATE), + greaterThan: greaterThan(DATE), + greaterThanOrEqualTo: greaterThanOrEqualTo(DATE), + in: inOp(DATE), + notIn: notIn(DATE), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.DATE_WHERE_INPUT = DATE_WHERE_INPUT; +const BYTES_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'BytesWhereInput', + description: 'The BytesWhereInput input type is used in operations that involve filtering objects by a field of type Bytes.', + fields: { + equalTo: equalTo(BYTES), + notEqualTo: notEqualTo(BYTES), + lessThan: lessThan(BYTES), + lessThanOrEqualTo: lessThanOrEqualTo(BYTES), + greaterThan: greaterThan(BYTES), + greaterThanOrEqualTo: greaterThanOrEqualTo(BYTES), + in: inOp(BYTES), + notIn: notIn(BYTES), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.BYTES_WHERE_INPUT = BYTES_WHERE_INPUT; +const FILE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'FileWhereInput', + description: 'The FileWhereInput input type is used in operations that involve filtering objects by a field of type File.', + fields: { + equalTo: equalTo(FILE), + notEqualTo: notEqualTo(FILE), + lessThan: lessThan(FILE), + lessThanOrEqualTo: lessThanOrEqualTo(FILE), + greaterThan: greaterThan(FILE), + greaterThanOrEqualTo: greaterThanOrEqualTo(FILE), + in: inOp(FILE), + notIn: notIn(FILE), + exists, + matchesRegex, + options, + inQueryKey, + notInQueryKey + } +}); +exports.FILE_WHERE_INPUT = FILE_WHERE_INPUT; +const GEO_POINT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoPointWhereInput', + description: 'The GeoPointWhereInput input type is used in operations that involve filtering objects by a field of type GeoPoint.', + fields: { + exists, + nearSphere: { + description: 'This is the nearSphere operator to specify a constraint to select the objects where the values of a geo point field is near to another geo point.', + type: GEO_POINT_INPUT + }, + maxDistance: { + description: 'This is the maxDistance operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + maxDistanceInRadians: { + description: 'This is the maxDistanceInRadians operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + maxDistanceInMiles: { + description: 'This is the maxDistanceInMiles operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in miles) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + maxDistanceInKilometers: { + description: 'This is the maxDistanceInKilometers operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in kilometers) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + within: { + description: 'This is the within operator to specify a constraint to select the objects where the values of a geo point field is within a specified box.', + type: WITHIN_INPUT + }, + geoWithin: { + description: 'This is the geoWithin operator to specify a constraint to select the objects where the values of a geo point field is within a specified polygon or sphere.', + type: GEO_WITHIN_INPUT + } + } +}); +exports.GEO_POINT_WHERE_INPUT = GEO_POINT_WHERE_INPUT; +const POLYGON_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'PolygonWhereInput', + description: 'The PolygonWhereInput input type is used in operations that involve filtering objects by a field of type Polygon.', + fields: { + exists, + geoIntersects: { + description: 'This is the geoIntersects operator to specify a constraint to select the objects where the values of a polygon field intersect a specified point.', + type: GEO_INTERSECTS_INPUT + } + } +}); +exports.POLYGON_WHERE_INPUT = POLYGON_WHERE_INPUT; +const ELEMENT = new _graphql.GraphQLObjectType({ + name: 'Element', + description: "The Element object type is used to return array items' value.", + fields: { + value: { + description: 'Return the value of the element in the array', + type: new _graphql.GraphQLNonNull(ANY) + } + } +}); // Default static union type, we update types and resolveType function later + +exports.ELEMENT = ELEMENT; +let ARRAY_RESULT; +exports.ARRAY_RESULT = ARRAY_RESULT; + +const loadArrayResult = (parseGraphQLSchema, parseClasses) => { + const classTypes = parseClasses.filter(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType ? true : false).map(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType); + exports.ARRAY_RESULT = ARRAY_RESULT = new _graphql.GraphQLUnionType({ + name: 'ArrayResult', + description: 'Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments', + types: () => [ELEMENT, ...classTypes], + resolveType: value => { + if (value.__type === 'Object' && value.className && value.objectId) { + if (parseGraphQLSchema.parseClassTypes[value.className]) { + return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType; + } else { + return ELEMENT; + } + } else { + return ELEMENT; + } + } + }); + parseGraphQLSchema.graphQLTypes.push(ARRAY_RESULT); +}; + +exports.loadArrayResult = loadArrayResult; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLType(_links.GraphQLUpload, true); + parseGraphQLSchema.addGraphQLType(ANY, true); + parseGraphQLSchema.addGraphQLType(OBJECT, true); + parseGraphQLSchema.addGraphQLType(DATE, true); + parseGraphQLSchema.addGraphQLType(BYTES, true); + parseGraphQLSchema.addGraphQLType(FILE, true); + parseGraphQLSchema.addGraphQLType(FILE_INFO, true); + parseGraphQLSchema.addGraphQLType(FILE_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_POINT_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_POINT, true); + parseGraphQLSchema.addGraphQLType(PARSE_OBJECT, true); + parseGraphQLSchema.addGraphQLType(READ_PREFERENCE, true); + parseGraphQLSchema.addGraphQLType(READ_OPTIONS_INPUT, true); + parseGraphQLSchema.addGraphQLType(SEARCH_INPUT, true); + parseGraphQLSchema.addGraphQLType(TEXT_INPUT, true); + parseGraphQLSchema.addGraphQLType(BOX_INPUT, true); + parseGraphQLSchema.addGraphQLType(WITHIN_INPUT, true); + parseGraphQLSchema.addGraphQLType(CENTER_SPHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_WITHIN_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_INTERSECTS_INPUT, true); + parseGraphQLSchema.addGraphQLType(ID_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(STRING_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(NUMBER_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(BOOLEAN_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(ARRAY_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(KEY_VALUE_INPUT, true); + parseGraphQLSchema.addGraphQLType(OBJECT_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(DATE_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(BYTES_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(FILE_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_POINT_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(POLYGON_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(ELEMENT, true); + parseGraphQLSchema.addGraphQLType(ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(USER_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(ROLE_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(PUBLIC_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(ACL, true); + parseGraphQLSchema.addGraphQLType(USER_ACL, true); + parseGraphQLSchema.addGraphQLType(ROLE_ACL, true); + parseGraphQLSchema.addGraphQLType(PUBLIC_ACL, true); + parseGraphQLSchema.addGraphQLType(SUBQUERY_INPUT, true); + parseGraphQLSchema.addGraphQLType(SELECT_INPUT, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcy5qcyJdLCJuYW1lcyI6WyJUeXBlVmFsaWRhdGlvbkVycm9yIiwiRXJyb3IiLCJjb25zdHJ1Y3RvciIsInZhbHVlIiwidHlwZSIsInBhcnNlU3RyaW5nVmFsdWUiLCJwYXJzZUludFZhbHVlIiwiaW50IiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwicGFyc2VGbG9hdFZhbHVlIiwiZmxvYXQiLCJpc05hTiIsInBhcnNlQm9vbGVhblZhbHVlIiwicGFyc2VWYWx1ZSIsImtpbmQiLCJLaW5kIiwiU1RSSU5HIiwiSU5UIiwiRkxPQVQiLCJCT09MRUFOIiwiTElTVCIsInBhcnNlTGlzdFZhbHVlcyIsInZhbHVlcyIsIk9CSkVDVCIsInBhcnNlT2JqZWN0RmllbGRzIiwiZmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwicmVkdWNlIiwib2JqZWN0IiwiZmllbGQiLCJuYW1lIiwiQU5ZIiwiR3JhcGhRTFNjYWxhclR5cGUiLCJkZXNjcmlwdGlvbiIsInNlcmlhbGl6ZSIsInBhcnNlTGl0ZXJhbCIsImFzdCIsInBhcnNlRGF0ZUlzb1ZhbHVlIiwiZGF0ZSIsIkRhdGUiLCJzZXJpYWxpemVEYXRlSXNvIiwidG9JU09TdHJpbmciLCJwYXJzZURhdGVJc29MaXRlcmFsIiwiREFURSIsIl9fdHlwZSIsImlzbyIsImZpbmQiLCJCWVRFUyIsImJhc2U2NCIsInBhcnNlRmlsZVZhbHVlIiwidXJsIiwidW5kZWZpbmVkIiwiRklMRSIsIkZJTEVfSU5GTyIsIkdyYXBoUUxPYmplY3RUeXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiRklMRV9JTlBVVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJmaWxlIiwidXBsb2FkIiwiR3JhcGhRTFVwbG9hZCIsInVubGluayIsIkdyYXBoUUxCb29sZWFuIiwiR0VPX1BPSU5UX0ZJRUxEUyIsImxhdGl0dWRlIiwiR3JhcGhRTEZsb2F0IiwibG9uZ2l0dWRlIiwiR0VPX1BPSU5UX0lOUFVUIiwiR0VPX1BPSU5UIiwiUE9MWUdPTl9JTlBVVCIsIkdyYXBoUUxMaXN0IiwiUE9MWUdPTiIsIlVTRVJfQUNMX0lOUFVUIiwidXNlcklkIiwiR3JhcGhRTElEIiwicmVhZCIsIndyaXRlIiwiUk9MRV9BQ0xfSU5QVVQiLCJyb2xlTmFtZSIsIlBVQkxJQ19BQ0xfSU5QVVQiLCJBQ0xfSU5QVVQiLCJ1c2VycyIsInJvbGVzIiwicHVibGljIiwiVVNFUl9BQ0wiLCJST0xFX0FDTCIsIlBVQkxJQ19BQ0wiLCJBQ0wiLCJyZXNvbHZlIiwicCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwicnVsZSIsImluZGV4T2YiLCJwdXNoIiwibGVuZ3RoIiwicmVwbGFjZSIsIk9CSkVDVF9JRCIsIkNMQVNTX05BTUVfQVRUIiwiR0xPQkFMX09SX09CSkVDVF9JRF9BVFQiLCJPQkpFQ1RfSURfQVRUIiwiQ1JFQVRFRF9BVF9BVFQiLCJVUERBVEVEX0FUX0FUVCIsIklOUFVUX0ZJRUxEUyIsIkNSRUFURV9SRVNVTFRfRklFTERTIiwib2JqZWN0SWQiLCJjcmVhdGVkQXQiLCJVUERBVEVfUkVTVUxUX0ZJRUxEUyIsInVwZGF0ZWRBdCIsIlBBUlNFX09CSkVDVF9GSUVMRFMiLCJQQVJTRV9PQkpFQ1QiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsIlNFU1NJT05fVE9LRU5fQVRUIiwiUkVBRF9QUkVGRVJFTkNFIiwiR3JhcGhRTEVudW1UeXBlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJSRUFEX1BSRUZFUkVOQ0VfQVRUIiwiSU5DTFVERV9SRUFEX1BSRUZFUkVOQ0VfQVRUIiwiU1VCUVVFUllfUkVBRF9QUkVGRVJFTkNFX0FUVCIsIlJFQURfT1BUSU9OU19JTlBVVCIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsIlJFQURfT1BUSU9OU19BVFQiLCJXSEVSRV9BVFQiLCJTS0lQX0FUVCIsIkdyYXBoUUxJbnQiLCJMSU1JVF9BVFQiLCJDT1VOVF9BVFQiLCJTRUFSQ0hfSU5QVVQiLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwiVEVYVF9JTlBVVCIsInNlYXJjaCIsIkJPWF9JTlBVVCIsImJvdHRvbUxlZnQiLCJ1cHBlclJpZ2h0IiwiV0lUSElOX0lOUFVUIiwiYm94IiwiQ0VOVEVSX1NQSEVSRV9JTlBVVCIsImNlbnRlciIsImRpc3RhbmNlIiwiR0VPX1dJVEhJTl9JTlBVVCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJHRU9fSU5URVJTRUNUU19JTlBVVCIsInBvaW50IiwiZXF1YWxUbyIsIm5vdEVxdWFsVG8iLCJsZXNzVGhhbiIsImxlc3NUaGFuT3JFcXVhbFRvIiwiZ3JlYXRlclRoYW4iLCJncmVhdGVyVGhhbk9yRXF1YWxUbyIsImluT3AiLCJub3RJbiIsImV4aXN0cyIsIm1hdGNoZXNSZWdleCIsIm9wdGlvbnMiLCJTVUJRVUVSWV9JTlBVVCIsImNsYXNzTmFtZSIsIndoZXJlIiwiYXNzaWduIiwiU0VMRUNUX0lOUFVUIiwicXVlcnkiLCJrZXkiLCJpblF1ZXJ5S2V5Iiwibm90SW5RdWVyeUtleSIsIklEX1dIRVJFX0lOUFVUIiwiaW4iLCJTVFJJTkdfV0hFUkVfSU5QVVQiLCJ0ZXh0IiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiY29udGFpbmVkQnkiLCJjb250YWlucyIsIktFWV9WQUxVRV9JTlBVVCIsIk9CSkVDVF9XSEVSRV9JTlBVVCIsIkRBVEVfV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsIkZJTEVfV0hFUkVfSU5QVVQiLCJHRU9fUE9JTlRfV0hFUkVfSU5QVVQiLCJuZWFyU3BoZXJlIiwibWF4RGlzdGFuY2UiLCJtYXhEaXN0YW5jZUluUmFkaWFucyIsIm1heERpc3RhbmNlSW5NaWxlcyIsIm1heERpc3RhbmNlSW5LaWxvbWV0ZXJzIiwid2l0aGluIiwiZ2VvV2l0aGluIiwiUE9MWUdPTl9XSEVSRV9JTlBVVCIsImdlb0ludGVyc2VjdHMiLCJFTEVNRU5UIiwiQVJSQVlfUkVTVUxUIiwibG9hZEFycmF5UmVzdWx0IiwicGFyc2VHcmFwaFFMU2NoZW1hIiwicGFyc2VDbGFzc2VzIiwiY2xhc3NUeXBlcyIsImZpbHRlciIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiR3JhcGhRTFVuaW9uVHlwZSIsInR5cGVzIiwicmVzb2x2ZVR5cGUiLCJncmFwaFFMVHlwZXMiLCJsb2FkIiwiYWRkR3JhcGhRTFR5cGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFnQkE7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsbUJBQU4sU0FBa0NDLEtBQWxDLENBQXdDO0FBQ3RDQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUUMsSUFBUixFQUFjO0FBQ3ZCLFVBQU8sR0FBRUQsS0FBTSxtQkFBa0JDLElBQUssRUFBdEM7QUFDRDs7QUFIcUM7Ozs7QUFNeEMsTUFBTUMsZ0JBQWdCLEdBQUlGLEtBQUQsSUFBVztBQUNsQyxNQUFJLE9BQU9BLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsV0FBT0EsS0FBUDtBQUNEOztBQUVELFFBQU0sSUFBSUgsbUJBQUosQ0FBd0JHLEtBQXhCLEVBQStCLFFBQS9CLENBQU47QUFDRCxDQU5EOzs7O0FBUUEsTUFBTUcsYUFBYSxHQUFJSCxLQUFELElBQVc7QUFDL0IsTUFBSSxPQUFPQSxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLFVBQU1JLEdBQUcsR0FBR0MsTUFBTSxDQUFDTCxLQUFELENBQWxCOztBQUNBLFFBQUlLLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkYsR0FBakIsQ0FBSixFQUEyQjtBQUN6QixhQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7QUFF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WSxjQUFuQixDQUFrQy9ILFVBQWxDLEVBQThDLElBQTlDO0FBQ0FtSCxFQUFBQSxrQkFBa0IsQ0FBQ1ksY0FBbkIsQ0FBa0NoRCxjQUFsQyxFQUFrRCxJQUFsRDtBQUNBb0MsRUFBQUEsa0JBQWtCLENBQUNZLGNBQW5CLENBQWtDNUMsWUFBbEMsRUFBZ0QsSUFBaEQ7QUFDRCxDQTVDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEtpbmQsXG4gIEdyYXBoUUxOb25OdWxsLFxuICBHcmFwaFFMU2NhbGFyVHlwZSxcbiAgR3JhcGhRTElELFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMT2JqZWN0VHlwZSxcbiAgR3JhcGhRTEludGVyZmFjZVR5cGUsXG4gIEdyYXBoUUxFbnVtVHlwZSxcbiAgR3JhcGhRTEludCxcbiAgR3JhcGhRTEZsb2F0LFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTEJvb2xlYW4sXG4gIEdyYXBoUUxVbmlvblR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgdG9HbG9iYWxJZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgR3JhcGhRTFVwbG9hZCB9IGZyb20gJ0BncmFwaHFsLXRvb2xzL2xpbmtzJztcblxuY2xhc3MgVHlwZVZhbGlkYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IodmFsdWUsIHR5cGUpIHtcbiAgICBzdXBlcihgJHt2YWx1ZX0gaXMgbm90IGEgdmFsaWQgJHt0eXBlfWApO1xuICB9XG59XG5cbmNvbnN0IHBhcnNlU3RyaW5nVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ1N0cmluZycpO1xufTtcblxuY29uc3QgcGFyc2VJbnRWYWx1ZSA9ICh2YWx1ZSkgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGludCA9IE51bWJlcih2YWx1ZSk7XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIoaW50KSkge1xuICAgICAgcmV0dXJuIGludDtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0ludCcpO1xufTtcblxuY29uc3QgcGFyc2VGbG9hdFZhbHVlID0gKHZhbHVlKSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgZmxvYXQgPSBOdW1iZXIodmFsdWUpO1xuICAgIGlmICghaXNOYU4oZmxvYXQpKSB7XG4gICAgICByZXR1cm4gZmxvYXQ7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdGbG9hdCcpO1xufTtcblxuY29uc3QgcGFyc2VCb29sZWFuVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdCb29sZWFuJyk7XG59O1xuXG5jb25zdCBwYXJzZVZhbHVlID0gKHZhbHVlKSA9PiB7XG4gIHN3aXRjaCAodmFsdWUua2luZCkge1xuICAgIGNhc2UgS2luZC5TVFJJTkc6XG4gICAgICByZXR1cm4gcGFyc2VTdHJpbmdWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuSU5UOlxuICAgICAgcmV0dXJuIHBhcnNlSW50VmFsdWUodmFsdWUudmFsdWUpO1xuXG4gICAgY2FzZSBLaW5kLkZMT0FUOlxuICAgICAgcmV0dXJuIHBhcnNlRmxvYXRWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuQk9PTEVBTjpcbiAgICAgIHJldHVybiBwYXJzZUJvb2xlYW5WYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuTElTVDpcbiAgICAgIHJldHVybiBwYXJzZUxpc3RWYWx1ZXModmFsdWUudmFsdWVzKTtcblxuICAgIGNhc2UgS2luZC5PQkpFQ1Q6XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RGaWVsZHModmFsdWUuZmllbGRzKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdmFsdWUudmFsdWU7XG4gIH1cbn07XG5cbmNvbnN0IHBhcnNlTGlzdFZhbHVlcyA9ICh2YWx1ZXMpID0+IHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xuICAgIHJldHVybiB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4gcGFyc2VWYWx1ZSh2YWx1ZSkpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWVzLCAnTGlzdCcpO1xufTtcblxuY29uc3QgcGFyc2VPYmplY3RGaWVsZHMgPSAoZmllbGRzKSA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KGZpZWxkcykpIHtcbiAgICByZXR1cm4gZmllbGRzLnJlZHVjZShcbiAgICAgIChvYmplY3QsIGZpZWxkKSA9PiAoe1xuICAgICAgICAuLi5vYmplY3QsXG4gICAgICAgIFtmaWVsZC5uYW1lLnZhbHVlXTogcGFyc2VWYWx1ZShmaWVsZC52YWx1ZSksXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGZpZWxkcywgJ09iamVjdCcpO1xufTtcblxuY29uc3QgQU5ZID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0FueScsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQW55IHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGFueSB0eXBlIG9mIHZhbHVlLicsXG4gIHBhcnNlVmFsdWU6ICh2YWx1ZSkgPT4gdmFsdWUsXG4gIHNlcmlhbGl6ZTogKHZhbHVlKSA9PiB2YWx1ZSxcbiAgcGFyc2VMaXRlcmFsOiAoYXN0KSA9PiBwYXJzZVZhbHVlKGFzdCksXG59KTtcblxuY29uc3QgT0JKRUNUID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ09iamVjdCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgT2JqZWN0IHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIG9iamVjdHMuJyxcbiAgcGFyc2VWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdPYmplY3QnKTtcbiAgfSxcbiAgc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ09iamVjdCcpO1xuICB9LFxuICBwYXJzZUxpdGVyYWwoYXN0KSB7XG4gICAgaWYgKGFzdC5raW5kID09PSBLaW5kLk9CSkVDVCkge1xuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0RmllbGRzKGFzdC5maWVsZHMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnT2JqZWN0Jyk7XG4gIH0sXG59KTtcblxuY29uc3QgcGFyc2VEYXRlSXNvVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgIGlmICghaXNOYU4oZGF0ZSkpIHtcbiAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cbiAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0RhdGUnKTtcbn07XG5cbmNvbnN0IHNlcmlhbGl6ZURhdGVJc28gPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG59O1xuXG5jb25zdCBwYXJzZURhdGVJc29MaXRlcmFsID0gKGFzdCkgPT4ge1xuICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgcmV0dXJuIHBhcnNlRGF0ZUlzb1ZhbHVlKGFzdC52YWx1ZSk7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ0RhdGUnKTtcbn07XG5cbmNvbnN0IERBVEUgPSBuZXcgR3JhcGhRTFNjYWxhclR5cGUoe1xuICBuYW1lOiAnRGF0ZScsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRGF0ZSBzY2FsYXIgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgYW5kIHR5cGVzIHRoYXQgaW52b2x2ZSBkYXRlcy4nLFxuICBwYXJzZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29WYWx1ZSh2YWx1ZSksXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICB2YWx1ZS5fX3R5cGUgPT09ICdEYXRlJyAmJlxuICAgICAgdmFsdWUuaXNvXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6IHZhbHVlLl9fdHlwZSxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29WYWx1ZSh2YWx1ZS5pc28pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0RhdGUnKTtcbiAgfSxcbiAgc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4gc2VyaWFsaXplRGF0ZUlzbyh2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnICYmXG4gICAgICB2YWx1ZS5pc29cbiAgICApIHtcbiAgICAgIHJldHVybiBzZXJpYWxpemVEYXRlSXNvKHZhbHVlLmlzbyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG4gIH0sXG4gIHBhcnNlTGl0ZXJhbChhc3QpIHtcbiAgICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29MaXRlcmFsKGFzdCksXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYXN0LmtpbmQgPT09IEtpbmQuT0JKRUNUKSB7XG4gICAgICBjb25zdCBfX3R5cGUgPSBhc3QuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnX190eXBlJyk7XG4gICAgICBjb25zdCBpc28gPSBhc3QuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnaXNvJyk7XG4gICAgICBpZiAoX190eXBlICYmIF9fdHlwZS52YWx1ZSAmJiBfX3R5cGUudmFsdWUudmFsdWUgPT09ICdEYXRlJyAmJiBpc28pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBfX3R5cGU6IF9fdHlwZS52YWx1ZS52YWx1ZSxcbiAgICAgICAgICBpc286IHBhcnNlRGF0ZUlzb0xpdGVyYWwoaXNvLnZhbHVlKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ0RhdGUnKTtcbiAgfSxcbn0pO1xuXG5jb25zdCBCWVRFUyA9IG5ldyBHcmFwaFFMU2NhbGFyVHlwZSh7XG4gIG5hbWU6ICdCeXRlcycsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQnl0ZXMgc2NhbGFyIHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIGFuZCB0eXBlcyB0aGF0IGludm9sdmUgYmFzZSA2NCBiaW5hcnkgZGF0YS4nLFxuICBwYXJzZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ0J5dGVzJyxcbiAgICAgICAgYmFzZTY0OiB2YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJyAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmJhc2U2NCA9PT0gJ3N0cmluZydcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0J5dGVzJyk7XG4gIH0sXG4gIHNlcmlhbGl6ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJyAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmJhc2U2NCA9PT0gJ3N0cmluZydcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZS5iYXNlNjQ7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdCeXRlcycpO1xuICB9LFxuICBwYXJzZUxpdGVyYWwoYXN0KSB7XG4gICAgaWYgKGFzdC5raW5kID09PSBLaW5kLlNUUklORykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnQnl0ZXMnLFxuICAgICAgICBiYXNlNjQ6IGFzdC52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChhc3Qua2luZCA9PT0gS2luZC5PQkpFQ1QpIHtcbiAgICAgIGNvbnN0IF9fdHlwZSA9IGFzdC5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdfX3R5cGUnKTtcbiAgICAgIGNvbnN0IGJhc2U2NCA9IGFzdC5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdiYXNlNjQnKTtcbiAgICAgIGlmIChcbiAgICAgICAgX190eXBlICYmXG4gICAgICAgIF9fdHlwZS52YWx1ZSAmJlxuICAgICAgICBfX3R5cGUudmFsdWUudmFsdWUgPT09ICdCeXRlcycgJiZcbiAgICAgICAgYmFzZTY0ICYmXG4gICAgICAgIGJhc2U2NC52YWx1ZSAmJlxuICAgICAgICB0eXBlb2YgYmFzZTY0LnZhbHVlLnZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgX190eXBlOiBfX3R5cGUudmFsdWUudmFsdWUsXG4gICAgICAgICAgYmFzZTY0OiBiYXNlNjQudmFsdWUudmFsdWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IoYXN0LmtpbmQsICdCeXRlcycpO1xuICB9LFxufSk7XG5cbmNvbnN0IHBhcnNlRmlsZVZhbHVlID0gKHZhbHVlKSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogJ0ZpbGUnLFxuICAgICAgbmFtZTogdmFsdWUsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUuX190eXBlID09PSAnRmlsZScgJiZcbiAgICB0eXBlb2YgdmFsdWUubmFtZSA9PT0gJ3N0cmluZycgJiZcbiAgICAodmFsdWUudXJsID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHZhbHVlLnVybCA9PT0gJ3N0cmluZycpXG4gICkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRmlsZScpO1xufTtcblxuY29uc3QgRklMRSA9IG5ldyBHcmFwaFFMU2NhbGFyVHlwZSh7XG4gIG5hbWU6ICdGaWxlJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBGaWxlIHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGZpbGVzLicsXG4gIHBhcnNlVmFsdWU6IHBhcnNlRmlsZVZhbHVlLFxuICBzZXJpYWxpemU6ICh2YWx1ZSkgPT4ge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0ZpbGUnICYmXG4gICAgICB0eXBlb2YgdmFsdWUubmFtZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICh2YWx1ZS51cmwgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdmFsdWUudXJsID09PSAnc3RyaW5nJylcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZS5uYW1lO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRmlsZScpO1xuICB9LFxuICBwYXJzZUxpdGVyYWwoYXN0KSB7XG4gICAgaWYgKGFzdC5raW5kID09PSBLaW5kLlNUUklORykge1xuICAgICAgcmV0dXJuIHBhcnNlRmlsZVZhbHVlKGFzdC52YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChhc3Qua2luZCA9PT0gS2luZC5PQkpFQ1QpIHtcbiAgICAgIGNvbnN0IF9fdHlwZSA9IGFzdC5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdfX3R5cGUnKTtcbiAgICAgIGNvbnN0IG5hbWUgPSBhc3QuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnbmFtZScpO1xuICAgICAgY29uc3QgdXJsID0gYXN0LmZpZWxkcy5maW5kKChmaWVsZCkgPT4gZmllbGQubmFtZS52YWx1ZSA9PT0gJ3VybCcpO1xuICAgICAgaWYgKF9fdHlwZSAmJiBfX3R5cGUudmFsdWUgJiYgbmFtZSAmJiBuYW1lLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUZpbGVWYWx1ZSh7XG4gICAgICAgICAgX190eXBlOiBfX3R5cGUudmFsdWUudmFsdWUsXG4gICAgICAgICAgbmFtZTogbmFtZS52YWx1ZS52YWx1ZSxcbiAgICAgICAgICB1cmw6IHVybCAmJiB1cmwudmFsdWUgPyB1cmwudmFsdWUudmFsdWUgOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnRmlsZScpO1xuICB9LFxufSk7XG5cbmNvbnN0IEZJTEVfSU5GTyA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdGaWxlSW5mbycsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRmlsZUluZm8gb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGZpbGVzLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZmlsZSBuYW1lLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICB1cmw6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgdXJsIGluIHdoaWNoIHRoZSBmaWxlIGNhbiBiZSBkb3dubG9hZGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBGSUxFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnRmlsZUlucHV0JyxcbiAgZmllbGRzOiB7XG4gICAgZmlsZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBIEZpbGUgU2NhbGFyIGNhbiBiZSBhbiB1cmwgb3IgYSBGaWxlSW5mbyBvYmplY3QuIElmIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwgdGhlIGZpbGUgd2lsbCBiZSB1bmxpbmtlZC4nLFxuICAgICAgdHlwZTogRklMRSxcbiAgICB9LFxuICAgIHVwbG9hZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdVc2UgdGhpcyBmaWVsZCBpZiB5b3Ugd2FudCB0byBjcmVhdGUgYSBuZXcgZmlsZS4nLFxuICAgICAgdHlwZTogR3JhcGhRTFVwbG9hZCxcbiAgICB9LFxuICAgIHVubGluazoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdVc2UgdGhpcyBmaWVsZCBpZiB5b3Ugd2FudCB0byB1bmxpbmsgdGhlIGZpbGUgKHRoZSBmaWxlIHdpbGwgbm90IGJlIGRlbGV0ZWQgb24gY2xvdWQgc3RvcmFnZSknLFxuICAgICAgdHlwZTogR3JhcGhRTEJvb2xlYW4sXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBHRU9fUE9JTlRfRklFTERTID0ge1xuICBsYXRpdHVkZToge1xuICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbGF0aXR1ZGUuJyxcbiAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEZsb2F0KSxcbiAgfSxcbiAgbG9uZ2l0dWRlOiB7XG4gICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBsb25naXR1ZGUuJyxcbiAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEZsb2F0KSxcbiAgfSxcbn07XG5cbmNvbnN0IEdFT19QT0lOVF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1BvaW50SW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEdlb1BvaW50SW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGlucHV0dGluZyBmaWVsZHMgb2YgdHlwZSBnZW8gcG9pbnQuJyxcbiAgZmllbGRzOiBHRU9fUE9JTlRfRklFTERTLFxufSk7XG5cbmNvbnN0IEdFT19QT0lOVCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdHZW9Qb2ludCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvUG9pbnQgb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGdlbyBwb2ludCBmaWVsZHMuJyxcbiAgZmllbGRzOiBHRU9fUE9JTlRfRklFTERTLFxufSk7XG5cbmNvbnN0IFBPTFlHT05fSU5QVVQgPSBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKEdFT19QT0lOVF9JTlBVVCkpO1xuXG5jb25zdCBQT0xZR09OID0gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlQpKTtcblxuY29uc3QgVVNFUl9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdVc2VyQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSB1c2VycyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgdXNlcklkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0lEIG9mIHRoZSB0YXJnZXR0ZWQgVXNlci4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxJRCksXG4gICAgfSxcbiAgICByZWFkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdGhlIHVzZXIgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUk9MRV9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdSb2xlQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSByb2xlcyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFBVQkxJQ19BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0xJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnQWxsb3cgdG8gbWFuYWdlIHB1YmxpYyByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIGFjY2VzcyByaWdodHMuIElmIG5vdCBwcm92aWRlZCBvYmplY3Qgd2lsbCBiZSBwdWJsaWNseSByZWFkYWJsZSBhbmQgd3JpdGFibGUnLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTF9JTlBVVCkpLFxuICAgIH0sXG4gICAgcm9sZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWNjZXNzIGNvbnRyb2wgbGlzdCBmb3Igcm9sZXMuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoUk9MRV9BQ0xfSU5QVVQpKSxcbiAgICB9LFxuICAgIHB1YmxpYzoge1xuICAgICAgZGVzY3JpcHRpb246ICdQdWJsaWMgYWNjZXNzIGNvbnRyb2wgbGlzdC4nLFxuICAgICAgdHlwZTogUFVCTElDX0FDTF9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFVTRVJfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1VzZXJBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHVzZXJzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHVzZXJzIGhhdmUgcmVhZCBhbmQgd3JpdGUgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHVzZXJJZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdJRCBvZiB0aGUgdGFyZ2V0dGVkIFVzZXIuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB0aGUgdXNlciB0byByZWFkIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFJPTEVfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1JvbGVBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHJvbGVzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHJvbGUgaGF2ZSByZWFkIGFuZCB3cml0ZSByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUFVCTElDX0FDTCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0wnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSBwdWJsaWMgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgYW55b25lIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IGFueW9uZSB0byB3cml0ZSBvbiB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0FDTCcsXG4gIGRlc2NyaXB0aW9uOiAnQ3VycmVudCBhY2Nlc3MgY29udHJvbCBsaXN0IG9mIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTCkpLFxuICAgICAgcmVzb2x2ZShwKSB7XG4gICAgICAgIGNvbnN0IHVzZXJzID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHApLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgICBpZiAocnVsZSAhPT0gJyonICYmIHJ1bGUuaW5kZXhPZigncm9sZTonKSAhPT0gMCkge1xuICAgICAgICAgICAgdXNlcnMucHVzaCh7XG4gICAgICAgICAgICAgIHVzZXJJZDogdG9HbG9iYWxJZCgnX1VzZXInLCBydWxlKSxcbiAgICAgICAgICAgICAgcmVhZDogcFtydWxlXS5yZWFkID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICB3cml0ZTogcFtydWxlXS53cml0ZSA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1c2Vycy5sZW5ndGggPyB1c2VycyA6IG51bGw7XG4gICAgICB9LFxuICAgIH0sXG4gICAgcm9sZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWNjZXNzIGNvbnRyb2wgbGlzdCBmb3Igcm9sZXMuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoUk9MRV9BQ0wpKSxcbiAgICAgIHJlc29sdmUocCkge1xuICAgICAgICBjb25zdCByb2xlcyA9IFtdO1xuICAgICAgICBPYmplY3Qua2V5cyhwKS5mb3JFYWNoKChydWxlKSA9PiB7XG4gICAgICAgICAgaWYgKHJ1bGUuaW5kZXhPZigncm9sZTonKSA9PT0gMCkge1xuICAgICAgICAgICAgcm9sZXMucHVzaCh7XG4gICAgICAgICAgICAgIHJvbGVOYW1lOiBydWxlLnJlcGxhY2UoJ3JvbGU6JywgJycpLFxuICAgICAgICAgICAgICByZWFkOiBwW3J1bGVdLnJlYWQgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICAgIHdyaXRlOiBwW3J1bGVdLndyaXRlID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJvbGVzLmxlbmd0aCA/IHJvbGVzIDogbnVsbDtcbiAgICAgIH0sXG4gICAgfSxcbiAgICBwdWJsaWM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnUHVibGljIGFjY2VzcyBjb250cm9sIGxpc3QuJyxcbiAgICAgIHR5cGU6IFBVQkxJQ19BQ0wsXG4gICAgICByZXNvbHZlKHApIHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgKi9cbiAgICAgICAgcmV0dXJuIHBbJyonXVxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICByZWFkOiBwWycqJ10ucmVhZCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgd3JpdGU6IHBbJyonXS53cml0ZSA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IG51bGw7XG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgT0JKRUNUX0lEID0gbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxJRCk7XG5cbmNvbnN0IENMQVNTX05BTUVfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNsYXNzIG5hbWUgb2YgdGhlIG9iamVjdC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBPQkpFQ1RfSURfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBDUkVBVEVEX0FUX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBkYXRlIGluIHdoaWNoIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKERBVEUpLFxufTtcblxuY29uc3QgVVBEQVRFRF9BVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZGF0ZSBpbiB3aGljaCB0aGUgb2JqZWN0IHdhcyBsYXMgdXBkYXRlZC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoREFURSksXG59O1xuXG5jb25zdCBJTlBVVF9GSUVMRFMgPSB7XG4gIEFDTDoge1xuICAgIHR5cGU6IEFDTCxcbiAgfSxcbn07XG5cbmNvbnN0IENSRUFURV9SRVNVTFRfRklFTERTID0ge1xuICBvYmplY3RJZDogT0JKRUNUX0lEX0FUVCxcbiAgY3JlYXRlZEF0OiBDUkVBVEVEX0FUX0FUVCxcbn07XG5cbmNvbnN0IFVQREFURV9SRVNVTFRfRklFTERTID0ge1xuICB1cGRhdGVkQXQ6IFVQREFURURfQVRfQVRULFxufTtcblxuY29uc3QgUEFSU0VfT0JKRUNUX0ZJRUxEUyA9IHtcbiAgLi4uQ1JFQVRFX1JFU1VMVF9GSUVMRFMsXG4gIC4uLlVQREFURV9SRVNVTFRfRklFTERTLFxuICAuLi5JTlBVVF9GSUVMRFMsXG4gIEFDTDoge1xuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBQ0wpLFxuICAgIHJlc29sdmU6ICh7IEFDTCB9KSA9PiAoQUNMID8gQUNMIDogeyAnKic6IHsgcmVhZDogdHJ1ZSwgd3JpdGU6IHRydWUgfSB9KSxcbiAgfSxcbn07XG5cbmNvbnN0IFBBUlNFX09CSkVDVCA9IG5ldyBHcmFwaFFMSW50ZXJmYWNlVHlwZSh7XG4gIG5hbWU6ICdQYXJzZU9iamVjdCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUGFyc2VPYmplY3QgaW50ZXJmYWNlIHR5cGUgaXMgdXNlZCBhcyBhIGJhc2UgdHlwZSBmb3IgdGhlIGF1dG8gZ2VuZXJhdGVkIG9iamVjdCB0eXBlcy4nLFxuICBmaWVsZHM6IFBBUlNFX09CSkVDVF9GSUVMRFMsXG59KTtcblxuY29uc3QgU0VTU0lPTl9UT0tFTl9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIGN1cnJlbnQgdXNlciBzZXNzaW9uIHRva2VuLicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IFJFQURfUFJFRkVSRU5DRSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICBuYW1lOiAnUmVhZFByZWZlcmVuY2UnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFJlYWRQcmVmZXJlbmNlIGVudW0gdHlwZSBpcyB1c2VkIGluIHF1ZXJpZXMgaW4gb3JkZXIgdG8gc2VsZWN0IGluIHdoaWNoIGRhdGFiYXNlIHJlcGxpY2EgdGhlIG9wZXJhdGlvbiBtdXN0IHJ1bi4nLFxuICB2YWx1ZXM6IHtcbiAgICBQUklNQVJZOiB7IHZhbHVlOiAnUFJJTUFSWScgfSxcbiAgICBQUklNQVJZX1BSRUZFUlJFRDogeyB2YWx1ZTogJ1BSSU1BUllfUFJFRkVSUkVEJyB9LFxuICAgIFNFQ09OREFSWTogeyB2YWx1ZTogJ1NFQ09OREFSWScgfSxcbiAgICBTRUNPTkRBUllfUFJFRkVSUkVEOiB7IHZhbHVlOiAnU0VDT05EQVJZX1BSRUZFUlJFRCcgfSxcbiAgICBORUFSRVNUOiB7IHZhbHVlOiAnTkVBUkVTVCcgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBSRUFEX1BSRUZFUkVOQ0VfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBtYWluIHF1ZXJ5IHRvIGJlIGV4ZWN1dGVkLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBxdWVyaWVzIHRvIGJlIGV4ZWN1dGVkIHRvIGluY2x1ZGUgZmllbGRzLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IFNVQlFVRVJZX1JFQURfUFJFRkVSRU5DRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIHJlYWQgcHJlZmVyZW5jZSBmb3IgdGhlIHN1YnF1ZXJpZXMgdGhhdCBtYXkgYmUgcmVxdWlyZWQuJyxcbiAgdHlwZTogUkVBRF9QUkVGRVJFTkNFLFxufTtcblxuY29uc3QgUkVBRF9PUFRJT05TX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUmVhZE9wdGlvbnNJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUmVhZE9wdGlvbnNJbnB1dHQgdHlwZSBpcyB1c2VkIGluIHF1ZXJpZXMgaW4gb3JkZXIgdG8gc2V0IHRoZSByZWFkIHByZWZlcmVuY2VzLicsXG4gIGZpZWxkczoge1xuICAgIHJlYWRQcmVmZXJlbmNlOiBSRUFEX1BSRUZFUkVOQ0VfQVRULFxuICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZTogSU5DTFVERV9SRUFEX1BSRUZFUkVOQ0VfQVRULFxuICAgIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U6IFNVQlFVRVJZX1JFQURfUFJFRkVSRU5DRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgUkVBRF9PUFRJT05TX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGUgcmVhZCBvcHRpb25zIGZvciB0aGUgcXVlcnkgdG8gYmUgZXhlY3V0ZWQuJyxcbiAgdHlwZTogUkVBRF9PUFRJT05TX0lOUFVULFxufTtcblxuY29uc3QgV0hFUkVfQVRUID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlc2UgYXJlIHRoZSBjb25kaXRpb25zIHRoYXQgdGhlIG9iamVjdHMgbmVlZCB0byBtYXRjaCBpbiBvcmRlciB0byBiZSBmb3VuZCcsXG4gIHR5cGU6IE9CSkVDVCxcbn07XG5cbmNvbnN0IFNLSVBfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG51bWJlciBvZiBvYmplY3RzIHRoYXQgbXVzdCBiZSBza2lwcGVkIHRvIHJldHVybi4nLFxuICB0eXBlOiBHcmFwaFFMSW50LFxufTtcblxuY29uc3QgTElNSVRfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGxpbWl0IG51bWJlciBvZiBvYmplY3RzIHRoYXQgbXVzdCBiZSByZXR1cm5lZC4nLFxuICB0eXBlOiBHcmFwaFFMSW50LFxufTtcblxuY29uc3QgQ09VTlRfQVRUID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgdG90YWwgbWF0Y2hlZCBvYmplY3MgY291bnQgdGhhdCBpcyByZXR1cm5lZCB3aGVuIHRoZSBjb3VudCBmbGFnIGlzIHNldC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEludCksXG59O1xuXG5jb25zdCBTRUFSQ0hfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTZWFyY2hJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2VhcmNoSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgc2VhcmNoIG9wZXJhdGlvbiBvbiBhIGZ1bGwgdGV4dCBzZWFyY2guJyxcbiAgZmllbGRzOiB7XG4gICAgdGVybToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB0ZXJtIHRvIGJlIHNlYXJjaGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICBsYW5ndWFnZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBsYW5ndWFnZSB0byB0ZXRlcm1pbmUgdGhlIGxpc3Qgb2Ygc3RvcCB3b3JkcyBhbmQgdGhlIHJ1bGVzIGZvciB0b2tlbml6ZXIuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBjYXNlU2Vuc2l0aXZlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGZsYWcgdG8gZW5hYmxlIG9yIGRpc2FibGUgY2FzZSBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIGRpYWNyaXRpY1NlbnNpdGl2ZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIGRpYWNyaXRpYyBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFRFWFRfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdUZXh0SW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFRleHRJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHRleHQgb3BlcmF0aW9uIG9uIGEgY29uc3RyYWludC4nLFxuICBmaWVsZHM6IHtcbiAgICBzZWFyY2g6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgc2VhcmNoIHRvIGJlIGV4ZWN1dGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoU0VBUkNIX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEJPWF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0JveElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBCb3hJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmaXkgYSBib3ggb3BlcmF0aW9uIG9uIGEgd2l0aGluIGdlbyBxdWVyeS4nLFxuICBmaWVsZHM6IHtcbiAgICBib3R0b21MZWZ0OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGJvdHRvbSBsZWZ0IGNvb3JkaW5hdGVzIG9mIHRoZSBib3guJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gICAgdXBwZXJSaWdodDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cHBlciByaWdodCBjb29yZGluYXRlcyBvZiB0aGUgYm94LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR0VPX1BPSU5UX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFdJVEhJTl9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1dpdGhpbklucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBXaXRoaW5JbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHdpdGhpbiBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIGJveDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBib3ggdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoQk9YX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IENFTlRFUl9TUEhFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdDZW50ZXJTcGhlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQ2VudGVyU3BoZXJlSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgY2VudGVyU3BoZXJlIG9wZXJhdGlvbiBvbiBhIGdlb1dpdGhpbiBxdWVyeS4nLFxuICBmaWVsZHM6IHtcbiAgICBjZW50ZXI6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY2VudGVyIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gICAgZGlzdGFuY2U6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcmFkaXVzIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgR0VPX1dJVEhJTl9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1dpdGhpbklucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBHZW9XaXRoaW5JbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIGdlb1dpdGhpbiBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIHBvbHlnb246IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcG9seWdvbiB0byBiZSBzcGVjaWZpZWQuJyxcbiAgICAgIHR5cGU6IFBPTFlHT05fSU5QVVQsXG4gICAgfSxcbiAgICBjZW50ZXJTcGhlcmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgc3BoZXJlIHRvIGJlIHNwZWNpZmllZC4nLFxuICAgICAgdHlwZTogQ0VOVEVSX1NQSEVSRV9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEdFT19JTlRFUlNFQ1RTX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnR2VvSW50ZXJzZWN0c0lucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBHZW9JbnRlcnNlY3RzSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSBnZW9JbnRlcnNlY3RzIG9wZXJhdGlvbiBvbiBhIGNvbnN0cmFpbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgcG9pbnQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcG9pbnQgdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBHRU9fUE9JTlRfSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBlcXVhbFRvID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBlcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBlcXVhbHMgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBub3RFcXVhbFRvID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBkbyBub3QgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBsZXNzVGhhbiA9ICh0eXBlKSA9PiAoe1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgbGVzc1RoYW4gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGlzIGxlc3MgdGhhbiBhIHNwZWNpZmllZCB2YWx1ZS4nLFxuICB0eXBlLFxufSk7XG5cbmNvbnN0IGxlc3NUaGFuT3JFcXVhbFRvID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBsZXNzVGhhbk9yRXF1YWxUbyBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlIG9mIGEgZmllbGQgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGEgc3BlY2lmaWVkIHZhbHVlLicsXG4gIHR5cGUsXG59KTtcblxuY29uc3QgZ3JlYXRlclRoYW4gPSAodHlwZSkgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGdyZWF0ZXJUaGFuIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBncmVhdGVyIHRoYW4gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBncmVhdGVyVGhhbk9yRXF1YWxUbyA9ICh0eXBlKSA9PiAoe1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgZ3JlYXRlclRoYW5PckVxdWFsVG8gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhIHNwZWNpZmllZCB2YWx1ZS4nLFxuICB0eXBlLFxufSk7XG5cbmNvbnN0IGluT3AgPSAodHlwZSkgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGluIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBlcXVhbHMgYW55IHZhbHVlIGluIHRoZSBzcGVjaWZpZWQgYXJyYXkuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KHR5cGUpLFxufSk7XG5cbmNvbnN0IG5vdEluID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RJbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlIG9mIGEgZmllbGQgZG8gbm90IGVxdWFsIGFueSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIGFycmF5LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTGlzdCh0eXBlKSxcbn0pO1xuXG5jb25zdCBleGlzdHMgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBleGlzdHMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZXhpc3RzIChvciBkbyBub3QgZXhpc3QpLicsXG4gIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxufTtcblxuY29uc3QgbWF0Y2hlc1JlZ2V4ID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgbWF0Y2hlc1JlZ2V4IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBtYXRjaGVzIGEgc3BlY2lmaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbi4nLFxuICB0eXBlOiBHcmFwaFFMU3RyaW5nLFxufTtcblxuY29uc3Qgb3B0aW9ucyA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG9wdGlvbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBvcHRpb25hbCBmbGFncyAoc3VjaCBhcyBcImlcIiBhbmQgXCJtXCIpIHRvIGJlIGFkZGVkIHRvIGEgbWF0Y2hlc1JlZ2V4IG9wZXJhdGlvbiBpbiB0aGUgc2FtZSBzZXQgb2YgY29uc3RyYWludHMuJyxcbiAgdHlwZTogR3JhcGhRTFN0cmluZyxcbn07XG5cbmNvbnN0IFNVQlFVRVJZX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU3VicXVlcnlJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU3VicXVlcnlJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHN1YiBxdWVyeSB0byBhbm90aGVyIGNsYXNzLicsXG4gIGZpZWxkczoge1xuICAgIGNsYXNzTmFtZTogQ0xBU1NfTkFNRV9BVFQsXG4gICAgd2hlcmU6IE9iamVjdC5hc3NpZ24oe30sIFdIRVJFX0FUVCwge1xuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFdIRVJFX0FUVC50eXBlKSxcbiAgICB9KSxcbiAgfSxcbn0pO1xuXG5jb25zdCBTRUxFQ1RfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTZWxlY3RJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2VsZWN0SW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYW4gaW5RdWVyeUtleSBvciBhIG5vdEluUXVlcnlLZXkgb3BlcmF0aW9uIG9uIGEgY29uc3RyYWludC4nLFxuICBmaWVsZHM6IHtcbiAgICBxdWVyeToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBzdWJxdWVyeSB0byBiZSBleGVjdXRlZC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFNVQlFVRVJZX0lOUFVUKSxcbiAgICB9LFxuICAgIGtleToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBrZXkgaW4gdGhlIHJlc3VsdCBvZiB0aGUgc3VicXVlcnkgdGhhdCBtdXN0IG1hdGNoIChub3QgbWF0Y2gpIHRoZSBmaWVsZC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxTdHJpbmcpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgaW5RdWVyeUtleSA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGluUXVlcnlLZXkgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZXF1YWxzIHRvIGEga2V5IGluIHRoZSByZXN1bHQgb2YgYSBkaWZmZXJlbnQgcXVlcnkuJyxcbiAgdHlwZTogU0VMRUNUX0lOUFVULFxufTtcblxuY29uc3Qgbm90SW5RdWVyeUtleSA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG5vdEluUXVlcnlLZXkgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZG8gbm90IGVxdWFsIHRvIGEga2V5IGluIHRoZSByZXN1bHQgb2YgYSBkaWZmZXJlbnQgcXVlcnkuJyxcbiAgdHlwZTogU0VMRUNUX0lOUFVULFxufTtcblxuY29uc3QgSURfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdJZFdoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIElkV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYW4gaWQuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMSUQpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oR3JhcGhRTElEKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oR3JhcGhRTElEKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBpbjogaW5PcChHcmFwaFFMSUQpLFxuICAgIG5vdEluOiBub3RJbihHcmFwaFFMSUQpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgU1RSSU5HX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU3RyaW5nV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU3RyaW5nV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIFN0cmluZy4nLFxuICBmaWVsZHM6IHtcbiAgICBlcXVhbFRvOiBlcXVhbFRvKEdyYXBoUUxTdHJpbmcpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTFN0cmluZyksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEdyYXBoUUxTdHJpbmcpLFxuICAgIGxlc3NUaGFuT3JFcXVhbFRvOiBsZXNzVGhhbk9yRXF1YWxUbyhHcmFwaFFMU3RyaW5nKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oR3JhcGhRTFN0cmluZyksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEdyYXBoUUxTdHJpbmcpLFxuICAgIGluOiBpbk9wKEdyYXBoUUxTdHJpbmcpLFxuICAgIG5vdEluOiBub3RJbihHcmFwaFFMU3RyaW5nKSxcbiAgICBleGlzdHMsXG4gICAgbWF0Y2hlc1JlZ2V4LFxuICAgIG9wdGlvbnMsXG4gICAgdGV4dDoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSAkdGV4dCBvcGVyYXRvciB0byBzcGVjaWZ5IGEgZnVsbCB0ZXh0IHNlYXJjaCBjb25zdHJhaW50LicsXG4gICAgICB0eXBlOiBURVhUX0lOUFVULFxuICAgIH0sXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IE5VTUJFUl9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ051bWJlcldoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIE51bWJlcldoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBOdW1iZXIuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMRmxvYXQpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oR3JhcGhRTEZsb2F0KSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oR3JhcGhRTEZsb2F0KSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBpbjogaW5PcChHcmFwaFFMRmxvYXQpLFxuICAgIG5vdEluOiBub3RJbihHcmFwaFFMRmxvYXQpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgQk9PTEVBTl9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0Jvb2xlYW5XaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBCb29sZWFuV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIEJvb2xlYW4uJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMQm9vbGVhbiksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhHcmFwaFFMQm9vbGVhbiksXG4gICAgZXhpc3RzLFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBBUlJBWV9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0FycmF5V2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQXJyYXlXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgQXJyYXkuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhBTlkpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oQU5ZKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oQU5ZKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oQU5ZKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oQU5ZKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oQU5ZKSxcbiAgICBpbjogaW5PcChBTlkpLFxuICAgIG5vdEluOiBub3RJbihBTlkpLFxuICAgIGV4aXN0cyxcbiAgICBjb250YWluZWRCeToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBjb250YWluZWRCeSBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhbiBhcnJheSBmaWVsZCBpcyBjb250YWluZWQgYnkgYW5vdGhlciBzcGVjaWZpZWQgYXJyYXkuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChBTlkpLFxuICAgIH0sXG4gICAgY29udGFpbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgY29udGFpbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYW4gYXJyYXkgZmllbGQgY29udGFpbiBhbGwgZWxlbWVudHMgb2YgYW5vdGhlciBzcGVjaWZpZWQgYXJyYXkuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChBTlkpLFxuICAgIH0sXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEtFWV9WQUxVRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0tleVZhbHVlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FuIGVudHJ5IGZyb20gYW4gb2JqZWN0LCBpLmUuLCBhIHBhaXIgb2Yga2V5IGFuZCB2YWx1ZS4nLFxuICBmaWVsZHM6IHtcbiAgICBrZXk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGtleSB1c2VkIHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBvZiB0aGlzIGVudHJ5LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICB2YWx1ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdmFsdWUgb2YgdGhlIGVudHJ5LiBDb3VsZCBiZSBhbnkgdHlwZSBvZiBzY2FsYXIgZGF0YS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEFOWSksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBPQkpFQ1RfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdPYmplY3RXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBPYmplY3RXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgcmVzdWx0IGJ5IGEgZmllbGQgb2YgdHlwZSBPYmplY3QuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhLRVlfVkFMVUVfSU5QVVQpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBpbjogaW5PcChLRVlfVkFMVUVfSU5QVVQpLFxuICAgIG5vdEluOiBub3RJbihLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGxlc3NUaGFuT3JFcXVhbFRvOiBsZXNzVGhhbk9yRXF1YWxUbyhLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgREFURV9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0RhdGVXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBEYXRlV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIERhdGUuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhEQVRFKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKERBVEUpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihEQVRFKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oREFURSksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKERBVEUpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhEQVRFKSxcbiAgICBpbjogaW5PcChEQVRFKSxcbiAgICBub3RJbjogbm90SW4oREFURSksXG4gICAgZXhpc3RzLFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBCWVRFU19XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0J5dGVzV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQnl0ZXNXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgQnl0ZXMuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhCWVRFUyksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhCWVRFUyksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEJZVEVTKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oQllURVMpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihCWVRFUyksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEJZVEVTKSxcbiAgICBpbjogaW5PcChCWVRFUyksXG4gICAgbm90SW46IG5vdEluKEJZVEVTKSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEZJTEVfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdGaWxlV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRmlsZVdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBGaWxlLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oRklMRSksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhGSUxFKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oRklMRSksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEZJTEUpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihGSUxFKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oRklMRSksXG4gICAgaW46IGluT3AoRklMRSksXG4gICAgbm90SW46IG5vdEluKEZJTEUpLFxuICAgIGV4aXN0cyxcbiAgICBtYXRjaGVzUmVnZXgsXG4gICAgb3B0aW9ucyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgR0VPX1BPSU5UX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnR2VvUG9pbnRXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBHZW9Qb2ludFdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBHZW9Qb2ludC4nLFxuICBmaWVsZHM6IHtcbiAgICBleGlzdHMsXG4gICAgbmVhclNwaGVyZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBuZWFyU3BoZXJlIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIG5lYXIgdG8gYW5vdGhlciBnZW8gcG9pbnQuJyxcbiAgICAgIHR5cGU6IEdFT19QT0lOVF9JTlBVVCxcbiAgICB9LFxuICAgIG1heERpc3RhbmNlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiByYWRpYW5zKSBmcm9tIHRoZSBnZW8gcG9pbnQgc3BlY2lmaWVkIGluIHRoZSAkbmVhclNwaGVyZSBvcGVyYXRvci4nLFxuICAgICAgdHlwZTogR3JhcGhRTEZsb2F0LFxuICAgIH0sXG4gICAgbWF4RGlzdGFuY2VJblJhZGlhbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgbWF4RGlzdGFuY2VJblJhZGlhbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYSBnZW8gcG9pbnQgZmllbGQgaXMgYXQgYSBtYXggZGlzdGFuY2UgKGluIHJhZGlhbnMpIGZyb20gdGhlIGdlbyBwb2ludCBzcGVjaWZpZWQgaW4gdGhlICRuZWFyU3BoZXJlIG9wZXJhdG9yLicsXG4gICAgICB0eXBlOiBHcmFwaFFMRmxvYXQsXG4gICAgfSxcbiAgICBtYXhEaXN0YW5jZUluTWlsZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgbWF4RGlzdGFuY2VJbk1pbGVzIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiBtaWxlcykgZnJvbSB0aGUgZ2VvIHBvaW50IHNwZWNpZmllZCBpbiB0aGUgJG5lYXJTcGhlcmUgb3BlcmF0b3IuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxGbG9hdCxcbiAgICB9LFxuICAgIG1heERpc3RhbmNlSW5LaWxvbWV0ZXJzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlSW5LaWxvbWV0ZXJzIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiBraWxvbWV0ZXJzKSBmcm9tIHRoZSBnZW8gcG9pbnQgc3BlY2lmaWVkIGluIHRoZSAkbmVhclNwaGVyZSBvcGVyYXRvci4nLFxuICAgICAgdHlwZTogR3JhcGhRTEZsb2F0LFxuICAgIH0sXG4gICAgd2l0aGluOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIHdpdGhpbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyB3aXRoaW4gYSBzcGVjaWZpZWQgYm94LicsXG4gICAgICB0eXBlOiBXSVRISU5fSU5QVVQsXG4gICAgfSxcbiAgICBnZW9XaXRoaW46IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgZ2VvV2l0aGluIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIHdpdGhpbiBhIHNwZWNpZmllZCBwb2x5Z29uIG9yIHNwaGVyZS4nLFxuICAgICAgdHlwZTogR0VPX1dJVEhJTl9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFBPTFlHT05fV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQb2x5Z29uV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUG9seWdvbldoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBQb2x5Z29uLicsXG4gIGZpZWxkczoge1xuICAgIGV4aXN0cyxcbiAgICBnZW9JbnRlcnNlY3RzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGdlb0ludGVyc2VjdHMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYSBwb2x5Z29uIGZpZWxkIGludGVyc2VjdCBhIHNwZWNpZmllZCBwb2ludC4nLFxuICAgICAgdHlwZTogR0VPX0lOVEVSU0VDVFNfSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBFTEVNRU5UID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0VsZW1lbnQnLFxuICBkZXNjcmlwdGlvbjogXCJUaGUgRWxlbWVudCBvYmplY3QgdHlwZSBpcyB1c2VkIHRvIHJldHVybiBhcnJheSBpdGVtcycgdmFsdWUuXCIsXG4gIGZpZWxkczoge1xuICAgIHZhbHVlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1JldHVybiB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgaW4gdGhlIGFycmF5JyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBTlkpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuLy8gRGVmYXVsdCBzdGF0aWMgdW5pb24gdHlwZSwgd2UgdXBkYXRlIHR5cGVzIGFuZCByZXNvbHZlVHlwZSBmdW5jdGlvbiBsYXRlclxubGV0IEFSUkFZX1JFU1VMVDtcblxuY29uc3QgbG9hZEFycmF5UmVzdWx0ID0gKHBhcnNlR3JhcGhRTFNjaGVtYSwgcGFyc2VDbGFzc2VzKSA9PiB7XG4gIGNvbnN0IGNsYXNzVHlwZXMgPSBwYXJzZUNsYXNzZXNcbiAgICAuZmlsdGVyKChwYXJzZUNsYXNzKSA9PlxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1twYXJzZUNsYXNzLmNsYXNzTmFtZV1cbiAgICAgICAgLmNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgICAgICAgPyB0cnVlXG4gICAgICAgIDogZmFsc2VcbiAgICApXG4gICAgLm1hcChcbiAgICAgIChwYXJzZUNsYXNzKSA9PlxuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW3BhcnNlQ2xhc3MuY2xhc3NOYW1lXVxuICAgICAgICAgIC5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlXG4gICAgKTtcbiAgQVJSQVlfUkVTVUxUID0gbmV3IEdyYXBoUUxVbmlvblR5cGUoe1xuICAgIG5hbWU6ICdBcnJheVJlc3VsdCcsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVXNlIElubGluZSBGcmFnbWVudCBvbiBBcnJheSB0byBnZXQgcmVzdWx0czogaHR0cHM6Ly9ncmFwaHFsLm9yZy9sZWFybi9xdWVyaWVzLyNpbmxpbmUtZnJhZ21lbnRzJyxcbiAgICB0eXBlczogKCkgPT4gW0VMRU1FTlQsIC4uLmNsYXNzVHlwZXNdLFxuICAgIHJlc29sdmVUeXBlOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICh2YWx1ZS5fX3R5cGUgPT09ICdPYmplY3QnICYmIHZhbHVlLmNsYXNzTmFtZSAmJiB2YWx1ZS5vYmplY3RJZCkge1xuICAgICAgICBpZiAocGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1t2YWx1ZS5jbGFzc05hbWVdKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbdmFsdWUuY2xhc3NOYW1lXVxuICAgICAgICAgICAgLmNsYXNzR3JhcGhRTE91dHB1dFR5cGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEVMRU1FTlQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBFTEVNRU5UO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuZ3JhcGhRTFR5cGVzLnB1c2goQVJSQVlfUkVTVUxUKTtcbn07XG5cbmNvbnN0IGxvYWQgPSAocGFyc2VHcmFwaFFMU2NoZW1hKSA9PiB7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShHcmFwaFFMVXBsb2FkLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEFOWSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShPQkpFQ1QsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoREFURSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCWVRFUywgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShGSUxFLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEVfSU5GTywgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShGSUxFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19QT0lOVF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShHRU9fUE9JTlQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUEFSU0VfT0JKRUNULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJFQURfUFJFRkVSRU5DRSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShSRUFEX09QVElPTlNfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0VBUkNIX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFRFWFRfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQk9YX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFdJVEhJTl9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShDRU5URVJfU1BIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19XSVRISU5fSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX0lOVEVSU0VDVFNfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoSURfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU1RSSU5HX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKE5VTUJFUl9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCT09MRUFOX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEFSUkFZX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEtFWV9WQUxVRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShPQkpFQ1RfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoREFURV9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCWVRFU19XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShGSUxFX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19QT0lOVF9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShQT0xZR09OX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEVMRU1FTlQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQUNMX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFVTRVJfQUNMX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJPTEVfQUNMX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFBVQkxJQ19BQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQUNMLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFVTRVJfQUNMLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJPTEVfQUNMLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFBVQkxJQ19BQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU1VCUVVFUllfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0VMRUNUX0lOUFVULCB0cnVlKTtcbn07XG5cbmV4cG9ydCB7XG4gIFR5cGVWYWxpZGF0aW9uRXJyb3IsXG4gIHBhcnNlU3RyaW5nVmFsdWUsXG4gIHBhcnNlSW50VmFsdWUsXG4gIHBhcnNlRmxvYXRWYWx1ZSxcbiAgcGFyc2VCb29sZWFuVmFsdWUsXG4gIHBhcnNlVmFsdWUsXG4gIHBhcnNlTGlzdFZhbHVlcyxcbiAgcGFyc2VPYmplY3RGaWVsZHMsXG4gIEFOWSxcbiAgT0JKRUNULFxuICBwYXJzZURhdGVJc29WYWx1ZSxcbiAgc2VyaWFsaXplRGF0ZUlzbyxcbiAgREFURSxcbiAgQllURVMsXG4gIHBhcnNlRmlsZVZhbHVlLFxuICBTVUJRVUVSWV9JTlBVVCxcbiAgU0VMRUNUX0lOUFVULFxuICBGSUxFLFxuICBGSUxFX0lORk8sXG4gIEZJTEVfSU5QVVQsXG4gIEdFT19QT0lOVF9GSUVMRFMsXG4gIEdFT19QT0lOVF9JTlBVVCxcbiAgR0VPX1BPSU5ULFxuICBQT0xZR09OX0lOUFVULFxuICBQT0xZR09OLFxuICBPQkpFQ1RfSUQsXG4gIENMQVNTX05BTUVfQVRULFxuICBHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgT0JKRUNUX0lEX0FUVCxcbiAgVVBEQVRFRF9BVF9BVFQsXG4gIENSRUFURURfQVRfQVRULFxuICBJTlBVVF9GSUVMRFMsXG4gIENSRUFURV9SRVNVTFRfRklFTERTLFxuICBVUERBVEVfUkVTVUxUX0ZJRUxEUyxcbiAgUEFSU0VfT0JKRUNUX0ZJRUxEUyxcbiAgUEFSU0VfT0JKRUNULFxuICBTRVNTSU9OX1RPS0VOX0FUVCxcbiAgUkVBRF9QUkVGRVJFTkNFLFxuICBSRUFEX1BSRUZFUkVOQ0VfQVRULFxuICBJTkNMVURFX1JFQURfUFJFRkVSRU5DRV9BVFQsXG4gIFNVQlFVRVJZX1JFQURfUFJFRkVSRU5DRV9BVFQsXG4gIFJFQURfT1BUSU9OU19JTlBVVCxcbiAgUkVBRF9PUFRJT05TX0FUVCxcbiAgV0hFUkVfQVRULFxuICBTS0lQX0FUVCxcbiAgTElNSVRfQVRULFxuICBDT1VOVF9BVFQsXG4gIFNFQVJDSF9JTlBVVCxcbiAgVEVYVF9JTlBVVCxcbiAgQk9YX0lOUFVULFxuICBXSVRISU5fSU5QVVQsXG4gIENFTlRFUl9TUEhFUkVfSU5QVVQsXG4gIEdFT19XSVRISU5fSU5QVVQsXG4gIEdFT19JTlRFUlNFQ1RTX0lOUFVULFxuICBlcXVhbFRvLFxuICBub3RFcXVhbFRvLFxuICBsZXNzVGhhbixcbiAgbGVzc1RoYW5PckVxdWFsVG8sXG4gIGdyZWF0ZXJUaGFuLFxuICBncmVhdGVyVGhhbk9yRXF1YWxUbyxcbiAgaW5PcCxcbiAgbm90SW4sXG4gIGV4aXN0cyxcbiAgbWF0Y2hlc1JlZ2V4LFxuICBvcHRpb25zLFxuICBpblF1ZXJ5S2V5LFxuICBub3RJblF1ZXJ5S2V5LFxuICBJRF9XSEVSRV9JTlBVVCxcbiAgU1RSSU5HX1dIRVJFX0lOUFVULFxuICBOVU1CRVJfV0hFUkVfSU5QVVQsXG4gIEJPT0xFQU5fV0hFUkVfSU5QVVQsXG4gIEFSUkFZX1dIRVJFX0lOUFVULFxuICBLRVlfVkFMVUVfSU5QVVQsXG4gIE9CSkVDVF9XSEVSRV9JTlBVVCxcbiAgREFURV9XSEVSRV9JTlBVVCxcbiAgQllURVNfV0hFUkVfSU5QVVQsXG4gIEZJTEVfV0hFUkVfSU5QVVQsXG4gIEdFT19QT0lOVF9XSEVSRV9JTlBVVCxcbiAgUE9MWUdPTl9XSEVSRV9JTlBVVCxcbiAgQVJSQVlfUkVTVUxULFxuICBFTEVNRU5ULFxuICBBQ0xfSU5QVVQsXG4gIFVTRVJfQUNMX0lOUFVULFxuICBST0xFX0FDTF9JTlBVVCxcbiAgUFVCTElDX0FDTF9JTlBVVCxcbiAgQUNMLFxuICBVU0VSX0FDTCxcbiAgUk9MRV9BQ0wsXG4gIFBVQkxJQ19BQ0wsXG4gIGxvYWQsXG4gIGxvYWRBcnJheVJlc3VsdCxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultRelaySchema.js b/lib/GraphQL/loaders/defaultRelaySchema.js new file mode 100644 index 0000000000..7ad9579b75 --- /dev/null +++ b/lib/GraphQL/loaders/defaultRelaySchema.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.GLOBAL_ID_ATT = void 0; + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _parseClassTypes = require("./parseClassTypes"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const GLOBAL_ID_ATT = { + description: 'This is the global id.', + type: defaultGraphQLTypes.OBJECT_ID +}; +exports.GLOBAL_ID_ATT = GLOBAL_ID_ATT; + +const load = parseGraphQLSchema => { + const { + nodeInterface, + nodeField + } = (0, _graphqlRelay.nodeDefinitions)(async (globalId, context, queryInfo) => { + try { + const { + type, + id + } = (0, _graphqlRelay.fromGlobalId)(globalId); + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const { + keys, + include + } = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); + return _objectSpread({ + className: type + }, await objectsQueries.getObject(type, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses)); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }, obj => { + return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType; + }); + parseGraphQLSchema.addGraphQLType(nodeInterface, true); + parseGraphQLSchema.relayNodeInterface = nodeInterface; + parseGraphQLSchema.addGraphQLQuery('node', nodeField, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hLmpzIl0sIm5hbWVzIjpbIkdMT0JBTF9JRF9BVFQiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiT0JKRUNUX0lEIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsIm5vZGVJbnRlcmZhY2UiLCJub2RlRmllbGQiLCJnbG9iYWxJZCIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJpZCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJrZXlzIiwiaW5jbHVkZSIsImNsYXNzTmFtZSIsIm9iamVjdHNRdWVyaWVzIiwiZ2V0T2JqZWN0IiwidW5kZWZpbmVkIiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwib2JqIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsImFkZEdyYXBoUUxUeXBlIiwicmVsYXlOb2RlSW50ZXJmYWNlIiwiYWRkR3JhcGhRTFF1ZXJ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsYUFBYSxHQUFHO0FBQ3BCQyxFQUFBQSxXQUFXLEVBQUUsd0JBRE87QUFFcEJDLEVBQUFBLElBQUksRUFBRUMsbUJBQW1CLENBQUNDO0FBRk4sQ0FBdEI7OztBQUtBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsUUFBTTtBQUFFQyxJQUFBQSxhQUFGO0FBQWlCQyxJQUFBQTtBQUFqQixNQUErQixtQ0FDbkMsT0FBT0MsUUFBUCxFQUFpQkMsT0FBakIsRUFBMEJDLFNBQTFCLEtBQXdDO0FBQ3RDLFFBQUk7QUFDRixZQUFNO0FBQUVULFFBQUFBLElBQUY7QUFBUVUsUUFBQUE7QUFBUixVQUFlLGdDQUFhSCxRQUFiLENBQXJCO0FBQ0EsWUFBTTtBQUFFSSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCTCxPQUEvQjtBQUNBLFlBQU1NLGNBQWMsR0FBRyxnQ0FBY0wsU0FBZCxDQUF2QjtBQUVBLFlBQU07QUFBRU0sUUFBQUEsSUFBRjtBQUFRQyxRQUFBQTtBQUFSLFVBQW9CLDRDQUFzQkYsY0FBdEIsQ0FBMUI7QUFFQTtBQUNFRyxRQUFBQSxTQUFTLEVBQUVqQjtBQURiLFNBRU0sTUFBTWtCLGNBQWMsQ0FBQ0MsU0FBZixDQUNSbkIsSUFEUSxFQUVSVSxFQUZRLEVBR1JLLElBSFEsRUFJUkMsT0FKUSxFQUtSSSxTQUxRLEVBTVJBLFNBTlEsRUFPUlQsTUFQUSxFQVFSQyxJQVJRLEVBU1JDLElBVFEsRUFVUlQsa0JBQWtCLENBQUNpQixZQVZYLENBRlo7QUFlRCxLQXRCRCxDQXNCRSxPQUFPQyxDQUFQLEVBQVU7QUFDVmxCLE1BQUFBLGtCQUFrQixDQUFDbUIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRixHQTNCa0MsRUE0Qm5DRSxHQUFHLElBQUk7QUFDTCxXQUFPcEIsa0JBQWtCLENBQUNxQixlQUFuQixDQUFtQ0QsR0FBRyxDQUFDUCxTQUF2QyxFQUNKUyxzQkFESDtBQUVELEdBL0JrQyxDQUFyQztBQWtDQXRCLEVBQUFBLGtCQUFrQixDQUFDdUIsY0FBbkIsQ0FBa0N0QixhQUFsQyxFQUFpRCxJQUFqRDtBQUNBRCxFQUFBQSxrQkFBa0IsQ0FBQ3dCLGtCQUFuQixHQUF3Q3ZCLGFBQXhDO0FBQ0FELEVBQUFBLGtCQUFrQixDQUFDeUIsZUFBbkIsQ0FBbUMsTUFBbkMsRUFBMkN2QixTQUEzQyxFQUFzRCxJQUF0RDtBQUNELENBdENEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbm9kZURlZmluaXRpb25zLCBmcm9tR2xvYmFsSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCBnZXRGaWVsZE5hbWVzIGZyb20gJ2dyYXBocWwtbGlzdC1maWVsZHMnO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0ICogYXMgb2JqZWN0c1F1ZXJpZXMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzUXVlcmllcyc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUgfSBmcm9tICcuL3BhcnNlQ2xhc3NUeXBlcyc7XG5cbmNvbnN0IEdMT0JBTF9JRF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZ2xvYmFsIGlkLicsXG4gIHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUX0lELFxufTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGNvbnN0IHsgbm9kZUludGVyZmFjZSwgbm9kZUZpZWxkIH0gPSBub2RlRGVmaW5pdGlvbnMoXG4gICAgYXN5bmMgKGdsb2JhbElkLCBjb250ZXh0LCBxdWVyeUluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGZyb21HbG9iYWxJZChnbG9iYWxJZCk7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMocXVlcnlJbmZvKTtcblxuICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWU6IHR5cGUsXG4gICAgICAgICAgLi4uKGF3YWl0IG9iamVjdHNRdWVyaWVzLmdldE9iamVjdChcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgKSksXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9iaiA9PiB7XG4gICAgICByZXR1cm4gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tvYmouY2xhc3NOYW1lXVxuICAgICAgICAuY2xhc3NHcmFwaFFMT3V0cHV0VHlwZTtcbiAgICB9XG4gICk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKG5vZGVJbnRlcmZhY2UsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEucmVsYXlOb2RlSW50ZXJmYWNlID0gbm9kZUludGVyZmFjZTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxRdWVyeSgnbm9kZScsIG5vZGVGaWVsZCwgdHJ1ZSk7XG59O1xuXG5leHBvcnQgeyBHTE9CQUxfSURfQVRULCBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/filesMutations.js b/lib/GraphQL/loaders/filesMutations.js new file mode 100644 index 0000000000..216b62d7d9 --- /dev/null +++ b/lib/GraphQL/loaders/filesMutations.js @@ -0,0 +1,103 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.handleUpload = exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _links = require("@graphql-tools/links"); + +var _node = _interopRequireDefault(require("parse/node")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var _logger = _interopRequireDefault(require("../../logger")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const handleUpload = async (upload, config) => { + const { + createReadStream, + filename, + mimetype + } = await upload; + let data = null; + + if (createReadStream) { + const stream = createReadStream(); + data = await new Promise((resolve, reject) => { + const chunks = []; + stream.on('error', reject).on('data', chunk => chunks.push(chunk)).on('end', () => resolve(Buffer.concat(chunks))); + }); + } + + if (!data || !data.length) { + throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); + } + + if (filename.length > 128) { + throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); + } + + if (!filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) { + throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); + } + + try { + return { + fileInfo: await config.filesController.createFile(config, filename, data, mimetype) + }; + } catch (e) { + _logger.default.error('Error creating a file: ', e); + + throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, `Could not store file: ${filename}.`); + } +}; + +exports.handleUpload = handleUpload; + +const load = parseGraphQLSchema => { + const createMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'CreateFile', + description: 'The createFile mutation can be used to create and upload a new file.', + inputFields: { + upload: { + description: 'This is the new file to be created and uploaded.', + type: new _graphql.GraphQLNonNull(_links.GraphQLUpload) + } + }, + outputFields: { + fileInfo: { + description: 'This is the created file info.', + type: new _graphql.GraphQLNonNull(defaultGraphQLTypes.FILE_INFO) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + upload + } = args; + const { + config + } = context; + return handleUpload(upload, config); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(createMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(createMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('createFile', createMutation, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZmlsZXNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsiaGFuZGxlVXBsb2FkIiwidXBsb2FkIiwiY29uZmlnIiwiY3JlYXRlUmVhZFN0cmVhbSIsImZpbGVuYW1lIiwibWltZXR5cGUiLCJkYXRhIiwic3RyZWFtIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsImxlbmd0aCIsIlBhcnNlIiwiRXJyb3IiLCJGSUxFX1NBVkVfRVJST1IiLCJJTlZBTElEX0ZJTEVfTkFNRSIsIm1hdGNoIiwiZmlsZUluZm8iLCJmaWxlc0NvbnRyb2xsZXIiLCJjcmVhdGVGaWxlIiwiZSIsImxvZ2dlciIsImVycm9yIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImNyZWF0ZU11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMVXBsb2FkIiwib3V0cHV0RmllbGRzIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkZJTEVfSU5GTyIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFlBQVksR0FBRyxPQUFPQyxNQUFQLEVBQWVDLE1BQWYsS0FBMEI7QUFDN0MsUUFBTTtBQUFFQyxJQUFBQSxnQkFBRjtBQUFvQkMsSUFBQUEsUUFBcEI7QUFBOEJDLElBQUFBO0FBQTlCLE1BQTJDLE1BQU1KLE1BQXZEO0FBQ0EsTUFBSUssSUFBSSxHQUFHLElBQVg7O0FBQ0EsTUFBSUgsZ0JBQUos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QkFBa0IsQ0FBQ2UsY0FBbkIsQ0FDRWQsY0FBYyxDQUFDVyxJQUFmLENBQW9CSSxLQUFwQixDQUEwQlgsSUFBMUIsQ0FBK0JZLE1BRGpDLEVBRUUsSUFGRixFQUdFLElBSEY7QUFLQWpCLEVBQUFBLGtCQUFrQixDQUFDZSxjQUFuQixDQUFrQ2QsY0FBYyxDQUFDSSxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBTCxFQUFBQSxrQkFBa0IsQ0FBQ2tCLGtCQUFuQixDQUNFLFlBREYsRUFFRWpCLGNBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU1ELENBeENEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCB7IEdyYXBoUUxVcGxvYWQgfSBmcm9tICdAZ3JhcGhxbC10b29scy9saW5rcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5cbmNvbnN0IGhhbmRsZVVwbG9hZCA9IGFzeW5jICh1cGxvYWQsIGNvbmZpZykgPT4ge1xuICBjb25zdCB7IGNyZWF0ZVJlYWRTdHJlYW0sIGZpbGVuYW1lLCBtaW1ldHlwZSB9ID0gYXdhaXQgdXBsb2FkO1xuICBsZXQgZGF0YSA9IG51bGw7XG4gIGlmIChjcmVhdGVSZWFkU3RyZWFtKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY3JlYXRlUmVhZFN0cmVhbSgpO1xuICAgIGRhdGEgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIHN0cmVhbVxuICAgICAgICAub24oJ2Vycm9yJywgcmVqZWN0KVxuICAgICAgICAub24oJ2RhdGEnLCAoY2h1bmspID0+IGNodW5rcy5wdXNoKGNodW5rKSlcbiAgICAgICAgLm9uKCdlbmQnLCAoKSA9PiByZXNvbHZlKEJ1ZmZlci5jb25jYXQoY2h1bmtzKSkpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKCFkYXRhIHx8ICFkYXRhLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsICdJbnZhbGlkIGZpbGUgdXBsb2FkLicpO1xuICB9XG5cbiAgaWYgKGZpbGVuYW1lLmxlbmd0aCA+IDEyOCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSwgJ0ZpbGVuYW1lIHRvbyBsb25nLicpO1xuICB9XG5cbiAgaWYgKCFmaWxlbmFtZS5tYXRjaCgvXltfYS16QS1aMC05XVthLXpBLVowLTlAXFwuXFwgfl8tXSokLykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSxcbiAgICAgICdGaWxlbmFtZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJ1xuICAgICk7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiB7XG4gICAgICBmaWxlSW5mbzogYXdhaXQgY29uZmlnLmZpbGVzQ29udHJvbGxlci5jcmVhdGVGaWxlKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGZpbGVuYW1lLFxuICAgICAgICBkYXRhLFxuICAgICAgICBtaW1ldHlwZVxuICAgICAgKSxcbiAgICB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdFcnJvciBjcmVhdGluZyBhIGZpbGU6ICcsIGUpO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUixcbiAgICAgIGBDb3VsZCBub3Qgc3RvcmUgZmlsZTogJHtmaWxlbmFtZX0uYFxuICAgICk7XG4gIH1cbn07XG5cbmNvbnN0IGxvYWQgPSAocGFyc2VHcmFwaFFMU2NoZW1hKSA9PiB7XG4gIGNvbnN0IGNyZWF0ZU11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0NyZWF0ZUZpbGUnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBjcmVhdGVGaWxlIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhbmQgdXBsb2FkIGEgbmV3IGZpbGUuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgdXBsb2FkOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbmV3IGZpbGUgdG8gYmUgY3JlYXRlZCBhbmQgdXBsb2FkZWQuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxVcGxvYWQpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgZmlsZUluZm86IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjcmVhdGVkIGZpbGUgaW5mby4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoZGVmYXVsdEdyYXBoUUxUeXBlcy5GSUxFX0lORk8pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IHVwbG9hZCB9ID0gYXJncztcbiAgICAgICAgY29uc3QgeyBjb25maWcgfSA9IGNvbnRleHQ7XG4gICAgICAgIHJldHVybiBoYW5kbGVVcGxvYWQodXBsb2FkLCBjb25maWcpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNyZWF0ZU11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjcmVhdGVNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAnY3JlYXRlRmlsZScsXG4gICAgY3JlYXRlTXV0YXRpb24sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG59O1xuXG5leHBvcnQgeyBsb2FkLCBoYW5kbGVVcGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/functionsMutations.js b/lib/GraphQL/loaders/functionsMutations.js new file mode 100644 index 0000000000..7c1aeeef0e --- /dev/null +++ b/lib/GraphQL/loaders/functionsMutations.js @@ -0,0 +1,90 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _FunctionsRouter = require("../../Routers/FunctionsRouter"); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const load = parseGraphQLSchema => { + if (parseGraphQLSchema.functionNames.length > 0) { + const cloudCodeFunctionEnum = parseGraphQLSchema.addGraphQLType(new _graphql.GraphQLEnumType({ + name: 'CloudCodeFunction', + description: 'The CloudCodeFunction enum type contains a list of all available cloud code functions.', + values: parseGraphQLSchema.functionNames.reduce((values, functionName) => _objectSpread(_objectSpread({}, values), {}, { + [functionName]: { + value: functionName + } + }), {}) + }), true, true); + const callCloudCodeMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'CallCloudCode', + description: 'The callCloudCode mutation can be used to invoke a cloud code function.', + inputFields: { + functionName: { + description: 'This is the function to be called.', + type: new _graphql.GraphQLNonNull(cloudCodeFunctionEnum) + }, + params: { + description: 'These are the params to be passed to the function.', + type: defaultGraphQLTypes.OBJECT + } + }, + outputFields: { + result: { + description: 'This is the result value of the cloud code function execution.', + type: defaultGraphQLTypes.ANY + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + functionName, + params + } = args; + const { + config, + auth, + info + } = context; + return { + result: (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ + params: { + functionName + }, + config, + auth, + info, + body: params + })).response.result + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('callCloudCode', callCloudCodeMutation, true, true); + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZnVuY3Rpb25zTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJmdW5jdGlvbk5hbWVzIiwibGVuZ3RoIiwiY2xvdWRDb2RlRnVuY3Rpb25FbnVtIiwiYWRkR3JhcGhRTFR5cGUiLCJHcmFwaFFMRW51bVR5cGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJ2YWx1ZXMiLCJyZWR1Y2UiLCJmdW5jdGlvbk5hbWUiLCJ2YWx1ZSIsImNhbGxDbG91ZENvZGVNdXRhdGlvbiIsImlucHV0RmllbGRzIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwicGFyYW1zIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIk9CSkVDVCIsIm91dHB1dEZpZWxkcyIsInJlc3VsdCIsIkFOWSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwiRnVuY3Rpb25zUm91dGVyIiwiaGFuZGxlQ2xvdWRGdW5jdGlvbiIsImJvZHkiLCJyZXNwb25zZSIsImUiLCJoYW5kbGVFcnJvciIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsTUFBSUEsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDQyxNQUFqQyxHQUEwQyxDQUE5QyxFQUFpRDtBQUMvQyxVQUFNQyxxQkFBcUIsR0FBR0gsa0JBQWtCLENBQUNJLGNBQW5CLENBQzVCLElBQUlDLHdCQUFKLENBQW9CO0FBQ2xCQyxNQUFBQSxJQUFJLEVBQUUsbUJBRFk7QUFFbEJDLE1BQUFBLFdBQVcsRUFDVCx3RkFIZ0I7QUFJbEJDLE1BQUFBLE1BQU0sRUFBRVIsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDUSxNQUFqQyxDQUNOLENBQUNELE1BQUQsRUFBU0UsWUFBVCxxQ0FDS0YsTUFETDtBQUVFLFNBQUNFLFlBQUQsR0FBZ0I7QUFBRUMsVUFBQUEsS0FBSyxFQUFFRDtBQUFUO0FBRmxCLFFBRE0sRUFLTixFQUxNO0FBSlUsS0FBcEIsQ0FENEIsRUFhNUIsSUFiNEIsRUFjNUIsSUFkNEIsQ0FBOUI7QUFpQkEsVUFBTUUscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pETixNQUFBQSxJQUFJLEVBQUUsZUFEbUQ7QUFFekRDLE1BQUFBLFdBQVcsRUFDVCx5RUFIdUQ7QUFJekRNLE1BQUFBLFdBQVcsRUFBRTtBQUNYSCxRQUFBQSxZQUFZLEVBQUU7QUFDWkgsVUFBQUEsV0FBVyxFQUFFLG9DQUREO0FBRVpPLFVBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQloscUJBQW5CO0FBRk0sU0FESDtBQUtYYSxRQUFBQSxNQUFNLEVBQUU7QUFDTlQsVUFBQUEsV0FBVyxFQUFFLG9EQURQO0FBRU5PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNDO0FBRnBCO0FBTEcsT0FKNEM7QUFjekRDLE1BQUFBLFlBQVksRUFBRTtBQUNaQyxRQUFBQSxNQUFNLEVBQUU7QUFDTmIsVUFBQUEsV0FBVyxFQUNULGdFQUZJO0FBR05PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNJO0FBSHBCO0FBREksT0FkMkM7QUFxQnpEQyxNQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsS0FBeUI7QUFDNUMsWUFBSTtBQUNGLGdCQUFNO0FBQUVkLFlBQUFBLFlBQUY7QUFBZ0JNLFlBQUFBO0FBQWhCLGNBQTJCTyxJQUFqQztBQUNBLGdCQUFNO0FBQUVFLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEIsY0FBeUJILE9BQS9CO0FBRUEsaUJBQU87QUFDTEosWUFBQUEsTUFBTSxFQUFFLENBQUMsTUFBTVEsaUNBQWdCQyxtQkFBaEIsQ0FBb0M7QUFDakRiLGNBQUFBLE1BQU0sRUFBRTtBQUNOTixnQkFBQUE7QUFETSxlQUR5QztBQUlqRGUsY0FBQUEsTUFKaUQ7QUFLakRDLGNBQUFBLElBTGlEO0FBTWpEQyxjQUFBQSxJQU5pRDtBQU9qREcsY0FBQUEsSUFBSSxFQUFFZDtBQVAyQyxhQUFwQyxDQUFQLEVBUUplLFFBUkksQ0FRS1g7QUFUUixXQUFQO0FBV0QsU0FmRCxDQWVFLE9BQU9ZLENBQVAsRUFBVTtBQUNWaEMsVUFBQUEsa0JBQWtCLENBQUNpQyxXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBeEN3RCxLQUE3QixDQUE5QjtBQTJDQWhDLElBQUFBLGtCQUFrQixDQUFDSSxjQUFuQixDQUNFUSxxQkFBcUIsQ0FBQ1csSUFBdEIsQ0FBMkJXLEtBQTNCLENBQWlDcEIsSUFBakMsQ0FBc0NxQixNQUR4QyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FuQyxJQUFBQSxrQkFBa0IsQ0FBQ0ksY0FBbkIsQ0FBa0NRLHFCQUFxQixDQUFDRSxJQUF4RCxFQUE4RCxJQUE5RCxFQUFvRSxJQUFwRTtBQUNBZCxJQUFBQSxrQkFBa0IsQ0FBQ29DLGtCQUFuQixDQUNFLGVBREYsRUFFRXhCLHFCQUZGLEVBR0UsSUFIRixFQUlFLElBSkY7QUFNRDtBQUNGLENBM0VEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwsIEdyYXBoUUxFbnVtVHlwZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi4vLi4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgaWYgKHBhcnNlR3JhcGhRTFNjaGVtYS5mdW5jdGlvbk5hbWVzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjbG91ZENvZGVGdW5jdGlvbkVudW0gPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICBuZXcgR3JhcGhRTEVudW1UeXBlKHtcbiAgICAgICAgbmFtZTogJ0Nsb3VkQ29kZUZ1bmN0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoZSBDbG91ZENvZGVGdW5jdGlvbiBlbnVtIHR5cGUgY29udGFpbnMgYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY2xvdWQgY29kZSBmdW5jdGlvbnMuJyxcbiAgICAgICAgdmFsdWVzOiBwYXJzZUdyYXBoUUxTY2hlbWEuZnVuY3Rpb25OYW1lcy5yZWR1Y2UoXG4gICAgICAgICAgKHZhbHVlcywgZnVuY3Rpb25OYW1lKSA9PiAoe1xuICAgICAgICAgICAgLi4udmFsdWVzLFxuICAgICAgICAgICAgW2Z1bmN0aW9uTmFtZV06IHsgdmFsdWU6IGZ1bmN0aW9uTmFtZSB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHt9XG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIGNvbnN0IGNhbGxDbG91ZENvZGVNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogJ0NhbGxDbG91ZENvZGUnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgY2FsbENsb3VkQ29kZSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBpbnZva2UgYSBjbG91ZCBjb2RlIGZ1bmN0aW9uLicsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBmdW5jdGlvbk5hbWU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbG91ZENvZGVGdW5jdGlvbkVudW0pLFxuICAgICAgICB9LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgcGFyYW1zIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uJyxcbiAgICAgICAgICB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgcmVzdWx0OiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAnVGhpcyBpcyB0aGUgcmVzdWx0IHZhbHVlIG9mIHRoZSBjbG91ZCBjb2RlIGZ1bmN0aW9uIGV4ZWN1dGlvbi4nLFxuICAgICAgICAgIHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQU5ZLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBmdW5jdGlvbk5hbWUsIHBhcmFtcyB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHQ6IChhd2FpdCBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRGdW5jdGlvbih7XG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBib2R5OiBwYXJhbXMsXG4gICAgICAgICAgICB9KSkucmVzcG9uc2UucmVzdWx0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICBjYWxsQ2xvdWRDb2RlTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlXG4gICAgKTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2FsbENsb3VkQ29kZU11dGF0aW9uLnR5cGUsIHRydWUsIHRydWUpO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgICAnY2FsbENsb3VkQ29kZScsXG4gICAgICBjYWxsQ2xvdWRDb2RlTXV0YXRpb24sXG4gICAgICB0cnVlLFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassMutations.js b/lib/GraphQL/loaders/parseClassMutations.js new file mode 100644 index 0000000000..775475a289 --- /dev/null +++ b/lib/GraphQL/loaders/parseClassMutations.js @@ -0,0 +1,288 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); + +var _className = require("../transformers/className"); + +var _mutation = require("../transformers/mutation"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const getOnlyRequiredFields = (updatedFields, selectedFieldsString, includedFieldsString, nativeObjectFields) => { + const includedFields = includedFieldsString ? includedFieldsString.split(',') : []; + const selectedFields = selectedFieldsString ? selectedFieldsString.split(',') : []; + const missingFields = selectedFields.filter(field => !nativeObjectFields.includes(field) || includedFields.includes(field)).join(','); + + if (!missingFields.length) { + return { + needGet: false, + keys: '' + }; + } else { + return { + needGet: true, + keys: missingFields + }; + } +}; + +const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { + const className = parseClass.className; + const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); + const getGraphQLQueryName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + const { + create: isCreateEnabled = true, + update: isUpdateEnabled = true, + destroy: isDestroyEnabled = true, + createAlias = '', + updateAlias = '', + destroyAlias = '' + } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); + const { + classGraphQLCreateType, + classGraphQLUpdateType, + classGraphQLOutputType + } = parseGraphQLSchema.parseClassTypes[className]; + + if (isCreateEnabled) { + const createGraphQLMutationName = createAlias || `create${graphQLClassName}`; + const createGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: `Create${graphQLClassName}`, + description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`, + inputFields: { + fields: { + description: 'These are the fields that will be used to create the new object.', + type: classGraphQLCreateType || defaultGraphQLTypes.OBJECT + } + }, + outputFields: { + [getGraphQLQueryName]: { + description: 'This is the created object.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + let { + fields + } = args; + if (!fields) fields = {}; + const { + config, + auth, + info + } = context; + const parseFields = await (0, _mutation.transformTypes)('create', fields, { + className, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const createdObject = await objectsMutations.createObject(className, parseFields, config, auth, info); + const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + const { + keys: requiredKeys, + needGet + } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'createdAt', 'updatedAt']); + const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); + let optimizedObject = {}; + + if (needGet && !needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } else if (needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } + + return { + [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({}, createdObject), {}, { + updatedAt: createdObject.createdAt + }, parseFields), optimizedObject) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + + if (parseGraphQLSchema.addGraphQLType(createGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(createGraphQLMutation.type)) { + parseGraphQLSchema.addGraphQLMutation(createGraphQLMutationName, createGraphQLMutation); + } + } + + if (isUpdateEnabled) { + const updateGraphQLMutationName = updateAlias || `update${graphQLClassName}`; + const updateGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: `Update${graphQLClassName}`, + description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`, + inputFields: { + id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, + fields: { + description: 'These are the fields that will be used to update the object.', + type: classGraphQLUpdateType || defaultGraphQLTypes.OBJECT + } + }, + outputFields: { + [getGraphQLQueryName]: { + description: 'This is the updated object.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + let { + id, + fields + } = args; + if (!fields) fields = {}; + const { + config, + auth, + info + } = context; + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); + + if (globalIdObject.type === className) { + id = globalIdObject.id; + } + + const parseFields = await (0, _mutation.transformTypes)('update', fields, { + className, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const updatedObject = await objectsMutations.updateObject(className, id, parseFields, config, auth, info); + const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + const { + keys: requiredKeys, + needGet + } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'updatedAt']); + const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); + let optimizedObject = {}; + + if (needGet && !needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, id, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } else if (needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, id, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } + + return { + [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({ + objectId: id + }, updatedObject), parseFields), optimizedObject) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + + if (parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.type)) { + parseGraphQLSchema.addGraphQLMutation(updateGraphQLMutationName, updateGraphQLMutation); + } + } + + if (isDestroyEnabled) { + const deleteGraphQLMutationName = destroyAlias || `delete${graphQLClassName}`; + const deleteGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: `Delete${graphQLClassName}`, + description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`, + inputFields: { + id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT + }, + outputFields: { + [getGraphQLQueryName]: { + description: 'This is the deleted object.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + let { + id + } = args; + const { + config, + auth, + info + } = context; + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); + + if (globalIdObject.type === className) { + id = globalIdObject.id; + } + + const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + let optimizedObject = {}; + + if (keys && keys.split(',').filter(key => !['id', 'objectId'].includes(key)).length > 0) { + optimizedObject = await objectsQueries.getObject(className, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } + + await objectsMutations.deleteObject(className, id, config, auth, info); + return { + [getGraphQLQueryName]: _objectSpread({ + objectId: id + }, optimizedObject) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + + if (parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.type)) { + parseGraphQLSchema.addGraphQLMutation(deleteGraphQLMutationName, deleteGraphQLMutation); + } + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJnZXRPbmx5UmVxdWlyZWRGaWVsZHMiLCJ1cGRhdGVkRmllbGRzIiwic2VsZWN0ZWRGaWVsZHNTdHJpbmciLCJpbmNsdWRlZEZpZWxkc1N0cmluZyIsIm5hdGl2ZU9iamVjdEZpZWxkcyIsImluY2x1ZGVkRmllbGRzIiwic3BsaXQiLCJzZWxlY3RlZEZpZWxkcyIsIm1pc3NpbmdGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwiam9pbiIsImxlbmd0aCIsIm5lZWRHZXQiLCJrZXlzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiZ3JhcGhRTENsYXNzTmFtZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJjaGFyQXQiLCJ0b0xvd2VyQ2FzZSIsInNsaWNlIiwiY3JlYXRlIiwiaXNDcmVhdGVFbmFibGVkIiwidXBkYXRlIiwiaXNVcGRhdGVFbmFibGVkIiwiZGVzdHJveSIsImlzRGVzdHJveUVuYWJsZWQiLCJjcmVhdGVBbGlhcyIsInVwZGF0ZUFsaWFzIiwiZGVzdHJveUFsaWFzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsImNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY3JlYXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImNyZWF0ZUdyYXBoUUxNdXRhdGlvbiIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsImlucHV0RmllbGRzIiwiZmllbGRzIiwidHlwZSIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJPQkpFQ1QiLCJvdXRwdXRGaWVsZHMiLCJHcmFwaFFMTm9uTnVsbCIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJyZXEiLCJjcmVhdGVkT2JqZWN0Iiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsInN0YXJ0c1dpdGgiLCJtYXAiLCJyZXBsYWNlIiwiaW5jbHVkZSIsInJlcXVpcmVkS2V5cyIsIm5lZWRUb0dldEFsbEtleXMiLCJvYmplY3RzUXVlcmllcyIsInBhcnNlQ2xhc3NlcyIsIm9wdGltaXplZE9iamVjdCIsImdldE9iamVjdCIsIm9iamVjdElkIiwidW5kZWZpbmVkIiwidXBkYXRlZEF0IiwiY3JlYXRlZEF0IiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUiLCJ1cGRhdGVHcmFwaFFMTXV0YXRpb24iLCJpZCIsIkdMT0JBTF9PUl9PQkpFQ1RfSURfQVRUIiwiZ2xvYmFsSWRPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwidXBkYXRlT2JqZWN0IiwiZGVsZXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImRlbGV0ZUdyYXBoUUxNdXRhdGlvbiIsImtleSIsImRlbGV0ZU9iamVjdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUlBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLENBQzVCQyxhQUQ0QixFQUU1QkMsb0JBRjRCLEVBRzVCQyxvQkFINEIsRUFJNUJDLGtCQUo0QixLQUt6QjtBQUNILFFBQU1DLGNBQWMsR0FBR0Ysb0JBQW9CLEdBQ3ZDQSxvQkFBb0IsQ0FBQ0csS0FBckIsQ0FBMkIsR0FBM0IsQ0FEdUMsR0FFdkMsRUFGSjtBQUdBLFFBQU1DLGNBQWMsR0FBR0wsb0JBQW9CLEdBQ3ZDQSxvQkFBb0IsQ0FBQ0ksS0FBckIsQ0FBMkIsR0FBM0IsQ0FEdUMsR0FFdkMsRUFGSjtBQUdBLFFBQU1FLGFBQWEsR0FBR0QsY0FBYyxDQUNqQ0UsTUFEbUIsQ0FFbEJDLEtBQUssSUFDSCxDQUFDTixrQkFBa0IsQ0FBQ08sUUFBbkIsQ0FBNEJELEtBQTVCLENBQUQsSUFBdUNMLGNBQWMsQ0FBQ00sUUFBZixDQUF3QkQsS0FBeEIsQ0FIdkIsRUFLbkJFLElBTG1CLENBS2QsR0FMYyxDQUF0Qjs7QUFNQSxNQUFJLENBQUNKLGFBQWEsQ0FBQ0ssTUFBbkIsRUFBMkI7QUFDekIsV0FBTztBQUFFQyxNQUFBQSxPQUFPLEVBQUUsS0FBWDtBQUFrQkMsTUFBQUEsSUFBSSxFQUFFO0FBQXhCLEtBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxXQUFPO0FBQUVELE1BQUFBLE9BQU8sRUFBRSxJQUFYO0FBQWlCQyxNQUFBQSxJQUFJLEVBQUVQO0FBQXZCLEtBQVA7QUFDRDtBQUNGLENBdkJEOztBQXlCQSxNQUFNUSxJQUFJLEdBQUcsVUFDWEMsa0JBRFcsRUFFWEMsVUFGVyxFQUdYQyxnQkFIVyxFQUlYO0FBQ0EsUUFBTUMsU0FBUyxHQUFHRixVQUFVLENBQUNFLFNBQTdCO0FBQ0EsUUFBTUMsZ0JBQWdCLEdBQUcsNENBQTRCRCxTQUE1QixDQUF6QjtBQUNBLFFBQU1FLG1CQUFtQixHQUN2QkQsZ0JBQWdCLENBQUNFLE1BQWpCLENBQXdCLENBQXhCLEVBQTJCQyxXQUEzQixLQUEyQ0gsZ0JBQWdCLENBQUNJLEtBQWpCLENBQXVCLENBQXZCLENBRDdDO0FBR0EsUUFBTTtBQUNKQyxJQUFBQSxNQUFNLEVBQUVDLGVBQWUsR0FBRyxJQUR0QjtBQUVKQyxJQUFBQSxNQUFNLEVBQUVDLGVBQWUsR0FBRyxJQUZ0QjtBQUdKQyxJQUFBQSxPQUFPLEVBQUVDLGdCQUFnQixHQUFHLElBSHhCO0FBSVNDLElBQUFBLFdBQVcsR0FBRyxFQUp2QjtBQUtTQyxJQUFBQSxXQUFXLEdBQUcsRUFMdkI7QUFNVUMsSUFBQUEsWUFBWSxHQUFHO0FBTnpCLE1BT0Ysb0RBQTRCZixnQkFBNUIsQ0FQSjtBQVNBLFFBQU07QUFDSmdCLElBQUFBLHNCQURJO0FBRUpDLElBQUFBLHNCQUZJO0FBR0pDLElBQUFBO0FBSEksTUFJRnBCLGtCQUFrQixDQUFDcUIsZUFBbkIsQ0FBbUNsQixTQUFuQyxDQUpKOztBQU1BLE1BQUlPLGVBQUosRUFBcUI7QUFDbkIsVUFBTVkseUJBQXlCLEdBQzdCUCxXQUFXLElBQUssU0FBUVgsZ0JBQWlCLEVBRDNDO0FBRUEsVUFBTW1CLHFCQUFxQixHQUFHLGdEQUE2QjtBQUN6REMsTUFBQUEsSUFBSSxFQUFHLFNBQVFwQixnQkFBaUIsRUFEeUI7QUFFekRxQixNQUFBQSxXQUFXLEVBQUcsT0FBTUgseUJBQTBCLHVEQUFzRGxCLGdCQUFpQixTQUY1RDtBQUd6RHNCLE1BQUFBLFdBQVcsRUFBRTtBQUNYQyxRQUFBQSxNQUFNLEVBQUU7QUFDTkYsVUFBQUEsV0FBVyxFQUNULGtFQUZJO0FBR05HLFVBQUFBLElBQUksRUFBRVYsc0JBQXNCLElBQUlXLG1CQUFtQixDQUFDQztBQUg5QztBQURHLE9BSDRDO0FBVXpEQyxNQUFBQSxZQUFZLEVBQUU7QUFDWixTQUFDMUIsbUJBQUQsR0FBdUI7QUFDckJvQixVQUFBQSxXQUFXLEVBQUUsNkJBRFE7QUFFckJHLFVBQUFBLElBQUksRUFBRSxJQUFJSSx1QkFBSixDQUNKWixzQkFBc0IsSUFBSVMsbUJBQW1CLENBQUNDLE1BRDFDO0FBRmU7QUFEWCxPQVYyQztBQWtCekRHLE1BQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsWUFBSTtBQUNGLGNBQUk7QUFBRVQsWUFBQUE7QUFBRixjQUFhTyxJQUFqQjtBQUNBLGNBQUksQ0FBQ1AsTUFBTCxFQUFhQSxNQUFNLEdBQUcsRUFBVDtBQUNiLGdCQUFNO0FBQUVVLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEIsY0FBeUJKLE9BQS9CO0FBRUEsZ0JBQU1LLFdBQVcsR0FBRyxNQUFNLDhCQUFlLFFBQWYsRUFBeUJiLE1BQXpCLEVBQWlDO0FBQ3pEeEIsWUFBQUEsU0FEeUQ7QUFFekRILFlBQUFBLGtCQUZ5RDtBQUd6RHlDLFlBQUFBLEdBQUcsRUFBRTtBQUFFSixjQUFBQSxNQUFGO0FBQVVDLGNBQUFBLElBQVY7QUFBZ0JDLGNBQUFBO0FBQWhCO0FBSG9ELFdBQWpDLENBQTFCO0FBTUEsZ0JBQU1HLGFBQWEsR0FBRyxNQUFNQyxnQkFBZ0IsQ0FBQ0MsWUFBakIsQ0FDMUJ6QyxTQUQwQixFQUUxQnFDLFdBRjBCLEVBRzFCSCxNQUgwQixFQUkxQkMsSUFKMEIsRUFLMUJDLElBTDBCLENBQTVCO0FBT0EsZ0JBQU1qRCxjQUFjLEdBQUcsZ0NBQWM4QyxZQUFkLEVBQ3BCNUMsTUFEb0IsQ0FDYkMsS0FBSyxJQUFJQSxLQUFLLENBQUNvRCxVQUFOLENBQWtCLEdBQUV4QyxtQkFBb0IsR0FBeEMsQ0FESSxFQUVwQnlDLEdBRm9CLENBRWhCckQsS0FBSyxJQUFJQSxLQUFLLENBQUNzRCxPQUFOLENBQWUsR0FBRTFDLG1CQUFvQixHQUFyQyxFQUF5QyxFQUF6QyxDQUZPLENBQXZCO0FBR0EsZ0JBQU07QUFBRVAsWUFBQUEsSUFBRjtBQUFRa0QsWUFBQUE7QUFBUixjQUFvQiw4Q0FBc0IxRCxjQUF0QixDQUExQjtBQUNBLGdCQUFNO0FBQUVRLFlBQUFBLElBQUksRUFBRW1ELFlBQVI7QUFBc0JwRCxZQUFBQTtBQUF0QixjQUFrQ2QscUJBQXFCLENBQzNENEMsTUFEMkQsRUFFM0Q3QixJQUYyRCxFQUczRGtELE9BSDJELEVBSTNELENBQUMsSUFBRCxFQUFPLFVBQVAsRUFBbUIsV0FBbkIsRUFBZ0MsV0FBaEMsQ0FKMkQsQ0FBN0Q7QUFNQSxnQkFBTUUsZ0JBQWdCLEdBQUdDLGNBQWMsQ0FBQ0QsZ0JBQWYsQ0FDdkJqRCxVQUFVLENBQUMwQixNQURZLEVBRXZCN0IsSUFGdUIsRUFHdkJFLGtCQUFrQixDQUFDb0QsWUFISSxDQUF6QjtBQUtBLGNBQUlDLGVBQWUsR0FBRyxFQUF0Qjs7QUFDQSxjQUFJeEQsT0FBTyxJQUFJLENBQUNxRCxnQkFBaEIsRUFBa0M7QUFDaENHLFlBQUFBLGVBQWUsR0FBRyxNQUFNRixjQUFjLENBQUNHLFNBQWYsQ0FDdEJuRCxTQURzQixFQUV0QnVDLGFBQWEsQ0FBQ2EsUUFGUSxFQUd0Qk4sWUFIc0IsRUFJdEJELE9BSnNCLEVBS3RCUSxTQUxzQixFQU10QkEsU0FOc0IsRUFPdEJuQixNQVBzQixFQVF0QkMsSUFSc0IsRUFTdEJDLElBVHNCLEVBVXRCdkMsa0JBQWtCLENBQUNvRCxZQVZHLENBQXhCO0FBWUQsV0FiRCxNQWFPLElBQUlGLGdCQUFKLEVBQXNCO0FBQzNCRyxZQUFBQSxlQUFlLEdBQUcsTUFBTUYsY0FBYyxDQUFDRyxTQUFmLENBQ3RCbkQsU0FEc0IsRUFFdEJ1QyxhQUFhLENBQUNhLFFBRlEsRUFHdEJDLFNBSHNCLEVBSXRCUixPQUpzQixFQUt0QlEsU0FMc0IsRUFNdEJBLFNBTnNCLEVBT3RCbkIsTUFQc0IsRUFRdEJDLElBUnNCLEVBU3RCQyxJQVRzQixFQVV0QnZDLGtCQUFrQixDQUFDb0QsWUFWRyxDQUF4QjtBQVlEOztBQUNELGlCQUFPO0FBQ0wsYUFBQy9DLG1CQUFELGlEQUNLcUMsYUFETDtBQUVFZSxjQUFBQSxTQUFTLEVBQUVmLGFBQWEsQ0FBQ2dCO0FBRjNCLGVBR0tsQixXQUhMLEdBSUthLGVBSkw7QUFESyxXQUFQO0FBUUQsU0FyRUQsQ0FxRUUsT0FBT00sQ0FBUCxFQUFVO0FBQ1YzRCxVQUFBQSxrQkFBa0IsQ0FBQzRELFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUEzRndELEtBQTdCLENBQTlCOztBQThGQSxRQUNFM0Qsa0JBQWtCLENBQUM2RCxjQUFuQixDQUNFdEMscUJBQXFCLENBQUNXLElBQXRCLENBQTJCNEIsS0FBM0IsQ0FBaUNsQyxJQUFqQyxDQUFzQ21DLE1BRHhDLEtBR0EvRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDdEMscUJBQXFCLENBQUNLLElBQXhELENBSkYsRUFLRTtBQUNBNUIsTUFBQUEsa0JBQWtCLENBQUNnRSxrQkFBbkIsQ0FDRTFDLHlCQURGLEVBRUVDLHFCQUZGO0FBSUQ7QUFDRjs7QUFFRCxNQUFJWCxlQUFKLEVBQXFCO0FBQ25CLFVBQU1xRCx5QkFBeUIsR0FDN0JqRCxXQUFXLElBQUssU0FBUVosZ0JBQWlCLEVBRDNDO0FBRUEsVUFBTThELHFCQUFxQixHQUFHLGdEQUE2QjtBQUN6RDFDLE1BQUFBLElBQUksRUFBRyxTQUFRcEIsZ0JBQWlCLEVBRHlCO0FBRXpEcUIsTUFBQUEsV0FBVyxFQUFHLE9BQU13Qyx5QkFBMEIsb0RBQW1EN0QsZ0JBQWlCLFNBRnpEO0FBR3pEc0IsTUFBQUEsV0FBVyxFQUFFO0FBQ1h5QyxRQUFBQSxFQUFFLEVBQUV0QyxtQkFBbUIsQ0FBQ3VDLHVCQURiO0FBRVh6QyxRQUFBQSxNQUFNLEVBQUU7QUFDTkYsVUFBQUEsV0FBVyxFQUNULDhEQUZJO0FBR05HLFVBQUFBLElBQUksRUFBRVQsc0JBQXNCLElBQUlVLG1CQUFtQixDQUFDQztBQUg5QztBQUZHLE9BSDRDO0FBV3pEQyxNQUFBQSxZQUFZLEVBQUU7QUFDWixTQUFDMUIsbUJBQUQsR0FBdUI7QUFDckJvQixVQUFBQSxXQUFXLEVBQUUsNkJBRFE7QUFFckJHLFVBQUFBLElBQUksRUFBRSxJQUFJSSx1QkFBSixDQUNKWixzQkFBc0IsSUFBSVMsbUJBQW1CLENBQUNDLE1BRDFDO0FBRmU7QUFEWCxPQVgyQztBQW1CekRHLE1BQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsWUFBSTtBQUNGLGNBQUk7QUFBRStCLFlBQUFBLEVBQUY7QUFBTXhDLFlBQUFBO0FBQU4sY0FBaUJPLElBQXJCO0FBQ0EsY0FBSSxDQUFDUCxNQUFMLEVBQWFBLE1BQU0sR0FBRyxFQUFUO0FBQ2IsZ0JBQU07QUFBRVUsWUFBQUEsTUFBRjtBQUFVQyxZQUFBQSxJQUFWO0FBQWdCQyxZQUFBQTtBQUFoQixjQUF5QkosT0FBL0I7QUFFQSxnQkFBTWtDLGNBQWMsR0FBRyxnQ0FBYUYsRUFBYixDQUF2Qjs7QUFFQSxjQUFJRSxjQUFjLENBQUN6QyxJQUFmLEtBQXdCekIsU0FBNUIsRUFBdUM7QUFDckNnRSxZQUFBQSxFQUFFLEdBQUdFLGNBQWMsQ0FBQ0YsRUFBcEI7QUFDRDs7QUFFRCxnQkFBTTNCLFdBQVcsR0FBRyxNQUFNLDhCQUFlLFFBQWYsRUFBeUJiLE1BQXpCLEVBQWlDO0FBQ3pEeEIsWUFBQUEsU0FEeUQ7QUFFekRILFlBQUFBLGtCQUZ5RDtBQUd6RHlDLFlBQUFBLEdBQUcsRUFBRTtBQUFFSixjQUFBQSxNQUFGO0FBQVVDLGNBQUFBLElBQVY7QUFBZ0JDLGNBQUFBO0FBQWhCO0FBSG9ELFdBQWpDLENBQTFCO0FBTUEsZ0JBQU0rQixhQUFhLEdBQUcsTUFBTTNCLGdCQUFnQixDQUFDNEIsWUFBakIsQ0FDMUJwRSxTQUQwQixFQUUxQmdFLEVBRjBCLEVBRzFCM0IsV0FIMEIsRUFJMUJILE1BSjBCLEVBSzFCQyxJQUwwQixFQU0xQkMsSUFOMEIsQ0FBNUI7QUFTQSxnQkFBTWpELGNBQWMsR0FBRyxnQ0FBYzhDLFlBQWQsRUFDcEI1QyxNQURvQixDQUNiQyxLQUFLLElBQUlBLEtBQUssQ0FBQ29ELFVBQU4sQ0FBa0IsR0FBRXhDLG1CQUFvQixHQUF4QyxDQURJLEVBRXBCeUMsR0FGb0IsQ0FFaEJyRCxLQUFLLElBQUlBLEtBQUssQ0FBQ3NELE9BQU4sQ0FBZSxHQUFFMUMsbUJBQW9CLEdBQXJDLEVBQXlDLEVBQXpDLENBRk8sQ0FBdkI7QUFHQSxnQkFBTTtBQUFFUCxZQUFBQSxJQUFGO0FBQVFrRCxZQUFBQTtBQUFSLGNBQW9CLDhDQUFzQjFELGNBQXRCLENBQTFCO0FBQ0EsZ0JBQU07QUFBRVEsWUFBQUEsSUFBSSxFQUFFbUQsWUFBUjtBQUFzQnBELFlBQUFBO0FBQXRCLGNBQWtDZCxxQkFBcUIsQ0FDM0Q0QyxNQUQyRCxFQUUzRDdCLElBRjJELEVBRzNEa0QsT0FIMkQsRUFJM0QsQ0FBQyxJQUFELEVBQU8sVUFBUCxFQUFtQixXQUFuQixDQUoyRCxDQUE3RDtBQU1BLGdCQUFNRSxnQkFBZ0IsR0FBR0MsY0FBYyxDQUFDRCxnQkFBZixDQUN2QmpELFVBQVUsQ0FBQzBCLE1BRFksRUFFdkI3QixJQUZ1QixFQUd2QkUsa0JBQWtCLENBQUNvRCxZQUhJLENBQXpCO0FBS0EsY0FBSUMsZUFBZSxHQUFHLEVBQXRCOztBQUNBLGNBQUl4RCxPQUFPLElBQUksQ0FBQ3FELGdCQUFoQixFQUFrQztBQUNoQ0csWUFBQUEsZUFBZSxHQUFHLE1BQU1GLGNBQWMsQ0FBQ0csU0FBZixDQUN0Qm5ELFNBRHNCLEVBRXRCZ0UsRUFGc0IsRUFHdEJsQixZQUhzQixFQUl0QkQsT0FKc0IsRUFLdEJRLFNBTHNCLEVBTXRCQSxTQU5zQixFQU90Qm5CLE1BUHNCLEVBUXRCQyxJQVJzQixFQVN0QkMsSUFUc0IsRUFVdEJ2QyxrQkFBa0IsQ0FBQ29ELFlBVkcsQ0FBeEI7QUFZRCxXQWJELE1BYU8sSUFBSUYsZ0JBQUosRUFBc0I7QUFDM0JHLFlBQUFBLGVBQWUsR0FBRyxNQUFNRixjQUFjLENBQUNHLFNBQWYsQ0FDdEJuRCxTQURzQixFQUV0QmdFLEVBRnNCLEVBR3RCWCxTQUhzQixFQUl0QlIsT0FKc0IsRUFLdEJRLFNBTHNCLEVBTXRCQSxTQU5zQixFQU90Qm5CLE1BUHNCLEVBUXRCQyxJQVJzQixFQVN0QkMsSUFUc0IsRUFVdEJ2QyxrQkFBa0IsQ0FBQ29ELFlBVkcsQ0FBeEI7QUFZRDs7QUFDRCxpQkFBTztBQUNMLGFBQUMvQyxtQkFBRDtBQUNFa0QsY0FBQUEsUUFBUSxFQUFFWTtBQURaLGVBRUtHLGFBRkwsR0FHSzlCLFdBSEwsR0FJS2EsZUFKTDtBQURLLFdBQVA7QUFRRCxTQTdFRCxDQTZFRSxPQUFPTSxDQUFQLEVBQVU7QUFDVjNELFVBQUFBLGtCQUFrQixDQUFDNEQsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQXBHd0QsS0FBN0IsQ0FBOUI7O0FBdUdBLFFBQ0UzRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQ0VLLHFCQUFxQixDQUFDaEMsSUFBdEIsQ0FBMkI0QixLQUEzQixDQUFpQ2xDLElBQWpDLENBQXNDbUMsTUFEeEMsS0FHQS9ELGtCQUFrQixDQUFDNkQsY0FBbkIsQ0FBa0NLLHFCQUFxQixDQUFDdEMsSUFBeEQsQ0FKRixFQUtFO0FBQ0E1QixNQUFBQSxrQkFBa0IsQ0FBQ2dFLGtCQUFuQixDQUNFQyx5QkFERixFQUVFQyxxQkFGRjtBQUlEO0FBQ0Y7O0FBRUQsTUFBSXBELGdCQUFKLEVBQXNCO0FBQ3BCLFVBQU0wRCx5QkFBeUIsR0FDN0J2RCxZQUFZLElBQUssU0FBUWIsZ0JBQWlCLEVBRDVDO0FBRUEsVUFBTXFFLHFCQUFxQixHQUFHLGdEQUE2QjtBQUN6RGpELE1BQUFBLElBQUksRUFBRyxTQUFRcEIsZ0JBQWlCLEVBRHlCO0FBRXpEcUIsTUFBQUEsV0FBVyxFQUFHLE9BQU0rQyx5QkFBMEIsb0RBQW1EcEUsZ0JBQWlCLFNBRnpEO0FBR3pEc0IsTUFBQUEsV0FBVyxFQUFFO0FBQ1h5QyxRQUFBQSxFQUFFLEVBQUV0QyxtQkFBbUIsQ0FBQ3VDO0FBRGIsT0FINEM7QUFNekRyQyxNQUFBQSxZQUFZLEVBQUU7QUFDWixTQUFDMUIsbUJBQUQsR0FBdUI7QUFDckJvQixVQUFBQSxXQUFXLEVBQUUsNkJBRFE7QUFFckJHLFVBQUFBLElBQUksRUFBRSxJQUFJSSx1QkFBSixDQUNKWixzQkFBc0IsSUFBSVMsbUJBQW1CLENBQUNDLE1BRDFDO0FBRmU7QUFEWCxPQU4yQztBQWN6REcsTUFBQUEsbUJBQW1CLEVBQUUsT0FBT0MsSUFBUCxFQUFhQyxPQUFiLEVBQXNCQyxZQUF0QixLQUF1QztBQUMxRCxZQUFJO0FBQ0YsY0FBSTtBQUFFK0IsWUFBQUE7QUFBRixjQUFTakMsSUFBYjtBQUNBLGdCQUFNO0FBQUVHLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEIsY0FBeUJKLE9BQS9CO0FBRUEsZ0JBQU1rQyxjQUFjLEdBQUcsZ0NBQWFGLEVBQWIsQ0FBdkI7O0FBRUEsY0FBSUUsY0FBYyxDQUFDekMsSUFBZixLQUF3QnpCLFNBQTVCLEVBQXVDO0FBQ3JDZ0UsWUFBQUEsRUFBRSxHQUFHRSxjQUFjLENBQUNGLEVBQXBCO0FBQ0Q7O0FBRUQsZ0JBQU03RSxjQUFjLEdBQUcsZ0NBQWM4QyxZQUFkLEVBQ3BCNUMsTUFEb0IsQ0FDYkMsS0FBSyxJQUFJQSxLQUFLLENBQUNvRCxVQUFOLENBQWtCLEdBQUV4QyxtQkFBb0IsR0FBeEMsQ0FESSxFQUVwQnlDLEdBRm9CLENBRWhCckQsS0FBSyxJQUFJQSxLQUFLLENBQUNzRCxPQUFOLENBQWUsR0FBRTFDLG1CQUFvQixHQUFyQyxFQUF5QyxFQUF6QyxDQUZPLENBQXZCO0FBR0EsZ0JBQU07QUFBRVAsWUFBQUEsSUFBRjtBQUFRa0QsWUFBQUE7QUFBUixjQUFvQiw4Q0FBc0IxRCxjQUF0QixDQUExQjtBQUNBLGNBQUkrRCxlQUFlLEdBQUcsRUFBdEI7O0FBQ0EsY0FDRXZELElBQUksSUFDSkEsSUFBSSxDQUFDVCxLQUFMLENBQVcsR0FBWCxFQUFnQkcsTUFBaEIsQ0FBdUJrRixHQUFHLElBQUksQ0FBQyxDQUFDLElBQUQsRUFBTyxVQUFQLEVBQW1CaEYsUUFBbkIsQ0FBNEJnRixHQUE1QixDQUEvQixFQUNHOUUsTUFESCxHQUNZLENBSGQsRUFJRTtBQUNBeUQsWUFBQUEsZUFBZSxHQUFHLE1BQU1GLGNBQWMsQ0FBQ0csU0FBZixDQUN0Qm5ELFNBRHNCLEVBRXRCZ0UsRUFGc0IsRUFHdEJyRSxJQUhzQixFQUl0QmtELE9BSnNCLEVBS3RCUSxTQUxzQixFQU10QkEsU0FOc0IsRUFPdEJuQixNQVBzQixFQVF0QkMsSUFSc0IsRUFTdEJDLElBVHNCLEVBVXRCdkMsa0JBQWtCLENBQUNvRCxZQVZHLENBQXhCO0FBWUQ7O0FBQ0QsZ0JBQU1ULGdCQUFnQixDQUFDZ0MsWUFBakIsQ0FDSnhFLFNBREksRUFFSmdFLEVBRkksRUFHSjlCLE1BSEksRUFJSkMsSUFKSSxFQUtKQyxJQUxJLENBQU47QUFPQSxpQkFBTztBQUNMLGFBQUNsQyxtQkFBRDtBQUNFa0QsY0FBQUEsUUFBUSxFQUFFWTtBQURaLGVBRUtkLGVBRkw7QUFESyxXQUFQO0FBTUQsU0E5Q0QsQ0E4Q0UsT0FBT00sQ0FBUCxFQUFVO0FBQ1YzRCxVQUFBQSxrQkFBa0IsQ0FBQzRELFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUFoRXdELEtBQTdCLENBQTlCOztBQW1FQSxRQUNFM0Qsa0JBQWtCLENBQUM2RCxjQUFuQixDQUNFWSxxQkFBcUIsQ0FBQ3ZDLElBQXRCLENBQTJCNEIsS0FBM0IsQ0FBaUNsQyxJQUFqQyxDQUFzQ21DLE1BRHhDLEtBR0EvRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDWSxxQkFBcUIsQ0FBQzdDLElBQXhELENBSkYsRUFLRTtBQUNBNUIsTUFBQUEsa0JBQWtCLENBQUNnRSxrQkFBbkIsQ0FDRVEseUJBREYsRUFFRUMscUJBRkY7QUFJRDtBQUNGO0FBQ0YsQ0FoVkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZnJvbUdsb2JhbElkLCBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCB7XG4gIGV4dHJhY3RLZXlzQW5kSW5jbHVkZSxcbiAgZ2V0UGFyc2VDbGFzc011dGF0aW9uQ29uZmlnLFxufSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzTXV0YXRpb25zIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY2xhc3NOYW1lJztcbmltcG9ydCB7IHRyYW5zZm9ybVR5cGVzIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL211dGF0aW9uJztcblxuY29uc3QgZ2V0T25seVJlcXVpcmVkRmllbGRzID0gKFxuICB1cGRhdGVkRmllbGRzLFxuICBzZWxlY3RlZEZpZWxkc1N0cmluZyxcbiAgaW5jbHVkZWRGaWVsZHNTdHJpbmcsXG4gIG5hdGl2ZU9iamVjdEZpZWxkc1xuKSA9PiB7XG4gIGNvbnN0IGluY2x1ZGVkRmllbGRzID0gaW5jbHVkZWRGaWVsZHNTdHJpbmdcbiAgICA/IGluY2x1ZGVkRmllbGRzU3RyaW5nLnNwbGl0KCcsJylcbiAgICA6IFtdO1xuICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IHNlbGVjdGVkRmllbGRzU3RyaW5nXG4gICAgPyBzZWxlY3RlZEZpZWxkc1N0cmluZy5zcGxpdCgnLCcpXG4gICAgOiBbXTtcbiAgY29uc3QgbWlzc2luZ0ZpZWxkcyA9IHNlbGVjdGVkRmllbGRzXG4gICAgLmZpbHRlcihcbiAgICAgIGZpZWxkID0+XG4gICAgICAgICFuYXRpdmVPYmplY3RGaWVsZHMuaW5jbHVkZXMoZmllbGQpIHx8IGluY2x1ZGVkRmllbGRzLmluY2x1ZGVzKGZpZWxkKVxuICAgIClcbiAgICAuam9pbignLCcpO1xuICBpZiAoIW1pc3NpbmdGaWVsZHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHsgbmVlZEdldDogZmFsc2UsIGtleXM6ICcnIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHsgbmVlZEdldDogdHJ1ZSwga2V5czogbWlzc2luZ0ZpZWxkcyB9O1xuICB9XG59O1xuXG5jb25zdCBsb2FkID0gZnVuY3Rpb24oXG4gIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgcGFyc2VDbGFzcyxcbiAgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnXG4pIHtcbiAgY29uc3QgY2xhc3NOYW1lID0gcGFyc2VDbGFzcy5jbGFzc05hbWU7XG4gIGNvbnN0IGdyYXBoUUxDbGFzc05hbWUgPSB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwoY2xhc3NOYW1lKTtcbiAgY29uc3QgZ2V0R3JhcGhRTFF1ZXJ5TmFtZSA9XG4gICAgZ3JhcGhRTENsYXNzTmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGdyYXBoUUxDbGFzc05hbWUuc2xpY2UoMSk7XG5cbiAgY29uc3Qge1xuICAgIGNyZWF0ZTogaXNDcmVhdGVFbmFibGVkID0gdHJ1ZSxcbiAgICB1cGRhdGU6IGlzVXBkYXRlRW5hYmxlZCA9IHRydWUsXG4gICAgZGVzdHJveTogaXNEZXN0cm95RW5hYmxlZCA9IHRydWUsXG4gICAgY3JlYXRlQWxpYXM6IGNyZWF0ZUFsaWFzID0gJycsXG4gICAgdXBkYXRlQWxpYXM6IHVwZGF0ZUFsaWFzID0gJycsXG4gICAgZGVzdHJveUFsaWFzOiBkZXN0cm95QWxpYXMgPSAnJyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG5cbiAgaWYgKGlzQ3JlYXRlRW5hYmxlZCkge1xuICAgIGNvbnN0IGNyZWF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUgPVxuICAgICAgY3JlYXRlQWxpYXMgfHwgYGNyZWF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gO1xuICAgIGNvbnN0IGNyZWF0ZUdyYXBoUUxNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogYENyZWF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtjcmVhdGVHcmFwaFFMTXV0YXRpb25OYW1lfSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICdUaGVzZSBhcmUgdGhlIGZpZWxkcyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjcmVhdGUgdGhlIG5ldyBvYmplY3QuJyxcbiAgICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNULFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgICBbZ2V0R3JhcGhRTFF1ZXJ5TmFtZV06IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNyZWF0ZWQgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICAgICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVFxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB7IGZpZWxkcyB9ID0gYXJncztcbiAgICAgICAgICBpZiAoIWZpZWxkcykgZmllbGRzID0ge307XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGNyZWF0ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm9cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhtdXRhdGlvbkluZm8pXG4gICAgICAgICAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCkpXG4gICAgICAgICAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2UoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCwgJycpKTtcbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG4gICAgICAgICAgY29uc3QgeyBrZXlzOiByZXF1aXJlZEtleXMsIG5lZWRHZXQgfSA9IGdldE9ubHlSZXF1aXJlZEZpZWxkcyhcbiAgICAgICAgICAgIGZpZWxkcyxcbiAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgWydpZCcsICdvYmplY3RJZCcsICdjcmVhdGVkQXQnLCAndXBkYXRlZEF0J11cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSBvYmplY3RzUXVlcmllcy5uZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHMsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChuZWVkR2V0ICYmICFuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgY3JlYXRlZE9iamVjdC5vYmplY3RJZCxcbiAgICAgICAgICAgICAgcmVxdWlyZWRLZXlzLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmVlZFRvR2V0QWxsS2V5cykge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGNyZWF0ZWRPYmplY3Qub2JqZWN0SWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICAuLi5jcmVhdGVkT2JqZWN0LFxuICAgICAgICAgICAgICB1cGRhdGVkQXQ6IGNyZWF0ZWRPYmplY3QuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAuLi5wYXJzZUZpZWxkcyxcbiAgICAgICAgICAgICAgLi4ub3B0aW1pemVkT2JqZWN0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKFxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgICAgICBjcmVhdGVHcmFwaFFMTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZVxuICAgICAgKSAmJlxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUdyYXBoUUxNdXRhdGlvbi50eXBlKVxuICAgICkge1xuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAgICAgY3JlYXRlR3JhcGhRTE11dGF0aW9uTmFtZSxcbiAgICAgICAgY3JlYXRlR3JhcGhRTE11dGF0aW9uXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc1VwZGF0ZUVuYWJsZWQpIHtcbiAgICBjb25zdCB1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lID1cbiAgICAgIHVwZGF0ZUFsaWFzIHx8IGB1cGRhdGUke2dyYXBoUUxDbGFzc05hbWV9YDtcbiAgICBjb25zdCB1cGRhdGVHcmFwaFFMTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICAgIG5hbWU6IGBVcGRhdGUke2dyYXBoUUxDbGFzc05hbWV9YCxcbiAgICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7dXBkYXRlR3JhcGhRTE11dGF0aW9uTmFtZX0gbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gdXBkYXRlIGFuIG9iamVjdCBvZiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgICAgaWQ6IGRlZmF1bHRHcmFwaFFMVHlwZXMuR0xPQkFMX09SX09CSkVDVF9JRF9BVFQsXG4gICAgICAgIGZpZWxkczoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgJ1RoZXNlIGFyZSB0aGUgZmllbGRzIHRoYXQgd2lsbCBiZSB1c2VkIHRvIHVwZGF0ZSB0aGUgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMVXBkYXRlVHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cGRhdGVkIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChcbiAgICAgICAgICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsZXQgeyBpZCwgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICAgIGlmICghZmllbGRzKSBmaWVsZHMgPSB7fTtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGlkKTtcblxuICAgICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIGlkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcGFyc2VGaWVsZHMgPSBhd2FpdCB0cmFuc2Zvcm1UeXBlcygndXBkYXRlJywgZmllbGRzLCB7XG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c011dGF0aW9ucy51cGRhdGVPYmplY3QoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm9cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKG11dGF0aW9uSW5mbylcbiAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aChgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gKSlcbiAgICAgICAgICAgIC5tYXAoZmllbGQgPT4gZmllbGQucmVwbGFjZShgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gLCAnJykpO1xuICAgICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKHNlbGVjdGVkRmllbGRzKTtcbiAgICAgICAgICBjb25zdCB7IGtleXM6IHJlcXVpcmVkS2V5cywgbmVlZEdldCB9ID0gZ2V0T25seVJlcXVpcmVkRmllbGRzKFxuICAgICAgICAgICAgZmllbGRzLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICBbJ2lkJywgJ29iamVjdElkJywgJ3VwZGF0ZWRBdCddXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBuZWVkVG9HZXRBbGxLZXlzID0gb2JqZWN0c1F1ZXJpZXMubmVlZFRvR2V0QWxsS2V5cyhcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGxldCBvcHRpbWl6ZWRPYmplY3QgPSB7fTtcbiAgICAgICAgICBpZiAobmVlZEdldCAmJiAhbmVlZFRvR2V0QWxsS2V5cykge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICByZXF1aXJlZEtleXMsXG4gICAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICBvYmplY3RJZDogaWQsXG4gICAgICAgICAgICAgIC4uLnVwZGF0ZWRPYmplY3QsXG4gICAgICAgICAgICAgIC4uLnBhcnNlRmllbGRzLFxuICAgICAgICAgICAgICAuLi5vcHRpbWl6ZWRPYmplY3QsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICAgIHVwZGF0ZUdyYXBoUUxNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlXG4gICAgICApICYmXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUodXBkYXRlR3JhcGhRTE11dGF0aW9uLnR5cGUpXG4gICAgKSB7XG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKFxuICAgICAgICB1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lLFxuICAgICAgICB1cGRhdGVHcmFwaFFMTXV0YXRpb25cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzRGVzdHJveUVuYWJsZWQpIHtcbiAgICBjb25zdCBkZWxldGVHcmFwaFFMTXV0YXRpb25OYW1lID1cbiAgICAgIGRlc3Ryb3lBbGlhcyB8fCBgZGVsZXRlJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gICAgY29uc3QgZGVsZXRlR3JhcGhRTE11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgICBuYW1lOiBgRGVsZXRlJHtncmFwaFFMQ2xhc3NOYW1lfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSAke2RlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWV9IG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIGRlbGV0ZSBhbiBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICAgIGlucHV0RmllbGRzOiB7XG4gICAgICAgIGlkOiBkZWZhdWx0R3JhcGhRTFR5cGVzLkdMT0JBTF9PUl9PQkpFQ1RfSURfQVRULFxuICAgICAgfSxcbiAgICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgICBbZ2V0R3JhcGhRTFF1ZXJ5TmFtZV06IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGRlbGV0ZWQgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICAgICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVFxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB7IGlkIH0gPSBhcmdzO1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaWQpO1xuXG4gICAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IGNsYXNzTmFtZSkge1xuICAgICAgICAgICAgaWQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMobXV0YXRpb25JbmZvKVxuICAgICAgICAgICAgLmZpbHRlcihmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmApKVxuICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmAsICcnKSk7XG4gICAgICAgICAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGxldCBvcHRpbWl6ZWRPYmplY3QgPSB7fTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBrZXlzICYmXG4gICAgICAgICAgICBrZXlzLnNwbGl0KCcsJykuZmlsdGVyKGtleSA9PiAhWydpZCcsICdvYmplY3RJZCddLmluY2x1ZGVzKGtleSkpXG4gICAgICAgICAgICAgIC5sZW5ndGggPiAwXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuZGVsZXRlT2JqZWN0KFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mb1xuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICBvYmplY3RJZDogaWQsXG4gICAgICAgICAgICAgIC4uLm9wdGltaXplZE9iamVjdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICAgICAgZGVsZXRlR3JhcGhRTE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGVcbiAgICAgICkgJiZcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShkZWxldGVHcmFwaFFMTXV0YXRpb24udHlwZSlcbiAgICApIHtcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgICAgIGRlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWUsXG4gICAgICAgIGRlbGV0ZUdyYXBoUUxNdXRhdGlvblxuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassQueries.js b/lib/GraphQL/loaders/parseClassQueries.js new file mode 100644 index 0000000000..2901f2cf06 --- /dev/null +++ b/lib/GraphQL/loaders/parseClassQueries.js @@ -0,0 +1,150 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var _pluralize = _interopRequireDefault(require("pluralize")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); + +var _className = require("../transformers/className"); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const getParseClassQueryConfig = function (parseClassConfig) { + return parseClassConfig && parseClassConfig.query || {}; +}; + +const getQuery = async (parseClass, _source, args, context, queryInfo, parseClasses) => { + let { + id + } = args; + const { + options + } = args; + const { + readPreference, + includeReadPreference + } = options || {}; + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); + + if (globalIdObject.type === parseClass.className) { + id = globalIdObject.id; + } + + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + return await objectsQueries.getObject(parseClass.className, id, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses); +}; + +const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { + const className = parseClass.className; + const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); + const { + get: isGetEnabled = true, + find: isFindEnabled = true, + getAlias = '', + findAlias = '' + } = getParseClassQueryConfig(parseClassConfig); + const { + classGraphQLOutputType, + classGraphQLFindArgs, + classGraphQLFindResultType + } = parseGraphQLSchema.parseClassTypes[className]; + + if (isGetEnabled) { + const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + const getGraphQLQueryName = getAlias || lowerCaseClassName; + parseGraphQLSchema.addGraphQLQuery(getGraphQLQueryName, { + description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`, + args: { + id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, + options: defaultGraphQLTypes.READ_OPTIONS_ATT + }, + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT), + + async resolve(_source, args, context, queryInfo) { + try { + return await getQuery(parseClass, _source, args, context, queryInfo, parseGraphQLSchema.parseClasses); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + }); + } + + if (isFindEnabled) { + const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + const findGraphQLQueryName = findAlias || (0, _pluralize.default)(lowerCaseClassName); + parseGraphQLSchema.addGraphQLQuery(findGraphQLQueryName, { + description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`, + args: classGraphQLFindArgs, + type: new _graphql.GraphQLNonNull(classGraphQLFindResultType || defaultGraphQLTypes.OBJECT), + + async resolve(_source, args, context, queryInfo) { + try { + const { + where, + order, + skip, + first, + after, + last, + before, + options + } = args; + const { + readPreference, + includeReadPreference, + subqueryReadPreference + } = options || {}; + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); + const parseOrder = order && order.join(','); + return await objectsQueries.findObjects(className, where, parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + }); + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMuanMiXSwibmFtZXMiOlsiZ2V0UGFyc2VDbGFzc1F1ZXJ5Q29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInF1ZXJ5IiwiZ2V0UXVlcnkiLCJwYXJzZUNsYXNzIiwiX3NvdXJjZSIsImFyZ3MiLCJjb250ZXh0IiwicXVlcnlJbmZvIiwicGFyc2VDbGFzc2VzIiwiaWQiLCJvcHRpb25zIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInNlbGVjdGVkRmllbGRzIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiY2xhc3NOYW1lIiwia2V5cyIsImluY2x1ZGUiLCJvYmplY3RzUXVlcmllcyIsImdldE9iamVjdCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiZ2V0IiwiaXNHZXRFbmFibGVkIiwiZmluZCIsImlzRmluZEVuYWJsZWQiLCJnZXRBbGlhcyIsImZpbmRBbGlhcyIsImNsYXNzR3JhcGhRTE91dHB1dFR5cGUiLCJjbGFzc0dyYXBoUUxGaW5kQXJncyIsImNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwibG93ZXJDYXNlQ2xhc3NOYW1lIiwiY2hhckF0IiwidG9Mb3dlckNhc2UiLCJzbGljZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCIsIlJFQURfT1BUSU9OU19BVFQiLCJHcmFwaFFMTm9uTnVsbCIsIk9CSkVDVCIsInJlc29sdmUiLCJlIiwiaGFuZGxlRXJyb3IiLCJmaW5kR3JhcGhRTFF1ZXJ5TmFtZSIsIndoZXJlIiwib3JkZXIiLCJza2lwIiwiZmlyc3QiLCJhZnRlciIsImxhc3QiLCJiZWZvcmUiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsInBhcnNlT3JkZXIiLCJqb2luIiwiZmluZE9iamVjdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSx3QkFBd0IsR0FBRyxVQUMvQkMsZ0JBRCtCLEVBRS9CO0FBQ0EsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxLQUF0QyxJQUFnRCxFQUF2RDtBQUNELENBSkQ7O0FBTUEsTUFBTUMsUUFBUSxHQUFHLE9BQ2ZDLFVBRGUsRUFFZkMsT0FGZSxFQUdmQyxJQUhlLEVBSWZDLE9BSmUsRUFLZkMsU0FMZSxFQU1mQyxZQU5lLEtBT1o7QUFDSCxNQUFJO0FBQUVDLElBQUFBO0FBQUYsTUFBU0osSUFBYjtBQUNBLFFBQU07QUFBRUssSUFBQUE7QUFBRixNQUFjTCxJQUFwQjtBQUNBLFFBQU07QUFBRU0sSUFBQUEsY0FBRjtBQUFrQkMsSUFBQUE7QUFBbEIsTUFBNENGLE9BQU8sSUFBSSxFQUE3RDtBQUNBLFFBQU07QUFBRUcsSUFBQUEsTUFBRjtBQUFVQyxJQUFBQSxJQUFWO0FBQWdCQyxJQUFBQTtBQUFoQixNQUF5QlQsT0FBL0I7QUFDQSxRQUFNVSxjQUFjLEdBQUcsZ0NBQWNULFNBQWQsQ0FBdkI7QUFFQSxRQUFNVSxjQUFjLEdBQUcsZ0NBQWFSLEVBQWIsQ0FBdkI7O0FBRUEsTUFBSVEsY0FBYyxDQUFDQyxJQUFmLEtBQXdCZixVQUFVLENBQUNnQixTQUF2QyxFQUFrRDtBQUNoRFYsSUFBQUEsRUFBRSxHQUFHUSxjQUFjLENBQUNSLEVBQXBCO0FBQ0Q7O0FBRUQsUUFBTTtBQUFFVyxJQUFBQSxJQUFGO0FBQVFDLElBQUFBO0FBQVIsTUFBb0IsOENBQXNCTCxjQUF0QixDQUExQjtBQUVBLFNBQU8sTUFBTU0sY0FBYyxDQUFDQyxT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YlcsRUFjWGdELHNCQWRXLEVBZVgvQyxNQWZXLEVBZ0JYQyxJQWhCVyxFQWlCWEMsSUFqQlcsRUFrQlhDLGNBbEJXLEVBbUJYUyxrQkFBa0IsQ0FBQ2pCLFlBbkJSLENBQWI7QUFxQkQsU0EvQ0QsQ0ErQ0UsT0FBTzBDLENBQVAsRUFBVTtBQUNWekIsVUFBQUEsa0JBQWtCLENBQUMwQixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGOztBQXpEc0QsS0FBekQ7QUEyREQ7QUFDRixDQXRIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEdyYXBoUUxOb25OdWxsIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBmcm9tR2xvYmFsSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCBnZXRGaWVsZE5hbWVzIGZyb20gJ2dyYXBocWwtbGlzdC1maWVsZHMnO1xuaW1wb3J0IHBsdXJhbGl6ZSBmcm9tICdwbHVyYWxpemUnO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0ICogYXMgb2JqZWN0c1F1ZXJpZXMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzUXVlcmllcyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxDbGFzc0NvbmZpZyB9IGZyb20gJy4uLy4uL0NvbnRyb2xsZXJzL1BhcnNlR3JhcGhRTENvbnRyb2xsZXInO1xuaW1wb3J0IHsgdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2NsYXNzTmFtZSc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUgfSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5cbmNvbnN0IGdldFBhcnNlQ2xhc3NRdWVyeUNvbmZpZyA9IGZ1bmN0aW9uIChcbiAgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnXG4pIHtcbiAgcmV0dXJuIChwYXJzZUNsYXNzQ29uZmlnICYmIHBhcnNlQ2xhc3NDb25maWcucXVlcnkpIHx8IHt9O1xufTtcblxuY29uc3QgZ2V0UXVlcnkgPSBhc3luYyAoXG4gIHBhcnNlQ2xhc3MsXG4gIF9zb3VyY2UsXG4gIGFyZ3MsXG4gIGNvbnRleHQsXG4gIHF1ZXJ5SW5mbyxcbiAgcGFyc2VDbGFzc2VzXG4pID0+IHtcbiAgbGV0IHsgaWQgfSA9IGFyZ3M7XG4gIGNvbnN0IHsgb3B0aW9ucyB9ID0gYXJncztcbiAgY29uc3QgeyByZWFkUHJlZmVyZW5jZSwgaW5jbHVkZVJlYWRQcmVmZXJlbmNlIH0gPSBvcHRpb25zIHx8IHt9O1xuICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcbiAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaWQpO1xuXG4gIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSBwYXJzZUNsYXNzLmNsYXNzTmFtZSkge1xuICAgIGlkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gIH1cblxuICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG5cbiAgcmV0dXJuIGF3YWl0IG9iamVjdHNRdWVyaWVzLmdldE9iamVjdChcbiAgICBwYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICBpZCxcbiAgICBrZXlzLFxuICAgIGluY2x1ZGUsXG4gICAgcmVhZFByZWZlcmVuY2UsXG4gICAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICAgIGNvbmZpZyxcbiAgICBhdXRoLFxuICAgIGluZm8sXG4gICAgcGFyc2VDbGFzc2VzXG4gICk7XG59O1xuXG5jb25zdCBsb2FkID0gZnVuY3Rpb24gKFxuICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gIHBhcnNlQ2xhc3MsXG4gIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZ1xuKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICBjb25zdCBncmFwaFFMQ2xhc3NOYW1lID0gdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMKGNsYXNzTmFtZSk7XG4gIGNvbnN0IHtcbiAgICBnZXQ6IGlzR2V0RW5hYmxlZCA9IHRydWUsXG4gICAgZmluZDogaXNGaW5kRW5hYmxlZCA9IHRydWUsXG4gICAgZ2V0QWxpYXM6IGdldEFsaWFzID0gJycsXG4gICAgZmluZEFsaWFzOiBmaW5kQWxpYXMgPSAnJyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NRdWVyeUNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSxcbiAgICBjbGFzc0dyYXBoUUxGaW5kQXJncyxcbiAgICBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSxcbiAgfSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbY2xhc3NOYW1lXTtcblxuICBpZiAoaXNHZXRFbmFibGVkKSB7XG4gICAgY29uc3QgbG93ZXJDYXNlQ2xhc3NOYW1lID1cbiAgICAgIGdyYXBoUUxDbGFzc05hbWUuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBncmFwaFFMQ2xhc3NOYW1lLnNsaWNlKDEpO1xuXG4gICAgY29uc3QgZ2V0R3JhcGhRTFF1ZXJ5TmFtZSA9IGdldEFsaWFzIHx8IGxvd2VyQ2FzZUNsYXNzTmFtZTtcblxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoZ2V0R3JhcGhRTFF1ZXJ5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfSBxdWVyeSBjYW4gYmUgdXNlZCB0byBnZXQgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGJ5IGl0cyBpZC5gLFxuICAgICAgYXJnczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgICAgb3B0aW9uczogZGVmYXVsdEdyYXBoUUxUeXBlcy5SRUFEX09QVElPTlNfQVRULFxuICAgICAgfSxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChcbiAgICAgICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVFxuICAgICAgKSxcbiAgICAgIGFzeW5jIHJlc29sdmUoX3NvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGdldFF1ZXJ5KFxuICAgICAgICAgICAgcGFyc2VDbGFzcyxcbiAgICAgICAgICAgIF9zb3VyY2UsXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzRmluZEVuYWJsZWQpIHtcbiAgICBjb25zdCBsb3dlckNhc2VDbGFzc05hbWUgPVxuICAgICAgZ3JhcGhRTENsYXNzTmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGdyYXBoUUxDbGFzc05hbWUuc2xpY2UoMSk7XG5cbiAgICBjb25zdCBmaW5kR3JhcGhRTFF1ZXJ5TmFtZSA9IGZpbmRBbGlhcyB8fCBwbHVyYWxpemUobG93ZXJDYXNlQ2xhc3NOYW1lKTtcblxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoZmluZEdyYXBoUUxRdWVyeU5hbWUsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7ZmluZEdyYXBoUUxRdWVyeU5hbWV9IHF1ZXJ5IGNhbiBiZSB1c2VkIHRvIGZpbmQgb2JqZWN0cyBvZiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgYXJnczogY2xhc3NHcmFwaFFMRmluZEFyZ3MsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoXG4gICAgICAgIGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUXG4gICAgICApLFxuICAgICAgYXN5bmMgcmVzb2x2ZShfc291cmNlLCBhcmdzLCBjb250ZXh0LCBxdWVyeUluZm8pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgICAgc2tpcCxcbiAgICAgICAgICAgIGZpcnN0LFxuICAgICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgfSA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShcbiAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgIC5maWx0ZXIoKGZpZWxkKSA9PiBmaWVsZC5zdGFydHNXaXRoKCdlZGdlcy5ub2RlLicpKVxuICAgICAgICAgICAgICAubWFwKChmaWVsZCkgPT4gZmllbGQucmVwbGFjZSgnZWRnZXMubm9kZS4nLCAnJykpXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBwYXJzZU9yZGVyID0gb3JkZXIgJiYgb3JkZXIuam9pbignLCcpO1xuXG4gICAgICAgICAgcmV0dXJuIGF3YWl0IG9iamVjdHNRdWVyaWVzLmZpbmRPYmplY3RzKFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgd2hlcmUsXG4gICAgICAgICAgICBwYXJzZU9yZGVyLFxuICAgICAgICAgICAgc2tpcCxcbiAgICAgICAgICAgIGZpcnN0LFxuICAgICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgc2VsZWN0ZWRGaWVsZHMsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassTypes.js b/lib/GraphQL/loaders/parseClassTypes.js new file mode 100644 index 0000000000..4c178368a4 --- /dev/null +++ b/lib/GraphQL/loaders/parseClassTypes.js @@ -0,0 +1,531 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "extractKeysAndInclude", { + enumerable: true, + get: function () { + return _parseGraphQLUtils.extractKeysAndInclude; + } +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); + +var _className = require("../transformers/className"); + +var _inputType = require("../transformers/inputType"); + +var _outputType = require("../transformers/outputType"); + +var _constraintType = require("../transformers/constraintType"); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const getParseClassTypeConfig = function (parseClassConfig) { + return parseClassConfig && parseClassConfig.type || {}; +}; + +const getInputFieldsAndConstraints = function (parseClass, parseClassConfig) { + const classFields = Object.keys(parseClass.fields).concat('id'); + const { + inputFields: allowedInputFields, + outputFields: allowedOutputFields, + constraintFields: allowedConstraintFields, + sortFields: allowedSortFields + } = getParseClassTypeConfig(parseClassConfig); + let classOutputFields; + let classCreateFields; + let classUpdateFields; + let classConstraintFields; + let classSortFields; // All allowed customs fields + + const classCustomFields = classFields.filter(field => { + return !Object.keys(defaultGraphQLTypes.PARSE_OBJECT_FIELDS).includes(field) && field !== 'id'; + }); + + if (allowedInputFields && allowedInputFields.create) { + classCreateFields = classCustomFields.filter(field => { + return allowedInputFields.create.includes(field); + }); + } else { + classCreateFields = classCustomFields; + } + + if (allowedInputFields && allowedInputFields.update) { + classUpdateFields = classCustomFields.filter(field => { + return allowedInputFields.update.includes(field); + }); + } else { + classUpdateFields = classCustomFields; + } + + if (allowedOutputFields) { + classOutputFields = classCustomFields.filter(field => { + return allowedOutputFields.includes(field); + }); + } else { + classOutputFields = classCustomFields; + } // Filters the "password" field from class _User + + + if (parseClass.className === '_User') { + classOutputFields = classOutputFields.filter(outputField => outputField !== 'password'); + } + + if (allowedConstraintFields) { + classConstraintFields = classCustomFields.filter(field => { + return allowedConstraintFields.includes(field); + }); + } else { + classConstraintFields = classFields; + } + + if (allowedSortFields) { + classSortFields = allowedSortFields; + + if (!classSortFields.length) { + // must have at least 1 order field + // otherwise the FindArgs Input Type will throw. + classSortFields.push({ + field: 'id', + asc: true, + desc: true + }); + } + } else { + classSortFields = classFields.map(field => { + return { + field, + asc: true, + desc: true + }; + }); + } + + return { + classCreateFields, + classUpdateFields, + classConstraintFields, + classOutputFields, + classSortFields + }; +}; + +const load = (parseGraphQLSchema, parseClass, parseClassConfig) => { + const className = parseClass.className; + const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); + const { + classCreateFields, + classUpdateFields, + classOutputFields, + classConstraintFields, + classSortFields + } = getInputFieldsAndConstraints(parseClass, parseClassConfig); + const { + create: isCreateEnabled = true, + update: isUpdateEnabled = true + } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); + const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`; + let classGraphQLCreateType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLCreateTypeName, + description: `The ${classGraphQLCreateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, + fields: () => classCreateFields.reduce((fields, field) => { + const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); + + if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type: className === '_User' && (field === 'username' || field === 'password') || parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type + } + }); + } else { + return fields; + } + }, { + ACL: { + type: defaultGraphQLTypes.ACL_INPUT + } + }) + }); + classGraphQLCreateType = parseGraphQLSchema.addGraphQLType(classGraphQLCreateType); + const classGraphQLUpdateTypeName = `Update${graphQLClassName}FieldsInput`; + let classGraphQLUpdateType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLUpdateTypeName, + description: `The ${classGraphQLUpdateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, + fields: () => classUpdateFields.reduce((fields, field) => { + const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); + + if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type + } + }); + } else { + return fields; + } + }, { + ACL: { + type: defaultGraphQLTypes.ACL_INPUT + } + }) + }); + classGraphQLUpdateType = parseGraphQLSchema.addGraphQLType(classGraphQLUpdateType); + const classGraphQLPointerTypeName = `${graphQLClassName}PointerInput`; + let classGraphQLPointerType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLPointerTypeName, + description: `Allow to link OR add and link an object of the ${graphQLClassName} class.`, + fields: () => { + const fields = { + link: { + description: `Link an existing object from ${graphQLClassName} class. You can use either the global or the object id.`, + type: _graphql.GraphQLID + } + }; + + if (isCreateEnabled) { + fields['createAndLink'] = { + description: `Create and link an object from ${graphQLClassName} class.`, + type: classGraphQLCreateType + }; + } + + return fields; + } + }); + classGraphQLPointerType = parseGraphQLSchema.addGraphQLType(classGraphQLPointerType) || defaultGraphQLTypes.OBJECT; + const classGraphQLRelationTypeName = `${graphQLClassName}RelationInput`; + let classGraphQLRelationType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLRelationTypeName, + description: `Allow to add, remove, createAndAdd objects of the ${graphQLClassName} class into a relation field.`, + fields: () => { + const fields = { + add: { + description: `Add existing objects from the ${graphQLClassName} class into the relation. You can use either the global or the object ids.`, + type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) + }, + remove: { + description: `Remove existing objects from the ${graphQLClassName} class out of the relation. You can use either the global or the object ids.`, + type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) + } + }; + + if (isCreateEnabled) { + fields['createAndAdd'] = { + description: `Create and add objects of the ${graphQLClassName} class into the relation.`, + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLCreateType)) + }; + } + + return fields; + } + }); + classGraphQLRelationType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationType) || defaultGraphQLTypes.OBJECT; + const classGraphQLConstraintsTypeName = `${graphQLClassName}WhereInput`; + let classGraphQLConstraintsType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLConstraintsTypeName, + description: `The ${classGraphQLConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, + fields: () => _objectSpread(_objectSpread({}, classConstraintFields.reduce((fields, field) => { + if (['OR', 'AND', 'NOR'].includes(field)) { + parseGraphQLSchema.log.warn(`Field ${field} could not be added to the auto schema ${classGraphQLConstraintsTypeName} because it collided with an existing one.`); + return fields; + } + + const parseField = field === 'id' ? 'objectId' : field; + const type = (0, _constraintType.transformConstraintTypeToGraphQL)(parseClass.fields[parseField].type, parseClass.fields[parseField].targetClass, parseGraphQLSchema.parseClassTypes, field); + + if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type + } + }); + } else { + return fields; + } + }, {})), {}, { + OR: { + description: 'This is the OR operator to compound constraints.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) + }, + AND: { + description: 'This is the AND operator to compound constraints.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) + }, + NOR: { + description: 'This is the NOR operator to compound constraints.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) + } + }) + }); + classGraphQLConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLConstraintsType) || defaultGraphQLTypes.OBJECT; + const classGraphQLRelationConstraintsTypeName = `${graphQLClassName}RelationWhereInput`; + let classGraphQLRelationConstraintsType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLRelationConstraintsTypeName, + description: `The ${classGraphQLRelationConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, + fields: () => ({ + have: { + description: 'Run a relational/pointer query where at least one child object can match.', + type: classGraphQLConstraintsType + }, + haveNot: { + description: 'Run an inverted relational/pointer query where at least one child object can match.', + type: classGraphQLConstraintsType + }, + exists: { + description: 'Check if the relation/pointer contains objects.', + type: _graphql.GraphQLBoolean + } + }) + }); + classGraphQLRelationConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationConstraintsType) || defaultGraphQLTypes.OBJECT; + const classGraphQLOrderTypeName = `${graphQLClassName}Order`; + let classGraphQLOrderType = new _graphql.GraphQLEnumType({ + name: classGraphQLOrderTypeName, + description: `The ${classGraphQLOrderTypeName} input type is used when sorting objects of the ${graphQLClassName} class.`, + values: classSortFields.reduce((sortFields, fieldConfig) => { + const { + field, + asc, + desc + } = fieldConfig; + + const updatedSortFields = _objectSpread({}, sortFields); + + const value = field === 'id' ? 'objectId' : field; + + if (asc) { + updatedSortFields[`${field}_ASC`] = { + value + }; + } + + if (desc) { + updatedSortFields[`${field}_DESC`] = { + value: `-${value}` + }; + } + + return updatedSortFields; + }, {}) + }); + classGraphQLOrderType = parseGraphQLSchema.addGraphQLType(classGraphQLOrderType); + + const classGraphQLFindArgs = _objectSpread(_objectSpread({ + where: { + description: 'These are the conditions that the objects need to match in order to be found.', + type: classGraphQLConstraintsType + }, + order: { + description: 'The fields to be used when sorting the data fetched.', + type: classGraphQLOrderType ? new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLOrderType)) : _graphql.GraphQLString + }, + skip: defaultGraphQLTypes.SKIP_ATT + }, _graphqlRelay.connectionArgs), {}, { + options: defaultGraphQLTypes.READ_OPTIONS_ATT + }); + + const classGraphQLOutputTypeName = `${graphQLClassName}`; + const interfaces = [defaultGraphQLTypes.PARSE_OBJECT, parseGraphQLSchema.relayNodeInterface]; + + const parseObjectFields = _objectSpread({ + id: (0, _graphqlRelay.globalIdField)(className, obj => obj.objectId) + }, defaultGraphQLTypes.PARSE_OBJECT_FIELDS); + + const outputFields = () => { + return classOutputFields.reduce((fields, field) => { + const type = (0, _outputType.transformOutputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); + + if (parseClass.fields[field].type === 'Relation') { + const targetParseClassTypes = parseGraphQLSchema.parseClassTypes[parseClass.fields[field].targetClass]; + const args = targetParseClassTypes ? targetParseClassTypes.classGraphQLFindArgs : undefined; + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + args, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, + + async resolve(source, args, context, queryInfo) { + try { + const { + where, + order, + skip, + first, + after, + last, + before, + options + } = args; + const { + readPreference, + includeReadPreference, + subqueryReadPreference + } = options || {}; + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); + const parseOrder = order && order.join(','); + return objectsQueries.findObjects(source[field].className, _objectSpread({ + $relatedTo: { + object: { + __type: 'Pointer', + className: className, + objectId: source.objectId + }, + key: field + } + }, where || {}), parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + } + }); + } else if (parseClass.fields[field].type === 'Polygon') { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, + + async resolve(source) { + if (source[field] && source[field].coordinates) { + return source[field].coordinates.map(coordinate => ({ + latitude: coordinate[0], + longitude: coordinate[1] + })); + } else { + return null; + } + } + + } + }); + } else if (parseClass.fields[field].type === 'Array') { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments`, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, + + async resolve(source) { + if (!source[field]) return null; + return source[field].map(async elem => { + if (elem.className && elem.objectId && elem.__type === 'Object') { + return elem; + } else { + return { + value: elem + }; + } + }); + } + + } + }); + } else if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type + } + }); + } else { + return fields; + } + }, parseObjectFields); + }; + + let classGraphQLOutputType = new _graphql.GraphQLObjectType({ + name: classGraphQLOutputTypeName, + description: `The ${classGraphQLOutputTypeName} object type is used in operations that involve outputting objects of ${graphQLClassName} class.`, + interfaces, + fields: outputFields + }); + classGraphQLOutputType = parseGraphQLSchema.addGraphQLType(classGraphQLOutputType); + const { + connectionType, + edgeType + } = (0, _graphqlRelay.connectionDefinitions)({ + name: graphQLClassName, + connectionFields: { + count: defaultGraphQLTypes.COUNT_ATT + }, + nodeType: classGraphQLOutputType || defaultGraphQLTypes.OBJECT + }); + let classGraphQLFindResultType = undefined; + + if (parseGraphQLSchema.addGraphQLType(edgeType) && parseGraphQLSchema.addGraphQLType(connectionType, false, false, true)) { + classGraphQLFindResultType = connectionType; + } + + parseGraphQLSchema.parseClassTypes[className] = { + classGraphQLPointerType, + classGraphQLRelationType, + classGraphQLCreateType, + classGraphQLUpdateType, + classGraphQLConstraintsType, + classGraphQLRelationConstraintsType, + classGraphQLFindArgs, + classGraphQLOutputType, + classGraphQLFindResultType, + config: { + parseClassConfig, + isCreateEnabled, + isUpdateEnabled + } + }; + + if (className === '_User') { + const viewerType = new _graphql.GraphQLObjectType({ + name: 'Viewer', + description: `The Viewer object type is used in operations that involve outputting the current user data.`, + fields: () => ({ + sessionToken: defaultGraphQLTypes.SESSION_TOKEN_ATT, + user: { + description: 'This is the current user.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType) + } + }) + }); + parseGraphQLSchema.addGraphQLType(viewerType, true, true); + parseGraphQLSchema.viewerType = viewerType; + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1R5cGVzLmpzIl0sIm5hbWVzIjpbImdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInR5cGUiLCJnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzIiwicGFyc2VDbGFzcyIsImNsYXNzRmllbGRzIiwiT2JqZWN0Iiwia2V5cyIsImZpZWxkcyIsImNvbmNhdCIsImlucHV0RmllbGRzIiwiYWxsb3dlZElucHV0RmllbGRzIiwib3V0cHV0RmllbGRzIiwiYWxsb3dlZE91dHB1dEZpZWxkcyIsImNvbnN0cmFpbnRGaWVsZHMiLCJhbGxvd2VkQ29uc3RyYWludEZpZWxkcyIsInNvcnRGaWVsZHMiLCJhbGxvd2VkU29ydEZpZWxkcyIsImNsYXNzT3V0cHV0RmllbGRzIiwiY2xhc3NDcmVhdGVGaWVsZHMiLCJjbGFzc1VwZGF0ZUZpZWxkcyIsImNsYXNzQ29uc3RyYWludEZpZWxkcyIsImNsYXNzU29ydEZpZWxkcyIsImNsYXNzQ3VzdG9tRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiUEFSU0VfT0JKRUNUX0ZJRUxEUyIsImluY2x1ZGVzIiwiY3JlYXRlIiwidXBkYXRlIiwiY2xhc3NOYW1lIiwib3V0cHV0RmllbGQiLCJsZW5ndGgiLCJwdXNoIiwiYXNjIiwiZGVzYyIsIm1hcCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxDcmVhdGVUeXBlIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsInJlZHVjZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwicmVxdWlyZWQiLCJHcmFwaFFMTm9uTnVsbCIsIkFDTCIsIkFDTF9JTlBVVCIsImFkZEdyYXBoUUxUeXBlIiwiY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJsaW5rIiwiR3JhcGhRTElEIiwiT0JKRUNUIiwiY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlTmFtZSIsImNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSIsImFkZCIsIkdyYXBoUUxMaXN0IiwiT0JKRUNUX0lEIiwicmVtb3ZlIiwiY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZSIsImNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSIsImxvZyIsIndhcm4iLCJwYXJzZUZpZWxkIiwiT1IiLCJBTkQiLCJOT1IiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSIsImhhdmUiLCJoYXZlTm90IiwiZXhpc3RzIiwiR3JhcGhRTEJvb2xlYW4iLCJjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMT3JkZXJUeXBlIiwiR3JhcGhRTEVudW1UeXBlIiwidmFsdWVzIiwiZmllbGRDb25maWciLCJ1cGRhdGVkU29ydEZpZWxkcyIsInZhbHVlIiwiY2xhc3NHcmFwaFFMRmluZEFyZ3MiLCJ3aGVyZSIsIm9yZGVyIiwiR3JhcGhRTFN0cmluZyIsInNraXAiLCJTS0lQX0FUVCIsImNvbm5lY3Rpb25BcmdzIiwib3B0aW9ucyIsIlJFQURfT1BUSU9OU19BVFQiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSIsImludGVyZmFjZXMiLCJQQVJTRV9PQkpFQ1QiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJwYXJzZU9iamVjdEZpZWxkcyIsImlkIiwib2JqIiwib2JqZWN0SWQiLCJ0YXJnZXRQYXJzZUNsYXNzVHlwZXMiLCJhcmdzIiwidW5kZWZpbmVkIiwicmVzb2x2ZSIsInNvdXJjZSIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJmaXJzdCIsImFmdGVyIiwibGFzdCIsImJlZm9yZSIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJpbmNsdWRlIiwic3RhcnRzV2l0aCIsInJlcGxhY2UiLCJwYXJzZU9yZGVyIiwiam9pbiIsIm9iamVjdHNRdWVyaWVzIiwiZmluZE9iamVjdHMiLCIkcmVsYXRlZFRvIiwib2JqZWN0IiwiX190eXBlIiwia2V5IiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwiY29vcmRpbmF0ZXMiLCJjb29yZGluYXRlIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJlbGVtIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsIkdyYXBoUUxPYmplY3RUeXBlIiwiY29ubmVjdGlvblR5cGUiLCJlZGdlVHlwZSIsImNvbm5lY3Rpb25GaWVsZHMiLCJjb3VudCIsIkNPVU5UX0FUVCIsIm5vZGVUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJ2aWV3ZXJUeXBlIiwic2Vzc2lvblRva2VuIiwiU0VTU0lPTl9UT0tFTl9BVFQiLCJ1c2VyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUE7O0FBVUE7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBS0EsTUFBTUEsdUJBQXVCLEdBQUcsVUFDOUJDLGdCQUQ4QixFQUU5QjtBQUNBLFNBQVFBLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ0MsSUFBdEMsSUFBK0MsRUFBdEQ7QUFDRCxDQUpEOztBQU1BLE1BQU1DLDRCQUE0QixHQUFHLFVBQ25DQyxVQURtQyxFQUVuQ0gsZ0JBRm1DLEVBR25DO0FBQ0EsUUFBTUksV0FBVyxHQUFHQyxNQUFN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dUJBRDhDO0FBRTlDSyxJQUFBQSx3QkFGOEM7QUFHOUNwQixJQUFBQSxzQkFIOEM7QUFJOUNhLElBQUFBLHNCQUo4QztBQUs5Q2EsSUFBQUEsMkJBTDhDO0FBTTlDUSxJQUFBQSxtQ0FOOEM7QUFPOUNZLElBQUFBLG9CQVA4QztBQVE5Q3NELElBQUFBLHNCQVI4QztBQVM5Q1EsSUFBQUEsMEJBVDhDO0FBVTlDL0IsSUFBQUEsTUFBTSxFQUFFO0FBQ054SCxNQUFBQSxnQkFETTtBQUVOd0MsTUFBQUEsZUFGTTtBQUdOQyxNQUFBQTtBQUhNO0FBVnNDLEdBQWhEOztBQWlCQSxNQUFJWCxTQUFTLEtBQUssT0FBbEIsRUFBMkI7QUFDekIsVUFBTTBILFVBQVUsR0FBRyxJQUFJUiwwQkFBSixDQUFzQjtBQUN2Q25HLE1BQUFBLElBQUksRUFBRSxRQURpQztBQUV2Q0MsTUFBQUEsV0FBVyxFQUFHLDZGQUZ5QjtBQUd2Q3ZDLE1BQUFBLE1BQU0sRUFBRSxPQUFPO0FBQ2JrSixRQUFBQSxZQUFZLEVBQUVoSSxtQkFBbUIsQ0FBQ2lJLGlCQURyQjtBQUViQyxRQUFBQSxJQUFJLEVBQUU7QUFDSjdHLFVBQUFBLFdBQVcsRUFBRSwyQkFEVDtBQUVKN0MsVUFBQUEsSUFBSSxFQUFFLElBQUlrRCx1QkFBSixDQUFtQjRGLHNCQUFuQjtBQUZGO0FBRk8sT0FBUDtBQUgrQixLQUF0QixDQUFuQjtBQVdBekcsSUFBQUEsa0JBQWtCLENBQUNnQixjQUFuQixDQUFrQ2tHLFVBQWxDLEVBQThDLElBQTlDLEVBQW9ELElBQXBEO0FBQ0FsSCxJQUFBQSxrQkFBa0IsQ0FBQ2tILFVBQW5CLEdBQWdDQSxVQUFoQztBQUNEO0FBQ0YsQ0FwZEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFFMSUQsXG4gIEdyYXBoUUxPYmplY3RUeXBlLFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMRW51bVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHtcbiAgZ2xvYmFsSWRGaWVsZCxcbiAgY29ubmVjdGlvbkFyZ3MsXG4gIGNvbm5lY3Rpb25EZWZpbml0aW9ucyxcbn0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCAqIGFzIG9iamVjdHNRdWVyaWVzIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcgfSBmcm9tICcuLi8uLi9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9jbGFzc05hbWUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2lucHV0VHlwZSc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL291dHB1dFR5cGUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY29uc3RyYWludFR5cGUnO1xuaW1wb3J0IHtcbiAgZXh0cmFjdEtleXNBbmRJbmNsdWRlLFxuICBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcsXG59IGZyb20gJy4uL3BhcnNlR3JhcGhRTFV0aWxzJztcblxuY29uc3QgZ2V0UGFyc2VDbGFzc1R5cGVDb25maWcgPSBmdW5jdGlvbiAoXG4gIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZ1xuKSB7XG4gIHJldHVybiAocGFyc2VDbGFzc0NvbmZpZyAmJiBwYXJzZUNsYXNzQ29uZmlnLnR5cGUpIHx8IHt9O1xufTtcblxuY29uc3QgZ2V0SW5wdXRGaWVsZHNBbmRDb25zdHJhaW50cyA9IGZ1bmN0aW9uIChcbiAgcGFyc2VDbGFzcyxcbiAgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnXG4pIHtcbiAgY29uc3QgY2xhc3NGaWVsZHMgPSBPYmplY3Qua2V5cyhwYXJzZUNsYXNzLmZpZWxkcykuY29uY2F0KCdpZCcpO1xuICBjb25zdCB7XG4gICAgaW5wdXRGaWVsZHM6IGFsbG93ZWRJbnB1dEZpZWxkcyxcbiAgICBvdXRwdXRGaWVsZHM6IGFsbG93ZWRPdXRwdXRGaWVsZHMsXG4gICAgY29uc3RyYWludEZpZWxkczogYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMsXG4gICAgc29ydEZpZWxkczogYWxsb3dlZFNvcnRGaWVsZHMsXG4gIH0gPSBnZXRQYXJzZUNsYXNzVHlwZUNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBsZXQgY2xhc3NPdXRwdXRGaWVsZHM7XG4gIGxldCBjbGFzc0NyZWF0ZUZpZWxkcztcbiAgbGV0IGNsYXNzVXBkYXRlRmllbGRzO1xuICBsZXQgY2xhc3NDb25zdHJhaW50RmllbGRzO1xuICBsZXQgY2xhc3NTb3J0RmllbGRzO1xuXG4gIC8vIEFsbCBhbGxvd2VkIGN1c3RvbXMgZmllbGRzXG4gIGNvbnN0IGNsYXNzQ3VzdG9tRmllbGRzID0gY2xhc3NGaWVsZHMuZmlsdGVyKChmaWVsZCkgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICAhT2JqZWN0LmtleXMoZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1RfRklFTERTKS5pbmNsdWRlcyhmaWVsZCkgJiZcbiAgICAgIGZpZWxkICE9PSAnaWQnXG4gICAgKTtcbiAgfSk7XG5cbiAgaWYgKGFsbG93ZWRJbnB1dEZpZWxkcyAmJiBhbGxvd2VkSW5wdXRGaWVsZHMuY3JlYXRlKSB7XG4gICAgY2xhc3NDcmVhdGVGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZElucHV0RmllbGRzLmNyZWF0ZS5pbmNsdWRlcyhmaWVsZCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NDcmVhdGVGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcztcbiAgfVxuICBpZiAoYWxsb3dlZElucHV0RmllbGRzICYmIGFsbG93ZWRJbnB1dEZpZWxkcy51cGRhdGUpIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcigoZmllbGQpID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMudXBkYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRPdXRwdXRGaWVsZHMpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcigoZmllbGQpID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkT3V0cHV0RmllbGRzLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG4gIC8vIEZpbHRlcnMgdGhlIFwicGFzc3dvcmRcIiBmaWVsZCBmcm9tIGNsYXNzIF9Vc2VyXG4gIGlmIChwYXJzZUNsYXNzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNsYXNzT3V0cHV0RmllbGRzID0gY2xhc3NPdXRwdXRGaWVsZHMuZmlsdGVyKFxuICAgICAgKG91dHB1dEZpZWxkKSA9PiBvdXRwdXRGaWVsZCAhPT0gJ3Bhc3N3b3JkJ1xuICAgICk7XG4gIH1cblxuICBpZiAoYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMpIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMuaW5jbHVkZXMoZmllbGQpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNsYXNzQ29uc3RyYWludEZpZWxkcyA9IGNsYXNzRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRTb3J0RmllbGRzKSB7XG4gICAgY2xhc3NTb3J0RmllbGRzID0gYWxsb3dlZFNvcnRGaWVsZHM7XG4gICAgaWYgKCFjbGFzc1NvcnRGaWVsZHMubGVuZ3RoKSB7XG4gICAgICAvLyBtdXN0IGhhdmUgYXQgbGVhc3QgMSBvcmRlciBmaWVsZFxuICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBGaW5kQXJncyBJbnB1dCBUeXBlIHdpbGwgdGhyb3cuXG4gICAgICBjbGFzc1NvcnRGaWVsZHMucHVzaCh7XG4gICAgICAgIGZpZWxkOiAnaWQnLFxuICAgICAgICBhc2M6IHRydWUsXG4gICAgICAgIGRlc2M6IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NTb3J0RmllbGRzID0gY2xhc3NGaWVsZHMubWFwKChmaWVsZCkgPT4ge1xuICAgICAgcmV0dXJuIHsgZmllbGQsIGFzYzogdHJ1ZSwgZGVzYzogdHJ1ZSB9O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyxcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyxcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMsXG4gICAgY2xhc3NPdXRwdXRGaWVsZHMsXG4gICAgY2xhc3NTb3J0RmllbGRzLFxuICB9O1xufTtcblxuY29uc3QgbG9hZCA9IChcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICBwYXJzZUNsYXNzLFxuICBwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWdcbikgPT4ge1xuICBjb25zdCBjbGFzc05hbWUgPSBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgY29uc3QgZ3JhcGhRTENsYXNzTmFtZSA9IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTChjbGFzc05hbWUpO1xuICBjb25zdCB7XG4gICAgY2xhc3NDcmVhdGVGaWVsZHMsXG4gICAgY2xhc3NVcGRhdGVGaWVsZHMsXG4gICAgY2xhc3NPdXRwdXRGaWVsZHMsXG4gICAgY2xhc3NDb25zdHJhaW50RmllbGRzLFxuICAgIGNsYXNzU29ydEZpZWxkcyxcbiAgfSA9IGdldElucHV0RmllbGRzQW5kQ29uc3RyYWludHMocGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG5cbiAgY29uc3Qge1xuICAgIGNyZWF0ZTogaXNDcmVhdGVFbmFibGVkID0gdHJ1ZSxcbiAgICB1cGRhdGU6IGlzVXBkYXRlRW5hYmxlZCA9IHRydWUsXG4gIH0gPSBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcocGFyc2VDbGFzc0NvbmZpZyk7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUgPSBgQ3JlYXRlJHtncmFwaFFMQ2xhc3NOYW1lfUZpZWxkc0lucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGNyZWF0aW9uIG9mIG9iamVjdHMgaW4gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+XG4gICAgICBjbGFzc0NyZWF0ZUZpZWxkcy5yZWR1Y2UoXG4gICAgICAgIChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlLFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgICAgdHlwZTpcbiAgICAgICAgICAgICAgICAgIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiZcbiAgICAgICAgICAgICAgICAgICAgKGZpZWxkID09PSAndXNlcm5hbWUnIHx8IGZpZWxkID09PSAncGFzc3dvcmQnKSkgfHxcbiAgICAgICAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKVxuICAgICAgICAgICAgICAgICAgICA6IHR5cGUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIEFDTDogeyB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLkFDTF9JTlBVVCB9LFxuICAgICAgICB9XG4gICAgICApLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlXG4gICk7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUgPSBgVXBkYXRlJHtncmFwaFFMQ2xhc3NOYW1lfUZpZWxkc0lucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxVcGRhdGVUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGNyZWF0aW9uIG9mIG9iamVjdHMgaW4gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+XG4gICAgICBjbGFzc1VwZGF0ZUZpZWxkcy5yZWR1Y2UoXG4gICAgICAgIChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlLFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgQUNMOiB7IHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUIH0sXG4gICAgICAgIH1cbiAgICAgICksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVcbiAgKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVBvaW50ZXJJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBsaW5rIE9SIGFkZCBhbmQgbGluayBhbiBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IHtcbiAgICAgICAgbGluazoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgTGluayBhbiBleGlzdGluZyBvYmplY3QgZnJvbSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLiBZb3UgY2FuIHVzZSBlaXRoZXIgdGhlIGdsb2JhbCBvciB0aGUgb2JqZWN0IGlkLmAsXG4gICAgICAgICAgdHlwZTogR3JhcGhRTElELFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRMaW5rJ10gPSB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW5kIGxpbmsgYW4gb2JqZWN0IGZyb20gJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRzO1xuICAgIH0sXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlKSB8fFxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVJlbGF0aW9uSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBhZGQsIHJlbW92ZSwgY3JlYXRlQW5kQWRkIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byBhIHJlbGF0aW9uIGZpZWxkLmAsXG4gICAgZmllbGRzOiAoKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZHMgPSB7XG4gICAgICAgIGFkZDoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgQWRkIGV4aXN0aW5nIG9iamVjdHMgZnJvbSB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcyBpbnRvIHRoZSByZWxhdGlvbi4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZHMuYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQpLFxuICAgICAgICB9LFxuICAgICAgICByZW1vdmU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYFJlbW92ZSBleGlzdGluZyBvYmplY3RzIGZyb20gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3Mgb3V0IG9mIHRoZSByZWxhdGlvbi4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZHMuYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRBZGQnXSA9IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZSBhbmQgYWRkIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byB0aGUgcmVsYXRpb24uYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUpKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgfSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSkgfHxcbiAgICBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1XaGVyZUlucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIG9mICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+ICh7XG4gICAgICAuLi5jbGFzc0NvbnN0cmFpbnRGaWVsZHMucmVkdWNlKChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgIGlmIChbJ09SJywgJ0FORCcsICdOT1InXS5pbmNsdWRlcyhmaWVsZCkpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEubG9nLndhcm4oXG4gICAgICAgICAgICBgRmllbGQgJHtmaWVsZH0gY291bGQgbm90IGJlIGFkZGVkIHRvIHRoZSBhdXRvIHNjaGVtYSAke2NsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWV9IGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBvbmUuYFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJzZUZpZWxkID0gZmllbGQgPT09ICdpZCcgPyAnb2JqZWN0SWQnIDogZmllbGQ7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1Db25zdHJhaW50VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1twYXJzZUZpZWxkXS50eXBlLFxuICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW3BhcnNlRmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXMsXG4gICAgICAgICAgZmllbGRcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgIH1cbiAgICAgIH0sIHt9KSxcbiAgICAgIE9SOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgT1Igb3BlcmF0b3IgdG8gY29tcG91bmQgY29uc3RyYWludHMuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpKSxcbiAgICAgIH0sXG4gICAgICBBTkQ6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBBTkQgb3BlcmF0b3IgdG8gY29tcG91bmQgY29uc3RyYWludHMuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpKSxcbiAgICAgIH0sXG4gICAgICBOT1I6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBOT1Igb3BlcmF0b3IgdG8gY29tcG91bmQgY29uc3RyYWludHMuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpKSxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUgPVxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpIHx8XG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1SZWxhdGlvbldoZXJlSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgIGhhdmU6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1J1biBhIHJlbGF0aW9uYWwvcG9pbnRlciBxdWVyeSB3aGVyZSBhdCBsZWFzdCBvbmUgY2hpbGQgb2JqZWN0IGNhbiBtYXRjaC4nLFxuICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUsXG4gICAgICB9LFxuICAgICAgaGF2ZU5vdDoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnUnVuIGFuIGludmVydGVkIHJlbGF0aW9uYWwvcG9pbnRlciBxdWVyeSB3aGVyZSBhdCBsZWFzdCBvbmUgY2hpbGQgb2JqZWN0IGNhbiBtYXRjaC4nLFxuICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUsXG4gICAgICB9LFxuICAgICAgZXhpc3RzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgaWYgdGhlIHJlbGF0aW9uL3BvaW50ZXIgY29udGFpbnMgb2JqZWN0cy4nLFxuICAgICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlKSB8fFxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTE9yZGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfU9yZGVyYDtcbiAgbGV0IGNsYXNzR3JhcGhRTE9yZGVyVHlwZSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTE9yZGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgd2hlbiBzb3J0aW5nIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICB2YWx1ZXM6IGNsYXNzU29ydEZpZWxkcy5yZWR1Y2UoKHNvcnRGaWVsZHMsIGZpZWxkQ29uZmlnKSA9PiB7XG4gICAgICBjb25zdCB7IGZpZWxkLCBhc2MsIGRlc2MgfSA9IGZpZWxkQ29uZmlnO1xuICAgICAgY29uc3QgdXBkYXRlZFNvcnRGaWVsZHMgPSB7XG4gICAgICAgIC4uLnNvcnRGaWVsZHMsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmFsdWUgPSBmaWVsZCA9PT0gJ2lkJyA/ICdvYmplY3RJZCcgOiBmaWVsZDtcbiAgICAgIGlmIChhc2MpIHtcbiAgICAgICAgdXBkYXRlZFNvcnRGaWVsZHNbYCR7ZmllbGR9X0FTQ2BdID0geyB2YWx1ZSB9O1xuICAgICAgfVxuICAgICAgaWYgKGRlc2MpIHtcbiAgICAgICAgdXBkYXRlZFNvcnRGaWVsZHNbYCR7ZmllbGR9X0RFU0NgXSA9IHsgdmFsdWU6IGAtJHt2YWx1ZX1gIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdXBkYXRlZFNvcnRGaWVsZHM7XG4gICAgfSwge30pLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMT3JkZXJUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNsYXNzR3JhcGhRTE9yZGVyVHlwZVxuICApO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTEZpbmRBcmdzID0ge1xuICAgIHdoZXJlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgY29uZGl0aW9ucyB0aGF0IHRoZSBvYmplY3RzIG5lZWQgdG8gbWF0Y2ggaW4gb3JkZXIgdG8gYmUgZm91bmQuJyxcbiAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSxcbiAgICB9LFxuICAgIG9yZGVyOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBmaWVsZHMgdG8gYmUgdXNlZCB3aGVuIHNvcnRpbmcgdGhlIGRhdGEgZmV0Y2hlZC4nLFxuICAgICAgdHlwZTogY2xhc3NHcmFwaFFMT3JkZXJUeXBlXG4gICAgICAgID8gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPcmRlclR5cGUpKVxuICAgICAgICA6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBza2lwOiBkZWZhdWx0R3JhcGhRTFR5cGVzLlNLSVBfQVRULFxuICAgIC4uLmNvbm5lY3Rpb25BcmdzLFxuICAgIG9wdGlvbnM6IGRlZmF1bHRHcmFwaFFMVHlwZXMuUkVBRF9PUFRJT05TX0FUVCxcbiAgfTtcbiAgY29uc3QgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gIGNvbnN0IGludGVyZmFjZXMgPSBbXG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1QsXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLnJlbGF5Tm9kZUludGVyZmFjZSxcbiAgXTtcbiAgY29uc3QgcGFyc2VPYmplY3RGaWVsZHMgPSB7XG4gICAgaWQ6IGdsb2JhbElkRmllbGQoY2xhc3NOYW1lLCAob2JqKSA9PiBvYmoub2JqZWN0SWQpLFxuICAgIC4uLmRlZmF1bHRHcmFwaFFMVHlwZXMuUEFSU0VfT0JKRUNUX0ZJRUxEUyxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0RmllbGRzID0gKCkgPT4ge1xuICAgIHJldHVybiBjbGFzc091dHB1dEZpZWxkcy5yZWR1Y2UoKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSxcbiAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICApO1xuICAgICAgaWYgKHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldFBhcnNlQ2xhc3NUeXBlcyA9XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzc1xuICAgICAgICAgIF07XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0YXJnZXRQYXJzZUNsYXNzVHlwZXNcbiAgICAgICAgICA/IHRhcmdldFBhcnNlQ2xhc3NUeXBlcy5jbGFzc0dyYXBoUUxGaW5kQXJnc1xuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZFxuICAgICAgICAgICAgICA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKVxuICAgICAgICAgICAgICA6IHR5cGUsXG4gICAgICAgICAgICBhc3luYyByZXNvbHZlKHNvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgICAgd2hlcmUsXG4gICAgICAgICAgICAgICAgICBvcmRlcixcbiAgICAgICAgICAgICAgICAgIHNraXAsXG4gICAgICAgICAgICAgICAgICBmaXJzdCxcbiAgICAgICAgICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgICAgICAgICAgbGFzdCxcbiAgICAgICAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICAgICAgfSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgIH0gPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhxdWVyeUluZm8pO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEZpZWxkc1xuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChmaWVsZCkgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMubm9kZS4nKSlcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZmllbGQpID0+IGZpZWxkLnJlcGxhY2UoJ2VkZ2VzLm5vZGUuJywgJycpKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VPcmRlciA9IG9yZGVyICYmIG9yZGVyLmpvaW4oJywnKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3RzUXVlcmllcy5maW5kT2JqZWN0cyhcbiAgICAgICAgICAgICAgICAgIHNvdXJjZVtmaWVsZF0uY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAkcmVsYXRlZFRvOiB7XG4gICAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0SWQ6IHNvdXJjZS5vYmplY3RJZCxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIC4uLih3aGVyZSB8fCB7fSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgcGFyc2VPcmRlcixcbiAgICAgICAgICAgICAgICAgIHNraXAsXG4gICAgICAgICAgICAgICAgICBmaXJzdCxcbiAgICAgICAgICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgICAgICAgICAgbGFzdCxcbiAgICAgICAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzLFxuICAgICAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAocGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkXG4gICAgICAgICAgICAgID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpXG4gICAgICAgICAgICAgIDogdHlwZSxcbiAgICAgICAgICAgIGFzeW5jIHJlc29sdmUoc291cmNlKSB7XG4gICAgICAgICAgICAgIGlmIChzb3VyY2VbZmllbGRdICYmIHNvdXJjZVtmaWVsZF0uY29vcmRpbmF0ZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlW2ZpZWxkXS5jb29yZGluYXRlcy5tYXAoKGNvb3JkaW5hdGUpID0+ICh7XG4gICAgICAgICAgICAgICAgICBsYXRpdHVkZTogY29vcmRpbmF0ZVswXSxcbiAgICAgICAgICAgICAgICAgIGxvbmdpdHVkZTogY29vcmRpbmF0ZVsxXSxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAocGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBVc2UgSW5saW5lIEZyYWdtZW50IG9uIEFycmF5IHRvIGdldCByZXN1bHRzOiBodHRwczovL2dyYXBocWwub3JnL2xlYXJuL3F1ZXJpZXMvI2lubGluZS1mcmFnbWVudHNgLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkXG4gICAgICAgICAgICAgID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpXG4gICAgICAgICAgICAgIDogdHlwZSxcbiAgICAgICAgICAgIGFzeW5jIHJlc29sdmUoc291cmNlKSB7XG4gICAgICAgICAgICAgIGlmICghc291cmNlW2ZpZWxkXSkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIHJldHVybiBzb3VyY2VbZmllbGRdLm1hcChhc3luYyAoZWxlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgIGVsZW0uY2xhc3NOYW1lICYmXG4gICAgICAgICAgICAgICAgICBlbGVtLm9iamVjdElkICYmXG4gICAgICAgICAgICAgICAgICBlbGVtLl9fdHlwZSA9PT0gJ09iamVjdCdcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogZWxlbSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZFxuICAgICAgICAgICAgICA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKVxuICAgICAgICAgICAgICA6IHR5cGUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICB9XG4gICAgfSwgcGFyc2VPYmplY3RGaWVsZHMpO1xuICB9O1xuICBsZXQgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZX0gb2JqZWN0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBvdXRwdXR0aW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGludGVyZmFjZXMsXG4gICAgZmllbGRzOiBvdXRwdXRGaWVsZHMsXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgKTtcblxuICBjb25zdCB7IGNvbm5lY3Rpb25UeXBlLCBlZGdlVHlwZSB9ID0gY29ubmVjdGlvbkRlZmluaXRpb25zKHtcbiAgICBuYW1lOiBncmFwaFFMQ2xhc3NOYW1lLFxuICAgIGNvbm5lY3Rpb25GaWVsZHM6IHtcbiAgICAgIGNvdW50OiBkZWZhdWx0R3JhcGhRTFR5cGVzLkNPVU5UX0FUVCxcbiAgICB9LFxuICAgIG5vZGVUeXBlOiBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNULFxuICB9KTtcbiAgbGV0IGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlID0gdW5kZWZpbmVkO1xuICBpZiAoXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGVkZ2VUeXBlKSAmJlxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjb25uZWN0aW9uVHlwZSwgZmFsc2UsIGZhbHNlLCB0cnVlKVxuICApIHtcbiAgICBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSA9IGNvbm5lY3Rpb25UeXBlO1xuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tjbGFzc05hbWVdID0ge1xuICAgIGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUsXG4gICAgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlLFxuICAgIGNsYXNzR3JhcGhRTEZpbmRBcmdzLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUsXG4gICAgY29uZmlnOiB7XG4gICAgICBwYXJzZUNsYXNzQ29uZmlnLFxuICAgICAgaXNDcmVhdGVFbmFibGVkLFxuICAgICAgaXNVcGRhdGVFbmFibGVkLFxuICAgIH0sXG4gIH07XG5cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNvbnN0IHZpZXdlclR5cGUgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgbmFtZTogJ1ZpZXdlcicsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSBWaWV3ZXIgb2JqZWN0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBvdXRwdXR0aW5nIHRoZSBjdXJyZW50IHVzZXIgZGF0YS5gLFxuICAgICAgZmllbGRzOiAoKSA9PiAoe1xuICAgICAgICBzZXNzaW9uVG9rZW46IGRlZmF1bHRHcmFwaFFMVHlwZXMuU0VTU0lPTl9UT0tFTl9BVFQsXG4gICAgICAgIHVzZXI6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGN1cnJlbnQgdXNlci4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlKSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIH0pO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh2aWV3ZXJUeXBlLCB0cnVlLCB0cnVlKTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEudmlld2VyVHlwZSA9IHZpZXdlclR5cGU7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSwgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaDirectives.js b/lib/GraphQL/loaders/schemaDirectives.js new file mode 100644 index 0000000000..6ddca35850 --- /dev/null +++ b/lib/GraphQL/loaders/schemaDirectives.js @@ -0,0 +1,72 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.definitions = void 0; + +var _graphqlTag = _interopRequireDefault(require("graphql-tag")); + +var _utils = require("@graphql-tools/utils"); + +var _FunctionsRouter = require("../../Routers/FunctionsRouter"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const definitions = (0, _graphqlTag.default)` + directive @resolve(to: String) on FIELD_DEFINITION + directive @mock(with: Any!) on FIELD_DEFINITION +`; +exports.definitions = definitions; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions; + + class ResolveDirectiveVisitor extends _utils.SchemaDirectiveVisitor { + visitFieldDefinition(field) { + field.resolve = async (_source, args, context) => { + try { + const { + config, + auth, + info + } = context; + let functionName = field.name; + + if (this.args.to) { + functionName = this.args.to; + } + + return (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ + params: { + functionName + }, + config, + auth, + info, + body: args + })).response.result; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }; + } + + } + + parseGraphQLSchema.graphQLSchemaDirectives.resolve = ResolveDirectiveVisitor; + + class MockDirectiveVisitor extends _utils.SchemaDirectiveVisitor { + visitFieldDefinition(field) { + field.resolve = () => { + return this.args.with; + }; + } + + } + + parseGraphQLSchema.graphQLSchemaDirectives.mock = MockDirectiveVisitor; +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcy5qcyJdLCJuYW1lcyI6WyJkZWZpbml0aW9ucyIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiUmVzb2x2ZURpcmVjdGl2ZVZpc2l0b3IiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRGaWVsZERlZmluaXRpb24iLCJmaWVsZCIsInJlc29sdmUiLCJfc291cmNlIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsImZ1bmN0aW9uTmFtZSIsIm5hbWUiLCJ0byIsIkZ1bmN0aW9uc1JvdXRlciIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwYXJhbXMiLCJib2R5IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJlIiwiaGFuZGxlRXJyb3IiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyIsIk1vY2tEaXJlY3RpdmVWaXNpdG9yIiwid2l0aCIsIm1vY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVPLE1BQU1BLFdBQVcsR0FBRyx3QkFBSTs7O0NBQXhCOzs7QUFLUCxNQUFNQyxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDQSxFQUFBQSxrQkFBa0IsQ0FBQ0Msa0NBQW5CLEdBQXdESCxXQUF4RDs7QUFFQSxRQUFNSSx1QkFBTixTQUFzQ0MsNkJBQXRDLENBQTZEO0FBQzNEQyxJQUFBQSxvQkFBb0IsQ0FBQ0MsS0FBRCxFQUFRO0FBQzFCQSxNQUFBQSxLQUFLLENBQUNDLE9BQU4sR0FBZ0IsT0FBT0MsT0FBUCxFQUFnQkMsSUFBaEIsRUFBc0JDLE9BQXRCLEtBQWtDO0FBQ2hELFlBQUk7QUFDRixnQkFBTTtBQUFFQyxZQUFBQSxNQUFGO0FBQVVDLFlBQUFBLElBQVY7QUFBZ0JDLFlBQUFBO0FBQWhCLGNBQXlCSCxPQUEvQjtBQUVBLGNBQUlJLFlBQVksR0FBR1IsS0FBSyxDQUFDUyxJQUF6Qjs7QUFDQSxjQUFJLEtBQUtOLElBQUwsQ0FBVU8sRUFBZCxFQUFrQjtBQUNoQkYsWUFBQUEsWUFBWSxHQUFHLEtBQUtMLElBQUwsQ0FBVU8sRUFBekI7QUFDRDs7QUFFRCxpQkFBTyxDQUFDLE1BQU1DLGlDQUFnQkMsbUJBQWhCLENBQW9DO0FBQ2hEQyxZQUFBQSxNQUFNLEVBQUU7QUFDTkwsY0FBQUE7QUFETSxhQUR3QztBQUloREgsWUFBQUEsTUFKZ0Q7QUFLaERDLFlBQUFBLElBTGdEO0FBTWhEQyxZQUFBQSxJQU5nRDtBQU9oRE8sWUFBQUEsSUFBSSxFQUFFWDtBQVAwQyxXQUFwQyxDQUFQLEVBUUhZLFFBUkcsQ0FRTUMsTUFSYjtBQVNELFNBakJELENBaUJFLE9BQU9DLENBQVAsRUFBVTtBQUNWdEIsVUFBQUEsa0JBQWtCLENBQUN1QixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGLE9BckJEO0FBc0JEOztBQXhCMEQ7O0FBMkI3RHRCLEVBQUFBLGtCQUFrQixDQUFDd0IsdUJBQW5CLENBQTJDbEIsT0FBM0MsR0FBcURKLHVCQUFyRDs7QUFFQSxRQUFNdUIsb0JBQU4sU0FBbUN0Qiw2QkFBbkMsQ0FBMEQ7QUFDeERDLElBQUFBLG9CQUFvQixDQUFDQyxLQUFELEVBQVE7QUFDMUJBLE1BQUFBLEtBQUssQ0FBQ0MsT0FBTixHQUFnQixNQUFNO0FBQ3BCLGVBQU8sS0FBS0UsSUFBTCxDQUFVa0IsSUFBakI7QUFDRCxPQUZEO0FBR0Q7O0FBTHVEOztBQVExRDFCLEVBQUFBLGtCQUFrQixDQUFDd0IsdUJBQW5CLENBQTJDRyxJQUEzQyxHQUFrREYsb0JBQWxEO0FBQ0QsQ0F6Q0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZ3FsIGZyb20gJ2dyYXBocWwtdGFnJztcbmltcG9ydCB7IFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IgfSBmcm9tICdAZ3JhcGhxbC10b29scy91dGlscyc7XG5pbXBvcnQgeyBGdW5jdGlvbnNSb3V0ZXIgfSBmcm9tICcuLi8uLi9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlcic7XG5cbmV4cG9ydCBjb25zdCBkZWZpbml0aW9ucyA9IGdxbGBcbiAgZGlyZWN0aXZlIEByZXNvbHZlKHRvOiBTdHJpbmcpIG9uIEZJRUxEX0RFRklOSVRJT05cbiAgZGlyZWN0aXZlIEBtb2NrKHdpdGg6IEFueSEpIG9uIEZJRUxEX0RFRklOSVRJT05cbmA7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNEZWZpbml0aW9ucyA9IGRlZmluaXRpb25zO1xuXG4gIGNsYXNzIFJlc29sdmVEaXJlY3RpdmVWaXNpdG9yIGV4dGVuZHMgU2NoZW1hRGlyZWN0aXZlVmlzaXRvciB7XG4gICAgdmlzaXRGaWVsZERlZmluaXRpb24oZmllbGQpIHtcbiAgICAgIGZpZWxkLnJlc29sdmUgPSBhc3luYyAoX3NvdXJjZSwgYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgbGV0IGZ1bmN0aW9uTmFtZSA9IGZpZWxkLm5hbWU7XG4gICAgICAgICAgaWYgKHRoaXMuYXJncy50bykge1xuICAgICAgICAgICAgZnVuY3Rpb25OYW1lID0gdGhpcy5hcmdzLnRvO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiAoYXdhaXQgRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkRnVuY3Rpb24oe1xuICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgIGJvZHk6IGFyZ3MsXG4gICAgICAgICAgfSkpLnJlc3BvbnNlLnJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXMucmVzb2x2ZSA9IFJlc29sdmVEaXJlY3RpdmVWaXNpdG9yO1xuXG4gIGNsYXNzIE1vY2tEaXJlY3RpdmVWaXNpdG9yIGV4dGVuZHMgU2NoZW1hRGlyZWN0aXZlVmlzaXRvciB7XG4gICAgdmlzaXRGaWVsZERlZmluaXRpb24oZmllbGQpIHtcbiAgICAgIGZpZWxkLnJlc29sdmUgPSAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFyZ3Mud2l0aDtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzLm1vY2sgPSBNb2NrRGlyZWN0aXZlVmlzaXRvcjtcbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaMutations.js b/lib/GraphQL/loaders/schemaMutations.js new file mode 100644 index 0000000000..2f948e3d7a --- /dev/null +++ b/lib/GraphQL/loaders/schemaMutations.js @@ -0,0 +1,179 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); + +var _schemaFields = require("../transformers/schemaFields"); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +var _schemaQueries = require("./schemaQueries"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const load = parseGraphQLSchema => { + const createClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'CreateClass', + description: 'The createClass mutation can be used to create the schema for a new object class.', + inputFields: { + name: schemaTypes.CLASS_NAME_ATT, + schemaFields: { + description: "These are the schema's fields of the object class.", + type: schemaTypes.SCHEMA_FIELDS_INPUT + } + }, + outputFields: { + class: { + description: 'This is the created class.', + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + name, + schemaFields + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + + if (auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); + } + + const schema = await config.database.loadSchema({ + clearCache: true + }); + const parseClass = await schema.addClassIfNotExists(name, (0, _schemaFields.transformToParse)(schemaFields)); + return { + class: { + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + } + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(createClassMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(createClassMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('createClass', createClassMutation, true, true); + const updateClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'UpdateClass', + description: 'The updateClass mutation can be used to update the schema for an existing object class.', + inputFields: { + name: schemaTypes.CLASS_NAME_ATT, + schemaFields: { + description: "These are the schema's fields of the object class.", + type: schemaTypes.SCHEMA_FIELDS_INPUT + } + }, + outputFields: { + class: { + description: 'This is the updated class.', + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + name, + schemaFields + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + + if (auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); + } + + const schema = await config.database.loadSchema({ + clearCache: true + }); + const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); + const parseClass = await schema.updateClass(name, (0, _schemaFields.transformToParse)(schemaFields, existingParseClass.fields), undefined, undefined, config.database); + return { + class: { + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + } + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(updateClassMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(updateClassMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('updateClass', updateClassMutation, true, true); + const deleteClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'DeleteClass', + description: 'The deleteClass mutation can be used to delete an existing object class.', + inputFields: { + name: schemaTypes.CLASS_NAME_ATT + }, + outputFields: { + class: { + description: 'This is the deleted class.', + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + name + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + + if (auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); + } + + const schema = await config.database.loadSchema({ + clearCache: true + }); + const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); + await config.database.deleteSchema(name); + return { + class: { + name: existingParseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(existingParseClass.fields) + } + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(deleteClassMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(deleteClassMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('deleteClass', deleteClassMutation, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJjcmVhdGVDbGFzc011dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwic2NoZW1hRmllbGRzIiwidHlwZSIsIlNDSEVNQV9GSUVMRFNfSU5QVVQiLCJvdXRwdXRGaWVsZHMiLCJjbGFzcyIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJtdXRhdGVBbmRHZXRQYXlsb2FkIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaXNSZWFkT25seSIsIlBhcnNlIiwiRXJyb3IiLCJPUEVSQVRJT05fRk9SQklEREVOIiwic2NoZW1hIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJhZGRDbGFzc0lmTm90RXhpc3RzIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUNsYXNzTXV0YXRpb24iLCJleGlzdGluZ1BhcnNlQ2xhc3MiLCJ1cGRhdGVDbGFzcyIsInVuZGVmaW5lZCIsImRlbGV0ZUNsYXNzTXV0YXRpb24iLCJkZWxldGVTY2hlbWEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFJQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLFFBQU1DLG1CQUFtQixHQUFHLGdEQUE2QjtBQUN2REMsSUFBQUEsSUFBSSxFQUFFLGFBRGlEO0FBRXZEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHFEO0FBSXZEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWEYs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LDZCQUFTcEMsSUFBVCxFQUFlcUIsTUFBZixDQUFqQztBQUNBLGNBQU1OLE1BQU0sQ0FBQ08sUUFBUCxDQUFnQmtCLFlBQWhCLENBQTZCeEMsSUFBN0IsQ0FBTjtBQUNBLGVBQU87QUFDTFMsVUFBQUEsS0FBSyxFQUFFO0FBQ0xULFlBQUFBLElBQUksRUFBRW9DLGtCQUFrQixDQUFDVCxTQURwQjtBQUVMdEIsWUFBQUEsWUFBWSxFQUFFLHNDQUFtQitCLGtCQUFrQixDQUFDUixNQUF0QztBQUZUO0FBREYsU0FBUDtBQU1ELE9BdEJELENBc0JFLE9BQU9DLENBQVAsRUFBVTtBQUNWL0IsUUFBQUEsa0JBQWtCLENBQUNnQyxXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBdkNzRCxHQUE3QixDQUE1QjtBQTBDQS9CLEVBQUFBLGtCQUFrQixDQUFDaUMsY0FBbkIsQ0FDRVEsbUJBQW1CLENBQUMxQixJQUFwQixDQUF5Qm1CLEtBQXpCLENBQStCMUIsSUFBL0IsQ0FBb0MyQixNQUR0QyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FuQyxFQUFBQSxrQkFBa0IsQ0FBQ2lDLGNBQW5CLENBQWtDUSxtQkFBbUIsQ0FBQ2pDLElBQXRELEVBQTRELElBQTVELEVBQWtFLElBQWxFO0FBQ0FSLEVBQUFBLGtCQUFrQixDQUFDb0Msa0JBQW5CLENBQ0UsYUFERixFQUVFSyxtQkFGRixFQUdFLElBSEYsRUFJRSxJQUpGO0FBTUQsQ0FyTEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0ICogYXMgc2NoZW1hVHlwZXMgZnJvbSAnLi9zY2hlbWFUeXBlcyc7XG5pbXBvcnQge1xuICB0cmFuc2Zvcm1Ub1BhcnNlLFxuICB0cmFuc2Zvcm1Ub0dyYXBoUUwsXG59IGZyb20gJy4uL3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMnO1xuaW1wb3J0IHsgZW5mb3JjZU1hc3RlcktleUFjY2VzcyB9IGZyb20gJy4uL3BhcnNlR3JhcGhRTFV0aWxzJztcbmltcG9ydCB7IGdldENsYXNzIH0gZnJvbSAnLi9zY2hlbWFRdWVyaWVzJztcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGNvbnN0IGNyZWF0ZUNsYXNzTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnQ3JlYXRlQ2xhc3MnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBjcmVhdGVDbGFzcyBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBjcmVhdGUgdGhlIHNjaGVtYSBmb3IgYSBuZXcgb2JqZWN0IGNsYXNzLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgICAgc2NoZW1hRmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZXNlIGFyZSB0aGUgc2NoZW1hJ3MgZmllbGRzIG9mIHRoZSBvYmplY3QgY2xhc3MuXCIsXG4gICAgICAgIHR5cGU6IHNjaGVtYVR5cGVzLlNDSEVNQV9GSUVMRFNfSU5QVVQsXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBjbGFzczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNyZWF0ZWQgY2xhc3MuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBuYW1lLCBzY2hlbWFGaWVsZHMgfSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MoYXV0aCk7XG5cbiAgICAgICAgaWYgKGF1dGguaXNSZWFkT25seSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBjcmVhdGUgYSBzY2hlbWEuXCJcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgY29uZmlnLmRhdGFiYXNlLmxvYWRTY2hlbWEoeyBjbGVhckNhY2hlOiB0cnVlIH0pO1xuICAgICAgICBjb25zdCBwYXJzZUNsYXNzID0gYXdhaXQgc2NoZW1hLmFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICB0cmFuc2Zvcm1Ub1BhcnNlKHNjaGVtYUZpZWxkcylcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBjcmVhdGVDbGFzc011dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjcmVhdGVDbGFzc011dGF0aW9uLnR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKFxuICAgICdjcmVhdGVDbGFzcycsXG4gICAgY3JlYXRlQ2xhc3NNdXRhdGlvbixcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcblxuICBjb25zdCB1cGRhdGVDbGFzc011dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ1VwZGF0ZUNsYXNzJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgdXBkYXRlQ2xhc3MgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gdXBkYXRlIHRoZSBzY2hlbWEgZm9yIGFuIGV4aXN0aW5nIG9iamVjdCBjbGFzcy4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBuYW1lOiBzY2hlbWFUeXBlcy5DTEFTU19OQU1FX0FUVCxcbiAgICAgIHNjaGVtYUZpZWxkczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGVzZSBhcmUgdGhlIHNjaGVtYSdzIGZpZWxkcyBvZiB0aGUgb2JqZWN0IGNsYXNzLlwiLFxuICAgICAgICB0eXBlOiBzY2hlbWFUeXBlcy5TQ0hFTUFfRklFTERTX0lOUFVULFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgY2xhc3M6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cGRhdGVkIGNsYXNzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgbmFtZSwgc2NoZW1hRmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gdXBkYXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdQYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgY29uc3QgcGFyc2VDbGFzcyA9IGF3YWl0IHNjaGVtYS51cGRhdGVDbGFzcyhcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIHRyYW5zZm9ybVRvUGFyc2Uoc2NoZW1hRmllbGRzLCBleGlzdGluZ1BhcnNlQ2xhc3MuZmllbGRzKSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIGNvbmZpZy5kYXRhYmFzZVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNsYXNzOiB7XG4gICAgICAgICAgICBuYW1lOiBwYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYUZpZWxkczogdHJhbnNmb3JtVG9HcmFwaFFMKHBhcnNlQ2xhc3MuZmllbGRzKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIHVwZGF0ZUNsYXNzTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHVwZGF0ZUNsYXNzTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgJ3VwZGF0ZUNsYXNzJyxcbiAgICB1cGRhdGVDbGFzc011dGF0aW9uLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIGNvbnN0IGRlbGV0ZUNsYXNzTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnRGVsZXRlQ2xhc3MnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBkZWxldGVDbGFzcyBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBkZWxldGUgYW4gZXhpc3Rpbmcgb2JqZWN0IGNsYXNzLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBjbGFzczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGRlbGV0ZWQgY2xhc3MuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gZGVsZXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdQYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgYXdhaXQgY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShuYW1lKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogZXhpc3RpbmdQYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYUZpZWxkczogdHJhbnNmb3JtVG9HcmFwaFFMKGV4aXN0aW5nUGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgZGVsZXRlQ2xhc3NNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlQ2xhc3NNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAnZGVsZXRlQ2xhc3MnLFxuICAgIGRlbGV0ZUNsYXNzTXV0YXRpb24sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaQueries.js b/lib/GraphQL/loaders/schemaQueries.js new file mode 100644 index 0000000000..e1df2aa6b3 --- /dev/null +++ b/lib/GraphQL/loaders/schemaQueries.js @@ -0,0 +1,93 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.getClass = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphql = require("graphql"); + +var _schemaFields = require("../transformers/schemaFields"); + +var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const getClass = async (name, schema) => { + try { + return await schema.getOneSchema(name, true); + } catch (e) { + if (e === undefined) { + throw new _node.default.Error(_node.default.Error.INVALID_CLASS_NAME, `Class ${name} does not exist.`); + } else { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); + } + } +}; + +exports.getClass = getClass; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLQuery('class', { + description: 'The class query can be used to retrieve an existing object class.', + args: { + name: schemaTypes.CLASS_NAME_ATT + }, + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS), + resolve: async (_source, args, context) => { + try { + const { + name + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + const schema = await config.database.loadSchema({ + clearCache: true + }); + const parseClass = await getClass(name, schema); + return { + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }, true, true); + parseGraphQLSchema.addGraphQLQuery('classes', { + description: 'The classes query can be used to retrieve the existing object classes.', + type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(schemaTypes.CLASS))), + resolve: async (_source, _args, context) => { + try { + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + const schema = await config.database.loadSchema({ + clearCache: true + }); + return (await schema.getAllClasses(true)).map(parseClass => ({ + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + })); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hUXVlcmllcy5qcyJdLCJuYW1lcyI6WyJnZXRDbGFzcyIsIm5hbWUiLCJzY2hlbWEiLCJnZXRPbmVTY2hlbWEiLCJlIiwidW5kZWZpbmVkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImFyZ3MiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJyZXNvbHZlIiwiX3NvdXJjZSIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJjbGFzc05hbWUiLCJzY2hlbWFGaWVsZHMiLCJmaWVsZHMiLCJoYW5kbGVFcnJvciIsIkdyYXBoUUxMaXN0IiwiX2FyZ3MiLCJnZXRBbGxDbGFzc2VzIiwibWFwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsUUFBUSxHQUFHLE9BQU9DLElBQVAsRUFBYUMsTUFBYixLQUF3QjtBQUN2QyxNQUFJO0FBQ0YsV0FBTyxNQUFNQSxNQUFNLENBQUNDLFlBQVAsQ0FBb0JGLElBQXBCLEVBQTBCLElBQTFCLENBQWI7QUFDRCxHQUZELENBRUUsT0FBT0csQ0FBUCxFQUFVO0FBQ1YsUUFBSUEsQ0FBQyxLQUFLQyxTQUFWLEVBQXFCO0FBQ25CLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUgsU0FBUVAsSUFBSyxrQkFGVixDQUFOO0FBSUQsS0FMRCxNQUtPO0FBQ0wsWUFBTSxJQUFJSyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUUscUJBRFIsRUFFSix5QkFGSSxDQUFOO0FBSUQ7QUFDRjtBQUNGLENBaEJEOzs7O0FBa0JBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakNBLEVBQUFBLGtCQUFrQixDQUFDQyxlQUFuQixDQUNFLE9BREYsRUFFRTtBQUNFQyxJQUFBQSxXQUFXLEVBQ1QsbUVBRko7QUFHRUMsSUFBQUEsSUFBSSxFQUFFO0FBQ0piLE1BQUFBLElBQUksRUFBRWMsV0FBVyxDQUFDQztBQURkLEtBSFI7QUFNRUMsSUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CSCxXQUFXLENBQUNJLEtBQS9CLENBTlI7QUFPRUMsSUFBQUEsT0FBTyxFQUFFLE9BQU9DLE9BQVAsRUFBZ0JQLElBQWhCLEVBQXNCUSxPQUF0QixLQUFrQztBQUN6QyxVQUFJO0FBQ0YsY0FBTTtBQUFFckIsVUFBQUE7QUFBRixZQUFXYSxJQUFqQjtBQUNBLGNBQU07QUFBRVMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7QUFFQSxjQUFNdEIsTUFBTSxHQUFHLE1BQU1xQixNQUFNLENBQUNFLFFBQVAsQ0FBZ0JDLFVBQWhCLENBQTJCO0FBQUVDLFVBQUFBLFVBQVUsRUFBRTtBQUFkLFNBQTNCLENBQXJCO0FBQ0EsY0FBTUMsVUFBVSxHQUFHLE1BQU01QixRQUFRLENBQUNDLElBQUQsRUFBT0MsTUFBUCxDQUFqQztBQUNBLGVBQU87QUFDTEQsVUFBQUEsSUFBSSxFQUFFMkIsVUFBVSxDQUFDQyxTQURaO0FBRUxDLFVBQUFBLFlBQVksRUFBRSxzQ0FBbUJGLFVBQVUsQ0FBQ0csTUFBOUI7QUFGVCxTQUFQO0FBSUQsT0FaRCxDQVlFLE9BQU8zQixDQUFQLEVBQVU7QUFDVk8sUUFBQUEsa0JBQWtCLENBQUNxQixXQUFuQixDQUErQjVCLENBQS9CO0FBQ0Q7QUFDRjtBQXZCSCxHQUZGLEVBMkJFLElBM0JGLEVBNEJFLElBNUJGO0FBK0JBTyxFQUFBQSxrQkFBa0IsQ0FBQ0MsZUFBbkIsQ0FDRSxTQURGLEVBRUU7QUFDRUMsSUFBQUEsV0FBVyxFQUNULHdFQUZKO0FBR0VJLElBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUNKLElBQUllLG9CQUFKLENBQWdCLElBQUlmLHVCQUFKLENBQW1CSCxXQUFXLENBQUNJLEtBQS9CLENBQWhCLENBREksQ0FIUjtBQU1FQyxJQUFBQSxPQUFPLEVBQUUsT0FBT0MsT0FBUCxFQUFnQmEsS0FBaEIsRUFBdUJaLE9BQXZCLEtBQW1DO0FBQzFDLFVBQUk7QUFDRixjQUFNO0FBQUVDLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUE7QUFBVixZQUFtQkYsT0FBekI7QUFFQSx1REFBdUJFLElBQXZCO0FBRUEsY0FBTXRCLE1BQU0sR0FBRyxNQUFNcUIsTUFBTSxDQUFDRSxRQUFQLENBQWdCQyxVQUFoQixDQUEyQjtBQUFFQyxVQUFBQSxVQUFVLEVBQUU7QUFBZCxTQUEzQixDQUFyQjtBQUNBLGVBQU8sQ0FBQyxNQUFNekIsTUFBTSxDQUFDaUMsYUFBUCxDQUFxQixJQUFyQixDQUFQLEVBQW1DQyxHQUFuQyxDQUF1Q1IsVUFBVSxLQUFLO0FBQzNEM0IsVUFBQUEsSUFBSSxFQUFFMkIsVUFBVSxDQUFDQyxTQUQwQztBQUUzREMsVUFBQUEsWUFBWSxFQUFFLHNDQUFtQkYsVUFBVSxDQUFDRyxNQUE5QjtBQUY2QyxTQUFMLENBQWpELENBQVA7QUFJRCxPQVZELENBVUUsT0FBTzNCLENBQVAsRUFBVTtBQUNWTyxRQUFBQSxrQkFBa0IsQ0FBQ3FCLFdBQW5CLENBQStCNUIsQ0FBL0I7QUFDRDtBQUNGO0FBcEJILEdBRkYsRUF3QkUsSUF4QkYsRUF5QkUsSUF6QkY7QUEyQkQsQ0EzREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCwgR3JhcGhRTExpc3QgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IHRyYW5zZm9ybVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMnO1xuaW1wb3J0ICogYXMgc2NoZW1hVHlwZXMgZnJvbSAnLi9zY2hlbWFUeXBlcyc7XG5pbXBvcnQgeyBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRDbGFzcyA9IGFzeW5jIChuYW1lLCBzY2hlbWEpID0+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgc2NoZW1hLmdldE9uZVNjaGVtYShuYW1lLCB0cnVlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICBgQ2xhc3MgJHtuYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgJ0RhdGFiYXNlIGFkYXB0ZXIgZXJyb3IuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdjbGFzcycsXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgY2xhc3MgcXVlcnkgY2FuIGJlIHVzZWQgdG8gcmV0cmlldmUgYW4gZXhpc3Rpbmcgb2JqZWN0IGNsYXNzLicsXG4gICAgICBhcmdzOiB7XG4gICAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgICAgfSxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUyksXG4gICAgICByZXNvbHZlOiBhc3luYyAoX3NvdXJjZSwgYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MoYXV0aCk7XG5cbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgICAgY29uc3QgcGFyc2VDbGFzcyA9IGF3YWl0IGdldENsYXNzKG5hbWUsIHNjaGVtYSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IHBhcnNlQ2xhc3MuY2xhc3NOYW1lLFxuICAgICAgICAgICAgc2NoZW1hRmllbGRzOiB0cmFuc2Zvcm1Ub0dyYXBoUUwocGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdjbGFzc2VzJyxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBjbGFzc2VzIHF1ZXJ5IGNhbiBiZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBleGlzdGluZyBvYmplY3QgY2xhc3Nlcy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSlcbiAgICAgICksXG4gICAgICByZXNvbHZlOiBhc3luYyAoX3NvdXJjZSwgX2FyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MoYXV0aCk7XG5cbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgICAgcmV0dXJuIChhd2FpdCBzY2hlbWEuZ2V0QWxsQ2xhc3Nlcyh0cnVlKSkubWFwKHBhcnNlQ2xhc3MgPT4gKHtcbiAgICAgICAgICAgIG5hbWU6IHBhcnNlQ2xhc3MuY2xhc3NOYW1lLFxuICAgICAgICAgICAgc2NoZW1hRmllbGRzOiB0cmFuc2Zvcm1Ub0dyYXBoUUwocGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xufTtcblxuZXhwb3J0IHsgZ2V0Q2xhc3MsIGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaTypes.js b/lib/GraphQL/loaders/schemaTypes.js new file mode 100644 index 0000000000..face4b3b4b --- /dev/null +++ b/lib/GraphQL/loaders/schemaTypes.js @@ -0,0 +1,376 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.CLASS = exports.CLASS_NAME_ATT = exports.SCHEMA_FIELDS_INPUT = exports.SCHEMA_ACL_FIELD = exports.SCHEMA_RELATION_FIELD = exports.SCHEMA_RELATION_FIELD_INPUT = exports.SCHEMA_POINTER_FIELD = exports.SCHEMA_POINTER_FIELD_INPUT = exports.TARGET_CLASS_ATT = exports.SCHEMA_BYTES_FIELD = exports.SCHEMA_BYTES_FIELD_INPUT = exports.SCHEMA_POLYGON_FIELD = exports.SCHEMA_POLYGON_FIELD_INPUT = exports.SCHEMA_GEO_POINT_FIELD = exports.SCHEMA_GEO_POINT_FIELD_INPUT = exports.SCHEMA_FILE_FIELD = exports.SCHEMA_FILE_FIELD_INPUT = exports.SCHEMA_DATE_FIELD = exports.SCHEMA_DATE_FIELD_INPUT = exports.SCHEMA_OBJECT_FIELD = exports.SCHEMA_OBJECT_FIELD_INPUT = exports.SCHEMA_ARRAY_FIELD = exports.SCHEMA_ARRAY_FIELD_INPUT = exports.SCHEMA_BOOLEAN_FIELD = exports.SCHEMA_BOOLEAN_FIELD_INPUT = exports.SCHEMA_NUMBER_FIELD = exports.SCHEMA_NUMBER_FIELD_INPUT = exports.SCHEMA_STRING_FIELD = exports.SCHEMA_STRING_FIELD_INPUT = exports.SCHEMA_FIELD_INPUT = exports.SCHEMA_FIELD_NAME_ATT = void 0; + +var _graphql = require("graphql"); + +const SCHEMA_FIELD_NAME_ATT = { + description: 'This is the field name.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.SCHEMA_FIELD_NAME_ATT = SCHEMA_FIELD_NAME_ATT; +const SCHEMA_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaFieldInput', + description: 'The SchemaFieldInput is used to specify a field of an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_FIELD_INPUT = SCHEMA_FIELD_INPUT; +const SCHEMA_FIELD = new _graphql.GraphQLInterfaceType({ + name: 'SchemaField', + description: 'The SchemaField interface type is used as a base type for the different supported fields of an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + }, + resolveType: value => ({ + String: SCHEMA_STRING_FIELD, + Number: SCHEMA_NUMBER_FIELD, + Boolean: SCHEMA_BOOLEAN_FIELD, + Array: SCHEMA_ARRAY_FIELD, + Object: SCHEMA_OBJECT_FIELD, + Date: SCHEMA_DATE_FIELD, + File: SCHEMA_FILE_FIELD, + GeoPoint: SCHEMA_GEO_POINT_FIELD, + Polygon: SCHEMA_POLYGON_FIELD, + Bytes: SCHEMA_BYTES_FIELD, + Pointer: SCHEMA_POINTER_FIELD, + Relation: SCHEMA_RELATION_FIELD, + ACL: SCHEMA_ACL_FIELD + })[value.type] +}); +const SCHEMA_STRING_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaStringFieldInput', + description: 'The SchemaStringFieldInput is used to specify a field of type string for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_STRING_FIELD_INPUT = SCHEMA_STRING_FIELD_INPUT; +const SCHEMA_STRING_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaStringField', + description: 'The SchemaStringField is used to return information of a String field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_STRING_FIELD = SCHEMA_STRING_FIELD; +const SCHEMA_NUMBER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaNumberFieldInput', + description: 'The SchemaNumberFieldInput is used to specify a field of type number for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_NUMBER_FIELD_INPUT = SCHEMA_NUMBER_FIELD_INPUT; +const SCHEMA_NUMBER_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaNumberField', + description: 'The SchemaNumberField is used to return information of a Number field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_NUMBER_FIELD = SCHEMA_NUMBER_FIELD; +const SCHEMA_BOOLEAN_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaBooleanFieldInput', + description: 'The SchemaBooleanFieldInput is used to specify a field of type boolean for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BOOLEAN_FIELD_INPUT = SCHEMA_BOOLEAN_FIELD_INPUT; +const SCHEMA_BOOLEAN_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaBooleanField', + description: 'The SchemaBooleanField is used to return information of a Boolean field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BOOLEAN_FIELD = SCHEMA_BOOLEAN_FIELD; +const SCHEMA_ARRAY_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaArrayFieldInput', + description: 'The SchemaArrayFieldInput is used to specify a field of type array for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_ARRAY_FIELD_INPUT = SCHEMA_ARRAY_FIELD_INPUT; +const SCHEMA_ARRAY_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaArrayField', + description: 'The SchemaArrayField is used to return information of an Array field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_ARRAY_FIELD = SCHEMA_ARRAY_FIELD; +const SCHEMA_OBJECT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaObjectFieldInput', + description: 'The SchemaObjectFieldInput is used to specify a field of type object for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_OBJECT_FIELD_INPUT = SCHEMA_OBJECT_FIELD_INPUT; +const SCHEMA_OBJECT_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaObjectField', + description: 'The SchemaObjectField is used to return information of an Object field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_OBJECT_FIELD = SCHEMA_OBJECT_FIELD; +const SCHEMA_DATE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaDateFieldInput', + description: 'The SchemaDateFieldInput is used to specify a field of type date for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_DATE_FIELD_INPUT = SCHEMA_DATE_FIELD_INPUT; +const SCHEMA_DATE_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaDateField', + description: 'The SchemaDateField is used to return information of a Date field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_DATE_FIELD = SCHEMA_DATE_FIELD; +const SCHEMA_FILE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaFileFieldInput', + description: 'The SchemaFileFieldInput is used to specify a field of type file for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_FILE_FIELD_INPUT = SCHEMA_FILE_FIELD_INPUT; +const SCHEMA_FILE_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaFileField', + description: 'The SchemaFileField is used to return information of a File field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_FILE_FIELD = SCHEMA_FILE_FIELD; +const SCHEMA_GEO_POINT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaGeoPointFieldInput', + description: 'The SchemaGeoPointFieldInput is used to specify a field of type geo point for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_GEO_POINT_FIELD_INPUT = SCHEMA_GEO_POINT_FIELD_INPUT; +const SCHEMA_GEO_POINT_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaGeoPointField', + description: 'The SchemaGeoPointField is used to return information of a Geo Point field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_GEO_POINT_FIELD = SCHEMA_GEO_POINT_FIELD; +const SCHEMA_POLYGON_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaPolygonFieldInput', + description: 'The SchemaPolygonFieldInput is used to specify a field of type polygon for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_POLYGON_FIELD_INPUT = SCHEMA_POLYGON_FIELD_INPUT; +const SCHEMA_POLYGON_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaPolygonField', + description: 'The SchemaPolygonField is used to return information of a Polygon field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_POLYGON_FIELD = SCHEMA_POLYGON_FIELD; +const SCHEMA_BYTES_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaBytesFieldInput', + description: 'The SchemaBytesFieldInput is used to specify a field of type bytes for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BYTES_FIELD_INPUT = SCHEMA_BYTES_FIELD_INPUT; +const SCHEMA_BYTES_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaBytesField', + description: 'The SchemaBytesField is used to return information of a Bytes field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BYTES_FIELD = SCHEMA_BYTES_FIELD; +const TARGET_CLASS_ATT = { + description: 'This is the name of the target class for the field.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.TARGET_CLASS_ATT = TARGET_CLASS_ATT; +const SCHEMA_POINTER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'PointerFieldInput', + description: 'The PointerFieldInput is used to specify a field of type pointer for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_POINTER_FIELD_INPUT = SCHEMA_POINTER_FIELD_INPUT; +const SCHEMA_POINTER_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaPointerField', + description: 'The SchemaPointerField is used to return information of a Pointer field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_POINTER_FIELD = SCHEMA_POINTER_FIELD; +const SCHEMA_RELATION_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'RelationFieldInput', + description: 'The RelationFieldInput is used to specify a field of type relation for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_RELATION_FIELD_INPUT = SCHEMA_RELATION_FIELD_INPUT; +const SCHEMA_RELATION_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaRelationField', + description: 'The SchemaRelationField is used to return information of a Relation field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_RELATION_FIELD = SCHEMA_RELATION_FIELD; +const SCHEMA_ACL_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaACLField', + description: 'The SchemaACLField is used to return information of an ACL field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_ACL_FIELD = SCHEMA_ACL_FIELD; +const SCHEMA_FIELDS_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaFieldsInput', + description: `The CreateClassSchemaInput type is used to specify the schema for a new object class to be created.`, + fields: { + addStrings: { + description: 'These are the String fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_STRING_FIELD_INPUT)) + }, + addNumbers: { + description: 'These are the Number fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_NUMBER_FIELD_INPUT)) + }, + addBooleans: { + description: 'These are the Boolean fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BOOLEAN_FIELD_INPUT)) + }, + addArrays: { + description: 'These are the Array fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_ARRAY_FIELD_INPUT)) + }, + addObjects: { + description: 'These are the Object fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_OBJECT_FIELD_INPUT)) + }, + addDates: { + description: 'These are the Date fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_DATE_FIELD_INPUT)) + }, + addFiles: { + description: 'These are the File fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FILE_FIELD_INPUT)) + }, + addGeoPoint: { + description: 'This is the Geo Point field to be added to the class schema. Currently it is supported only one GeoPoint field per Class.', + type: SCHEMA_GEO_POINT_FIELD_INPUT + }, + addPolygons: { + description: 'These are the Polygon fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POLYGON_FIELD_INPUT)) + }, + addBytes: { + description: 'These are the Bytes fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BYTES_FIELD_INPUT)) + }, + addPointers: { + description: 'These are the Pointer fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POINTER_FIELD_INPUT)) + }, + addRelations: { + description: 'These are the Relation fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_RELATION_FIELD_INPUT)) + }, + remove: { + description: 'These are the fields to be removed from the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD_INPUT)) + } + } +}); +exports.SCHEMA_FIELDS_INPUT = SCHEMA_FIELDS_INPUT; +const CLASS_NAME_ATT = { + description: 'This is the name of the object class.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.CLASS_NAME_ATT = CLASS_NAME_ATT; +const CLASS = new _graphql.GraphQLObjectType({ + name: 'Class', + description: `The Class type is used to return the information about an object class.`, + fields: { + name: CLASS_NAME_ATT, + schemaFields: { + description: "These are the schema's fields of the object class.", + type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD))) + } + } +}); +exports.CLASS = CLASS; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLType(SCHEMA_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_ACL_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_FIELDS_INPUT, true); + parseGraphQLSchema.addGraphQLType(CLASS, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hVHlwZXMuanMiXSwibmFtZXMiOlsiU0NIRU1BX0ZJRUxEX05BTUVfQVRUIiwiZGVzY3JpcHRpb24iLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiU0NIRU1BX0ZJRUxEX0lOUFVUIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJmaWVsZHMiLCJTQ0hFTUFfRklFTEQiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsInJlc29sdmVUeXBlIiwidmFsdWUiLCJTdHJpbmciLCJTQ0hFTUFfU1RSSU5HX0ZJRUxEIiwiTnVtYmVyIiwiU0NIRU1BX05VTUJFUl9GSUVMRCIsIkJvb2xlYW4iLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRCIsIkFycmF5IiwiU0NIRU1BX0FSUkFZX0ZJRUxEIiwiT2JqZWN0IiwiU0NIRU1BX09CSkVDVF9GSUVMRCIsIkRhdGUiLCJTQ0hFTUFfREFURV9GSUVMRCIsIkZpbGUiLCJTQ0hFTUFfRklMRV9GSUVMRCIsIkdlb1BvaW50IiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRCIsIlBvbHlnb24iLCJTQ0hFTUFfUE9MWUdPTl9GSUVMRCIsIkJ5dGVzIiwiU0NIRU1BX0JZVEVTX0ZJRUxEIiwiUG9pbnRlciIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEIiwiUmVsYXRpb24iLCJTQ0hFTUFfUkVMQVRJT05fRklFTEQiLCJBQ0wiLCJTQ0hFTUFfQUNMX0ZJRUxEIiwiU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCIsIkdyYXBoUUxPYmplY3RUeXBlIiwiaW50ZXJmYWNlcyIsIlNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQiLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCIsIlNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQiLCJTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCIsIlNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVUIiwiVEFSR0VUX0NMQVNTX0FUVCIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUIiwidGFyZ2V0Q2xhc3NOYW1lIiwiU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0ZJRUxEU19JTlBVVCIsImFkZFN0cmluZ3MiLCJHcmFwaFFMTGlzdCIsImFkZE51bWJlcnMiLCJhZGRCb29sZWFucyIsImFkZEFycmF5cyIsImFkZE9iamVjdHMiLCJhZGREYXRlcyIsImFkZEZpbGVzIiwiYWRkR2VvUG9pbnQiLCJhZGRQb2x5Z29ucyIsImFkZEJ5dGVzIiwiYWRkUG9pbnRlcnMiLCJhZGRSZWxhdGlvbnMiLCJyZW1vdmUiLCJDTEFTU19OQU1FX0FUVCIsIkNMQVNTIiwic2NoZW1hRmllbGRzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImFkZEdyYXBoUUxUeXBlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBU0EsTUFBTUEscUJBQXFCLEdBQUc7QUFDNUJDLEVBQUFBLFdBQVcsRUFBRSx5QkFEZTtBQUU1QkMsRUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CQyxzQkFBbkI7QUFGc0IsQ0FBOUI7O0FBS0EsTUFBTUMsa0JBQWtCLEdBQUcsSUFBSUMsK0JBQUosQ0FBMkI7QUFDcERDLEVBQUFBLElBQUksRUFBRSxrQkFEOEM7QUFFcEROLEVBQUFBLFdBQVcsRUFDVCw0RUFIa0Q7QUFJcERPLEVBQUFBLE1BQU0sRUFBRTtBQUNORCxJQUFBQSxJQUFJLEVBQUVQO0FBREE7QUFKNEMsQ0FBM0IsQ0FBM0I7O0FBU0EsTUFBTVMsWUFBWSxHQUFHLElBQUlDLDZCQUFKLENBQXlCO0FBQzVDSCxFQUFBQSxJQUFJLEVBQUUsYUFEc0M7QUFFNUNOLEVBQUFBLFdBQVcsRUFDVCxxSEFIMEM7QUFJNUNPLEVBQUFBLE1BQU0s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QUFuQixDQUFrQzFCLDBCQUFsQyxFQUE4RCxJQUE5RDtBQUNBeUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDN0Msb0JBQWxDLEVBQXdELElBQXhEO0FBQ0E0QyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6Qix3QkFBbEMsRUFBNEQsSUFBNUQ7QUFDQXdCLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQzNDLGtCQUFsQyxFQUFzRCxJQUF0RDtBQUNBMEMsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkIsMEJBQWxDLEVBQThELElBQTlEO0FBQ0FzQixFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6QyxvQkFBbEMsRUFBd0QsSUFBeEQ7QUFDQXdDLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3JCLDJCQUFsQyxFQUErRCxJQUEvRDtBQUNBb0IsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkMscUJBQWxDLEVBQXlELElBQXpEO0FBQ0FzQyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0NyQyxnQkFBbEMsRUFBb0QsSUFBcEQ7QUFDQW9DLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3BCLG1CQUFsQyxFQUF1RCxJQUF2RDtBQUNBbUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDSixLQUFsQyxFQUF5QyxJQUF6QztBQUNELENBN0JEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxTdHJpbmcsXG4gIEdyYXBoUUxJbnB1dE9iamVjdFR5cGUsXG4gIEdyYXBoUUxMaXN0LFxuICBHcmFwaFFMT2JqZWN0VHlwZSxcbiAgR3JhcGhRTEludGVyZmFjZVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuXG5jb25zdCBTQ0hFTUFfRklFTERfTkFNRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZmllbGQgbmFtZS4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBTQ0hFTUFfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9GSUVMRCA9IG5ldyBHcmFwaFFMSW50ZXJmYWNlVHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRmllbGQgaW50ZXJmYWNlIHR5cGUgaXMgdXNlZCBhcyBhIGJhc2UgdHlwZSBmb3IgdGhlIGRpZmZlcmVudCBzdXBwb3J0ZWQgZmllbGRzIG9mIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxuICByZXNvbHZlVHlwZTogdmFsdWUgPT5cbiAgICAoe1xuICAgICAgU3RyaW5nOiBTQ0hFTUFfU1RSSU5HX0ZJRUxELFxuICAgICAgTnVtYmVyOiBTQ0hFTUFfTlVNQkVSX0ZJRUxELFxuICAgICAgQm9vbGVhbjogU0NIRU1BX0JPT0xFQU5fRklFTEQsXG4gICAgICBBcnJheTogU0NIRU1BX0FSUkFZX0ZJRUxELFxuICAgICAgT2JqZWN0OiBTQ0hFTUFfT0JKRUNUX0ZJRUxELFxuICAgICAgRGF0ZTogU0NIRU1BX0RBVEVfRklFTEQsXG4gICAgICBGaWxlOiBTQ0hFTUFfRklMRV9GSUVMRCxcbiAgICAgIEdlb1BvaW50OiBTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxELFxuICAgICAgUG9seWdvbjogU0NIRU1BX1BPTFlHT05fRklFTEQsXG4gICAgICBCeXRlczogU0NIRU1BX0JZVEVTX0ZJRUxELFxuICAgICAgUG9pbnRlcjogU0NIRU1BX1BPSU5URVJfRklFTEQsXG4gICAgICBSZWxhdGlvbjogU0NIRU1BX1JFTEFUSU9OX0ZJRUxELFxuICAgICAgQUNMOiBTQ0hFTUFfQUNMX0ZJRUxELFxuICAgIH1bdmFsdWUudHlwZV0pLFxufSk7XG5cbmNvbnN0IFNDSEVNQV9TVFJJTkdfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFTdHJpbmdGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFTdHJpbmdGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgc3RyaW5nIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfU1RSSU5HX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYVN0cmluZ0ZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFTdHJpbmdGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFN0cmluZyBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFOdW1iZXJGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFOdW1iZXJGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgbnVtYmVyIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfTlVNQkVSX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYU51bWJlckZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFOdW1iZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIE51bWJlciBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUJvb2xlYW5GaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgYm9vbGVhbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JPT0xFQU5fRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFCb29sZWFuRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBCb29sZWFuIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0FSUkFZX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQXJyYXlGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFBcnJheUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBhcnJheSBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0FSUkFZX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUFycmF5RmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUFycmF5RmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gQXJyYXkgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfT0JKRUNUX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hT2JqZWN0RmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hT2JqZWN0RmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIG9iamVjdCBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX09CSkVDVF9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFPYmplY3RGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hT2JqZWN0RmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gT2JqZWN0IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0RBVEVfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRGF0ZUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBkYXRlIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfREFURV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYURhdGVGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIERhdGUgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUZpbGVGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFGaWxlRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIGZpbGUgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9GSUxFX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUZpbGVGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRmlsZUZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgRmlsZSBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9HRU9fUE9JTlRfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFHZW9Qb2ludEZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUdlb1BvaW50RmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIGdlbyBwb2ludCBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0dFT19QT0lOVF9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFHZW9Qb2ludEZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFHZW9Qb2ludEZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgR2VvIFBvaW50IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hUG9seWdvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBwb2x5Z29uIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfUE9MWUdPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYVBvbHlnb25GaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFBvbHlnb24gZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfQllURVNfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFCeXRlc0ZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUJ5dGVzRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIGJ5dGVzIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfQllURVNfRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQnl0ZXNGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hQnl0ZXNGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIEJ5dGVzIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgVEFSR0VUX0NMQVNTX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgY2xhc3MgZm9yIHRoZSBmaWVsZC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBTQ0hFTUFfUE9JTlRFUl9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1BvaW50ZXJGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBQb2ludGVyRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIHBvaW50ZXIgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICAgIHRhcmdldENsYXNzTmFtZTogVEFSR0VUX0NMQVNTX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfUE9JTlRFUl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2ludGVyRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYVBvaW50ZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFBvaW50ZXIgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgICB0YXJnZXRDbGFzc05hbWU6IFRBUkdFVF9DTEFTU19BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUmVsYXRpb25GaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBSZWxhdGlvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSByZWxhdGlvbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9SRUxBVElPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFSZWxhdGlvbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFSZWxhdGlvbkZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgUmVsYXRpb24gZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgICB0YXJnZXRDbGFzc05hbWU6IFRBUkdFVF9DTEFTU19BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0FDTF9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFBQ0xGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hQUNMRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gQUNMIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0ZJRUxEU19JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUZpZWxkc0lucHV0JyxcbiAgZGVzY3JpcHRpb246IGBUaGUgQ3JlYXRlQ2xhc3NTY2hlbWFJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgc2NoZW1hIGZvciBhIG5ldyBvYmplY3QgY2xhc3MgdG8gYmUgY3JlYXRlZC5gLFxuICBmaWVsZHM6IHtcbiAgICBhZGRTdHJpbmdzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgU3RyaW5nIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9TVFJJTkdfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZE51bWJlcnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBOdW1iZXIgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkQm9vbGVhbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBCb29sZWFuIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRBcnJheXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBBcnJheSBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfQVJSQVlfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZE9iamVjdHM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBPYmplY3QgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX09CSkVDVF9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkRGF0ZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBEYXRlIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9EQVRFX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRGaWxlczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEZpbGUgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0ZJTEVfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZEdlb1BvaW50OiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIEdlbyBQb2ludCBmaWVsZCB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLiBDdXJyZW50bHkgaXQgaXMgc3VwcG9ydGVkIG9ubHkgb25lIEdlb1BvaW50IGZpZWxkIHBlciBDbGFzcy4nLFxuICAgICAgdHlwZTogU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCxcbiAgICB9LFxuICAgIGFkZFBvbHlnb25zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgUG9seWdvbiBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfUE9MWUdPTl9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkQnl0ZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBCeXRlcyBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfQllURVNfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZFBvaW50ZXJzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgUG9pbnRlciBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfUE9JTlRFUl9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkUmVsYXRpb25zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgUmVsYXRpb24gZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICByZW1vdmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBDTEFTU19OQU1FX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBvYmplY3QgY2xhc3MuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxTdHJpbmcpLFxufTtcblxuY29uc3QgQ0xBU1MgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnQ2xhc3MnLFxuICBkZXNjcmlwdGlvbjogYFRoZSBDbGFzcyB0eXBlIGlzIHVzZWQgdG8gcmV0dXJuIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhbiBvYmplY3QgY2xhc3MuYCxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogQ0xBU1NfTkFNRV9BVFQsXG4gICAgc2NoZW1hRmllbGRzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJUaGVzZSBhcmUgdGhlIHNjaGVtYSdzIGZpZWxkcyBvZiB0aGUgb2JqZWN0IGNsYXNzLlwiLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9GSUVMRCkpXG4gICAgICApLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfU1RSSU5HX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX05VTUJFUl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQk9PTEVBTl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQVJSQVlfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0FSUkFZX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX09CSkVDVF9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfREFURV9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklMRV9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9HRU9fUE9JTlRfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1BPTFlHT05fRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9CWVRFU19GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9JTlRFUl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9JTlRFUl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUkVMQVRJT05fRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1JFTEFUSU9OX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9BQ0xfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0ZJRUxEU19JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShDTEFTUywgdHJ1ZSk7XG59O1xuXG5leHBvcnQge1xuICBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIFNDSEVNQV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX1NUUklOR19GSUVMRCxcbiAgU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX05VTUJFUl9GSUVMRCxcbiAgU0NIRU1BX0JPT0xFQU5fRklFTERfSU5QVVQsXG4gIFNDSEVNQV9CT09MRUFOX0ZJRUxELFxuICBTQ0hFTUFfQVJSQVlfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9BUlJBWV9GSUVMRCxcbiAgU0NIRU1BX09CSkVDVF9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX09CSkVDVF9GSUVMRCxcbiAgU0NIRU1BX0RBVEVfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9EQVRFX0ZJRUxELFxuICBTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0ZJTEVfRklFTEQsXG4gIFNDSEVNQV9HRU9fUE9JTlRfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9HRU9fUE9JTlRfRklFTEQsXG4gIFNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfUE9MWUdPTl9GSUVMRCxcbiAgU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfQllURVNfRklFTEQsXG4gIFRBUkdFVF9DTEFTU19BVFQsXG4gIFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfUE9JTlRFUl9GSUVMRCxcbiAgU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfUkVMQVRJT05fRklFTEQsXG4gIFNDSEVNQV9BQ0xfRklFTEQsXG4gIFNDSEVNQV9GSUVMRFNfSU5QVVQsXG4gIENMQVNTX05BTUVfQVRULFxuICBDTEFTUyxcbiAgbG9hZCxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersMutations.js b/lib/GraphQL/loaders/usersMutations.js new file mode 100644 index 0000000000..b20234d4a5 --- /dev/null +++ b/lib/GraphQL/loaders/usersMutations.js @@ -0,0 +1,333 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _UsersRouter = _interopRequireDefault(require("../../Routers/UsersRouter")); + +var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); + +var _defaultGraphQLTypes = require("./defaultGraphQLTypes"); + +var _usersQueries = require("./usersQueries"); + +var _mutation = require("../transformers/mutation"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const usersRouter = new _UsersRouter.default(); + +const load = parseGraphQLSchema => { + if (parseGraphQLSchema.isUsersClassDisabled) { + return; + } + + const signUpMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'SignUp', + description: 'The signUp mutation can be used to create and sign up a new user.', + inputFields: { + fields: { + descriptions: 'These are the fields of the new user to be created and signed up.', + type: parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType + } + }, + outputFields: { + viewer: { + description: 'This is the new user that was created, signed up and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + const { + fields + } = args; + const { + config, + auth, + info + } = context; + const parseFields = await (0, _mutation.transformTypes)('create', fields, { + className: '_User', + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const { + sessionToken, + objectId + } = await objectsMutations.createObject('_User', parseFields, config, auth, info); + context.info.sessionToken = sessionToken; + return { + viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(signUpMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true); + const logInWithMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'LogInWith', + description: 'The logInWith mutation can be used to signup, login user with 3rd party authentication system. This mutation create a user if the authData do not correspond to an existing one.', + inputFields: { + authData: { + descriptions: 'This is the auth data of your custom auth provider', + type: new _graphql.GraphQLNonNull(_defaultGraphQLTypes.OBJECT) + }, + fields: { + descriptions: 'These are the fields of the user to be created/updated and logged in.', + type: new _graphql.GraphQLInputObjectType({ + name: 'UserLoginWithInput', + fields: () => { + const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType.getFields(); + return Object.keys(classGraphQLCreateFields).reduce((fields, fieldName) => { + if (fieldName !== 'password' && fieldName !== 'username' && fieldName !== 'authData') { + fields[fieldName] = classGraphQLCreateFields[fieldName]; + } + + return fields; + }, {}); + } + }) + } + }, + outputFields: { + viewer: { + description: 'This is the new user that was created, signed up and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + const { + fields, + authData + } = args; + const { + config, + auth, + info + } = context; + const parseFields = await (0, _mutation.transformTypes)('create', fields, { + className: '_User', + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const { + sessionToken, + objectId + } = await objectsMutations.createObject('_User', _objectSpread(_objectSpread({}, parseFields), {}, { + authData + }), config, auth, info); + context.info.sessionToken = sessionToken; + return { + viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(logInWithMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(logInWithMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('logInWith', logInWithMutation, true, true); + const logInMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'LogIn', + description: 'The logIn mutation can be used to log in an existing user.', + inputFields: { + username: { + description: 'This is the username used to log in the user.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + password: { + description: 'This is the password used to log in the user.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + }, + outputFields: { + viewer: { + description: 'This is the existing user that was logged in and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + const { + username, + password + } = args; + const { + config, + auth, + info + } = context; + const { + sessionToken, + objectId + } = (await usersRouter.handleLogIn({ + body: { + username, + password + }, + query: {}, + config, + auth, + info + })).response; + context.info.sessionToken = sessionToken; + return { + viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(logInMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(logInMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('logIn', logInMutation, true, true); + const logOutMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'LogOut', + description: 'The logOut mutation can be used to log out an existing user.', + outputFields: { + viewer: { + description: 'This is the existing user that was logged out and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (_args, context, mutationInfo) => { + try { + const { + config, + auth, + info + } = context; + const viewer = await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', auth.user.id); + await usersRouter.handleLogOut({ + config, + auth, + info + }); + return { + viewer + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(logOutMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(logOutMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('logOut', logOutMutation, true, true); + const resetPasswordMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'ResetPassword', + description: 'The resetPassword mutation can be used to reset the password of an existing user.', + inputFields: { + email: { + descriptions: 'Email of the user that should receive the reset email', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + }, + outputFields: { + ok: { + description: "It's always true.", + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + }, + mutateAndGetPayload: async ({ + email + }, context) => { + const { + config, + auth, + info + } = context; + await usersRouter.handleResetRequest({ + body: { + email + }, + config, + auth, + info + }); + return { + ok: true + }; + } + }); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); + const sendVerificationEmailMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'SendVerificationEmail', + description: 'The sendVerificationEmail mutation can be used to send the verification email again.', + inputFields: { + email: { + descriptions: 'Email of the user that should receive the verification email', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + }, + outputFields: { + ok: { + description: "It's always true.", + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + }, + mutateAndGetPayload: async ({ + email + }, context) => { + try { + const { + config, + auth, + info + } = context; + await usersRouter.handleVerificationEmailRequest({ + body: { + email + }, + config, + auth, + info + }); + return { + ok: true + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('sendVerificationEmail', sendVerificationEmailMutation, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsidXNlcnNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNpZ25VcE11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJmaWVsZHMiLCJkZXNjcmlwdGlvbnMiLCJ0eXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsIm91dHB1dEZpZWxkcyIsInZpZXdlciIsIkdyYXBoUUxOb25OdWxsIiwidmlld2VyVHlwZSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJjbGFzc05hbWUiLCJyZXEiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3RJZCIsIm9iamVjdHNNdXRhdGlvbnMiLCJjcmVhdGVPYmplY3QiLCJlIiwiaGFuZGxlRXJyb3IiLCJhZGRHcmFwaFFMVHlwZSIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIiwibG9nSW5XaXRoTXV0YXRpb24iLCJhdXRoRGF0YSIsIk9CSkVDVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJjbGFzc0dyYXBoUUxDcmVhdGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiZmllbGROYW1lIiwibG9nSW5NdXRhdGlvbiIsInVzZXJuYW1lIiwiR3JhcGhRTFN0cmluZyIsInBhc3N3b3JkIiwiaGFuZGxlTG9nSW4iLCJib2R5IiwicXVlcnkiLCJyZXNwb25zZSIsImxvZ091dE11dGF0aW9uIiwiX2FyZ3MiLCJ1c2VyIiwiaWQiLCJoYW5kbGVMb2dPdXQiLCJyZXNldFBhc3N3b3JkTXV0YXRpb24iLCJlbWFpbCIsIm9rIiwiR3JhcGhRTEJvb2xlYW4iLCJoYW5kbGVSZXNldFJlcXVlc3QiLCJzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbiIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQU1BOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLFdBQVcsR0FBRyxJQUFJQyxvQkFBSixFQUFwQjs7QUFFQSxNQUFNQyxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLE1BQUlBLGtCQUFrQixDQUFDQyxvQkFBdkIsRUFBNkM7QUFDM0M7QUFDRDs7QUFFRCxRQUFNQyxjQUFjLEdBQUcsZ0RBQTZCO0FBQ2xEQyxJQUFBQSxJQUFJLEVBQUUsUUFENEM7QUFFbERDLElBQUFBLFdBQVcsRUFDVCxtRUFIZ0Q7QUFJbERDLElBQUFBLFdBQVcsRUFBRTtBQUNYQyxNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUNWLG1FQUZJO0FBR05DLFFBQUFBLElBQUksRUFDRlIsa0JBQWtCLENBQUNTLGVBQW5CLENBQW1DLE9BQW5DLEVBQTRDQztBQUp4QztBQURHLEtBSnFDO0FBWWxEQyxJQUFBQSxZQUFZLEVBQUU7QUFDWkMsTUFBQUEsTUFBTSxFQUFFO0FBQ05SLFFBQUFBLFdBQVcsRUFDVCw0RUFGSTtBQUdOSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJiLGtCQUFrQixDQUFDYyxVQUF0QztBQUhBO0FBREksS0Fab0M7QUFtQmxEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsRUFBc0JDLFlBQXRCLEtBQXVDO0FBQzFELFVBQUk7QUFDRixjQUFNO0FBQUVaLFVBQUFBO0FBQUYsWUFBYVUsSUFBbkI7QUFDQSxjQUFNO0FBQUVHLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUEsSUFBVjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBeUJKLE9BQS9CO0FBRUEsY0FBTUssV0FBVyxHQUFHLE1BQU0sOEJBQWUsUUFBZixFQUF5QmhCLE1BQXpCLEVBQWlDO0FBQ3pEaUIsVUFBQUEsU0FBUyxFQUFFLE9BRDhDO0FBRXpEdkIsVUFBQUEsa0JBRnlEO0FBR3pEd0IsVUFBQUEsR0FBRyxFQUFFO0FBQUVMLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEI7QUFIb0QsU0FBakMsQ0FBMUI7QUFNQSxjQUFNO0FBQUVJLFVBQUFBLFlBQUY7QUFBZ0JDLFVBQUFBO0FBQWhCLFlBQTZCLE1BQU1DLGdCQUFnQixDQUFDQyxZQUFqQixDQUN2QyxPQUR1QyxFQUV2Q04sV0FGdUMsRUFHdkNILE1BSHVDLEVBSXZDQyxJQUp1QyxFQUt2Q0MsSUFMdUMsQ0FBekM7QUFRQUosUUFBQUEsT0FBTyxDQUFDSSxJQUFSLENBQWFJLFlBQWIsR0FBNEJBLFlBQTVCO0FBRUEsZUFBTztBQUNMYixVQUFBQSxNQUFNLEVBQUUsTUFBTSwyQ0FDWkssT0FEWSxFQUVaQyxZQUZZLEVBR1osY0FIWSxFQUlaUSxRQUpZO0FBRFQsU0FBUDtBQVFELE9BNUJELENBNEJFLE9BQU9HLENBQVAsRUFBVTtBQUNWN0IsUUFBQUEsa0JBQWtCLENBQUM4QixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBbkRpRCxHQUE3QixDQUF2QjtBQXNEQTdCLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FDRTdCLGNBQWMsQ0FBQ2MsSUFBZixDQUFvQmdCLEtBQXBCLENBQTBCeEIsSUFBMUIsQ0FBK0J5QixNQURqQyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDN0IsY0FBYyxDQUFDTSxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxRQUF0QyxFQUFnRGhDLGNBQWhELEVBQWdFLElBQWhFLEVBQXNFLElBQXRFO0FBQ0EsUUFBTWlDLGlCQUFpQixHQUFHLGdEQUE2QjtBQUNyRGhDLElBQUFBLElBQUksRUFBRSxXQUQrQztBQUVyREMsSUFBQUEsV0FBVyxFQUNULGtMQUhtRDtBQUlyREMsSUFBQUEsV0FBVyxFQUFFO0FBQ1grQixNQUFBQSxRQUFRLEVBQUU7QUFDUjdCLFFBQUFBLFlBQVksRUFBRSxvREFETjtBQUVSQyxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJ3QiwyQkFBbkI7QUFGRSxPQURDO0FBS1gvQixNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUNWLHVFQUZJO0FBR05DLFFBQUFBLElBQUksRUFBRSxJQUFJOEIsK0JBQUosQ0FBMkI7QUFDL0JuQyxVQUFBQSxJQUFJLEVBQUUsb0JBRHlCO0FBRS9CRyxVQUFBQSxNQUFNLEVBQUUsTUFBTTtBQUNaLGtCQUFNaUMsd0JBQXdCLEdBQUd2QyxrQkFBa0IsQ0FBQ1MsZUFBbkIsQ0FDL0IsT0FEK0IsRUFFL0JDLHNCQUYrQixDQUVSOEIsU0FGUSxFQUFqQztBQUdBLG1CQUFPQyxNQUFNLENBQUNDLElBQVAsQ0FBWUgsd0JBQVosRUFBc0NJLE1BQXRDLENBQ0wsQ0FBQ3JDLE1BQUQsRUFBU3NDLFNBQVQsS0FBdUI7QUFDckIsa0JBQ0VBLFNBQVMsS0FBSyxVQUFkLElBQ0FBLFNBQVMsS0FBSyxVQURkLElBRUFBLFNBQVMsS0FBSyxVQUhoQixFQUlFO0FBQ0F0QyxnQkFBQUEsTUFBTSxDQUFDc0MsU0FBRCxDQUFOLEdBQW9CTCx3QkFBd0IsQ0FBQ0ssU0FBRCxDQUE1QztBQUNEOztBQUNELHFCQUFPdEMsTUFBUDtBQUNELGFBVkksRUFXTCxFQVhLLENBQVA7QUFhRDtBQW5COEIsU0FBM0I7QUFIQTtBQUxHLEtBSndDO0FBbUNyREssSUFBQUEsWUFBWSxFQUFFO0FBQ1pDLE1BQUFBLE1BQU0sRUFBRTtBQUNOUixRQUFBQSxXQUFXLEVBQ1QsNEVBRkk7QUFHTkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1CYixrQkFBa0IsQ0FBQ2MsVUFBdEM7QUFIQTtBQURJLEtBbkN1QztBQTBDckRDLElBQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsVUFBSTtBQUNGLGNBQU07QUFBRVosVUFBQUEsTUFBRjtBQUFVOEIsVUFBQUE7QUFBVixZQUF1QnBCLElBQTdCO0FBQ0EsY0FBTTtBQUFFRyxVQUFBQSxNQUFGO0FBQVVDLFVBQUFBLElBQVY7QUFBZ0JDLFVBQUFBO0FBQWhCLFlBQXlCSixPQUEvQjtBQUVBLGNBQU1LLFdBQVcsR0FBRyxNQUFNLDhCQUFlLFFBQWYsRUFBeUJoQixNQUF6QixFQUFpQztBQUN6RGlCLFVBQUFBLFNBQVMsRUFBRSxPQUQ4QztBQUV6RHZCLFVBQUFBLGtCQUZ5RDtBQUd6RHdCLFVBQUFBLEdBQUcsRUFBRTtBQUFFTCxZQUFBQSxNQUFGO0FBQVVDLFlBQUFBLElBQVY7QUFBZ0JDLFlBQUFBO0FBQWhCO0FBSG9ELFNBQWpDLENBQTFCO0FBTUEsY0FBTTtBQUFFSSxVQUFBQSxZQUFGO0FBQWdCQyxVQUFBQTtBQUFoQixZQUE2QixNQUFNQyxnQkFBZ0IsQ0FBQ0MsWUFBakIsQ0FDdkMsT0FEdUMsa0NBRWxDTixXQUZrQztBQUVyQmMsVUFBQUE7QUFGcUIsWUFHdkNqQixNQUh1QyxFQUl2Q0MsSUFKdUMsRUFLdkNDLElBTHVDLENBQXpDO0FBUUFKLFFBQUFBLE9BQU8sQ0FBQ0ksSUFBUixDQUFhSSxZQUFiLEdBQTRCQSxZQUE1QjtBQUVBLGVBQU87QUFDTGIsVUFBQUEsTUFBTSxFQUFFLE1BQU0sMkNBQ1pLLE9BRFksRUFFWkMsWUFGWSxFQUdaLGNBSFksRUFJWlEsUUFKWTtBQURULFNBQVA7QUFRRCxPQTVCRCxDQTRCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQTFFb0QsR0FBN0IsQ0FBMUI7QUE2RUE3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VJLGlCQUFpQixDQUFDbkIsSUFBbEIsQ0FBdUJnQixLQUF2QixDQUE2QnhCLElBQTdCLENBQWtDeUIsTUFEcEMsRUFFRSxJQUZGLEVBR0UsSUFIRjtBQUtBakMsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQ0ksaUJBQWlCLENBQUMzQixJQUFwRCxFQUEwRCxJQUExRCxFQUFnRSxJQUFoRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUNFLFdBREYsRUFFRUMsaUJBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU9BLFFBQU1VLGFBQWEsR0FBRyxnREFBNkI7QUFDakQxQyxJQUFBQSxJQUFJLEVBQUUsT0FEMkM7QUFFakRDLElBQUFBLFdBQVcsRUFBRSw0REFGb0M7QUFHakRDLElBQUFBLFdBQVcsRUFBRTtBQUNYeUMsTUFBQUEsUUFBUSxFQUFFO0FBQ1IxQyxRQUFBQSxXQUFXLEVBQUUsK0NBREw7QUFFUkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1Ca0Msc0JBQW5CO0FBRkUsT0FEQztBQUtYQyxNQUFBQSxRQUFRLEVBQUU7QUFDUjVDLFFBQUFBLFdBQVcsRUFBRSwrQ0FETDtBQUVSSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJrQyxzQkFBbkI7QUFGRTtBQUxDLEtBSG9DO0FBYWpEcEMsSUFBQUEsWUFBWSxFQUFFO0FBQ1pDLE1BQUFBLE1BQU0sRUFBRTtBQUNOUixRQUFBQSxXQUFXLEVBQ1Qsd0VBRkk7QUFHTkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1CYixrQkFBa0IsQ0FBQ2MsVUFBdEM7QUFIQTtBQURJLEtBYm1DO0FBb0JqREMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBT0MsSUFBUCxFQUFhQyxPQUFiLEVBQXNCQyxZQUF0QixLQUF1QztBQUMxRCxVQUFJO0FBQ0YsY0FBTTtBQUFFNEIsVUFBQUEsUUFBRjtBQUFZRSxVQUFBQTtBQUFaLFlBQXlCaEMsSUFBL0I7QUFDQSxjQUFNO0FBQUVHLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUEsSUFBVjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBeUJKLE9BQS9CO0FBRUEsY0FBTTtBQUFFUSxVQUFBQSxZQUFGO0FBQWdCQyxVQUFBQTtBQUFoQixZQUE2QixDQUNqQyxNQUFNN0IsV0FBVyxDQUFDb0QsV0FBWixDQUF3QjtBQUM1QkMsVUFBQUEsSUFBSSxFQUFFO0FBQ0pKLFlBQUFBLFFBREk7QUFFSkUsWUFBQUE7QUFGSSxXQURzQjtBQUs1QkcsVUFBQUEsS0FBSyxFQUFFLEVBTHFCO0FBTTVCaEMsVUFBQUEsTUFONEI7QUFPNUJDLFVBQUFBLElBUDRCO0FBUTVCQyxVQUFBQTtBQVI0QixTQUF4QixDQUQyQixFQVdqQytCLFFBWEY7QUFhQW5DLFFBQUFBLE9BQU8sQ0FBQ0ksSUFBUixDQUFhSSxZQUFiLEdBQTRCQSxZQUE1QjtBQUVBLGVBQU87QUFDTGIsVUFBQUEsTUFBTSxFQUFFLE1BQU0sMkNBQ1pLLE9BRFksRUFFWkMsWUFGWSxFQUdaLGNBSFksRUFJWlEsUUFKWTtBQURULFNBQVA7QUFRRCxPQTNCRCxDQTJCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQW5EZ0QsR0FBN0IsQ0FBdEI7QUFzREE3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VjLGFBQWEsQ0FBQzdCLElBQWQsQ0FBbUJnQixLQUFuQixDQUF5QnhCLElBQXpCLENBQThCeUIsTUFEaEMsRUFFRSxJQUZGLEVBR0UsSUFIRjtBQUtBakMsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQ2MsYUFBYSxDQUFDckMsSUFBaEQsRUFBc0QsSUFBdEQsRUFBNEQsSUFBNUQ7QUFDQVIsRUFBQUEsa0JBQWtCLENBQUNrQyxrQkFBbkIsQ0FBc0MsT0FBdEMsRUFBK0NXLGFBQS9DLEVBQThELElBQTlELEVBQW9FLElBQXBFO0FBRUEsUUFBTVEsY0FBYyxHQUFHLGdEQUE2QjtBQUNsRGxELElBQUFBLElBQUksRUFBRSxRQUQ0QztBQUVsREMsSUFBQUEsV0FBVyxFQUFFLDhEQUZxQztBQUdsRE8sSUFBQUEsWUFBWSxFQUFFO0FBQ1pDLE1BQUFBLE1BQU0sRUFBRTtBQUNOUixRQUFBQSxXQUFXLEVBQ1QseUVBRkk7QUFHTkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1CYixrQkFBa0IsQ0FBQ2MsVUFBdEM7QUFIQTtBQURJLEtBSG9DO0FBVWxEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPdUMsS0FBUCxFQUFjckMsT0FBZCxFQUF1QkMsWUFBdkIsS0FBd0M7QUFDM0QsVUFBSTtBQUNGLGNBQU07QUFBRUMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNTCxNQUFNLEdBQUcsTUFBTSwyQ0FDbkJLLE9BRG1CLEVBRW5CQyxZQUZtQixFQUduQixjQUhtQixFQUluQkUsSUFBSSxDQUFDbUMsSUFBTCxDQUFVQyxFQUpTLENBQXJCO0FBT0EsY0FBTTNELFdBQVcsQ0FBQzRELFlBQVosQ0FBeUI7QUFDN0J0QyxVQUFBQSxNQUQ2QjtBQUU3QkMsVUFBQUEsSUFGNkI7QUFHN0JDLFVBQUFBO0FBSDZCLFNBQXpCLENBQU47QUFNQSxlQUFPO0FBQUVULFVBQUFBO0FBQUYsU0FBUDtBQUNELE9BakJELENBaUJFLE9BQU9pQixDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQS9CaUQsR0FBN0IsQ0FBdkI7QUFrQ0E3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VzQixjQUFjLENBQUNyQyxJQUFmLENBQW9CZ0IsS0FBcEIsQ0FBMEJ4QixJQUExQixDQUErQnlCLE1BRGpDLEVBRUUsSUFGRixFQUdFLElBSEY7QUFLQWpDLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FBa0NzQixjQUFjLENBQUM3QyxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxRQUF0QyxFQUFnRG1CLGNBQWhELEVBQWdFLElBQWhFLEVBQXNFLElBQXRFO0FBRUEsUUFBTUsscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pEdkQsSUFBQUEsSUFBSSxFQUFFLGVBRG1EO0FBRXpEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHVEO0FBSXpEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWHNELE1BQUFBLEtBQUssRUFBRTtBQUNMcEQsUUFBQUEsWUFBWSxFQUFFLHVEQURUO0FBRUxDLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmtDLHNCQUFuQjtBQUZEO0FBREksS0FKNEM7QUFVekRwQyxJQUFBQSxZQUFZLEVBQUU7QUFDWmlELE1BQUFBLEVBQUUsRUFBRTtBQUNGeEQsUUFBQUEsV0FBVyxFQUFFLG1CQURYO0FBRUZJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmdELHVCQUFuQjtBQUZKO0FBRFEsS0FWMkM7QUFnQnpEOUMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBTztBQUFFNEMsTUFBQUE7QUFBRixLQUFQLEVBQWtCMUMsT0FBbEIsS0FBOEI7QUFDakQsWUFBTTtBQUFFRSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCSixPQUEvQjtBQUVBLFlBQU1wQixXQUFXLENBQUNpRSxrQkFBWixDQUErQjtBQUNuQ1osUUFBQUEsSUFBSSxFQUFFO0FBQ0pTLFVBQUFBO0FBREksU0FENkI7QUFJbkN4QyxRQUFBQSxNQUptQztBQUtuQ0MsUUFBQUEsSUFMbUM7QUFNbkNDLFFBQUFBO0FBTm1DLE9BQS9CLENBQU47QUFTQSxhQUFPO0FBQUV1QyxRQUFBQSxFQUFFLEVBQUU7QUFBTixPQUFQO0FBQ0Q7QUE3QndELEdBQTdCLENBQTlCO0FBZ0NBNUQsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUNFMkIscUJBQXFCLENBQUMxQyxJQUF0QixDQUEyQmdCLEtBQTNCLENBQWlDeEIsSUFBakMsQ0FBc0N5QixNQUR4QyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDMkIscUJBQXFCLENBQUNsRCxJQUF4RCxFQUE4RCxJQUE5RCxFQUFvRSxJQUFwRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUNFLGVBREYsRUFFRXdCLHFCQUZGLEVBR0UsSUFIRixFQUlFLElBSkY7QUFPQSxRQUFNSyw2QkFBNkIsR0FBRyxnREFBNkI7QUFDakU1RCxJQUFBQSxJQUFJLEVBQUUsdUJBRDJEO0FBRWpFQyxJQUFBQSxXQUFXLEVBQ1Qsc0ZBSCtEO0FBSWpFQyxJQUFBQSxXQUFXLEVBQUU7QUFDWHNELE1BQUFBLEtBQUssRUFBRTtBQUNMcEQsUUFBQUEsWUFBWSxFQUNWLDhEQUZHO0FBR0xDLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmtDLHNCQUFuQjtBQUhEO0FBREksS0FKb0Q7QUFXakVwQyxJQUFBQSxZQUFZLEVBQUU7QUFDWmlELE1BQUFBLEVBQUUsRUFBRTtBQUNGeEQsUUFBQUEsV0FBVyxFQUFFLG1CQURYO0FBRUZJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmdELHVCQUFuQjtBQUZKO0FBRFEsS0FYbUQ7QUFpQmpFOUMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBTztBQUFFNEMsTUFBQUE7QUFBRixLQUFQLEVBQWtCMUMsT0FBbEIsS0FBOEI7QUFDakQsVUFBSTtBQUNGLGNBQU07QUFBRUUsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNcEIsV0FBVyxDQUFDbUUsOEJBQVosQ0FBMkM7QUFDL0NkLFVBQUFBLElBQUksRUFBRTtBQUNKUyxZQUFBQTtBQURJLFdBRHlDO0FBSS9DeEMsVUFBQUEsTUFKK0M7QUFLL0NDLFVBQUFBLElBTCtDO0FBTS9DQyxVQUFBQTtBQU4rQyxTQUEzQyxDQUFOO0FBU0EsZUFBTztBQUFFdUMsVUFBQUEsRUFBRSxFQUFFO0FBQU4sU0FBUDtBQUNELE9BYkQsQ0FhRSxPQUFPL0IsQ0FBUCxFQUFVO0FBQ1Y3QixRQUFBQSxrQkFBa0IsQ0FBQzhCLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUFsQ2dFLEdBQTdCLENBQXRDO0FBcUNBN0IsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUNFZ0MsNkJBQTZCLENBQUMvQyxJQUE5QixDQUFtQ2dCLEtBQW5DLENBQXlDeEIsSUFBekMsQ0FBOEN5QixNQURoRCxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VnQyw2QkFBNkIsQ0FBQ3ZELElBRGhDLEVBRUUsSUFGRixFQUdFLElBSEY7QUFLQVIsRUFBQUEsa0JBQWtCLENBQUNrQyxrQkFBbkIsQ0FDRSx1QkFERixFQUVFNkIsNkJBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU1ELENBdFdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxTdHJpbmcsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMSW5wdXRPYmplY3RUeXBlLFxufSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCBVc2Vyc1JvdXRlciBmcm9tICcuLi8uLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcbmltcG9ydCAqIGFzIG9iamVjdHNNdXRhdGlvbnMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzTXV0YXRpb25zJztcbmltcG9ydCB7IE9CSkVDVCB9IGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgeyBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbiB9IGZyb20gJy4vdXNlcnNRdWVyaWVzJztcbmltcG9ydCB7IHRyYW5zZm9ybVR5cGVzIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL211dGF0aW9uJztcblxuY29uc3QgdXNlcnNSb3V0ZXIgPSBuZXcgVXNlcnNSb3V0ZXIoKTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGlmIChwYXJzZUdyYXBoUUxTY2hlbWEuaXNVc2Vyc0NsYXNzRGlzYWJsZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBzaWduVXBNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdTaWduVXAnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBzaWduVXAgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGFuZCBzaWduIHVwIGEgbmV3IHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczpcbiAgICAgICAgICAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgb2YgdGhlIG5ldyB1c2VyIHRvIGJlIGNyZWF0ZWQgYW5kIHNpZ25lZCB1cC4nLFxuICAgICAgICB0eXBlOlxuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbJ19Vc2VyJ10uY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhpcyBpcyB0aGUgbmV3IHVzZXIgdGhhdCB3YXMgY3JlYXRlZCwgc2lnbmVkIHVwIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgeyBzZXNzaW9uVG9rZW4sIG9iamVjdElkIH0gPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm9cbiAgICAgICAgKTtcblxuICAgICAgICBjb250ZXh0LmluZm8uc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmlld2VyOiBhd2FpdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbihcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBtdXRhdGlvbkluZm8sXG4gICAgICAgICAgICAndmlld2VyLnVzZXIuJyxcbiAgICAgICAgICAgIG9iamVjdElkXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBzaWduVXBNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoc2lnblVwTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ3NpZ25VcCcsIHNpZ25VcE11dGF0aW9uLCB0cnVlLCB0cnVlKTtcbiAgY29uc3QgbG9nSW5XaXRoTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnTG9nSW5XaXRoJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgbG9nSW5XaXRoIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIHNpZ251cCwgbG9naW4gdXNlciB3aXRoIDNyZCBwYXJ0eSBhdXRoZW50aWNhdGlvbiBzeXN0ZW0uIFRoaXMgbXV0YXRpb24gY3JlYXRlIGEgdXNlciBpZiB0aGUgYXV0aERhdGEgZG8gbm90IGNvcnJlc3BvbmQgdG8gYW4gZXhpc3Rpbmcgb25lLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIGF1dGhEYXRhOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczogJ1RoaXMgaXMgdGhlIGF1dGggZGF0YSBvZiB5b3VyIGN1c3RvbSBhdXRoIHByb3ZpZGVyJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKE9CSkVDVCksXG4gICAgICB9LFxuICAgICAgZmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczpcbiAgICAgICAgICAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgb2YgdGhlIHVzZXIgdG8gYmUgY3JlYXRlZC91cGRhdGVkIGFuZCBsb2dnZWQgaW4uJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgICAgICAgIG5hbWU6ICdVc2VyTG9naW5XaXRoSW5wdXQnLFxuICAgICAgICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlRmllbGRzID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tcbiAgICAgICAgICAgICAgJ19Vc2VyJ1xuICAgICAgICAgICAgXS5jbGFzc0dyYXBoUUxDcmVhdGVUeXBlLmdldEZpZWxkcygpO1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNsYXNzR3JhcGhRTENyZWF0ZUZpZWxkcykucmVkdWNlKFxuICAgICAgICAgICAgICAoZmllbGRzLCBmaWVsZE5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICBmaWVsZE5hbWUgIT09ICdwYXNzd29yZCcgJiZcbiAgICAgICAgICAgICAgICAgIGZpZWxkTmFtZSAhPT0gJ3VzZXJuYW1lJyAmJlxuICAgICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAnYXV0aERhdGEnXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZHNbZmllbGROYW1lXSA9IGNsYXNzR3JhcGhRTENyZWF0ZUZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7fVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhpcyBpcyB0aGUgbmV3IHVzZXIgdGhhdCB3YXMgY3JlYXRlZCwgc2lnbmVkIHVwIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRzLCBhdXRoRGF0YSB9ID0gYXJncztcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgY29uc3QgcGFyc2VGaWVsZHMgPSBhd2FpdCB0cmFuc2Zvcm1UeXBlcygnY3JlYXRlJywgZmllbGRzLCB7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHsgc2Vzc2lvblRva2VuLCBvYmplY3RJZCB9ID0gYXdhaXQgb2JqZWN0c011dGF0aW9ucy5jcmVhdGVPYmplY3QoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7IC4uLnBhcnNlRmllbGRzLCBhdXRoRGF0YSB9LFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm9cbiAgICAgICAgKTtcblxuICAgICAgICBjb250ZXh0LmluZm8uc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmlld2VyOiBhd2FpdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbihcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBtdXRhdGlvbkluZm8sXG4gICAgICAgICAgICAndmlld2VyLnVzZXIuJyxcbiAgICAgICAgICAgIG9iamVjdElkXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBsb2dJbldpdGhNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nSW5XaXRoTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgJ2xvZ0luV2l0aCcsXG4gICAgbG9nSW5XaXRoTXV0YXRpb24sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG5cbiAgY29uc3QgbG9nSW5NdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdMb2dJbicsXG4gICAgZGVzY3JpcHRpb246ICdUaGUgbG9nSW4gbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gbG9nIGluIGFuIGV4aXN0aW5nIHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgdXNlcm5hbWU6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1c2VybmFtZSB1c2VkIHRvIGxvZyBpbiB0aGUgdXNlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgICAgcGFzc3dvcmQ6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBwYXNzd29yZCB1c2VkIHRvIGxvZyBpbiB0aGUgdXNlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICB2aWV3ZXI6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoaXMgaXMgdGhlIGV4aXN0aW5nIHVzZXIgdGhhdCB3YXMgbG9nZ2VkIGluIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCB7IHNlc3Npb25Ub2tlbiwgb2JqZWN0SWQgfSA9IChcbiAgICAgICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVMb2dJbih7XG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBxdWVyeToge30sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICB9KVxuICAgICAgICApLnJlc3BvbnNlO1xuXG4gICAgICAgIGNvbnRleHQuaW5mby5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uVG9rZW47XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2aWV3ZXI6IGF3YWl0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuKFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIG11dGF0aW9uSW5mbyxcbiAgICAgICAgICAgICd2aWV3ZXIudXNlci4nLFxuICAgICAgICAgICAgb2JqZWN0SWRcbiAgICAgICAgICApLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGxvZ0luTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGxvZ0luTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2xvZ0luJywgbG9nSW5NdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgY29uc3QgbG9nT3V0TXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnTG9nT3V0JyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBsb2dPdXQgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gbG9nIG91dCBhbiBleGlzdGluZyB1c2VyLicsXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICB2aWV3ZXI6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoaXMgaXMgdGhlIGV4aXN0aW5nIHVzZXIgdGhhdCB3YXMgbG9nZ2VkIG91dCBhbmQgcmV0dXJuZWQgYXMgYSB2aWV3ZXIuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHBhcnNlR3JhcGhRTFNjaGVtYS52aWV3ZXJUeXBlKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoX2FyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgY29uc3Qgdmlld2VyID0gYXdhaXQgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4oXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBtdXRhdGlvbkluZm8sXG4gICAgICAgICAgJ3ZpZXdlci51c2VyLicsXG4gICAgICAgICAgYXV0aC51c2VyLmlkXG4gICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgdXNlcnNSb3V0ZXIuaGFuZGxlTG9nT3V0KHtcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyB2aWV3ZXIgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBsb2dPdXRNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nT3V0TXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2xvZ091dCcsIGxvZ091dE11dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCByZXNldFBhc3N3b3JkTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnUmVzZXRQYXNzd29yZCcsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhlIHJlc2V0UGFzc3dvcmQgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gcmVzZXQgdGhlIHBhc3N3b3JkIG9mIGFuIGV4aXN0aW5nIHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZW1haWw6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOiAnRW1haWwgb2YgdGhlIHVzZXIgdGhhdCBzaG91bGQgcmVjZWl2ZSB0aGUgcmVzZXQgZW1haWwnLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBvazoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJdCdzIGFsd2F5cyB0cnVlLlwiLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jICh7IGVtYWlsIH0sIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVSZXNldFJlcXVlc3Qoe1xuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgZW1haWwsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgaW5mbyxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICByZXNldFBhc3N3b3JkTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHJlc2V0UGFzc3dvcmRNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAncmVzZXRQYXNzd29yZCcsXG4gICAgcmVzZXRQYXNzd29yZE11dGF0aW9uLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIGNvbnN0IHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ1NlbmRWZXJpZmljYXRpb25FbWFpbCcsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhlIHNlbmRWZXJpZmljYXRpb25FbWFpbCBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBzZW5kIHRoZSB2ZXJpZmljYXRpb24gZW1haWwgYWdhaW4uJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZW1haWw6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOlxuICAgICAgICAgICdFbWFpbCBvZiB0aGUgdXNlciB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSB2ZXJpZmljYXRpb24gZW1haWwnLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBvazoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJdCdzIGFsd2F5cyB0cnVlLlwiLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jICh7IGVtYWlsIH0sIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGF3YWl0IHVzZXJzUm91dGVyLmhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCh7XG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbi50eXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKFxuICAgICdzZW5kVmVyaWZpY2F0aW9uRW1haWwnLFxuICAgIHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersQueries.js b/lib/GraphQL/loaders/usersQueries.js new file mode 100644 index 0000000000..f12a5633f4 --- /dev/null +++ b/lib/GraphQL/loaders/usersQueries.js @@ -0,0 +1,111 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getUserFromSessionToken = exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _rest = _interopRequireDefault(require("../../rest")); + +var _parseClassTypes = require("./parseClassTypes"); + +var _Auth = require("../../Auth"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const getUserFromSessionToken = async (context, queryInfo, keysPrefix, userId) => { + const { + info, + config + } = context; + + if (!info || !info.sessionToken) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + const sessionToken = info.sessionToken; + const selectedFields = (0, _graphqlListFields.default)(queryInfo).filter(field => field.startsWith(keysPrefix)).map(field => field.replace(keysPrefix, '')); + const keysAndInclude = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); + const { + keys + } = keysAndInclude; + let { + include + } = keysAndInclude; + + if (userId && !keys && !include) { + return { + sessionToken + }; + } else if (keys && !include) { + include = 'user'; + } + + if (userId) { + // We need to re create the auth context + // to avoid security breach if userId is provided + context.auth = new _Auth.Auth({ + config, + isMaster: context.auth.isMaster, + user: { + id: userId + } + }); + } + + const options = {}; + + if (keys) { + options.keys = keys.split(',').map(key => `${key}`).join(','); + } + + if (include) { + options.include = include.split(',').map(included => `${included}`).join(','); + } + + const response = await _rest.default.find(config, context.auth, '_User', // Get the user it self from auth object + { + objectId: context.auth.user.id + }, options, info.clientVersion, info.context); + + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } else { + const user = response.results[0]; + return { + sessionToken, + user + }; + } +}; + +exports.getUserFromSessionToken = getUserFromSessionToken; + +const load = parseGraphQLSchema => { + if (parseGraphQLSchema.isUsersClassDisabled) { + return; + } + + parseGraphQLSchema.addGraphQLQuery('viewer', { + description: 'The viewer query can be used to return the current user data.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType), + + async resolve(_source, _args, context, queryInfo) { + try { + return await getUserFromSessionToken(context, queryInfo, 'user.', false); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + }, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImdldFVzZXJGcm9tU2Vzc2lvblRva2VuIiwiY29udGV4dCIsInF1ZXJ5SW5mbyIsImtleXNQcmVmaXgiLCJ1c2VySWQiLCJpbmZvIiwiY29uZmlnIiwic2Vzc2lvblRva2VuIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsInNlbGVjdGVkRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsImtleXNBbmRJbmNsdWRlIiwia2V5cyIsImluY2x1ZGUiLCJhdXRoIiwiQXV0aCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwib3B0aW9ucyIsInNwbGl0Iiwia2V5Iiwiam9pbiIsImluY2x1ZGVkIiwicmVzcG9uc2UiLCJyZXN0IiwiZmluZCIsIm9iamVjdElkIiwiY2xpZW50VmVyc2lvbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2FkIiwicGFyc2VHcmFwaFFMU2NoZW1hIiwiaXNVc2Vyc0NsYXNzRGlzYWJsZWQiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsInZpZXdlclR5cGUiLCJyZXNvbHZlIiwiX3NvdXJjZSIsIl9hcmdzIiwiZSIsImhhbmRsZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSx1QkFBdUIsR0FBRyxPQUM5QkMsT0FEOEIsRUFFOUJDLFNBRjhCLEVBRzlCQyxVQUg4QixFQUk5QkMsTUFKOEIsS0FLM0I7QUFDSCxRQUFNO0FBQUVDLElBQUFBLElBQUY7QUFBUUMsSUFBQUE7QUFBUixNQUFtQkwsT0FBekI7O0FBQ0EsTUFBSSxDQUFDSSxJQUFELElBQVMsQ0FBQ0EsSUFBSSxDQUFDRSxZQUFuQixFQUFpQztBQUMvQixVQUFNLElB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QUFuQixDQUNFLFFBREYsRUFFRTtBQUNFQyxJQUFBQSxXQUFXLEVBQ1QsK0RBRko7QUFHRUMsSUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CTCxrQkFBa0IsQ0FBQ00sVUFBdEMsQ0FIUjs7QUFJRSxVQUFNQyxPQUFOLENBQWNDLE9BQWQsRUFBdUJDLEtBQXZCLEVBQThCOUMsT0FBOUIsRUFBdUNDLFNBQXZDLEVBQWtEO0FBQ2hELFVBQUk7QUFDRixlQUFPLE1BQU1GLHVCQUF1QixDQUNsQ0MsT0FEa0MsRUFFbENDLFNBRmtDLEVBR2xDLE9BSGtDLEVBSWxDLEtBSmtDLENBQXBDO0FBTUQsT0FQRCxDQU9FLE9BQU84QyxDQUFQLEVBQVU7QUFDVlYsUUFBQUEsa0JBQWtCLENBQUNXLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7O0FBZkgsR0FGRixFQW1CRSxJQW5CRixFQW9CRSxJQXBCRjtBQXNCRCxDQTNCRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEdyYXBoUUxOb25OdWxsIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuaW1wb3J0IHsgZXh0cmFjdEtleXNBbmRJbmNsdWRlIH0gZnJvbSAnLi9wYXJzZUNsYXNzVHlwZXMnO1xuaW1wb3J0IHsgQXV0aCB9IGZyb20gJy4uLy4uL0F1dGgnO1xuXG5jb25zdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbiA9IGFzeW5jIChcbiAgY29udGV4dCxcbiAgcXVlcnlJbmZvLFxuICBrZXlzUHJlZml4LFxuICB1c2VySWRcbikgPT4ge1xuICBjb25zdCB7IGluZm8sIGNvbmZpZyB9ID0gY29udGV4dDtcbiAgaWYgKCFpbmZvIHx8ICFpbmZvLnNlc3Npb25Ub2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTixcbiAgICAgICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nXG4gICAgKTtcbiAgfVxuICBjb25zdCBzZXNzaW9uVG9rZW4gPSBpbmZvLnNlc3Npb25Ub2tlbjtcbiAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbylcbiAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoa2V5c1ByZWZpeCkpXG4gICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKGtleXNQcmVmaXgsICcnKSk7XG5cbiAgY29uc3Qga2V5c0FuZEluY2x1ZGUgPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuICBjb25zdCB7IGtleXMgfSA9IGtleXNBbmRJbmNsdWRlO1xuICBsZXQgeyBpbmNsdWRlIH0gPSBrZXlzQW5kSW5jbHVkZTtcblxuICBpZiAodXNlcklkICYmICFrZXlzICYmICFpbmNsdWRlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlc3Npb25Ub2tlbixcbiAgICB9O1xuICB9IGVsc2UgaWYgKGtleXMgJiYgIWluY2x1ZGUpIHtcbiAgICBpbmNsdWRlID0gJ3VzZXInO1xuICB9XG5cbiAgaWYgKHVzZXJJZCkge1xuICAgIC8vIFdlIG5lZWQgdG8gcmUgY3JlYXRlIHRoZSBhdXRoIGNvbnRleHRcbiAgICAvLyB0byBhdm9pZCBzZWN1cml0eSBicmVhY2ggaWYgdXNlcklkIGlzIHByb3ZpZGVkXG4gICAgY29udGV4dC5hdXRoID0gbmV3IEF1dGgoe1xuICAgICAgY29uZmlnLFxuICAgICAgaXNNYXN0ZXI6IGNvbnRleHQuYXV0aC5pc01hc3RlcixcbiAgICAgIHVzZXI6IHsgaWQ6IHVzZXJJZCB9LFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICBpZiAoa2V5cykge1xuICAgIG9wdGlvbnMua2V5cyA9IGtleXNcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAubWFwKGtleSA9PiBgJHtrZXl9YClcbiAgICAgIC5qb2luKCcsJyk7XG4gIH1cbiAgaWYgKGluY2x1ZGUpIHtcbiAgICBvcHRpb25zLmluY2x1ZGUgPSBpbmNsdWRlXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcChpbmNsdWRlZCA9PiBgJHtpbmNsdWRlZH1gKVxuICAgICAgLmpvaW4oJywnKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVzdC5maW5kKFxuICAgIGNvbmZpZyxcbiAgICBjb250ZXh0LmF1dGgsXG4gICAgJ19Vc2VyJyxcbiAgICAvLyBHZXQgdGhlIHVzZXIgaXQgc2VsZiBmcm9tIGF1dGggb2JqZWN0XG4gICAgeyBvYmplY3RJZDogY29udGV4dC5hdXRoLnVzZXIuaWQgfSxcbiAgICBvcHRpb25zLFxuICAgIGluZm8uY2xpZW50VmVyc2lvbixcbiAgICBpbmZvLmNvbnRleHRcbiAgKTtcbiAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sXG4gICAgICAnSW52YWxpZCBzZXNzaW9uIHRva2VuJ1xuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlc3Npb25Ub2tlbixcbiAgICAgIHVzZXIsXG4gICAgfTtcbiAgfVxufTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGlmIChwYXJzZUdyYXBoUUxTY2hlbWEuaXNVc2Vyc0NsYXNzRGlzYWJsZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICd2aWV3ZXInLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIHZpZXdlciBxdWVyeSBjYW4gYmUgdXNlZCB0byByZXR1cm4gdGhlIGN1cnJlbnQgdXNlciBkYXRhLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgYXN5bmMgcmVzb2x2ZShfc291cmNlLCBfYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuKFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICAgICd1c2VyLicsXG4gICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCB7IGxvYWQsIGdldFVzZXJGcm9tU2Vzc2lvblRva2VuIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/parseGraphQLUtils.js b/lib/GraphQL/parseGraphQLUtils.js new file mode 100644 index 0000000000..3677a6ca26 --- /dev/null +++ b/lib/GraphQL/parseGraphQLUtils.js @@ -0,0 +1,69 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.enforceMasterKeyAccess = enforceMasterKeyAccess; +exports.toGraphQLError = toGraphQLError; +exports.getParseClassMutationConfig = exports.extractKeysAndInclude = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _apolloServerCore = require("apollo-server-core"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function enforceMasterKeyAccess(auth) { + if (!auth.isMaster) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, 'unauthorized: master key is required'); + } +} + +function toGraphQLError(error) { + let code, message; + + if (error instanceof _node.default.Error) { + code = error.code; + message = error.message; + } else { + code = _node.default.Error.INTERNAL_SERVER_ERROR; + message = 'Internal server error'; + } + + return new _apolloServerCore.ApolloError(message, code); +} + +const extractKeysAndInclude = selectedFields => { + selectedFields = selectedFields.filter(field => !field.includes('__typename')); // Handles "id" field for both current and included objects + + selectedFields = selectedFields.map(field => { + if (field === 'id') return 'objectId'; + return field.endsWith('.id') ? `${field.substring(0, field.lastIndexOf('.id'))}.objectId` : field; + }); + let keys = undefined; + let include = undefined; + + if (selectedFields.length > 0) { + keys = [...new Set(selectedFields)].join(','); // We can use this shortcut since optimization is handled + // later on RestQuery, avoid overhead here. + + include = keys; + } + + return { + // If authData is detected keys will not work properly + // since authData has a special storage behavior + // so we need to skip keys currently + keys: keys && keys.indexOf('authData') === -1 ? keys : undefined, + include + }; +}; + +exports.extractKeysAndInclude = extractKeysAndInclude; + +const getParseClassMutationConfig = function (parseClassConfig) { + return parseClassConfig && parseClassConfig.mutation || {}; +}; + +exports.getParseClassMutationConfig = getParseClassMutationConfig; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML3BhcnNlR3JhcGhRTFV0aWxzLmpzIl0sIm5hbWVzIjpbImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJhdXRoIiwiaXNNYXN0ZXIiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInRvR3JhcGhRTEVycm9yIiwiZXJyb3IiLCJjb2RlIiwibWVzc2FnZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIkFwb2xsb0Vycm9yIiwiZXh0cmFjdEtleXNBbmRJbmNsdWRlIiwic2VsZWN0ZWRGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwibWFwIiwiZW5kc1dpdGgiLCJzdWJzdHJpbmciLCJsYXN0SW5kZXhPZiIsImtleXMiLCJ1bmRlZmluZWQiLCJpbmNsdWRlIiwibGVuZ3RoIiwiU2V0Iiwiam9pbiIsImluZGV4T2YiLCJnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWciLCJwYXJzZUNsYXNzQ29uZmlnIiwibXV0YXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sU0FBU0Esc0JBQVQsQ0FBZ0NDLElBQWhDLEVBQXNDO0FBQzNDLE1BQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFWLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxtQkFBNUIsRUFBaUQsc0NBQWpELENBQU47QUFDRDtBQUNGOztBQUVNLFNBQVNDLGNBQVQsQ0FBd0JDLEtBQXhCLEVBQStCO0FBQ3BDLE1BQUlDLElBQUosRUFBVUMsT0FBVjs7QUFDQSxNQUFJRixLQUFLLFlBQVlKLGNBQU1DLEtBQTNCLEVBQWtDO0FBQ2hDSSxJQUFBQSxJQUFJLEdBQUdELEtBQUssQ0FBQ0MsSUFBYjtBQUNBQyxJQUFBQSxPQUFPLEdBQUdGLEtBQUssQ0FBQ0UsT0FBaEI7QUFDRCxHQUhELE1BR087QUFDTEQsSUFBQUEsSUFBSSxHQUFHTCxjQUFNQyxLQUFOLENBQVlNLHFCQUFuQjtBQUNBRCxJQUFBQSxPQUFPLEdBQUcsdUJBQVY7QUFDRDs7QUFDRCxTQUFPLElBQUlFLDZCQUFKLENBQWdCRixPQUFoQixFQUF5QkQsSUFBekIsQ0FBUDtBQUNEOztBQUVNLE1BQU1JLHFCQUFxQixHQUFHQyxjQUFjLElBQUk7QUFDckRBLEVBQUFBLGNBQWMsR0FBR0EsY0FBYyxDQUFDQyxNQUFmLENBQXNCQyxLQUFLLElBQUksQ0FBQ0EsS0FBSyxDQUFDQyxRQUFOLENBQWUsWUFBZixDQUFoQyxDQUFqQixDQURxRCxDQUVyRDs7QUFDQUgsRUFBQUEsY0FBYyxHQUFHQSxjQUFjLENBQUNJLEdBQWYsQ0FBbUJGLEtBQUssSUFBSTtBQUMzQyxRQUFJQSxLQUFLLEtBQUssSUFBZCxFQUFvQixPQUFPLFVBQVA7QUFDcEIsV0FBT0EsS0FBSyxDQUFDRyxRQUFOLENBQWUsS0FBZixJQUNGLEdBQUVILEtBQUssQ0FBQ0ksU0FBTixDQUFnQixDQUFoQixFQUFtQkosS0FBSyxDQUFDSyxXQUFOLENBQWtCLEtBQWxCLENBQW5CLENBQTZDLFdBRDdDLEdBRUhMLEtBRko7QUFHRCxHQUxnQixDQUFqQjtBQU1BLE1BQUlNLElBQUksR0FBR0MsU0FBWDtBQUNBLE1BQUlDLE9BQU8sR0FBR0QsU0FBZDs7QUFFQSxNQUFJVCxjQUFjLENBQUNXLE1BQWYsR0FBd0IsQ0FBNUIsRUFBK0I7QUFDN0JILElBQUFBLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSUksR0FBSixDQUFRWixjQUFSLENBQUosRUFBNkJhLElBQTdCLENBQWtDLEdBQWxDLENBQVAsQ0FENkIsQ0FFN0I7QUFDQTs7QUFDQUgsSUFBQUEsT0FBTyxHQUFHRixJQUFWO0FBQ0Q7O0FBRUQsU0FBTztBQUNMO0FBQ0E7QUFDQTtBQUNBQSxJQUFBQSxJQUFJLEVBQUVBLElBQUksSUFBSUEsSUFBSSxDQUFDTSxPQUFMLENBQWEsVUFBYixNQUE2QixDQUFDLENBQXRDLEdBQTBDTixJQUExQyxHQUFpREMsU0FKbEQ7QUFLTEMsSUFBQUE7QUFMSyxHQUFQO0FBT0QsQ0ExQk07Ozs7QUE0QkEsTUFBTUssMkJBQTJCLEdBQUcsVUFBVUMsZ0JBQVYsRUFBNEI7QUFDckUsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxRQUF0QyxJQUFtRCxFQUExRDtBQUNELENBRk0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBBcG9sbG9FcnJvciB9IGZyb20gJ2Fwb2xsby1zZXJ2ZXItY29yZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpIHtcbiAgaWYgKCFhdXRoLmlzTWFzdGVyKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9HcmFwaFFMRXJyb3IoZXJyb3IpIHtcbiAgbGV0IGNvZGUsIG1lc3NhZ2U7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgY29kZSA9IGVycm9yLmNvZGU7XG4gICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gIH0gZWxzZSB7XG4gICAgY29kZSA9IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjtcbiAgICBtZXNzYWdlID0gJ0ludGVybmFsIHNlcnZlciBlcnJvcic7XG4gIH1cbiAgcmV0dXJuIG5ldyBBcG9sbG9FcnJvcihtZXNzYWdlLCBjb2RlKTtcbn1cblxuZXhwb3J0IGNvbnN0IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSA9IHNlbGVjdGVkRmllbGRzID0+IHtcbiAgc2VsZWN0ZWRGaWVsZHMgPSBzZWxlY3RlZEZpZWxkcy5maWx0ZXIoZmllbGQgPT4gIWZpZWxkLmluY2x1ZGVzKCdfX3R5cGVuYW1lJykpO1xuICAvLyBIYW5kbGVzIFwiaWRcIiBmaWVsZCBmb3IgYm90aCBjdXJyZW50IGFuZCBpbmNsdWRlZCBvYmplY3RzXG4gIHNlbGVjdGVkRmllbGRzID0gc2VsZWN0ZWRGaWVsZHMubWFwKGZpZWxkID0+IHtcbiAgICBpZiAoZmllbGQgPT09ICdpZCcpIHJldHVybiAnb2JqZWN0SWQnO1xuICAgIHJldHVybiBmaWVsZC5lbmRzV2l0aCgnLmlkJylcbiAgICAgID8gYCR7ZmllbGQuc3Vic3RyaW5nKDAsIGZpZWxkLmxhc3RJbmRleE9mKCcuaWQnKSl9Lm9iamVjdElkYFxuICAgICAgOiBmaWVsZDtcbiAgfSk7XG4gIGxldCBrZXlzID0gdW5kZWZpbmVkO1xuICBsZXQgaW5jbHVkZSA9IHVuZGVmaW5lZDtcblxuICBpZiAoc2VsZWN0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgIGtleXMgPSBbLi4ubmV3IFNldChzZWxlY3RlZEZpZWxkcyldLmpvaW4oJywnKTtcbiAgICAvLyBXZSBjYW4gdXNlIHRoaXMgc2hvcnRjdXQgc2luY2Ugb3B0aW1pemF0aW9uIGlzIGhhbmRsZWRcbiAgICAvLyBsYXRlciBvbiBSZXN0UXVlcnksIGF2b2lkIG92ZXJoZWFkIGhlcmUuXG4gICAgaW5jbHVkZSA9IGtleXM7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC8vIElmIGF1dGhEYXRhIGlzIGRldGVjdGVkIGtleXMgd2lsbCBub3Qgd29yayBwcm9wZXJseVxuICAgIC8vIHNpbmNlIGF1dGhEYXRhIGhhcyBhIHNwZWNpYWwgc3RvcmFnZSBiZWhhdmlvclxuICAgIC8vIHNvIHdlIG5lZWQgdG8gc2tpcCBrZXlzIGN1cnJlbnRseVxuICAgIGtleXM6IGtleXMgJiYga2V5cy5pbmRleE9mKCdhdXRoRGF0YScpID09PSAtMSA/IGtleXMgOiB1bmRlZmluZWQsXG4gICAgaW5jbHVkZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcgPSBmdW5jdGlvbiAocGFyc2VDbGFzc0NvbmZpZykge1xuICByZXR1cm4gKHBhcnNlQ2xhc3NDb25maWcgJiYgcGFyc2VDbGFzc0NvbmZpZy5tdXRhdGlvbikgfHwge307XG59O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/className.js b/lib/GraphQL/transformers/className.js new file mode 100644 index 0000000000..a3b221d3fe --- /dev/null +++ b/lib/GraphQL/transformers/className.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformClassNameToGraphQL = void 0; + +const transformClassNameToGraphQL = className => { + if (className[0] === '_') { + className = className.slice(1); + } + + return className[0].toUpperCase() + className.slice(1); +}; + +exports.transformClassNameToGraphQL = transformClassNameToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jbGFzc05hbWUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMIiwiY2xhc3NOYW1lIiwic2xpY2UiLCJ0b1VwcGVyQ2FzZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLDJCQUEyQixHQUFHQyxTQUFTLElBQUk7QUFDL0MsTUFBSUEsU0FBUyxDQUFDLENBQUQsQ0FBVCxLQUFpQixHQUFyQixFQUEwQjtBQUN4QkEsSUFBQUEsU0FBUyxHQUFHQSxTQUFTLENBQUNDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBWjtBQUNEOztBQUNELFNBQU9ELFNBQVMsQ0FBQyxDQUFELENBQVQsQ0FBYUUsV0FBYixLQUE2QkYsU0FBUyxDQUFDQyxLQUFWLENBQWdCLENBQWhCLENBQXBDO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCA9IGNsYXNzTmFtZSA9PiB7XG4gIGlmIChjbGFzc05hbWVbMF0gPT09ICdfJykge1xuICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBjbGFzc05hbWUuc2xpY2UoMSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/constraintType.js b/lib/GraphQL/transformers/constraintType.js new file mode 100644 index 0000000000..8303be5643 --- /dev/null +++ b/lib/GraphQL/transformers/constraintType.js @@ -0,0 +1,73 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformConstraintTypeToGraphQL = void 0; + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const transformConstraintTypeToGraphQL = (parseType, targetClass, parseClassTypes, fieldName) => { + if (fieldName === 'id' || fieldName === 'objectId') { + return defaultGraphQLTypes.ID_WHERE_INPUT; + } + + switch (parseType) { + case 'String': + return defaultGraphQLTypes.STRING_WHERE_INPUT; + + case 'Number': + return defaultGraphQLTypes.NUMBER_WHERE_INPUT; + + case 'Boolean': + return defaultGraphQLTypes.BOOLEAN_WHERE_INPUT; + + case 'Array': + return defaultGraphQLTypes.ARRAY_WHERE_INPUT; + + case 'Object': + return defaultGraphQLTypes.OBJECT_WHERE_INPUT; + + case 'Date': + return defaultGraphQLTypes.DATE_WHERE_INPUT; + + case 'Pointer': + if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { + return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'File': + return defaultGraphQLTypes.FILE_WHERE_INPUT; + + case 'GeoPoint': + return defaultGraphQLTypes.GEO_POINT_WHERE_INPUT; + + case 'Polygon': + return defaultGraphQLTypes.POLYGON_WHERE_INPUT; + + case 'Bytes': + return defaultGraphQLTypes.BYTES_WHERE_INPUT; + + case 'ACL': + return defaultGraphQLTypes.OBJECT_WHERE_INPUT; + + case 'Relation': + if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { + return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + default: + return undefined; + } +}; + +exports.transformConstraintTypeToGraphQL = transformConstraintTypeToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jb25zdHJhaW50VHlwZS5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1Db25zdHJhaW50VHlwZVRvR3JhcGhRTCIsInBhcnNlVHlwZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwiZmllbGROYW1lIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIklEX1dIRVJFX0lOUFVUIiwiU1RSSU5HX1dIRVJFX0lOUFVUIiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiT0JKRUNUX1dIRVJFX0lOUFVUIiwiREFURV9XSEVSRV9JTlBVVCIsImNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlIiwiT0JKRUNUIiwiRklMRV9XSEVSRV9JTlBVVCIsIkdFT19QT0lOVF9XSEVSRV9JTlBVVCIsIlBPTFlHT05fV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7QUFFQSxNQUFNQSxnQ0FBZ0MsR0FBRyxDQUN2Q0MsU0FEdUMsRUFFdkNDLFdBRnVDLEVBR3ZDQyxlQUh1QyxFQUl2Q0MsU0FKdUMsS0FLcEM7QUFDSCxNQUFJQSxTQUFTLEtBQUssSUFBZCxJQUFzQkEsU0FBUyxLQUFLLFVBQXhDLEVBQW9EO0FBQ2xELFdBQU9DLG1CQUFtQixDQUFDQyxjQUEzQjtBQUNEOztBQUVELFVBQVFMLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPSSxtQkFBbUIsQ0FBQ0Usa0JBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9GLG1CQUFtQixDQUFDRyxrQkFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsYUFBT0gsbUJBQW1CLENBQUNJLG1CQUEzQjs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPSixtQkFBbUIsQ0FBQ0ssaUJBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9MLG1CQUFtQixDQUFDTSxrQkFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT04sbUJBQW1CLENBQUNPLGdCQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxVQUNFVCxlQUFlLENBQUNELFdBQUQsQ0FBZixJQUNBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBRi9CLEVBR0U7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBQXBDO0FBQ0QsT0FMRCxNQUtPO0FBQ0wsZUFBT1IsbUJBQW1CLENBQUNTLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT1QsbUJBQW1CLENBQUNVLGdCQUEzQjs7QUFDRixTQUFLLFVBQUw7QUFDRSxhQUFPVixtQkFBbUIsQ0FBQ1cscUJBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9YLG1CQUFtQixDQUFDWSxtQkFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1osbUJBQW1CLENBQUNhLGlCQUEzQjs7QUFDRixTQUFLLEtBQUw7QUFDRSxhQUFPYixtQkFBbUIsQ0FBQ00sa0JBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLFVBQ0VSLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLElBQ0FDLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FGL0IsRUFHRTtBQUNBLGVBQU9WLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FBcEM7QUFDRCxPQUxELE1BS087QUFDTCxlQUFPUixtQkFBbUIsQ0FBQ1MsTUFBM0I7QUFDRDs7QUFDSDtBQUNFLGFBQU9LLFNBQVA7QUExQ0o7QUE0Q0QsQ0F0REQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5cbmNvbnN0IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMID0gKFxuICBwYXJzZVR5cGUsXG4gIHRhcmdldENsYXNzLFxuICBwYXJzZUNsYXNzVHlwZXMsXG4gIGZpZWxkTmFtZVxuKSA9PiB7XG4gIGlmIChmaWVsZE5hbWUgPT09ICdpZCcgfHwgZmllbGROYW1lID09PSAnb2JqZWN0SWQnKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuSURfV0hFUkVfSU5QVVQ7XG4gIH1cblxuICBzd2l0Y2ggKHBhcnNlVHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5TVFJJTkdfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk5VTUJFUl9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJPT0xFQU5fV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQVJSQVlfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVF9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkRBVEVfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlRfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuZXhwb3J0IHsgdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/inputType.js b/lib/GraphQL/transformers/inputType.js new file mode 100644 index 0000000000..8606eaa889 --- /dev/null +++ b/lib/GraphQL/transformers/inputType.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformInputTypeToGraphQL = void 0; + +var _graphql = require("graphql"); + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const transformInputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { + switch (parseType) { + case 'String': + return _graphql.GraphQLString; + + case 'Number': + return _graphql.GraphQLFloat; + + case 'Boolean': + return _graphql.GraphQLBoolean; + + case 'Array': + return new _graphql.GraphQLList(defaultGraphQLTypes.ANY); + + case 'Object': + return defaultGraphQLTypes.OBJECT; + + case 'Date': + return defaultGraphQLTypes.DATE; + + case 'Pointer': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLPointerType) { + return parseClassTypes[targetClass].classGraphQLPointerType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'Relation': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationType) { + return parseClassTypes[targetClass].classGraphQLRelationType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'File': + return defaultGraphQLTypes.FILE_INPUT; + + case 'GeoPoint': + return defaultGraphQLTypes.GEO_POINT_INPUT; + + case 'Polygon': + return defaultGraphQLTypes.POLYGON_INPUT; + + case 'Bytes': + return defaultGraphQLTypes.BYTES; + + case 'ACL': + return defaultGraphQLTypes.ACL_INPUT; + + default: + return undefined; + } +}; + +exports.transformInputTypeToGraphQL = transformInputTypeToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9pbnB1dFR5cGUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMIiwicGFyc2VUeXBlIiwidGFyZ2V0Q2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJHcmFwaFFMU3RyaW5nIiwiR3JhcGhRTEZsb2F0IiwiR3JhcGhRTEJvb2xlYW4iLCJHcmFwaFFMTGlzdCIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJBTlkiLCJPQkpFQ1QiLCJEQVRFIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUiLCJGSUxFX0lOUFVUIiwiR0VPX1BPSU5UX0lOUFVUIiwiUE9MWUdPTl9JTlBVVCIsIkJZVEVTIiwiQUNMX0lOUFVUIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBTUE7Ozs7OztBQUVBLE1BQU1BLDJCQUEyQixHQUFHLENBQ2xDQyxTQURrQyxFQUVsQ0MsV0FGa0MsRUFHbENDLGVBSGtDLEtBSS9CO0FBQ0gsVUFBUUYsU0FBUjtBQUNFLFNBQUssUUFBTDtBQUNFLGFBQU9HLHNCQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9DLHFCQUFQOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9DLHVCQUFQOztBQUNGLFNBQUssT0FBTDtBQUNFLGFBQU8sSUFBSUMsb0JBQUosQ0FBZ0JDLG1CQUFtQixDQUFDQyxHQUFwQyxDQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9ELG1CQUFtQixDQUFDRSxNQUEzQjs7QUFDRixTQUFLLE1BQUw7QUFDRSxhQUFPRixtQkFBbUIsQ0FBQ0csSUFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsVUFDRVIsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBSC9CLEVBSUU7QUFDQSxlQUFPVCxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0osbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxVQUFMO0FBQ0UsVUFDRVAsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBSC9CLEVBSUU7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0wsbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNNLFVBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU9OLG1CQUFtQixDQUFDTyxlQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPUCxtQkFBbUIsQ0FBQ1EsYUFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1IsbUJBQW1CLENBQUNTLEtBQTNCOztBQUNGLFNBQUssS0FBTDtBQUNFLGFBQU9ULG1CQUFtQixDQUFDVSxTQUEzQjs7QUFDRjtBQUNFLGFBQU9DLFNBQVA7QUE1Q0o7QUE4Q0QsQ0FuREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMRmxvYXQsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMTGlzdCxcbn0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5cbmNvbnN0IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCA9IChcbiAgcGFyc2VUeXBlLFxuICB0YXJnZXRDbGFzcyxcbiAgcGFyc2VDbGFzc1R5cGVzXG4pID0+IHtcbiAgc3dpdGNoIChwYXJzZVR5cGUpIHtcbiAgICBjYXNlICdTdHJpbmcnOlxuICAgICAgcmV0dXJuIEdyYXBoUUxTdHJpbmc7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiBHcmFwaFFMRmxvYXQ7XG4gICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICByZXR1cm4gR3JhcGhRTEJvb2xlYW47XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIG5ldyBHcmFwaFFMTGlzdChkZWZhdWx0R3JhcGhRTFR5cGVzLkFOWSk7XG4gICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkRBVEU7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlcyAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUG9pbnRlclR5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxQb2ludGVyVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBjYXNlICdSZWxhdGlvbic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlcyAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9JTlBVVDtcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlRfSU5QVVQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX0lOUFVUO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5BQ0xfSU5QVVQ7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/mutation.js b/lib/GraphQL/transformers/mutation.js new file mode 100644 index 0000000000..76c3e3144e --- /dev/null +++ b/lib/GraphQL/transformers/mutation.js @@ -0,0 +1,275 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformTypes = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphqlRelay = require("graphql-relay"); + +var _filesMutations = require("../loaders/filesMutations"); + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const transformTypes = async (inputType, fields, { + className, + parseGraphQLSchema, + req +}) => { + const { + classGraphQLCreateType, + classGraphQLUpdateType, + config: { + isCreateEnabled, + isUpdateEnabled + } + } = parseGraphQLSchema.parseClassTypes[className]; + const parseClass = parseGraphQLSchema.parseClasses.find(clazz => clazz.className === className); + + if (fields) { + const classGraphQLCreateTypeFields = isCreateEnabled && classGraphQLCreateType ? classGraphQLCreateType.getFields() : null; + const classGraphQLUpdateTypeFields = isUpdateEnabled && classGraphQLUpdateType ? classGraphQLUpdateType.getFields() : null; + const promises = Object.keys(fields).map(async field => { + let inputTypeField; + + if (inputType === 'create' && classGraphQLCreateTypeFields) { + inputTypeField = classGraphQLCreateTypeFields[field]; + } else if (classGraphQLUpdateTypeFields) { + inputTypeField = classGraphQLUpdateTypeFields[field]; + } + + if (inputTypeField) { + switch (true) { + case inputTypeField.type === defaultGraphQLTypes.GEO_POINT_INPUT: + fields[field] = transformers.geoPoint(fields[field]); + break; + + case inputTypeField.type === defaultGraphQLTypes.POLYGON_INPUT: + fields[field] = transformers.polygon(fields[field]); + break; + + case inputTypeField.type === defaultGraphQLTypes.FILE_INPUT: + fields[field] = await transformers.file(fields[field], req); + break; + + case parseClass.fields[field].type === 'Relation': + fields[field] = await transformers.relation(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); + break; + + case parseClass.fields[field].type === 'Pointer': + fields[field] = await transformers.pointer(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); + break; + } + } + }); + await Promise.all(promises); + if (fields.ACL) fields.ACL = transformers.ACL(fields.ACL); + } + + return fields; +}; + +exports.transformTypes = transformTypes; +const transformers = { + file: async ({ + file, + upload + }, { + config + }) => { + if (file === null && !upload) { + return null; + } + + if (upload) { + const { + fileInfo + } = await (0, _filesMutations.handleUpload)(upload, config); + return _objectSpread(_objectSpread({}, fileInfo), {}, { + __type: 'File' + }); + } else if (file && file.name) { + return { + name: file.name, + __type: 'File', + url: file.url + }; + } + + throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); + }, + polygon: value => ({ + __type: 'Polygon', + coordinates: value.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]) + }), + geoPoint: value => _objectSpread(_objectSpread({}, value), {}, { + __type: 'GeoPoint' + }), + ACL: value => { + const parseACL = {}; + + if (value.public) { + parseACL['*'] = { + read: value.public.read, + write: value.public.write + }; + } + + if (value.users) { + value.users.forEach(rule => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(rule.userId); + + if (globalIdObject.type === '_User') { + rule.userId = globalIdObject.id; + } + + parseACL[rule.userId] = { + read: rule.read, + write: rule.write + }; + }); + } + + if (value.roles) { + value.roles.forEach(rule => { + parseACL[`role:${rule.roleName}`] = { + read: rule.read, + write: rule.write + }; + }); + } + + return parseACL; + }, + relation: async (targetClass, field, value, parseGraphQLSchema, { + config, + auth, + info + }) => { + if (Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide at least one operation on the relation mutation of field ${field}`); + const op = { + __op: 'Batch', + ops: [] + }; + let nestedObjectsToAdd = []; + + if (value.createAndAdd) { + nestedObjectsToAdd = (await Promise.all(value.createAndAdd.map(async input => { + const parseFields = await transformTypes('create', input, { + className: targetClass, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + return objectsMutations.createObject(targetClass, parseFields, config, auth, info); + }))).map(object => ({ + __type: 'Pointer', + className: targetClass, + objectId: object.objectId + })); + } + + if (value.add || nestedObjectsToAdd.length > 0) { + if (!value.add) value.add = []; + value.add = value.add.map(input => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); + + if (globalIdObject.type === targetClass) { + input = globalIdObject.id; + } + + return { + __type: 'Pointer', + className: targetClass, + objectId: input + }; + }); + op.ops.push({ + __op: 'AddRelation', + objects: [...value.add, ...nestedObjectsToAdd] + }); + } + + if (value.remove) { + op.ops.push({ + __op: 'RemoveRelation', + objects: value.remove.map(input => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); + + if (globalIdObject.type === targetClass) { + input = globalIdObject.id; + } + + return { + __type: 'Pointer', + className: targetClass, + objectId: input + }; + }) + }); + } + + return op; + }, + pointer: async (targetClass, field, value, parseGraphQLSchema, { + config, + auth, + info + }) => { + if (Object.keys(value).length > 1 || Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide link OR createLink on the pointer mutation of field ${field}`); + let nestedObjectToAdd; + + if (value.createAndLink) { + const parseFields = await transformTypes('create', value.createAndLink, { + className: targetClass, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + nestedObjectToAdd = await objectsMutations.createObject(targetClass, parseFields, config, auth, info); + return { + __type: 'Pointer', + className: targetClass, + objectId: nestedObjectToAdd.objectId + }; + } + + if (value.link) { + let objectId = value.link; + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(objectId); + + if (globalIdObject.type === targetClass) { + objectId = globalIdObject.id; + } + + return { + __type: 'Pointer', + className: targetClass, + objectId + }; + } + } +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9tdXRhdGlvbi5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1UeXBlcyIsImlucHV0VHlwZSIsImZpZWxkcyIsImNsYXNzTmFtZSIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInJlcSIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY29uZmlnIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwicGFyc2VDbGFzc1R5cGVzIiwicGFyc2VDbGFzcyIsInBhcnNlQ2xhc3NlcyIsImZpbmQiLCJjbGF6eiIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzIiwicHJvbWlzZXMiLCJPYmplY3QiLCJrZXlzIiwibWFwIiwiZmllbGQiLCJpbnB1dFR5cGVGaWVsZCIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiR0VPX1BPSU5UX0lOUFVUIiwidHJhbnNmb3JtZXJzIiwiZ2VvUG9pbnQiLCJQT0xZR09OX0lOUFVUIiwicG9seWdvbiIsIkZJTEVfSU5QVVQiLCJmaWxlIiwicmVsYXRpb24iLCJ0YXJnZXRDbGFzcyIsInBvaW50ZXIiLCJQcm9taXNlIiwiYWxsIiwiQUNMIiwidXBsb2FkIiwiZmlsZUluZm8iLCJfX3R5cGUiLCJuYW1lIiwidXJsIiwiUGFyc2UiLCJFcnJvciIsIkZJTEVfU0FWRV9FUlJPUiIsInZhbHVlIiwiY29vcmRpbmF0ZXMiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsInBhcnNlQUNMIiwicHVibGljIiwicmVhZCIsIndyaXRlIiwidXNlcnMiLCJmb3JFYWNoIiwicnVsZSIsImdsb2JhbElkT2JqZWN0IiwidXNlcklkIiwiaWQiLCJyb2xlcyIsInJvbGVOYW1lIiwiYXV0aCIsImluZm8iLCJsZW5ndGgiLCJJTlZBTElEX1BPSU5URVIiLCJvcCIsIl9fb3AiLCJvcHMiLCJuZXN0ZWRPYmplY3RzVG9BZGQiLCJjcmVhdGVBbmRBZGQiLCJpbnB1dCIsInBhcnNlRmllbGRzIiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsIm9iamVjdCIsIm9iamVjdElkIiwiYWRkIiwicHVzaCIsIm9iamVjdHMiLCJyZW1vdmUiLCJuZXN0ZWRPYmplY3RUb0FkZCIsImNyZWF0ZUFuZExpbmsiLCJsaW5rIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsY0FBYyxHQUFHLE9BQ3JCQyxTQURxQixFQUVyQkMsTUFGcUIsRUFHckI7QUFBRUMsRUFBQUEsU0FBRjtBQUFhQyxFQUFBQSxrQkFBYjtBQUFpQ0MsRUFBQUE7QUFBakMsQ0FIcUIsS0FJbEI7QUFDSCxRQUFNO0FBQ0pDLElBQUFBLHNCQURJO0FBRUpDLElBQUFBLHNCQUZJO0FBR0pDLElBQUFBLE1BQU0sRUFBRTtBQUFFQyxNQUFBQSxlQUFGO0FBQW1CQyxNQUFBQTtBQUFuQjtBQUhKLE1BSUZOLGtCQUFrQixDQUFDTyxlQUFuQixDQUFtQ1IsU0FBbkMsQ0FKSjtBQUtBLFFBQU1TLFVBQVUsR0FBR1Isa0JBQWtCLENBQUNTLFlBQW5CLENBQWdDQyxJQUFoQyxDQUNoQkMsS0FBRCxJQUFXQSxLQUFLLENBQUNaLFNBQU4sS0FBb0JBLFNBRGQsQ0FBbkI7O0FBR0EsTUFBSUQsTUFBSixFQUFZO0FBQ1YsVUFBTWMsNEJBQTRCLEdBQ2hDUCxlQUFlLElBQUlILHNCQUFuQixHQUNJQSxzQkFBc0IsQ0FBQ1csU0FBdkIsRUFESixHQUVJLElBSE47QUFJQSxVQUFNQyw0QkFBNEIsR0FDaENSLGVBQWUsSUFBSUgsc0JBQW5CLEdBQ0lBLHNCQUFzQixDQUFDVSxTQUF2QixFQURKLEdBRUksSUFITjtBQUlBLFVBQU1FLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVluQixNQUFaLEVBQW9Cb0IsR0FBcEIsQ0FBd0IsTUFB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T0FBUDtBQUtEOztBQUNELFFBQUk5QixLQUFLLENBQUNxQyxJQUFWLEVBQWdCO0FBQ2QsVUFBSVAsUUFBUSxHQUFHOUIsS0FBSyxDQUFDcUMsSUFBckI7QUFDQSxZQUFNMUIsY0FBYyxHQUFHLGdDQUFhbUIsUUFBYixDQUF2Qjs7QUFDQSxVQUFJbkIsY0FBYyxDQUFDbEMsSUFBZixLQUF3QlUsV0FBNUIsRUFBeUM7QUFDdkMyQyxRQUFBQSxRQUFRLEdBQUduQixjQUFjLENBQUNFLEVBQTFCO0FBQ0Q7O0FBQ0QsYUFBTztBQUNMbkIsUUFBQUEsTUFBTSxFQUFFLFNBREg7QUFFTHZDLFFBQUFBLFNBQVMsRUFBRWdDLFdBRk47QUFHTDJDLFFBQUFBO0FBSEssT0FBUDtBQUtEO0FBQ0Y7QUFwTGtCLENBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgeyBoYW5kbGVVcGxvYWQgfSBmcm9tICcuLi9sb2FkZXJzL2ZpbGVzTXV0YXRpb25zJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi4vbG9hZGVycy9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCAqIGFzIG9iamVjdHNNdXRhdGlvbnMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzTXV0YXRpb25zJztcblxuY29uc3QgdHJhbnNmb3JtVHlwZXMgPSBhc3luYyAoXG4gIGlucHV0VHlwZTogJ2NyZWF0ZScgfCAndXBkYXRlJyxcbiAgZmllbGRzLFxuICB7IGNsYXNzTmFtZSwgcGFyc2VHcmFwaFFMU2NoZW1hLCByZXEgfVxuKSA9PiB7XG4gIGNvbnN0IHtcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUsXG4gICAgY29uZmlnOiB7IGlzQ3JlYXRlRW5hYmxlZCwgaXNVcGRhdGVFbmFibGVkIH0sXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG4gIGNvbnN0IHBhcnNlQ2xhc3MgPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgKGNsYXp6KSA9PiBjbGF6ei5jbGFzc05hbWUgPT09IGNsYXNzTmFtZVxuICApO1xuICBpZiAoZmllbGRzKSB7XG4gICAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZUZpZWxkcyA9XG4gICAgICBpc0NyZWF0ZUVuYWJsZWQgJiYgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZVxuICAgICAgICA/IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUuZ2V0RmllbGRzKClcbiAgICAgICAgOiBudWxsO1xuICAgIGNvbnN0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVGaWVsZHMgPVxuICAgICAgaXNVcGRhdGVFbmFibGVkICYmIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVcbiAgICAgICAgPyBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLmdldEZpZWxkcygpXG4gICAgICAgIDogbnVsbDtcbiAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKGZpZWxkcykubWFwKGFzeW5jIChmaWVsZCkgPT4ge1xuICAgICAgbGV0IGlucHV0VHlwZUZpZWxkO1xuICAgICAgaWYgKGlucHV0VHlwZSA9PT0gJ2NyZWF0ZScgJiYgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZUZpZWxkcykge1xuICAgICAgICBpbnB1dFR5cGVGaWVsZCA9IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHNbZmllbGRdO1xuICAgICAgfSBlbHNlIGlmIChjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzKSB7XG4gICAgICAgIGlucHV0VHlwZUZpZWxkID0gY2xhc3NHcmFwaFFMVXBkYXRlVHlwZUZpZWxkc1tmaWVsZF07XG4gICAgICB9XG4gICAgICBpZiAoaW5wdXRUeXBlRmllbGQpIHtcbiAgICAgICAgc3dpdGNoICh0cnVlKSB7XG4gICAgICAgICAgY2FzZSBpbnB1dFR5cGVGaWVsZC50eXBlID09PSBkZWZhdWx0R3JhcGhRTFR5cGVzLkdFT19QT0lOVF9JTlBVVDpcbiAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSB0cmFuc2Zvcm1lcnMuZ2VvUG9pbnQoZmllbGRzW2ZpZWxkXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGlucHV0VHlwZUZpZWxkLnR5cGUgPT09IGRlZmF1bHRHcmFwaFFMVHlwZXMuUE9MWUdPTl9JTlBVVDpcbiAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSB0cmFuc2Zvcm1lcnMucG9seWdvbihmaWVsZHNbZmllbGRdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgaW5wdXRUeXBlRmllbGQudHlwZSA9PT0gZGVmYXVsdEdyYXBoUUxUeXBlcy5GSUxFX0lOUFVUOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IGF3YWl0IHRyYW5zZm9ybWVycy5maWxlKGZpZWxkc1tmaWVsZF0sIHJlcSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IGF3YWl0IHRyYW5zZm9ybWVycy5yZWxhdGlvbihcbiAgICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgICByZXFcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcic6XG4gICAgICAgICAgICBmaWVsZHNbZmllbGRdID0gYXdhaXQgdHJhbnNmb3JtZXJzLnBvaW50ZXIoXG4gICAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICAgICAgZmllbGQsXG4gICAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0sXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgICAgcmVxXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgaWYgKGZpZWxkcy5BQ0wpIGZpZWxkcy5BQ0wgPSB0cmFuc2Zvcm1lcnMuQUNMKGZpZWxkcy5BQ0wpO1xuICB9XG4gIHJldHVybiBmaWVsZHM7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1lcnMgPSB7XG4gIGZpbGU6IGFzeW5jICh7IGZpbGUsIHVwbG9hZCB9LCB7IGNvbmZpZyB9KSA9PiB7XG4gICAgaWYgKGZpbGUgPT09IG51bGwgJiYgIXVwbG9hZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh1cGxvYWQpIHtcbiAgICAgIGNvbnN0IHsgZmlsZUluZm8gfSA9IGF3YWl0IGhhbmRsZVVwbG9hZCh1cGxvYWQsIGNvbmZpZyk7XG4gICAgICByZXR1cm4geyAuLi5maWxlSW5mbywgX190eXBlOiAnRmlsZScgfTtcbiAgICB9IGVsc2UgaWYgKGZpbGUgJiYgZmlsZS5uYW1lKSB7XG4gICAgICByZXR1cm4geyBuYW1lOiBmaWxlLm5hbWUsIF9fdHlwZTogJ0ZpbGUnLCB1cmw6IGZpbGUudXJsIH07XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsICdJbnZhbGlkIGZpbGUgdXBsb2FkLicpO1xuICB9LFxuICBwb2x5Z29uOiAodmFsdWUpID0+ICh7XG4gICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgY29vcmRpbmF0ZXM6IHZhbHVlLm1hcCgoZ2VvUG9pbnQpID0+IFtcbiAgICAgIGdlb1BvaW50LmxhdGl0dWRlLFxuICAgICAgZ2VvUG9pbnQubG9uZ2l0dWRlLFxuICAgIF0pLFxuICB9KSxcbiAgZ2VvUG9pbnQ6ICh2YWx1ZSkgPT4gKHtcbiAgICAuLi52YWx1ZSxcbiAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gIH0pLFxuICBBQ0w6ICh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IHBhcnNlQUNMID0ge307XG4gICAgaWYgKHZhbHVlLnB1YmxpYykge1xuICAgICAgcGFyc2VBQ0xbJyonXSA9IHtcbiAgICAgICAgcmVhZDogdmFsdWUucHVibGljLnJlYWQsXG4gICAgICAgIHdyaXRlOiB2YWx1ZS5wdWJsaWMud3JpdGUsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodmFsdWUudXNlcnMpIHtcbiAgICAgIHZhbHVlLnVzZXJzLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQocnVsZS51c2VySWQpO1xuICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgIHJ1bGUudXNlcklkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGFyc2VBQ0xbcnVsZS51c2VySWRdID0ge1xuICAgICAgICAgIHJlYWQ6IHJ1bGUucmVhZCxcbiAgICAgICAgICB3cml0ZTogcnVsZS53cml0ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodmFsdWUucm9sZXMpIHtcbiAgICAgIHZhbHVlLnJvbGVzLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgcGFyc2VBQ0xbYHJvbGU6JHtydWxlLnJvbGVOYW1lfWBdID0ge1xuICAgICAgICAgIHJlYWQ6IHJ1bGUucmVhZCxcbiAgICAgICAgICB3cml0ZTogcnVsZS53cml0ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VBQ0w7XG4gIH0sXG4gIHJlbGF0aW9uOiBhc3luYyAoXG4gICAgdGFyZ2V0Q2xhc3MsXG4gICAgZmllbGQsXG4gICAgdmFsdWUsXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgIHsgY29uZmlnLCBhdXRoLCBpbmZvIH1cbiAgKSA9PiB7XG4gICAgaWYgKE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGggPT09IDApXG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUE9JTlRFUixcbiAgICAgICAgYFlvdSBuZWVkIHRvIHByb3ZpZGUgYXQgbGVhc3Qgb25lIG9wZXJhdGlvbiBvbiB0aGUgcmVsYXRpb24gbXV0YXRpb24gb2YgZmllbGQgJHtmaWVsZH1gXG4gICAgICApO1xuXG4gICAgY29uc3Qgb3AgPSB7XG4gICAgICBfX29wOiAnQmF0Y2gnLFxuICAgICAgb3BzOiBbXSxcbiAgICB9O1xuICAgIGxldCBuZXN0ZWRPYmplY3RzVG9BZGQgPSBbXTtcblxuICAgIGlmICh2YWx1ZS5jcmVhdGVBbmRBZGQpIHtcbiAgICAgIG5lc3RlZE9iamVjdHNUb0FkZCA9IChcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgdmFsdWUuY3JlYXRlQW5kQWRkLm1hcChhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIGlucHV0LCB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0c011dGF0aW9ucy5jcmVhdGVPYmplY3QoXG4gICAgICAgICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICAgICAgICBwYXJzZUZpZWxkcyxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICkubWFwKChvYmplY3QpID0+ICh7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICBvYmplY3RJZDogb2JqZWN0Lm9iamVjdElkLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5hZGQgfHwgbmVzdGVkT2JqZWN0c1RvQWRkLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghdmFsdWUuYWRkKSB2YWx1ZS5hZGQgPSBbXTtcbiAgICAgIHZhbHVlLmFkZCA9IHZhbHVlLmFkZC5tYXAoKGlucHV0KSA9PiB7XG4gICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGlucHV0KTtcbiAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IHRhcmdldENsYXNzKSB7XG4gICAgICAgICAgaW5wdXQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgb2JqZWN0SWQ6IGlucHV0LFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBvcC5vcHMucHVzaCh7XG4gICAgICAgIF9fb3A6ICdBZGRSZWxhdGlvbicsXG4gICAgICAgIG9iamVjdHM6IFsuLi52YWx1ZS5hZGQsIC4uLm5lc3RlZE9iamVjdHNUb0FkZF0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUucmVtb3ZlKSB7XG4gICAgICBvcC5vcHMucHVzaCh7XG4gICAgICAgIF9fb3A6ICdSZW1vdmVSZWxhdGlvbicsXG4gICAgICAgIG9iamVjdHM6IHZhbHVlLnJlbW92ZS5tYXAoKGlucHV0KSA9PiB7XG4gICAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaW5wdXQpO1xuICAgICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSB0YXJnZXRDbGFzcykge1xuICAgICAgICAgICAgaW5wdXQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgICAgIG9iamVjdElkOiBpbnB1dCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gb3A7XG4gIH0sXG4gIHBvaW50ZXI6IGFzeW5jIChcbiAgICB0YXJnZXRDbGFzcyxcbiAgICBmaWVsZCxcbiAgICB2YWx1ZSxcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgeyBjb25maWcsIGF1dGgsIGluZm8gfVxuICApID0+IHtcbiAgICBpZiAoT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA+IDEgfHwgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMClcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9QT0lOVEVSLFxuICAgICAgICBgWW91IG5lZWQgdG8gcHJvdmlkZSBsaW5rIE9SIGNyZWF0ZUxpbmsgb24gdGhlIHBvaW50ZXIgbXV0YXRpb24gb2YgZmllbGQgJHtmaWVsZH1gXG4gICAgICApO1xuXG4gICAgbGV0IG5lc3RlZE9iamVjdFRvQWRkO1xuICAgIGlmICh2YWx1ZS5jcmVhdGVBbmRMaW5rKSB7XG4gICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCB2YWx1ZS5jcmVhdGVBbmRMaW5rLCB7XG4gICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgfSk7XG4gICAgICBuZXN0ZWRPYmplY3RUb0FkZCA9IGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuY3JlYXRlT2JqZWN0KFxuICAgICAgICB0YXJnZXRDbGFzcyxcbiAgICAgICAgcGFyc2VGaWVsZHMsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgaW5mb1xuICAgICAgKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICBvYmplY3RJZDogbmVzdGVkT2JqZWN0VG9BZGQub2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodmFsdWUubGluaykge1xuICAgICAgbGV0IG9iamVjdElkID0gdmFsdWUubGluaztcbiAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKG9iamVjdElkKTtcbiAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSB0YXJnZXRDbGFzcykge1xuICAgICAgICBvYmplY3RJZCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgIG9iamVjdElkLFxuICAgICAgfTtcbiAgICB9XG4gIH0sXG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1UeXBlcyB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/outputType.js b/lib/GraphQL/transformers/outputType.js new file mode 100644 index 0000000000..e01c729f6f --- /dev/null +++ b/lib/GraphQL/transformers/outputType.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformOutputTypeToGraphQL = void 0; + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +var _graphql = require("graphql"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const transformOutputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { + switch (parseType) { + case 'String': + return _graphql.GraphQLString; + + case 'Number': + return _graphql.GraphQLFloat; + + case 'Boolean': + return _graphql.GraphQLBoolean; + + case 'Array': + return new _graphql.GraphQLList(defaultGraphQLTypes.ARRAY_RESULT); + + case 'Object': + return defaultGraphQLTypes.OBJECT; + + case 'Date': + return defaultGraphQLTypes.DATE; + + case 'Pointer': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLOutputType) { + return parseClassTypes[targetClass].classGraphQLOutputType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'Relation': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLFindResultType) { + return new _graphql.GraphQLNonNull(parseClassTypes[targetClass].classGraphQLFindResultType); + } else { + return new _graphql.GraphQLNonNull(defaultGraphQLTypes.OBJECT); + } + + case 'File': + return defaultGraphQLTypes.FILE_INFO; + + case 'GeoPoint': + return defaultGraphQLTypes.GEO_POINT; + + case 'Polygon': + return defaultGraphQLTypes.POLYGON; + + case 'Bytes': + return defaultGraphQLTypes.BYTES; + + case 'ACL': + return new _graphql.GraphQLNonNull(defaultGraphQLTypes.ACL); + + default: + return undefined; + } +}; + +exports.transformOutputTypeToGraphQL = transformOutputTypeToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlLmpzIl0sIm5hbWVzIjpbInRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwiLCJwYXJzZVR5cGUiLCJ0YXJnZXRDbGFzcyIsInBhcnNlQ2xhc3NUeXBlcyIsIkdyYXBoUUxTdHJpbmciLCJHcmFwaFFMRmxvYXQiLCJHcmFwaFFMQm9vbGVhbiIsIkdyYXBoUUxMaXN0IiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkFSUkFZX1JFU1VMVCIsIk9CSkVDVCIsIkRBVEUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkZJTEVfSU5GTyIsIkdFT19QT0lOVCIsIlBPTFlHT04iLCJCWVRFUyIsIkFDTCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7QUFRQSxNQUFNQSw0QkFBNEIsR0FBRyxDQUNuQ0MsU0FEbUMsRUFFbkNDLFdBRm1DLEVBR25DQyxlQUhtQyxLQUloQztBQUNILFVBQVFGLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPRyxzQkFBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPQyxxQkFBUDs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPQyx1QkFBUDs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPLElBQUlDLG9CQUFKLENBQWdCQyxtQkFBbUIsQ0FBQ0MsWUFBcEMsQ0FBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPRCxtQkFBbUIsQ0FBQ0UsTUFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNHLElBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLFVBQ0VSLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUgvQixFQUlFO0FBQ0EsZUFBT1QsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUFwQztBQUNELE9BTkQsTUFNTztBQUNMLGVBQU9KLG1CQUFtQixDQUFDRSxNQUEzQjtBQUNEOztBQUNILFNBQUssVUFBTDtBQUNFLFVBQ0VQLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJXLDBCQUgvQixFQUlFO0FBQ0EsZUFBTyxJQUFJQyx1QkFBSixDQUNMWCxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsMEJBRHhCLENBQVA7QUFHRCxPQVJELE1BUU87QUFDTCxlQUFPLElBQUlDLHVCQUFKLENBQW1CTixtQkFBbUIsQ0FBQ0UsTUFBdkMsQ0FBUDtBQUNEOztBQUNILFNBQUssTUFBTDtBQUNFLGFBQU9GLG1CQUFtQixDQUFDTyxTQUEzQjs7QUFDRixTQUFLLFVBQUw7QUFDRSxhQUFPUCxtQkFBbUIsQ0FBQ1EsU0FBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsYUFBT1IsbUJBQW1CLENBQUNTLE9BQTNCOztBQUNGLFNBQUssT0FBTDtBQUNFLGFBQU9ULG1CQUFtQixDQUFDVSxLQUEzQjs7QUFDRixTQUFLLEtBQUw7QUFDRSxhQUFPLElBQUlKLHVCQUFKLENBQW1CTixtQkFBbUIsQ0FBQ1csR0FBdkMsQ0FBUDs7QUFDRjtBQUNFLGFBQU9DLFNBQVA7QUE5Q0o7QUFnREQsQ0FyREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQge1xuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMRmxvYXQsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTE5vbk51bGwsXG59IGZyb20gJ2dyYXBocWwnO1xuXG5jb25zdCB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMID0gKFxuICBwYXJzZVR5cGUsXG4gIHRhcmdldENsYXNzLFxuICBwYXJzZUNsYXNzVHlwZXNcbikgPT4ge1xuICBzd2l0Y2ggKHBhcnNlVHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gR3JhcGhRTFN0cmluZztcbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAgcmV0dXJuIEdyYXBoUUxGbG9hdDtcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiBHcmFwaFFMQm9vbGVhbjtcbiAgICBjYXNlICdBcnJheSc6XG4gICAgICByZXR1cm4gbmV3IEdyYXBoUUxMaXN0KGRlZmF1bHRHcmFwaFFMVHlwZXMuQVJSQVlfUkVTVUxUKTtcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuREFURTtcbiAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgIGlmIChcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMT3V0cHV0VHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBjYXNlICdSZWxhdGlvbic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlcyAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGVcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgR3JhcGhRTE5vbk51bGwoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1QpO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9JTkZPO1xuICAgIGNhc2UgJ0dlb1BvaW50JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkdFT19QT0lOVDtcbiAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLlBPTFlHT047XG4gICAgY2FzZSAnQnl0ZXMnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQllURVM7XG4gICAgY2FzZSAnQUNMJzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhRTE5vbk51bGwoZGVmYXVsdEdyYXBoUUxUeXBlcy5BQ0wpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/transformers/query.js b/lib/GraphQL/transformers/query.js new file mode 100644 index 0000000000..00f6aa5854 --- /dev/null +++ b/lib/GraphQL/transformers/query.js @@ -0,0 +1,273 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformQueryInputToParse = exports.transformQueryConstraintInputToParse = void 0; + +var _graphqlRelay = require("graphql-relay"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const parseQueryMap = { + OR: '$or', + AND: '$and', + NOR: '$nor' +}; +const parseConstraintMap = { + equalTo: '$eq', + notEqualTo: '$ne', + lessThan: '$lt', + lessThanOrEqualTo: '$lte', + greaterThan: '$gt', + greaterThanOrEqualTo: '$gte', + in: '$in', + notIn: '$nin', + exists: '$exists', + inQueryKey: '$select', + notInQueryKey: '$dontSelect', + inQuery: '$inQuery', + notInQuery: '$notInQuery', + containedBy: '$containedBy', + contains: '$all', + matchesRegex: '$regex', + options: '$options', + text: '$text', + search: '$search', + term: '$term', + language: '$language', + caseSensitive: '$caseSensitive', + diacriticSensitive: '$diacriticSensitive', + nearSphere: '$nearSphere', + maxDistance: '$maxDistance', + maxDistanceInRadians: '$maxDistanceInRadians', + maxDistanceInMiles: '$maxDistanceInMiles', + maxDistanceInKilometers: '$maxDistanceInKilometers', + within: '$within', + box: '$box', + geoWithin: '$geoWithin', + polygon: '$polygon', + centerSphere: '$centerSphere', + geoIntersects: '$geoIntersects', + point: '$point' +}; + +const transformQueryConstraintInputToParse = (constraints, parentFieldName, className, parentConstraints, parseClasses) => { + const fields = parseClasses.find(parseClass => parseClass.className === className).fields; + + if (parentFieldName === 'id' && className) { + Object.keys(constraints).forEach(constraintName => { + const constraintValue = constraints[constraintName]; + + if (typeof constraintValue === 'string') { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(constraintValue); + + if (globalIdObject.type === className) { + constraints[constraintName] = globalIdObject.id; + } + } else if (Array.isArray(constraintValue)) { + constraints[constraintName] = constraintValue.map(value => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(value); + + if (globalIdObject.type === className) { + return globalIdObject.id; + } + + return value; + }); + } + }); + parentConstraints.objectId = constraints; + delete parentConstraints.id; + } + + Object.keys(constraints).forEach(fieldName => { + let fieldValue = constraints[fieldName]; + + if (parseConstraintMap[fieldName]) { + constraints[parseConstraintMap[fieldName]] = constraints[fieldName]; + delete constraints[fieldName]; + } + /** + * If we have a key-value pair, we need to change the way the constraint is structured. + * + * Example: + * From: + * { + * "someField": { + * "lessThan": { + * "key":"foo.bar", + * "value": 100 + * }, + * "greaterThan": { + * "key":"foo.bar", + * "value": 10 + * } + * } + * } + * + * To: + * { + * "someField.foo.bar": { + * "$lt": 100, + * "$gt": 10 + * } + * } + */ + + + if (fieldValue.key && fieldValue.value && parentConstraints && parentFieldName) { + delete parentConstraints[parentFieldName]; + parentConstraints[`${parentFieldName}.${fieldValue.key}`] = _objectSpread(_objectSpread({}, parentConstraints[`${parentFieldName}.${fieldValue.key}`]), {}, { + [parseConstraintMap[fieldName]]: fieldValue.value + }); + } else if (fields[parentFieldName] && (fields[parentFieldName].type === 'Pointer' || fields[parentFieldName].type === 'Relation')) { + const { + targetClass + } = fields[parentFieldName]; + + if (fieldName === 'exists') { + if (fields[parentFieldName].type === 'Relation') { + const whereTarget = fieldValue ? 'where' : 'notWhere'; + + if (constraints[whereTarget]) { + if (constraints[whereTarget].objectId) { + constraints[whereTarget].objectId = _objectSpread(_objectSpread({}, constraints[whereTarget].objectId), {}, { + $exists: fieldValue + }); + } else { + constraints[whereTarget].objectId = { + $exists: fieldValue + }; + } + } else { + const parseWhereTarget = fieldValue ? '$inQuery' : '$notInQuery'; + parentConstraints[parentFieldName][parseWhereTarget] = { + where: { + objectId: { + $exists: true + } + }, + className: targetClass + }; + } + + delete constraints.$exists; + } else { + parentConstraints[parentFieldName].$exists = fieldValue; + } + + return; + } + + switch (fieldName) { + case 'have': + parentConstraints[parentFieldName].$inQuery = { + where: fieldValue, + className: targetClass + }; + transformQueryInputToParse(parentConstraints[parentFieldName].$inQuery.where, targetClass, parseClasses); + break; + + case 'haveNot': + parentConstraints[parentFieldName].$notInQuery = { + where: fieldValue, + className: targetClass + }; + transformQueryInputToParse(parentConstraints[parentFieldName].$notInQuery.where, targetClass, parseClasses); + break; + } + + delete constraints[fieldName]; + return; + } + + switch (fieldName) { + case 'point': + if (typeof fieldValue === 'object' && !fieldValue.__type) { + fieldValue.__type = 'GeoPoint'; + } + + break; + + case 'nearSphere': + if (typeof fieldValue === 'object' && !fieldValue.__type) { + fieldValue.__type = 'GeoPoint'; + } + + break; + + case 'box': + if (typeof fieldValue === 'object' && fieldValue.bottomLeft && fieldValue.upperRight) { + fieldValue = [_objectSpread({ + __type: 'GeoPoint' + }, fieldValue.bottomLeft), _objectSpread({ + __type: 'GeoPoint' + }, fieldValue.upperRight)]; + constraints[parseConstraintMap[fieldName]] = fieldValue; + } + + break; + + case 'polygon': + if (fieldValue instanceof Array) { + fieldValue.forEach(geoPoint => { + if (typeof geoPoint === 'object' && !geoPoint.__type) { + geoPoint.__type = 'GeoPoint'; + } + }); + } + + break; + + case 'centerSphere': + if (typeof fieldValue === 'object' && fieldValue.center && fieldValue.distance) { + fieldValue = [_objectSpread({ + __type: 'GeoPoint' + }, fieldValue.center), fieldValue.distance]; + constraints[parseConstraintMap[fieldName]] = fieldValue; + } + + break; + } + + if (typeof fieldValue === 'object') { + if (fieldName === 'where') { + transformQueryInputToParse(fieldValue, className, parseClasses); + } else { + transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); + } + } + }); +}; + +exports.transformQueryConstraintInputToParse = transformQueryConstraintInputToParse; + +const transformQueryInputToParse = (constraints, className, parseClasses) => { + if (!constraints || typeof constraints !== 'object') { + return; + } + + Object.keys(constraints).forEach(fieldName => { + const fieldValue = constraints[fieldName]; + + if (parseQueryMap[fieldName]) { + delete constraints[fieldName]; + fieldName = parseQueryMap[fieldName]; + constraints[fieldName] = fieldValue; + fieldValue.forEach(fieldValueItem => { + transformQueryInputToParse(fieldValueItem, className, parseClasses); + }); + return; + } else { + transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); + } + }); +}; + +exports.transformQueryInputToParse = transformQueryInputToParse; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9xdWVyeS5qcyJdLCJuYW1lcyI6WyJwYXJzZVF1ZXJ5TWFwIiwiT1IiLCJBTkQiLCJOT1IiLCJwYXJzZUNvbnN0cmFpbnRNYXAiLCJlcXVhbFRvIiwibm90RXF1YWxUbyIsImxlc3NUaGFuIiwibGVzc1RoYW5PckVxdWFsVG8iLCJncmVhdGVyVGhhbiIsImdyZWF0ZXJUaGFuT3JFcXVhbFRvIiwiaW4iLCJub3RJbiIsImV4aXN0cyIsImluUXVlcnlLZXkiLCJub3RJblF1ZXJ5S2V5IiwiaW5RdWVyeSIsIm5vdEluUXVlcnkiLCJjb250YWluZWRCeSIsImNvbnRhaW5zIiwibWF0Y2hlc1JlZ2V4Iiwib3B0aW9ucyIsInRleHQiLCJzZWFyY2giLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwibmVhclNwaGVyZSIsIm1heERpc3RhbmNlIiwibWF4RGlzdGFuY2VJblJhZGlhbnMiLCJtYXhEaXN0YW5jZUluTWlsZXMiLCJtYXhEaXN0YW5jZUluS2lsb21ldGVycyIsIndpdGhpbiIsImJveCIsImdlb1dpdGhpbiIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJnZW9JbnRlcnNlY3RzIiwicG9pbnQiLCJ0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UiLCJjb25zdHJhaW50cyIsInBhcmVudEZpZWxkTmFtZSIsImNsYXNzTmFtZSIsInBhcmVudENvbnN0cmFpbnRzIiwicGFyc2VDbGFzc2VzIiwiZmllbGRzIiwiZmluZCIsInBhcnNlQ2xhc3MiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImNvbnN0cmFpbnROYW1lIiwiY29uc3RyYWludFZhbHVlIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiaWQiLCJBcnJheSIsImlzQXJyYXkiLCJtYXAiLCJ2YWx1ZSIsIm9iamVjdElkIiwiZmllbGROYW1lIiwiZmllbGRWYWx1ZSIsImtleSIsInRhcmdldENsYXNzIiwid2hlcmVUYXJnZXQiLCIkZXhpc3RzIiwicGFyc2VXaGVyZVRhcmdldCIsIndoZXJlIiwiJGluUXVlcnkiLCJ0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSIsIiRub3RJblF1ZXJ5IiwiX190eXBlIiwiYm90dG9tTGVmdCIsInVwcGVyUmlnaHQiLCJnZW9Qb2ludCIsImNlbnRlciIsImRpc3RhbmNlIiwiZmllbGRWYWx1ZUl0ZW0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7Ozs7Ozs7QUFFQSxNQUFNQSxhQUFhLEdBQUc7QUFDcEJDLEVBQUFBLEVBQUUsRUFBRSxLQURnQjtBQUVwQkMsRUFBQUEsR0FBRyxFQUFFLE1BRmU7QUFHcEJDLEVBQUFBLEdBQUcsRUFBRTtBQUhlLENBQXRCO0FBTUEsTUFBTUMsa0JBQWtCLEdBQUc7QUFDekJDLEVBQUFBLE9BQU8sRUFBRSxLQURnQjtBQUV6QkMsRUFBQUEsVUFBVSxFQUFFLEtBRmE7QUFHekJDLEVBQUFBLFFBQVEsRUFBRSxLQUhlO0FBSXpCQyxFQUFBQSxpQkFBaUIsRUFBRSxNQUpNO0FBS3pCQyxFQUFBQSxXQUFXLEVBQUUsS0FMWTtBQU16QkMsRUFBQUEsb0JBQW9CLEVBQUUsTUFORztBQU96QkMsRUFBQUEsRUFBRSxFQUFFLEtBUHFCO0FBUXpCQyxFQUFBQSxLQUFLLEVBQUUsTUFSa0I7QUFTekJDLEVBQUFBLE1BQU0sRUFBRSxTQVRpQjtBQVV6QkMsRUFBQUEsVUFBVSxFQUFFLFNBVmE7QUFXekJDLEVBQUFBLGFBQWEsRUFBRSxhQVhVO0FBWXpCQyxFQUFBQSxPQUFPLEVBQUUsVUFaZ0I7QUFhekJDLEVBQUFBLFVBQVUsRUFBRSxhQWJhO0FBY3pCQyxFQUFBQSxXQUFXLEVBQUUsY0FkWTtBQWV6QkMsRUFBQUEsUUFBUSxFQUFFLE1BZmU7QUFnQnpCQyxFQUFBQSxZQUFZLEVBQUUsUUFoQlc7QUFpQnpCQyxFQUFBQSxPQUFPLEVBQUUsVUFqQmdCO0FBa0J6QkMsRUFBQUEsSUFBSSxFQUFFLE9BbEJtQjtBQW1CekJD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LGFBQWEsQ0FBQzhELFNBQUQsQ0FBakIsRUFBOEI7QUFDNUIsYUFBT3JCLFdBQVcsQ0FBQ3FCLFNBQUQsQ0FBbEI7QUFDQUEsTUFBQUEsU0FBUyxHQUFHOUQsYUFBYSxDQUFDOEQsU0FBRCxDQUF6QjtBQUNBckIsTUFBQUEsV0FBVyxDQUFDcUIsU0FBRCxDQUFYLEdBQXlCQyxVQUF6QjtBQUNBQSxNQUFBQSxVQUFVLENBQUNaLE9BQVgsQ0FBbUI0QixjQUFjLElBQUk7QUFDbkNSLFFBQUFBLDBCQUEwQixDQUFDUSxjQUFELEVBQWlCcEMsU0FBakIsRUFBNEJFLFlBQTVCLENBQTFCO0FBQ0QsT0FGRDtBQUdBO0FBQ0QsS0FSRCxNQVFPO0FBQ0xMLE1BQUFBLG9DQUFvQyxDQUNsQ3VCLFVBRGtDLEVBRWxDRCxTQUZrQyxFQUdsQ25CLFNBSGtDLEVBSWxDRixXQUprQyxFQUtsQ0ksWUFMa0MsQ0FBcEM7QUFPRDtBQUNGLEdBcEJEO0FBcUJELENBMUJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5cbmNvbnN0IHBhcnNlUXVlcnlNYXAgPSB7XG4gIE9SOiAnJG9yJyxcbiAgQU5EOiAnJGFuZCcsXG4gIE5PUjogJyRub3InLFxufTtcblxuY29uc3QgcGFyc2VDb25zdHJhaW50TWFwID0ge1xuICBlcXVhbFRvOiAnJGVxJyxcbiAgbm90RXF1YWxUbzogJyRuZScsXG4gIGxlc3NUaGFuOiAnJGx0JyxcbiAgbGVzc1RoYW5PckVxdWFsVG86ICckbHRlJyxcbiAgZ3JlYXRlclRoYW46ICckZ3QnLFxuICBncmVhdGVyVGhhbk9yRXF1YWxUbzogJyRndGUnLFxuICBpbjogJyRpbicsXG4gIG5vdEluOiAnJG5pbicsXG4gIGV4aXN0czogJyRleGlzdHMnLFxuICBpblF1ZXJ5S2V5OiAnJHNlbGVjdCcsXG4gIG5vdEluUXVlcnlLZXk6ICckZG9udFNlbGVjdCcsXG4gIGluUXVlcnk6ICckaW5RdWVyeScsXG4gIG5vdEluUXVlcnk6ICckbm90SW5RdWVyeScsXG4gIGNvbnRhaW5lZEJ5OiAnJGNvbnRhaW5lZEJ5JyxcbiAgY29udGFpbnM6ICckYWxsJyxcbiAgbWF0Y2hlc1JlZ2V4OiAnJHJlZ2V4JyxcbiAgb3B0aW9uczogJyRvcHRpb25zJyxcbiAgdGV4dDogJyR0ZXh0JyxcbiAgc2VhcmNoOiAnJHNlYXJjaCcsXG4gIHRlcm06ICckdGVybScsXG4gIGxhbmd1YWdlOiAnJGxhbmd1YWdlJyxcbiAgY2FzZVNlbnNpdGl2ZTogJyRjYXNlU2Vuc2l0aXZlJyxcbiAgZGlhY3JpdGljU2Vuc2l0aXZlOiAnJGRpYWNyaXRpY1NlbnNpdGl2ZScsXG4gIG5lYXJTcGhlcmU6ICckbmVhclNwaGVyZScsXG4gIG1heERpc3RhbmNlOiAnJG1heERpc3RhbmNlJyxcbiAgbWF4RGlzdGFuY2VJblJhZGlhbnM6ICckbWF4RGlzdGFuY2VJblJhZGlhbnMnLFxuICBtYXhEaXN0YW5jZUluTWlsZXM6ICckbWF4RGlzdGFuY2VJbk1pbGVzJyxcbiAgbWF4RGlzdGFuY2VJbktpbG9tZXRlcnM6ICckbWF4RGlzdGFuY2VJbktpbG9tZXRlcnMnLFxuICB3aXRoaW46ICckd2l0aGluJyxcbiAgYm94OiAnJGJveCcsXG4gIGdlb1dpdGhpbjogJyRnZW9XaXRoaW4nLFxuICBwb2x5Z29uOiAnJHBvbHlnb24nLFxuICBjZW50ZXJTcGhlcmU6ICckY2VudGVyU3BoZXJlJyxcbiAgZ2VvSW50ZXJzZWN0czogJyRnZW9JbnRlcnNlY3RzJyxcbiAgcG9pbnQ6ICckcG9pbnQnLFxufTtcblxuY29uc3QgdHJhbnNmb3JtUXVlcnlDb25zdHJhaW50SW5wdXRUb1BhcnNlID0gKFxuICBjb25zdHJhaW50cyxcbiAgcGFyZW50RmllbGROYW1lLFxuICBjbGFzc05hbWUsXG4gIHBhcmVudENvbnN0cmFpbnRzLFxuICBwYXJzZUNsYXNzZXNcbikgPT4ge1xuICBjb25zdCBmaWVsZHMgPSBwYXJzZUNsYXNzZXMuZmluZChcbiAgICBwYXJzZUNsYXNzID0+IHBhcnNlQ2xhc3MuY2xhc3NOYW1lID09PSBjbGFzc05hbWVcbiAgKS5maWVsZHM7XG4gIGlmIChwYXJlbnRGaWVsZE5hbWUgPT09ICdpZCcgJiYgY2xhc3NOYW1lKSB7XG4gICAgT2JqZWN0LmtleXMoY29uc3RyYWludHMpLmZvckVhY2goY29uc3RyYWludE5hbWUgPT4ge1xuICAgICAgY29uc3QgY29uc3RyYWludFZhbHVlID0gY29uc3RyYWludHNbY29uc3RyYWludE5hbWVdO1xuICAgICAgaWYgKHR5cGVvZiBjb25zdHJhaW50VmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGNvbnN0cmFpbnRWYWx1ZSk7XG5cbiAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IGNsYXNzTmFtZSkge1xuICAgICAgICAgIGNvbnN0cmFpbnRzW2NvbnN0cmFpbnROYW1lXSA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY29uc3RyYWludFZhbHVlKSkge1xuICAgICAgICBjb25zdHJhaW50c1tjb25zdHJhaW50TmFtZV0gPSBjb25zdHJhaW50VmFsdWUubWFwKHZhbHVlID0+IHtcbiAgICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZCh2YWx1ZSk7XG5cbiAgICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwYXJlbnRDb25zdHJhaW50cy5vYmplY3RJZCA9IGNvbnN0cmFpbnRzO1xuICAgIGRlbGV0ZSBwYXJlbnRDb25zdHJhaW50cy5pZDtcbiAgfVxuICBPYmplY3Qua2V5cyhjb25zdHJhaW50cykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgIGxldCBmaWVsZFZhbHVlID0gY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICBpZiAocGFyc2VDb25zdHJhaW50TWFwW2ZpZWxkTmFtZV0pIHtcbiAgICAgIGNvbnN0cmFpbnRzW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXSA9IGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG4gICAgICBkZWxldGUgY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgd2UgaGF2ZSBhIGtleS12YWx1ZSBwYWlyLCB3ZSBuZWVkIHRvIGNoYW5nZSB0aGUgd2F5IHRoZSBjb25zdHJhaW50IGlzIHN0cnVjdHVyZWQuXG4gICAgICpcbiAgICAgKiBFeGFtcGxlOlxuICAgICAqICAgRnJvbTpcbiAgICAgKiAgIHtcbiAgICAgKiAgICAgXCJzb21lRmllbGRcIjoge1xuICAgICAqICAgICAgIFwibGVzc1RoYW5cIjoge1xuICAgICAqICAgICAgICAgXCJrZXlcIjpcImZvby5iYXJcIixcbiAgICAgKiAgICAgICAgIFwidmFsdWVcIjogMTAwXG4gICAgICogICAgICAgfSxcbiAgICAgKiAgICAgICBcImdyZWF0ZXJUaGFuXCI6IHtcbiAgICAgKiAgICAgICAgIFwia2V5XCI6XCJmb28uYmFyXCIsXG4gICAgICogICAgICAgICBcInZhbHVlXCI6IDEwXG4gICAgICogICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogICB9XG4gICAgICpcbiAgICAgKiAgIFRvOlxuICAgICAqICAge1xuICAgICAqICAgICBcInNvbWVGaWVsZC5mb28uYmFyXCI6IHtcbiAgICAgKiAgICAgICBcIiRsdFwiOiAxMDAsXG4gICAgICogICAgICAgXCIkZ3RcIjogMTBcbiAgICAgKiAgICAgIH1cbiAgICAgKiAgIH1cbiAgICAgKi9cbiAgICBpZiAoXG4gICAgICBmaWVsZFZhbHVlLmtleSAmJlxuICAgICAgZmllbGRWYWx1ZS52YWx1ZSAmJlxuICAgICAgcGFyZW50Q29uc3RyYWludHMgJiZcbiAgICAgIHBhcmVudEZpZWxkTmFtZVxuICAgICkge1xuICAgICAgZGVsZXRlIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV07XG4gICAgICBwYXJlbnRDb25zdHJhaW50c1tgJHtwYXJlbnRGaWVsZE5hbWV9LiR7ZmllbGRWYWx1ZS5rZXl9YF0gPSB7XG4gICAgICAgIC4uLnBhcmVudENvbnN0cmFpbnRzW2Ake3BhcmVudEZpZWxkTmFtZX0uJHtmaWVsZFZhbHVlLmtleX1gXSxcbiAgICAgICAgW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXTogZmllbGRWYWx1ZS52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdICYmXG4gICAgICAoZmllbGRzW3BhcmVudEZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInIHx8XG4gICAgICAgIGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbicpXG4gICAgKSB7XG4gICAgICBjb25zdCB7IHRhcmdldENsYXNzIH0gPSBmaWVsZHNbcGFyZW50RmllbGROYW1lXTtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdleGlzdHMnKSB7XG4gICAgICAgIGlmIChmaWVsZHNbcGFyZW50RmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgY29uc3Qgd2hlcmVUYXJnZXQgPSBmaWVsZFZhbHVlID8gJ3doZXJlJyA6ICdub3RXaGVyZSc7XG4gICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XSkge1xuICAgICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XS5vYmplY3RJZCkge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgLi4uY29uc3RyYWludHNbd2hlcmVUYXJnZXRdLm9iamVjdElkLFxuICAgICAgICAgICAgICAgICRleGlzdHM6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgJGV4aXN0czogZmllbGRWYWx1ZSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VXaGVyZVRhcmdldCA9IGZpZWxkVmFsdWUgPyAnJGluUXVlcnknIDogJyRub3RJblF1ZXJ5JztcbiAgICAgICAgICAgIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV1bcGFyc2VXaGVyZVRhcmdldF0gPSB7XG4gICAgICAgICAgICAgIHdoZXJlOiB7IG9iamVjdElkOiB7ICRleGlzdHM6IHRydWUgfSB9LFxuICAgICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzLiRleGlzdHM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyZW50Q29uc3RyYWludHNbcGFyZW50RmllbGROYW1lXS4kZXhpc3RzID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgICAgICBjYXNlICdoYXZlJzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdoYXZlTm90JzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN3aXRjaCAoZmllbGROYW1lKSB7XG4gICAgICBjYXNlICdwb2ludCc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbmVhclNwaGVyZSc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYm94JzpcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIGZpZWxkVmFsdWUuYm90dG9tTGVmdCAmJlxuICAgICAgICAgIGZpZWxkVmFsdWUudXBwZXJSaWdodFxuICAgICAgICApIHtcbiAgICAgICAgICBmaWVsZFZhbHVlID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgICAgIC4uLmZpZWxkVmFsdWUuYm90dG9tTGVmdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ0dlb1BvaW50JyxcbiAgICAgICAgICAgICAgLi4uZmllbGRWYWx1ZS51cHBlclJpZ2h0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0cmFpbnRzW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXSA9IGZpZWxkVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwb2x5Z29uJzpcbiAgICAgICAgaWYgKGZpZWxkVmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGZpZWxkVmFsdWUuZm9yRWFjaChnZW9Qb2ludCA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGdlb1BvaW50ID09PSAnb2JqZWN0JyAmJiAhZ2VvUG9pbnQuX190eXBlKSB7XG4gICAgICAgICAgICAgIGdlb1BvaW50Ll9fdHlwZSA9ICdHZW9Qb2ludCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjZW50ZXJTcGhlcmUnOlxuICAgICAgICBpZiAoXG4gICAgICAgICAgdHlwZW9mIGZpZWxkVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgZmllbGRWYWx1ZS5jZW50ZXIgJiZcbiAgICAgICAgICBmaWVsZFZhbHVlLmRpc3RhbmNlXG4gICAgICAgICkge1xuICAgICAgICAgIGZpZWxkVmFsdWUgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ0dlb1BvaW50JyxcbiAgICAgICAgICAgICAgLi4uZmllbGRWYWx1ZS5jZW50ZXIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZmllbGRWYWx1ZS5kaXN0YW5jZSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0cmFpbnRzW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXSA9IGZpZWxkVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICd3aGVyZScpIHtcbiAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoZmllbGRWYWx1ZSwgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJhbnNmb3JtUXVlcnlDb25zdHJhaW50SW5wdXRUb1BhcnNlKFxuICAgICAgICAgIGZpZWxkVmFsdWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICBjb25zdHJhaW50cyxcbiAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufTtcblxuY29uc3QgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UgPSAoY29uc3RyYWludHMsIGNsYXNzTmFtZSwgcGFyc2VDbGFzc2VzKSA9PiB7XG4gIGlmICghY29uc3RyYWludHMgfHwgdHlwZW9mIGNvbnN0cmFpbnRzICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIE9iamVjdC5rZXlzKGNvbnN0cmFpbnRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgY29uc3QgZmllbGRWYWx1ZSA9IGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG5cbiAgICBpZiAocGFyc2VRdWVyeU1hcFtmaWVsZE5hbWVdKSB7XG4gICAgICBkZWxldGUgY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICAgIGZpZWxkTmFtZSA9IHBhcnNlUXVlcnlNYXBbZmllbGROYW1lXTtcbiAgICAgIGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV0gPSBmaWVsZFZhbHVlO1xuICAgICAgZmllbGRWYWx1ZS5mb3JFYWNoKGZpZWxkVmFsdWVJdGVtID0+IHtcbiAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoZmllbGRWYWx1ZUl0ZW0sIGNsYXNzTmFtZSwgcGFyc2VDbGFzc2VzKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UoXG4gICAgICAgIGZpZWxkVmFsdWUsXG4gICAgICAgIGZpZWxkTmFtZSxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBjb25zdHJhaW50cyxcbiAgICAgICAgcGFyc2VDbGFzc2VzXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UsIHRyYW5zZm9ybVF1ZXJ5SW5wdXRUb1BhcnNlIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/transformers/schemaFields.js b/lib/GraphQL/transformers/schemaFields.js new file mode 100644 index 0000000000..471edae4eb --- /dev/null +++ b/lib/GraphQL/transformers/schemaFields.js @@ -0,0 +1,128 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformToGraphQL = exports.transformToParse = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const transformToParse = (graphQLSchemaFields, existingFields) => { + if (!graphQLSchemaFields) { + return {}; + } + + let parseSchemaFields = {}; + + const reducerGenerator = type => (parseSchemaFields, field) => { + if (type === 'Remove') { + if (existingFields[field.name]) { + return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { + [field.name]: { + __op: 'Delete' + } + }); + } else { + return parseSchemaFields; + } + } + + if (graphQLSchemaFields.remove && graphQLSchemaFields.remove.find(removeField => removeField.name === field.name)) { + return parseSchemaFields; + } + + if (parseSchemaFields[field.name] || existingFields && existingFields[field.name]) { + throw new _node.default.Error(_node.default.Error.INVALID_KEY_NAME, `Duplicated field name: ${field.name}`); + } + + if (type === 'Relation' || type === 'Pointer') { + return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { + [field.name]: { + type, + targetClass: field.targetClassName + } + }); + } + + return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { + [field.name]: { + type + } + }); + }; + + if (graphQLSchemaFields.addStrings) { + parseSchemaFields = graphQLSchemaFields.addStrings.reduce(reducerGenerator('String'), parseSchemaFields); + } + + if (graphQLSchemaFields.addNumbers) { + parseSchemaFields = graphQLSchemaFields.addNumbers.reduce(reducerGenerator('Number'), parseSchemaFields); + } + + if (graphQLSchemaFields.addBooleans) { + parseSchemaFields = graphQLSchemaFields.addBooleans.reduce(reducerGenerator('Boolean'), parseSchemaFields); + } + + if (graphQLSchemaFields.addArrays) { + parseSchemaFields = graphQLSchemaFields.addArrays.reduce(reducerGenerator('Array'), parseSchemaFields); + } + + if (graphQLSchemaFields.addObjects) { + parseSchemaFields = graphQLSchemaFields.addObjects.reduce(reducerGenerator('Object'), parseSchemaFields); + } + + if (graphQLSchemaFields.addDates) { + parseSchemaFields = graphQLSchemaFields.addDates.reduce(reducerGenerator('Date'), parseSchemaFields); + } + + if (graphQLSchemaFields.addFiles) { + parseSchemaFields = graphQLSchemaFields.addFiles.reduce(reducerGenerator('File'), parseSchemaFields); + } + + if (graphQLSchemaFields.addGeoPoint) { + parseSchemaFields = [graphQLSchemaFields.addGeoPoint].reduce(reducerGenerator('GeoPoint'), parseSchemaFields); + } + + if (graphQLSchemaFields.addPolygons) { + parseSchemaFields = graphQLSchemaFields.addPolygons.reduce(reducerGenerator('Polygon'), parseSchemaFields); + } + + if (graphQLSchemaFields.addBytes) { + parseSchemaFields = graphQLSchemaFields.addBytes.reduce(reducerGenerator('Bytes'), parseSchemaFields); + } + + if (graphQLSchemaFields.addPointers) { + parseSchemaFields = graphQLSchemaFields.addPointers.reduce(reducerGenerator('Pointer'), parseSchemaFields); + } + + if (graphQLSchemaFields.addRelations) { + parseSchemaFields = graphQLSchemaFields.addRelations.reduce(reducerGenerator('Relation'), parseSchemaFields); + } + + if (existingFields && graphQLSchemaFields.remove) { + parseSchemaFields = graphQLSchemaFields.remove.reduce(reducerGenerator('Remove'), parseSchemaFields); + } + + return parseSchemaFields; +}; + +exports.transformToParse = transformToParse; + +const transformToGraphQL = parseSchemaFields => { + return Object.keys(parseSchemaFields).map(name => ({ + name, + type: parseSchemaFields[name].type, + targetClassName: parseSchemaFields[name].targetClass + })); +}; + +exports.transformToGraphQL = transformToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtVG9QYXJzZSIsImdyYXBoUUxTY2hlbWFGaWVsZHMiLCJleGlzdGluZ0ZpZWxkcyIsInBhcnNlU2NoZW1hRmllbGRzIiwicmVkdWNlckdlbmVyYXRvciIsInR5cGUiLCJmaWVsZCIsIm5hbWUiLCJfX29wIiwicmVtb3ZlIiwiZmluZCIsInJlbW92ZUZpZWxkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfS0VZX05BTUUiLCJ0YXJnZXRDbGFzcyIsInRhcmdldENsYXNzTmFtZSIsImFkZFN0cmluZ3MiLCJyZWR1Y2UiLCJhZGROdW1iZXJzIiwiYWRkQm9vbGVhbnMiLCJhZGRBcnJheXMiLCJhZGRPYmplY3RzIiwiYWRkRGF0ZXMiLCJhZGRGaWxlcyIsImFkZEdlb1BvaW50IiwiYWRkUG9seWdvbnMiLCJhZGRCeXRlcyIsImFkZFBvaW50ZXJzIiwiYWRkUmVsYXRpb25zIiwidHJhbnNmb3JtVG9HcmFwaFFMIiwiT2JqZWN0Iiwia2V5cyIsIm1hcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7Ozs7O0FBRUEsTUFBTUEsZ0JBQWdCLEdBQUcsQ0FBQ0MsbUJBQUQsRUFBc0JDLGNBQXRCLEtBQXlDO0FBQ2hFLE1BQUksQ0FBQ0QsbUJBQUwsRUFBMEI7QUFDeEIsV0FBTyxFQUFQO0FBQ0Q7O0FBRUQsTUFBSUUsaUJBQWlCLEdBQUcsRUFBeEI7O0FBRUEsUUFBTUMsZ0JBQWdCLEdBQUdDLElBQUksSUFBSSxDQUFDRixpQkFBRCxFQUFvQkcsS0FBcEIsS0FBOEI7QUFDN0QsUUFBSUQsSUFBSSxLQUFLLFFBQWIsRUFBdUI7QUFDckIsVUFBSUgsY0FBYyxDQUFDSSxLQUFLLENBQUNDLElBQVAsQ0FBbEIsRUFBZ0M7QUFDOUIsK0NBQ0tKLGlCQURMO0FBRUUsV0FBQ0csS0FBSyxDQUFDQyxJQUFQLEdBQWM7QUFDWkMsWUFBQUEsSUFB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O0FBd0lBLE1BQU0yQixrQkFBa0IsR0FBRzNCLGlCQUFpQixJQUFJO0FBQzlDLFNBQU80QixNQUFNLENBQUNDLElBQVAsQ0FBWTdCLGlCQUFaLEVBQStCOEIsR0FBL0IsQ0FBbUMxQixJQUFJLEtBQUs7QUFDakRBLElBQUFBLElBRGlEO0FBRWpERixJQUFBQSxJQUFJLEVBQUVGLGlCQUFpQixDQUFDSSxJQUFELENBQWpCLENBQXdCRixJQUZtQjtBQUdqRFcsSUFBQUEsZUFBZSxFQUFFYixpQkFBaUIsQ0FBQ0ksSUFBRCxDQUFqQixDQUF3QlE7QUFIUSxHQUFMLENBQXZDLENBQVA7QUFLRCxDQU5EIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5jb25zdCB0cmFuc2Zvcm1Ub1BhcnNlID0gKGdyYXBoUUxTY2hlbWFGaWVsZHMsIGV4aXN0aW5nRmllbGRzKSA9PiB7XG4gIGlmICghZ3JhcGhRTFNjaGVtYUZpZWxkcykge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGxldCBwYXJzZVNjaGVtYUZpZWxkcyA9IHt9O1xuXG4gIGNvbnN0IHJlZHVjZXJHZW5lcmF0b3IgPSB0eXBlID0+IChwYXJzZVNjaGVtYUZpZWxkcywgZmllbGQpID0+IHtcbiAgICBpZiAodHlwZSA9PT0gJ1JlbW92ZScpIHtcbiAgICAgIGlmIChleGlzdGluZ0ZpZWxkc1tmaWVsZC5uYW1lXSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnBhcnNlU2NoZW1hRmllbGRzLFxuICAgICAgICAgIFtmaWVsZC5uYW1lXToge1xuICAgICAgICAgICAgX19vcDogJ0RlbGV0ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwYXJzZVNjaGVtYUZpZWxkcztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKFxuICAgICAgZ3JhcGhRTFNjaGVtYUZpZWxkcy5yZW1vdmUgJiZcbiAgICAgIGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlLmZpbmQoXG4gICAgICAgIHJlbW92ZUZpZWxkID0+IHJlbW92ZUZpZWxkLm5hbWUgPT09IGZpZWxkLm5hbWVcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybiBwYXJzZVNjaGVtYUZpZWxkcztcbiAgICB9XG4gICAgaWYgKFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNbZmllbGQubmFtZV0gfHxcbiAgICAgIChleGlzdGluZ0ZpZWxkcyAmJiBleGlzdGluZ0ZpZWxkc1tmaWVsZC5uYW1lXSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgYER1cGxpY2F0ZWQgZmllbGQgbmFtZTogJHtmaWVsZC5uYW1lfWBcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnUmVsYXRpb24nIHx8IHR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucGFyc2VTY2hlbWFGaWVsZHMsXG4gICAgICAgIFtmaWVsZC5uYW1lXToge1xuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgdGFyZ2V0Q2xhc3M6IGZpZWxkLnRhcmdldENsYXNzTmFtZSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAuLi5wYXJzZVNjaGVtYUZpZWxkcyxcbiAgICAgIFtmaWVsZC5uYW1lXToge1xuICAgICAgICB0eXBlLFxuICAgICAgfSxcbiAgICB9O1xuICB9O1xuXG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFN0cmluZ3MpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkU3RyaW5ncy5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdTdHJpbmcnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGROdW1iZXJzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZE51bWJlcnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignTnVtYmVyJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkQm9vbGVhbnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkQm9vbGVhbnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignQm9vbGVhbicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEFycmF5cykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRBcnJheXMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignQXJyYXknKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRPYmplY3RzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZE9iamVjdHMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignT2JqZWN0JyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkRGF0ZXMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkRGF0ZXMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignRGF0ZScpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEZpbGVzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZEZpbGVzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0ZpbGUnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRHZW9Qb2ludCkge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gW2dyYXBoUUxTY2hlbWFGaWVsZHMuYWRkR2VvUG9pbnRdLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0dlb1BvaW50JyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9seWdvbnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9seWdvbnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignUG9seWdvbicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJ5dGVzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJ5dGVzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0J5dGVzJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9pbnRlcnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9pbnRlcnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignUG9pbnRlcicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFJlbGF0aW9ucykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRSZWxhdGlvbnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignUmVsYXRpb24nKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZXhpc3RpbmdGaWVsZHMgJiYgZ3JhcGhRTFNjaGVtYUZpZWxkcy5yZW1vdmUpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1JlbW92ZScpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlU2NoZW1hRmllbGRzO1xufTtcblxuY29uc3QgdHJhbnNmb3JtVG9HcmFwaFFMID0gcGFyc2VTY2hlbWFGaWVsZHMgPT4ge1xuICByZXR1cm4gT2JqZWN0LmtleXMocGFyc2VTY2hlbWFGaWVsZHMpLm1hcChuYW1lID0+ICh7XG4gICAgbmFtZSxcbiAgICB0eXBlOiBwYXJzZVNjaGVtYUZpZWxkc1tuYW1lXS50eXBlLFxuICAgIHRhcmdldENsYXNzTmFtZTogcGFyc2VTY2hlbWFGaWVsZHNbbmFtZV0udGFyZ2V0Q2xhc3MsXG4gIH0pKTtcbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybVRvUGFyc2UsIHRyYW5zZm9ybVRvR3JhcGhRTCB9O1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/Client.js b/lib/LiveQuery/Client.js new file mode 100644 index 0000000000..205e284d05 --- /dev/null +++ b/lib/LiveQuery/Client.js @@ -0,0 +1,114 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Client = void 0; + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const dafaultFields = ['className', 'objectId', 'updatedAt', 'createdAt', 'ACL']; + +class Client { + constructor(id, parseWebSocket, hasMasterKey = false, sessionToken, installationId) { + this.id = id; + this.parseWebSocket = parseWebSocket; + this.hasMasterKey = hasMasterKey; + this.sessionToken = sessionToken; + this.installationId = installationId; + this.roles = []; + this.subscriptionInfos = new Map(); + this.pushConnect = this._pushEvent('connected'); + this.pushSubscribe = this._pushEvent('subscribed'); + this.pushUnsubscribe = this._pushEvent('unsubscribed'); + this.pushCreate = this._pushEvent('create'); + this.pushEnter = this._pushEvent('enter'); + this.pushUpdate = this._pushEvent('update'); + this.pushDelete = this._pushEvent('delete'); + this.pushLeave = this._pushEvent('leave'); + } + + static pushResponse(parseWebSocket, message) { + _logger.default.verbose('Push Response : %j', message); + + parseWebSocket.send(message); + } + + static pushError(parseWebSocket, code, error, reconnect = true, requestId = null) { + Client.pushResponse(parseWebSocket, JSON.stringify({ + op: 'error', + error, + code, + reconnect, + requestId + })); + } + + addSubscriptionInfo(requestId, subscriptionInfo) { + this.subscriptionInfos.set(requestId, subscriptionInfo); + } + + getSubscriptionInfo(requestId) { + return this.subscriptionInfos.get(requestId); + } + + deleteSubscriptionInfo(requestId) { + return this.subscriptionInfos.delete(requestId); + } + + _pushEvent(type) { + return function (subscriptionId, parseObjectJSON, parseOriginalObjectJSON) { + const response = { + op: type, + clientId: this.id, + installationId: this.installationId + }; + + if (typeof subscriptionId !== 'undefined') { + response['requestId'] = subscriptionId; + } + + if (typeof parseObjectJSON !== 'undefined') { + let fields; + + if (this.subscriptionInfos.has(subscriptionId)) { + fields = this.subscriptionInfos.get(subscriptionId).fields; + } + + response['object'] = this._toJSONWithFields(parseObjectJSON, fields); + + if (parseOriginalObjectJSON) { + response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, fields); + } + } + + Client.pushResponse(this.parseWebSocket, JSON.stringify(response)); + }; + } + + _toJSONWithFields(parseObjectJSON, fields) { + if (!fields) { + return parseObjectJSON; + } + + const limitedParseObject = {}; + + for (const field of dafaultFields) { + limitedParseObject[field] = parseObjectJSON[field]; + } + + for (const field of fields) { + if (field in parseObjectJSON) { + limitedParseObject[field] = parseObjectJSON[field]; + } + } + + return limitedParseObject; + } + +} + +exports.Client = Client; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvQ2xpZW50LmpzIl0sIm5hbWVzIjpbImRhZmF1bHRGaWVsZHMiLCJDbGllbnQiLCJjb25zdHJ1Y3RvciIsImlkIiwicGFyc2VXZWJTb2NrZXQiLCJoYXNNYXN0ZXJLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInJvbGVzIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJNYXAiLCJwdXNoQ29ubmVjdCIsIl9wdXNoRXZlbnQiLCJwdXNoU3Vic2NyaWJlIiwicHVzaFVuc3Vic2NyaWJlIiwicHVzaENyZWF0ZSIsInB1c2hFbnRlciIsInB1c2hVcGRhdGUiLCJwdXNoRGVsZXRlIiwicHVzaExlYXZlIiwicHVzaFJlc3BvbnNlIiwibWVzc2FnZSIsImxvZ2dlciIsInZlcmJvc2UiLCJzZW5kIiwicHVzaEVycm9yIiwiY29kZSIsImVycm9yIiwicmVjb25uZWN0IiwicmVxdWVzdElkIiwiSlNPTiIsInN0cmluZ2lmeSIsIm9wIiwiYWRkU3Vic2NyaXB0aW9uSW5mbyIsInN1YnNjcmlwdGlvbkluZm8iLCJzZXQiLCJnZXRTdWJzY3JpcHRpb25JbmZvIiwiZ2V0IiwiZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyIsImRlbGV0ZSIsInR5cGUiLCJzdWJzY3JpcHRpb25JZCIsInBhcnNlT2JqZWN0SlNPTiIsInBhcnNlT3JpZ2luYWxPYmplY3RKU09OIiwicmVzcG9uc2UiLCJjbGllbnRJZCIsImZpZWxkcyIsImhhcyIsIl90b0pTT05XaXRoRmllbGRzIiwibGltaXRlZFBhcnNlT2JqZWN0IiwiZmllbGQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUtBLE1BQU1BLGFBQWEsR0FBRyxDQUFDLFdBQUQsRUFBYyxVQUFkLEVBQTBCLFdBQTFCLEVBQXVDLFdBQXZDLEVBQW9ELEtBQXBELENBQXRCOztBQUVBLE1BQU1DLE1BQU4sQ0FBYTtBQWtCWEMsRUFBQUEsV0FBVyxDQUNUQyxFQURTLEVBRVRDLGNBRlMsRUFHVEMs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cnQgdHlwZSB7IEZsYXR0ZW5lZE9iamVjdERhdGEgfSBmcm9tICcuL1N1YnNjcmlwdGlvbic7XG5leHBvcnQgdHlwZSBNZXNzYWdlID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNvbnN0IGRhZmF1bHRGaWVsZHMgPSBbJ2NsYXNzTmFtZScsICdvYmplY3RJZCcsICd1cGRhdGVkQXQnLCAnY3JlYXRlZEF0JywgJ0FDTCddO1xuXG5jbGFzcyBDbGllbnQge1xuICBpZDogbnVtYmVyO1xuICBwYXJzZVdlYlNvY2tldDogYW55O1xuICBoYXNNYXN0ZXJLZXk6IGJvb2xlYW47XG4gIHNlc3Npb25Ub2tlbjogc3RyaW5nO1xuICBpbnN0YWxsYXRpb25JZDogc3RyaW5nO1xuICB1c2VySWQ6IHN0cmluZztcbiAgcm9sZXM6IEFycmF5PHN0cmluZz47XG4gIHN1YnNjcmlwdGlvbkluZm9zOiBPYmplY3Q7XG4gIHB1c2hDb25uZWN0OiBGdW5jdGlvbjtcbiAgcHVzaFN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hVbnN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hDcmVhdGU6IEZ1bmN0aW9uO1xuICBwdXNoRW50ZXI6IEZ1bmN0aW9uO1xuICBwdXNoVXBkYXRlOiBGdW5jdGlvbjtcbiAgcHVzaERlbGV0ZTogRnVuY3Rpb247XG4gIHB1c2hMZWF2ZTogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaWQ6IG51bWJlcixcbiAgICBwYXJzZVdlYlNvY2tldDogYW55LFxuICAgIGhhc01hc3RlcktleTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIHNlc3Npb25Ub2tlbjogc3RyaW5nLFxuICAgIGluc3RhbGxhdGlvbklkOiBzdHJpbmdcbiAgKSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyc2VXZWJTb2NrZXQgPSBwYXJzZVdlYlNvY2tldDtcbiAgICB0aGlzLmhhc01hc3RlcktleSA9IGhhc01hc3RlcktleTtcbiAgICB0aGlzLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gICAgdGhpcy5yb2xlcyA9IFtdO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5wdXNoQ29ubmVjdCA9IHRoaXMuX3B1c2hFdmVudCgnY29ubmVjdGVkJyk7XG4gICAgdGhpcy5wdXNoU3Vic2NyaWJlID0gdGhpcy5fcHVzaEV2ZW50KCdzdWJzY3JpYmVkJyk7XG4gICAgdGhpcy5wdXNoVW5zdWJzY3JpYmUgPSB0aGlzLl9wdXNoRXZlbnQoJ3Vuc3Vic2NyaWJlZCcpO1xuICAgIHRoaXMucHVzaENyZWF0ZSA9IHRoaXMuX3B1c2hFdmVudCgnY3JlYXRlJyk7XG4gICAgdGhpcy5wdXNoRW50ZXIgPSB0aGlzLl9wdXNoRXZlbnQoJ2VudGVyJyk7XG4gICAgdGhpcy5wdXNoVXBkYXRlID0gdGhpcy5fcHVzaEV2ZW50KCd1cGRhdGUnKTtcbiAgICB0aGlzLnB1c2hEZWxldGUgPSB0aGlzLl9wdXNoRXZlbnQoJ2RlbGV0ZScpO1xuICAgIHRoaXMucHVzaExlYXZlID0gdGhpcy5fcHVzaEV2ZW50KCdsZWF2ZScpO1xuICB9XG5cbiAgc3RhdGljIHB1c2hSZXNwb25zZShwYXJzZVdlYlNvY2tldDogYW55LCBtZXNzYWdlOiBNZXNzYWdlKTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ1B1c2ggUmVzcG9uc2UgOiAlaicsIG1lc3NhZ2UpO1xuICAgIHBhcnNlV2ViU29ja2V0LnNlbmQobWVzc2FnZSk7XG4gIH1cblxuICBzdGF0aWMgcHVzaEVycm9yKFxuICAgIHBhcnNlV2ViU29ja2V0OiBhbnksXG4gICAgY29kZTogbnVtYmVyLFxuICAgIGVycm9yOiBzdHJpbmcsXG4gICAgcmVjb25uZWN0OiBib29sZWFuID0gdHJ1ZSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlciB8IHZvaWQgPSBudWxsXG4gICk6IHZvaWQge1xuICAgIENsaWVudC5wdXNoUmVzcG9uc2UoXG4gICAgICBwYXJzZVdlYlNvY2tldCxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgb3A6ICdlcnJvcicsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBjb2RlLFxuICAgICAgICByZWNvbm5lY3QsXG4gICAgICAgIHJlcXVlc3RJZCxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIsIHN1YnNjcmlwdGlvbkluZm86IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3Muc2V0KHJlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mbyk7XG4gIH1cblxuICBnZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZDogbnVtYmVyKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZVN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5kZWxldGUocmVxdWVzdElkKTtcbiAgfVxuXG4gIF9wdXNoRXZlbnQodHlwZTogc3RyaW5nKTogRnVuY3Rpb24ge1xuICAgIHJldHVybiBmdW5jdGlvbiAoXG4gICAgICBzdWJzY3JpcHRpb25JZDogbnVtYmVyLFxuICAgICAgcGFyc2VPYmplY3RKU09OOiBhbnksXG4gICAgICBwYXJzZU9yaWdpbmFsT2JqZWN0SlNPTjogYW55XG4gICAgKTogdm9pZCB7XG4gICAgICBjb25zdCByZXNwb25zZTogTWVzc2FnZSA9IHtcbiAgICAgICAgb3A6IHR5cGUsXG4gICAgICAgIGNsaWVudElkOiB0aGlzLmlkLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogdGhpcy5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXNwb25zZVsncmVxdWVzdElkJ10gPSBzdWJzY3JpcHRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFyc2VPYmplY3RKU09OICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBsZXQgZmllbGRzO1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25JbmZvcy5oYXMoc3Vic2NyaXB0aW9uSWQpKSB7XG4gICAgICAgICAgZmllbGRzID0gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQoc3Vic2NyaXB0aW9uSWQpLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTiwgZmllbGRzKTtcbiAgICAgICAgaWYgKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OKSB7XG4gICAgICAgICAgcmVzcG9uc2VbJ29yaWdpbmFsJ10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OLCBmaWVsZHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBDbGllbnQucHVzaFJlc3BvbnNlKHRoaXMucGFyc2VXZWJTb2NrZXQsIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XG4gICAgfTtcbiAgfVxuXG4gIF90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTjogYW55LCBmaWVsZHM6IGFueSk6IEZsYXR0ZW5lZE9iamVjdERhdGEge1xuICAgIGlmICghZmllbGRzKSB7XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RKU09OO1xuICAgIH1cbiAgICBjb25zdCBsaW1pdGVkUGFyc2VPYmplY3QgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGRhZmF1bHRGaWVsZHMpIHtcbiAgICAgIGxpbWl0ZWRQYXJzZU9iamVjdFtmaWVsZF0gPSBwYXJzZU9iamVjdEpTT05bZmllbGRdO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgaWYgKGZpZWxkIGluIHBhcnNlT2JqZWN0SlNPTikge1xuICAgICAgICBsaW1pdGVkUGFyc2VPYmplY3RbZmllbGRdID0gcGFyc2VPYmplY3RKU09OW2ZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbWl0ZWRQYXJzZU9iamVjdDtcbiAgfVxufVxuXG5leHBvcnQgeyBDbGllbnQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Id.js b/lib/LiveQuery/Id.js new file mode 100644 index 0000000000..379e29b88d --- /dev/null +++ b/lib/LiveQuery/Id.js @@ -0,0 +1,26 @@ +"use strict"; + +class Id { + constructor(className, objectId) { + this.className = className; + this.objectId = objectId; + } + + toString() { + return this.className + ':' + this.objectId; + } + + static fromString(str) { + var split = str.split(':'); + + if (split.length !== 2) { + throw new TypeError('Cannot create Id object from this string'); + } + + return new Id(split[0], split[1]); + } + +} + +module.exports = Id; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvSWQuanMiXSwibmFtZXMiOlsiSWQiLCJjb25zdHJ1Y3RvciIsImNsYXNzTmFtZSIsIm9iamVjdElkIiwidG9TdHJpbmciLCJmcm9tU3RyaW5nIiwic3RyIiwic3BsaXQiLCJsZW5ndGgiLCJUeXBlRXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEVBQU4sQ0FBUztBQUlQQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLFFBQXBCLEVBQXNDO0FBQy9DLFNBQUtELFNBQUwsR0FBaUJBLFNBQWpCO0FBQ0EsU0FBS0MsUUFBTCxHQUFnQkEsUUFBaEI7QUFDRDs7QUFDREMsRUFBQUEsUUFBUSxHQUFXO0FBQ2pCLFdBQU8sS0FBS0YsU0FBTCxHQUFpQixHQUFqQixHQUF1QixLQUFLQyxRQUFuQztBQUNEOztBQUVELFNBQU9FLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQStCO0FBQzdCLFFBQUlDLEtBQUssR0FBR0QsR0FBRyxDQUFDQyxLQUFKLENBQVUsR0FBVixDQUFaOztBQUNBLFFBQUlBLEtBQUssQ0FBQ0MsTUFBTixLQUFpQixDQUFyQixFQUF3QjtBQUN0QixZQUFNLElBQUlDLFNBQUosQ0FBYywwQ0FBZCxDQUFOO0FBQ0Q7O0FBQ0QsV0FBTyxJQUFJVCxFQUFKLENBQU9PLEtBQUssQ0FBQyxDQUFELENBQVosRUFBaUJBLEtBQUssQ0FBQyxDQUFELENBQXRCLENBQVA7QUFDRDs7QUFsQk07O0FBcUJURyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLEVBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgSWQge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgb2JqZWN0SWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6IHN0cmluZykge1xuICAgIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIHRoaXMub2JqZWN0SWQgPSBvYmplY3RJZDtcbiAgfVxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNsYXNzTmFtZSArICc6JyArIHRoaXMub2JqZWN0SWQ7XG4gIH1cblxuICBzdGF0aWMgZnJvbVN0cmluZyhzdHI6IHN0cmluZykge1xuICAgIHZhciBzcGxpdCA9IHN0ci5zcGxpdCgnOicpO1xuICAgIGlmIChzcGxpdC5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjcmVhdGUgSWQgb2JqZWN0IGZyb20gdGhpcyBzdHJpbmcnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJZChzcGxpdFswXSwgc3BsaXRbMV0pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSWQ7XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseCloudCodePublisher.js b/lib/LiveQuery/ParseCloudCodePublisher.js new file mode 100644 index 0000000000..974770a79f --- /dev/null +++ b/lib/LiveQuery/ParseCloudCodePublisher.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseCloudCodePublisher = void 0; + +var _ParsePubSub = require("./ParsePubSub"); + +var _node = _interopRequireDefault(require("parse/node")); + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseCloudCodePublisher { + // config object of the publisher, right now it only contains the redisURL, + // but we may extend it later. + constructor(config = {}) { + this.parsePublisher = _ParsePubSub.ParsePubSub.createPublisher(config); + } + + onCloudCodeAfterSave(request) { + this._onCloudCodeMessage(_node.default.applicationId + 'afterSave', request); + } + + onCloudCodeAfterDelete(request) { + this._onCloudCodeMessage(_node.default.applicationId + 'afterDelete', request); + } // Request is the request object from cloud code functions. request.object is a ParseObject. + + + _onCloudCodeMessage(type, request) { + _logger.default.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original); // We need the full JSON which includes className + + + const message = { + currentParseObject: request.object._toFullJSON() + }; + + if (request.original) { + message.originalParseObject = request.original._toFullJSON(); + } + + this.parsePublisher.publish(type, JSON.stringify(message)); + } + +} + +exports.ParseCloudCodePublisher = ParseCloudCodePublisher; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIuanMiXSwibmFtZXMiOlsiUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsInBhcnNlUHVibGlzaGVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVQdWJsaXNoZXIiLCJvbkNsb3VkQ29kZUFmdGVyU2F2ZSIsInJlcXVlc3QiLCJfb25DbG91ZENvZGVNZXNzYWdlIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwib25DbG91ZENvZGVBZnRlckRlbGV0ZSIsInR5cGUiLCJsb2dnZXIiLCJ2ZXJib3NlIiwib2JqZWN0Iiwib3JpZ2luYWwiLCJtZXNzYWdlIiwiY3VycmVudFBhcnNlT2JqZWN0IiwiX3RvRnVsbEpTT04iLCJvcmlnaW5hbFBhcnNlT2JqZWN0IiwicHVibGlzaCIsIkpTT04iLCJzdHJpbmdpZnkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHVCQUFOLENBQThCO0FBRzVCO0FBQ0E7QUFDQUMsRUFBQUEsV0FBVyxDQUFDQyxNQUFXLEdBQUcsRUFBZixFQUFtQjtBQUM1QixTQUFLQyxjQUFMLEdBQXNCQyx5QkFBWUMsZUFBWixDQUE0QkgsTUFBNUIsQ0FBdEI7QUFDRDs7QUFFREksRUFBQUEsb0JBQW9CLENBQUNDLE9BQUQsRUFBcUI7QUFDdkMsU0FBS0MsbUJBQUwsQ0FBeUJDLGNBQU1DLGFBQU4sR0FBc0IsV0FBL0MsRUFBNERILE9BQTVEO0FBQ0Q7O0FBRURJLEVBQUFBLHNCQUFzQixDQUFDSixPQUFELEVBQXFCO0FBQ3pDLFNBQUtDLG1CQUFMLENBQXlCQyxjQUFNQyxhQUFOLEdBQXNCLGFBQS9DLEVBQThESCxPQUE5RDtBQUNELEdBZjJCLENBaUI1Qjs7O0FBQ0FDLEVBQUFBLG1CQUFtQixDQUFDSSxJQUFELEVBQWVMLE9BQWYsRUFBbUM7QUFDcERNLG9CQUFPQyxPQUFQLENBQ0UsMERBREYsRUFFRVAsT0FBTyxDQUFDUSxNQUZWLEVBR0VSLE9BQU8sQ0FBQ1MsUUFIVixFQURvRCxDQU1wRDs7O0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RDLE1BQUFBLGtCQUFrQixFQUFFWCxPQUFPLENBQUNRLE1BQVIsQ0FBZUksV0FBZjtBQUROLEtBQWhCOztBQUdBLFFBQUlaLE9BQU8sQ0FBQ1MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsT0FBTyxDQUFDRyxtQkFBUixHQUE4QmIsT0FBTyxDQUFDUyxRQUFSLENBQWlCRyxXQUFqQixFQUE5QjtBQUNEOztBQUNELFNBQUtoQixjQUFMLENBQW9Ca0IsT0FBcEIsQ0FBNEJULElBQTVCLEVBQWtDVSxJQUFJLENBQUNDLFNBQUwsQ0FBZU4sT0FBZixDQUFsQztBQUNEOztBQWhDMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZVB1YlN1YiB9IGZyb20gJy4vUGFyc2VQdWJTdWInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuXG5jbGFzcyBQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlciB7XG4gIHBhcnNlUHVibGlzaGVyOiBPYmplY3Q7XG5cbiAgLy8gY29uZmlnIG9iamVjdCBvZiB0aGUgcHVibGlzaGVyLCByaWdodCBub3cgaXQgb25seSBjb250YWlucyB0aGUgcmVkaXNVUkwsXG4gIC8vIGJ1dCB3ZSBtYXkgZXh0ZW5kIGl0IGxhdGVyLlxuICBjb25zdHJ1Y3Rvcihjb25maWc6IGFueSA9IHt9KSB7XG4gICAgdGhpcy5wYXJzZVB1Ymxpc2hlciA9IFBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG5cbiAgb25DbG91ZENvZGVBZnRlclNhdmUocmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5fb25DbG91ZENvZGVNZXNzYWdlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJywgcmVxdWVzdCk7XG4gIH1cblxuICBvbkNsb3VkQ29kZUFmdGVyRGVsZXRlKHJlcXVlc3Q6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2xvdWRDb2RlTWVzc2FnZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJywgcmVxdWVzdCk7XG4gIH1cblxuICAvLyBSZXF1ZXN0IGlzIHRoZSByZXF1ZXN0IG9iamVjdCBmcm9tIGNsb3VkIGNvZGUgZnVuY3Rpb25zLiByZXF1ZXN0Lm9iamVjdCBpcyBhIFBhcnNlT2JqZWN0LlxuICBfb25DbG91ZENvZGVNZXNzYWdlKHR5cGU6IHN0cmluZywgcmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUmF3IHJlcXVlc3QgZnJvbSBjbG91ZCBjb2RlIGN1cnJlbnQgOiAlaiB8IG9yaWdpbmFsIDogJWonLFxuICAgICAgcmVxdWVzdC5vYmplY3QsXG4gICAgICByZXF1ZXN0Lm9yaWdpbmFsXG4gICAgKTtcbiAgICAvLyBXZSBuZWVkIHRoZSBmdWxsIEpTT04gd2hpY2ggaW5jbHVkZXMgY2xhc3NOYW1lXG4gICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgIGN1cnJlbnRQYXJzZU9iamVjdDogcmVxdWVzdC5vYmplY3QuX3RvRnVsbEpTT04oKSxcbiAgICB9O1xuICAgIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgICBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgPSByZXF1ZXN0Lm9yaWdpbmFsLl90b0Z1bGxKU09OKCk7XG4gICAgfVxuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIucHVibGlzaCh0eXBlLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlKSk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/ParseLiveQueryServer.js b/lib/LiveQuery/ParseLiveQueryServer.js new file mode 100644 index 0000000000..921c301c59 --- /dev/null +++ b/lib/LiveQuery/ParseLiveQueryServer.js @@ -0,0 +1,847 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseLiveQueryServer = void 0; + +var _tv = _interopRequireDefault(require("tv4")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _Subscription = require("./Subscription"); + +var _Client = require("./Client"); + +var _ParseWebSocketServer = require("./ParseWebSocketServer"); + +var _logger = _interopRequireDefault(require("../logger")); + +var _RequestSchema = _interopRequireDefault(require("./RequestSchema")); + +var _QueryTools = require("./QueryTools"); + +var _ParsePubSub = require("./ParsePubSub"); + +var _SchemaController = _interopRequireDefault(require("../Controllers/SchemaController")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _uuid = require("uuid"); + +var _triggers = require("../triggers"); + +var _Auth = require("../Auth"); + +var _Controllers = require("../Controllers"); + +var _lruCache = _interopRequireDefault(require("lru-cache")); + +var _UsersRouter = _interopRequireDefault(require("../Routers/UsersRouter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseLiveQueryServer { + // className -> (queryHash -> subscription) + // The subscriber we use to get object update from publisher + constructor(server, config = {}, parseServerConfig = {}) { + this.server = server; + this.clients = new Map(); + this.subscriptions = new Map(); + this.config = config; + config.appId = config.appId || _node.default.applicationId; + config.masterKey = config.masterKey || _node.default.masterKey; // Store keys, convert obj to map + + const keyPairs = config.keyPairs || {}; + this.keyPairs = new Map(); + + for (const key of Object.keys(keyPairs)) { + this.keyPairs.set(key, keyPairs[key]); + } + + _logger.default.verbose('Support key pairs', this.keyPairs); // Initialize Parse + + + _node.default.Object.disableSingleInstance(); + + const serverURL = config.serverURL || _node.default.serverURL; + _node.default.serverURL = serverURL; + + _node.default.initialize(config.appId, _node.default.javaScriptKey, config.masterKey); // The cache controller is a proper cache controller + // with access to User and Roles + + + this.cacheController = (0, _Controllers.getCacheController)(parseServerConfig); + config.cacheTimeout = config.cacheTimeout || 5 * 1000; // 5s + // This auth cache stores the promises for each auth resolution. + // The main benefit is to be able to reuse the same user / session token resolution. + + this.authCache = new _lruCache.default({ + max: 500, + // 500 concurrent + maxAge: config.cacheTimeout + }); // Initialize websocket server + + this.parseWebSocketServer = new _ParseWebSocketServer.ParseWebSocketServer(server, parseWebsocket => this._onConnect(parseWebsocket), config); // Initialize subscriber + + this.subscriber = _ParsePubSub.ParsePubSub.createSubscriber(config); + this.subscriber.subscribe(_node.default.applicationId + 'afterSave'); + this.subscriber.subscribe(_node.default.applicationId + 'afterDelete'); // Register message handler for subscriber. When publisher get messages, it will publish message + // to the subscribers and the handler will be called. + + this.subscriber.on('message', (channel, messageStr) => { + _logger.default.verbose('Subscribe messsage %j', messageStr); + + let message; + + try { + message = JSON.parse(messageStr); + } catch (e) { + _logger.default.error('unable to parse message', messageStr, e); + + return; + } + + this._inflateParseObject(message); + + if (channel === _node.default.applicationId + 'afterSave') { + this._onAfterSave(message); + } else if (channel === _node.default.applicationId + 'afterDelete') { + this._onAfterDelete(message); + } else { + _logger.default.error('Get message %s from unknown channel %j', message, channel); + } + }); + } // Message is the JSON object from publisher. Message.currentParseObject is the ParseObject JSON after changes. + // Message.originalParseObject is the original ParseObject JSON. + + + _inflateParseObject(message) { + // Inflate merged object + const currentParseObject = message.currentParseObject; + + _UsersRouter.default.removeHiddenProperties(currentParseObject); + + let className = currentParseObject.className; + let parseObject = new _node.default.Object(className); + + parseObject._finishFetch(currentParseObject); + + message.currentParseObject = parseObject; // Inflate original object + + const originalParseObject = message.originalParseObject; + + if (originalParseObject) { + _UsersRouter.default.removeHiddenProperties(originalParseObject); + + className = originalParseObject.className; + parseObject = new _node.default.Object(className); + + parseObject._finishFetch(originalParseObject); + + message.originalParseObject = parseObject; + } + } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. + // Message.originalParseObject is the original ParseObject. + + + _onAfterDelete(message) { + _logger.default.verbose(_node.default.applicationId + 'afterDelete is triggered'); + + let deletedParseObject = message.currentParseObject.toJSON(); + const classLevelPermissions = message.classLevelPermissions; + const className = deletedParseObject.className; + + _logger.default.verbose('ClassName: %j | ObjectId: %s', className, deletedParseObject.id); + + _logger.default.verbose('Current client number : %d', this.clients.size); + + const classSubscriptions = this.subscriptions.get(className); + + if (typeof classSubscriptions === 'undefined') { + _logger.default.debug('Can not find subscriptions under this class ' + className); + + return; + } + + for (const subscription of classSubscriptions.values()) { + const isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription); + + if (!isSubscriptionMatched) { + continue; + } + + for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { + const client = this.clients.get(clientId); + + if (typeof client === 'undefined') { + continue; + } + + for (const requestId of requestIds) { + const acl = message.currentParseObject.getACL(); // Check CLP + + const op = this._getCLPOperation(subscription.query); + + let res = {}; + + this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { + // Check ACL + return this._matchesACL(acl, client, requestId); + }).then(isMatched => { + if (!isMatched) { + return null; + } + + res = { + event: 'Delete', + sessionToken: client.sessionToken, + object: deletedParseObject, + clients: this.clients.size, + subscriptions: this.subscriptions.size, + useMasterKey: client.hasMasterKey, + installationId: client.installationId, + sendEvent: true + }; + return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); + }).then(() => { + if (!res.sendEvent) { + return; + } + + if (res.object && typeof res.object.toJSON === 'function') { + deletedParseObject = res.object.toJSON(); + deletedParseObject.className = className; + } + + client.pushDelete(requestId, deletedParseObject); + }).catch(error => { + _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); + + _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); + }); + } + } + } + } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. + // Message.originalParseObject is the original ParseObject. + + + _onAfterSave(message) { + _logger.default.verbose(_node.default.applicationId + 'afterSave is triggered'); + + let originalParseObject = null; + + if (message.originalParseObject) { + originalParseObject = message.originalParseObject.toJSON(); + } + + const classLevelPermissions = message.classLevelPermissions; + let currentParseObject = message.currentParseObject.toJSON(); + const className = currentParseObject.className; + + _logger.default.verbose('ClassName: %s | ObjectId: %s', className, currentParseObject.id); + + _logger.default.verbose('Current client number : %d', this.clients.size); + + const classSubscriptions = this.subscriptions.get(className); + + if (typeof classSubscriptions === 'undefined') { + _logger.default.debug('Can not find subscriptions under this class ' + className); + + return; + } + + for (const subscription of classSubscriptions.values()) { + const isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription); + + const isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription); + + for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { + const client = this.clients.get(clientId); + + if (typeof client === 'undefined') { + continue; + } + + for (const requestId of requestIds) { + // Set orignal ParseObject ACL checking promise, if the object does not match + // subscription, we do not need to check ACL + let originalACLCheckingPromise; + + if (!isOriginalSubscriptionMatched) { + originalACLCheckingPromise = Promise.resolve(false); + } else { + let originalACL; + + if (message.originalParseObject) { + originalACL = message.originalParseObject.getACL(); + } + + originalACLCheckingPromise = this._matchesACL(originalACL, client, requestId); + } // Set current ParseObject ACL checking promise, if the object does not match + // subscription, we do not need to check ACL + + + let currentACLCheckingPromise; + let res = {}; + + if (!isCurrentSubscriptionMatched) { + currentACLCheckingPromise = Promise.resolve(false); + } else { + const currentACL = message.currentParseObject.getACL(); + currentACLCheckingPromise = this._matchesACL(currentACL, client, requestId); + } + + const op = this._getCLPOperation(subscription.query); + + this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { + return Promise.all([originalACLCheckingPromise, currentACLCheckingPromise]); + }).then(([isOriginalMatched, isCurrentMatched]) => { + _logger.default.verbose('Original %j | Current %j | Match: %s, %s, %s, %s | Query: %s', originalParseObject, currentParseObject, isOriginalSubscriptionMatched, isCurrentSubscriptionMatched, isOriginalMatched, isCurrentMatched, subscription.hash); // Decide event type + + + let type; + + if (isOriginalMatched && isCurrentMatched) { + type = 'Update'; + } else if (isOriginalMatched && !isCurrentMatched) { + type = 'Leave'; + } else if (!isOriginalMatched && isCurrentMatched) { + if (originalParseObject) { + type = 'Enter'; + } else { + type = 'Create'; + } + } else { + return null; + } + + message.event = type; + res = { + event: type, + sessionToken: client.sessionToken, + object: currentParseObject, + original: originalParseObject, + clients: this.clients.size, + subscriptions: this.subscriptions.size, + useMasterKey: client.hasMasterKey, + installationId: client.installationId, + sendEvent: true + }; + return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); + }).then(() => { + if (!res.sendEvent) { + return; + } + + if (res.object && typeof res.object.toJSON === 'function') { + currentParseObject = res.object.toJSON(); + currentParseObject.className = res.object.className || className; + } + + if (res.original && typeof res.original.toJSON === 'function') { + originalParseObject = res.original.toJSON(); + originalParseObject.className = res.original.className || className; + } + + const functionName = 'push' + message.event; + + if (client[functionName]) { + client[functionName](requestId, currentParseObject, originalParseObject); + } + }, error => { + _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); + + _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); + }); + } + } + } + } + + _onConnect(parseWebsocket) { + parseWebsocket.on('message', request => { + if (typeof request === 'string') { + try { + request = JSON.parse(request); + } catch (e) { + _logger.default.error('unable to parse request', request, e); + + return; + } + } + + _logger.default.verbose('Request: %j', request); // Check whether this request is a valid request, return error directly if not + + + if (!_tv.default.validate(request, _RequestSchema.default['general']) || !_tv.default.validate(request, _RequestSchema.default[request.op])) { + _Client.Client.pushError(parseWebsocket, 1, _tv.default.error.message); + + _logger.default.error('Connect message error %s', _tv.default.error.message); + + return; + } + + switch (request.op) { + case 'connect': + this._handleConnect(parseWebsocket, request); + + break; + + case 'subscribe': + this._handleSubscribe(parseWebsocket, request); + + break; + + case 'update': + this._handleUpdateSubscription(parseWebsocket, request); + + break; + + case 'unsubscribe': + this._handleUnsubscribe(parseWebsocket, request); + + break; + + default: + _Client.Client.pushError(parseWebsocket, 3, 'Get unknown operation'); + + _logger.default.error('Get unknown operation', request.op); + + } + }); + parseWebsocket.on('disconnect', () => { + _logger.default.info(`Client disconnect: ${parseWebsocket.clientId}`); + + const clientId = parseWebsocket.clientId; + + if (!this.clients.has(clientId)) { + (0, _triggers.runLiveQueryEventHandlers)({ + event: 'ws_disconnect_error', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + error: `Unable to find client ${clientId}` + }); + + _logger.default.error(`Can not find client ${clientId} on disconnect`); + + return; + } // Delete client + + + const client = this.clients.get(clientId); + this.clients.delete(clientId); // Delete client from subscriptions + + for (const [requestId, subscriptionInfo] of _lodash.default.entries(client.subscriptionInfos)) { + const subscription = subscriptionInfo.subscription; + subscription.deleteClientSubscription(clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions + + const classSubscriptions = this.subscriptions.get(subscription.className); + + if (!subscription.hasSubscribingClient()) { + classSubscriptions.delete(subscription.hash); + } // If there is no subscriptions under this class, remove it from subscriptions + + + if (classSubscriptions.size === 0) { + this.subscriptions.delete(subscription.className); + } + } + + _logger.default.verbose('Current clients %d', this.clients.size); + + _logger.default.verbose('Current subscriptions %d', this.subscriptions.size); + + (0, _triggers.runLiveQueryEventHandlers)({ + event: 'ws_disconnect', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + useMasterKey: client.hasMasterKey, + installationId: client.installationId + }); + }); + (0, _triggers.runLiveQueryEventHandlers)({ + event: 'ws_connect', + clients: this.clients.size, + subscriptions: this.subscriptions.size + }); + } + + _matchesSubscription(parseObject, subscription) { + // Object is undefined or null, not match + if (!parseObject) { + return false; + } + + return (0, _QueryTools.matchesQuery)(parseObject, subscription.query); + } + + getAuthForSessionToken(sessionToken) { + if (!sessionToken) { + return Promise.resolve({}); + } + + const fromCache = this.authCache.get(sessionToken); + + if (fromCache) { + return fromCache; + } + + const authPromise = (0, _Auth.getAuthForSessionToken)({ + cacheController: this.cacheController, + sessionToken: sessionToken + }).then(auth => { + return { + auth, + userId: auth && auth.user && auth.user.id + }; + }).catch(error => { + // There was an error with the session token + const result = {}; + + if (error && error.code === _node.default.Error.INVALID_SESSION_TOKEN) { + result.error = error; + this.authCache.set(sessionToken, Promise.resolve(result), this.config.cacheTimeout); + } else { + this.authCache.del(sessionToken); + } + + return result; + }); + this.authCache.set(sessionToken, authPromise); + return authPromise; + } + + async _matchesCLP(classLevelPermissions, object, client, requestId, op) { + // try to match on user first, less expensive than with roles + const subscriptionInfo = client.getSubscriptionInfo(requestId); + const aclGroup = ['*']; + let userId; + + if (typeof subscriptionInfo !== 'undefined') { + const { + userId + } = await this.getAuthForSessionToken(subscriptionInfo.sessionToken); + + if (userId) { + aclGroup.push(userId); + } + } + + try { + await _SchemaController.default.validatePermission(classLevelPermissions, object.className, aclGroup, op); + return true; + } catch (e) { + _logger.default.verbose(`Failed matching CLP for ${object.id} ${userId} ${e}`); + + return false; + } // TODO: handle roles permissions + // Object.keys(classLevelPermissions).forEach((key) => { + // const perm = classLevelPermissions[key]; + // Object.keys(perm).forEach((key) => { + // if (key.indexOf('role')) + // }); + // }) + // // it's rejected here, check the roles + // var rolesQuery = new Parse.Query(Parse.Role); + // rolesQuery.equalTo("users", user); + // return rolesQuery.find({useMasterKey:true}); + + } + + _getCLPOperation(query) { + return typeof query === 'object' && Object.keys(query).length == 1 && typeof query.objectId === 'string' ? 'get' : 'find'; + } + + async _verifyACL(acl, token) { + if (!token) { + return false; + } + + const { + auth, + userId + } = await this.getAuthForSessionToken(token); // Getting the session token failed + // This means that no additional auth is available + // At this point, just bail out as no additional visibility can be inferred. + + if (!auth || !userId) { + return false; + } + + const isSubscriptionSessionTokenMatched = acl.getReadAccess(userId); + + if (isSubscriptionSessionTokenMatched) { + return true; + } // Check if the user has any roles that match the ACL + + + return Promise.resolve().then(async () => { + // Resolve false right away if the acl doesn't have any roles + const acl_has_roles = Object.keys(acl.permissionsById).some(key => key.startsWith('role:')); + + if (!acl_has_roles) { + return false; + } + + const roleNames = await auth.getUserRoles(); // Finally, see if any of the user's roles allow them read access + + for (const role of roleNames) { + // We use getReadAccess as `role` is in the form `role:roleName` + if (acl.getReadAccess(role)) { + return true; + } + } + + return false; + }).catch(() => { + return false; + }); + } + + async _matchesACL(acl, client, requestId) { + // Return true directly if ACL isn't present, ACL is public read, or client has master key + if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) { + return true; + } // Check subscription sessionToken matches ACL first + + + const subscriptionInfo = client.getSubscriptionInfo(requestId); + + if (typeof subscriptionInfo === 'undefined') { + return false; + } + + const subscriptionToken = subscriptionInfo.sessionToken; + const clientSessionToken = client.sessionToken; + + if (await this._verifyACL(acl, subscriptionToken)) { + return true; + } + + if (await this._verifyACL(acl, clientSessionToken)) { + return true; + } + + return false; + } + + async _handleConnect(parseWebsocket, request) { + if (!this._validateKeys(request, this.keyPairs)) { + _Client.Client.pushError(parseWebsocket, 4, 'Key in request is not valid'); + + _logger.default.error('Key in request is not valid'); + + return; + } + + const hasMasterKey = this._hasMasterKey(request, this.keyPairs); + + const clientId = (0, _uuid.v4)(); + const client = new _Client.Client(clientId, parseWebsocket, hasMasterKey, request.sessionToken, request.installationId); + + try { + const req = { + client, + event: 'connect', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + sessionToken: request.sessionToken, + useMasterKey: client.hasMasterKey, + installationId: request.installationId + }; + await (0, _triggers.maybeRunConnectTrigger)('beforeConnect', req); + parseWebsocket.clientId = clientId; + this.clients.set(parseWebsocket.clientId, client); + + _logger.default.info(`Create new client: ${parseWebsocket.clientId}`); + + client.pushConnect(); + (0, _triggers.runLiveQueryEventHandlers)(req); + } catch (error) { + _Client.Client.pushError(parseWebsocket, error.code || 141, error.message || error, false); + + _logger.default.error(`Failed running beforeConnect for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(error)); + } + } + + _hasMasterKey(request, validKeyPairs) { + if (!validKeyPairs || validKeyPairs.size == 0 || !validKeyPairs.has('masterKey')) { + return false; + } + + if (!request || !Object.prototype.hasOwnProperty.call(request, 'masterKey')) { + return false; + } + + return request.masterKey === validKeyPairs.get('masterKey'); + } + + _validateKeys(request, validKeyPairs) { + if (!validKeyPairs || validKeyPairs.size == 0) { + return true; + } + + let isValid = false; + + for (const [key, secret] of validKeyPairs) { + if (!request[key] || request[key] !== secret) { + continue; + } + + isValid = true; + break; + } + + return isValid; + } + + async _handleSubscribe(parseWebsocket, request) { + // If we can not find this client, return error to client + if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { + _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before subscribing'); + + _logger.default.error('Can not find this client, make sure you connect to server before subscribing'); + + return; + } + + const client = this.clients.get(parseWebsocket.clientId); + const className = request.query.className; + + try { + await (0, _triggers.maybeRunSubscribeTrigger)('beforeSubscribe', className, request); // Get subscription from subscriptions, create one if necessary + + const subscriptionHash = (0, _QueryTools.queryHash)(request.query); // Add className to subscriptions if necessary + + if (!this.subscriptions.has(className)) { + this.subscriptions.set(className, new Map()); + } + + const classSubscriptions = this.subscriptions.get(className); + let subscription; + + if (classSubscriptions.has(subscriptionHash)) { + subscription = classSubscriptions.get(subscriptionHash); + } else { + subscription = new _Subscription.Subscription(className, request.query.where, subscriptionHash); + classSubscriptions.set(subscriptionHash, subscription); + } // Add subscriptionInfo to client + + + const subscriptionInfo = { + subscription: subscription + }; // Add selected fields, sessionToken and installationId for this subscription if necessary + + if (request.query.fields) { + subscriptionInfo.fields = request.query.fields; + } + + if (request.sessionToken) { + subscriptionInfo.sessionToken = request.sessionToken; + } + + client.addSubscriptionInfo(request.requestId, subscriptionInfo); // Add clientId to subscription + + subscription.addClientSubscription(parseWebsocket.clientId, request.requestId); + client.pushSubscribe(request.requestId); + + _logger.default.verbose(`Create client ${parseWebsocket.clientId} new subscription: ${request.requestId}`); + + _logger.default.verbose('Current client number: %d', this.clients.size); + + (0, _triggers.runLiveQueryEventHandlers)({ + client, + event: 'subscribe', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + sessionToken: request.sessionToken, + useMasterKey: client.hasMasterKey, + installationId: client.installationId + }); + } catch (e) { + _Client.Client.pushError(parseWebsocket, e.code || 141, e.message || e, false, request.requestId); + + _logger.default.error(`Failed running beforeSubscribe on ${className} for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(e)); + } + } + + _handleUpdateSubscription(parseWebsocket, request) { + this._handleUnsubscribe(parseWebsocket, request, false); + + this._handleSubscribe(parseWebsocket, request); + } + + _handleUnsubscribe(parseWebsocket, request, notifyClient = true) { + // If we can not find this client, return error to client + if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { + _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing'); + + _logger.default.error('Can not find this client, make sure you connect to server before unsubscribing'); + + return; + } + + const requestId = request.requestId; + const client = this.clients.get(parseWebsocket.clientId); + + if (typeof client === 'undefined') { + _Client.Client.pushError(parseWebsocket, 2, 'Cannot find client with clientId ' + parseWebsocket.clientId + '. Make sure you connect to live query server before unsubscribing.'); + + _logger.default.error('Can not find this client ' + parseWebsocket.clientId); + + return; + } + + const subscriptionInfo = client.getSubscriptionInfo(requestId); + + if (typeof subscriptionInfo === 'undefined') { + _Client.Client.pushError(parseWebsocket, 2, 'Cannot find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId + '. Make sure you subscribe to live query server before unsubscribing.'); + + _logger.default.error('Can not find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId); + + return; + } // Remove subscription from client + + + client.deleteSubscriptionInfo(requestId); // Remove client from subscription + + const subscription = subscriptionInfo.subscription; + const className = subscription.className; + subscription.deleteClientSubscription(parseWebsocket.clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions + + const classSubscriptions = this.subscriptions.get(className); + + if (!subscription.hasSubscribingClient()) { + classSubscriptions.delete(subscription.hash); + } // If there is no subscriptions under this class, remove it from subscriptions + + + if (classSubscriptions.size === 0) { + this.subscriptions.delete(className); + } + + (0, _triggers.runLiveQueryEventHandlers)({ + client, + event: 'unsubscribe', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + sessionToken: subscriptionInfo.sessionToken, + useMasterKey: client.hasMasterKey, + installationId: client.installationId + }); + + if (!notifyClient) { + return; + } + + client.pushUnsubscribe(request.requestId); + + _logger.default.verbose(`Delete client: ${parseWebsocket.clientId} | subscription: ${request.requestId}`); + } + +} + +exports.ParseLiveQueryServer = ParseLiveQueryServer; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VMaXZlUXVlcnlTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsImNvbmZpZyIsInBhcnNlU2VydmVyQ29uZmlnIiwiY2xpZW50cyIsIk1hcCIsInN1YnNjcmlwdGlvbnMiLCJhcHBJZCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsIm1hc3RlcktleSIsImtleVBhaXJzIiwia2V5IiwiT2JqZWN0Iiwia2V5cyIsInNldCIsImxvZ2dlciIsInZlcmJvc2UiLCJkaXNhYmxlU2luZ2xlSW5zdGFuY2UiLCJzZXJ2ZXJVUkwiLCJpbml0aWFsaXplIiwiamF2YVNjcmlwdEtleSIsImNhY2hlQ29udHJvbGxlciIsImNhY2hlVGltZW91dCIsImF1dGhDYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsInBhcnNlV2ViU29ja2V0U2VydmVyIiwiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJwYXJzZVdlYnNvY2tldCIsIl9vbkNvbm5lY3QiLCJzdWJzY3JpYmVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVTdWJzY3JpYmVyIiwic3Vic2NyaWJlIiwib24iLCJjaGFubmVsIiwibWVzc2FnZVN0ciIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJlIiwiZXJyb3IiLCJfaW5mbGF0ZVBhcnNlT2JqZWN0IiwiX29uQWZ0ZXJTYXZlIiwiX29uQWZ0ZXJEZWxldGUiLCJjdXJyZW50UGFyc2VPYmplY3QiLCJVc2VyUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsImNsYXNzTmFtZSIsInBhcnNlT2JqZWN0IiwiX2ZpbmlzaEZldGNoIiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImRlbGV0ZWRQYXJzZU9iamVjdCIsInRvSlNPTiIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlkIiwic2l6ZSIsImNsYXNzU3Vic2NyaXB0aW9ucyIsImdldCIsImRlYnVnIiwic3Vic2NyaXB0aW9uIiwidmFsdWVzIiwiaXNTdWJzY3JpcHRpb25NYXRjaGVkIiwiX21hdGNoZXNTdWJzY3JpcHRpb24iLCJjbGllbnRJZCIsInJlcXVlc3RJZHMiLCJfIiwiZW50cmllcyIsImNsaWVudFJlcXVlc3RJZHMiLCJjbGllbnQiLCJyZXF1ZXN0SWQiLCJhY2wiLCJnZXRBQ0wiLCJvcCIsIl9nZXRDTFBPcGVyYXRpb24iLCJxdWVyeSIsInJlcyIsIl9tYXRjaGVzQ0xQIiwidGhlbiIsIl9tYXRjaGVzQUNMIiwiaXNNYXRjaGVkIiwiZXZlbnQiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3QiLCJ1c2VNYXN0ZXJLZXkiLCJoYXNNYXN0ZXJLZXkiLCJpbnN0YWxsYXRpb25JZCIsInNlbmRFdmVudCIsInB1c2hEZWxldGUiLCJjYXRjaCIsIkNsaWVudCIsInB1c2hFcnJvciIsInBhcnNlV2ViU29ja2V0IiwiY29kZSIsInN0cmluZ2lmeSIsImlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkIiwiaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCIsIm9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvcmlnaW5hbEFDTCIsImN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UiLCJjdXJyZW50QUNMIiwiYWxsIiwiaXNPcmlnaW5hbE1hdGNoZWQiLCJpc0N1cnJlbnRNYXRjaGVkIiwiaGFzaCIsInR5cGUiLCJvcmlnaW5hbCIsImZ1bmN0aW9uTmFtZSIsInJlcXVlc3QiLCJ0djQiLCJ2YWxpZGF0ZSIsIlJlcXVlc3RTY2hlbWEiLCJfaGFuZGxlQ29ubmVjdCIsIl9oYW5kbGVTdWJzY3JpYmUiLCJfaGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uIiwiX2hhbmRsZVVuc3Vic2NyaWJlIiwiaW5mbyIsImhhcyIsImRlbGV0ZSIsInN1YnNjcmlwdGlvbkluZm8iLCJzdWJzY3JpcHRpb25JbmZvcyIsImRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbiIsImhhc1N1YnNjcmliaW5nQ2xpZW50IiwiZ2V0QXV0aEZvclNlc3Npb25Ub2tlbiIsImZyb21DYWNoZSIsImF1dGhQcm9taXNlIiwiYXV0aCIsInVzZXJJZCIsInVzZXIiLCJyZXN1bHQiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsImRlbCIsImdldFN1YnNjcmlwdGlvbkluZm8iLCJhY2xHcm91cCIsInB1c2giLCJTY2hlbWFDb250cm9sbGVyIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwibGVuZ3RoIiwib2JqZWN0SWQiLCJfdmVyaWZ5QUNMIiwidG9rZW4iLCJpc1N1YnNjcmlwdGlvblNlc3Npb25Ub2tlbk1hdGNoZWQiLCJnZXRSZWFkQWNjZXNzIiwiYWNsX2hhc19yb2xlcyIsInBlcm1pc3Npb25zQnlJZCIsInNvbWUiLCJzdGFydHNXaXRoIiwicm9sZU5hbWVzIiwiZ2V0VXNlclJvbGVzIiwicm9sZSIsImdldFB1YmxpY1JlYWRBY2Nlc3MiLCJzdWJzY3JpcHRpb25Ub2tlbiIsImNsaWVudFNlc3Npb25Ub2tlbiIsIl92YWxpZGF0ZUtleXMiLCJfaGFzTWFzdGVyS2V5IiwicmVxIiwicHVzaENvbm5lY3QiLCJ2YWxpZEtleVBhaXJzIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaXNWYWxpZCIsInNlY3JldCIsInN1YnNjcmlwdGlvbkhhc2giLCJTdWJzY3JpcHRpb24iLCJ3aGVyZSIsImZpZWxkcyIsImFkZFN1YnNjcmlwdGlvbkluZm8iLCJhZGRDbGllbnRTdWJzY3JpcHRpb24iLCJwdXNoU3Vic2NyaWJlIiwibm90aWZ5Q2xpZW50IiwiZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyIsInB1c2hVbnN1YnNjcmliZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQU1BOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEsb0JBQU4sQ0FBMkI7QUFFekI7QUFJ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S3BELGFBQUwsQ0FBbUJvSCxNQUFuQixDQUEwQnhFLFNBQTFCO0FBQ0Q7O0FBQ0QsNkNBQTBCO0FBQ3hCcUIsTUFBQUEsTUFEd0I7QUFFeEJZLE1BQUFBLEtBQUssRUFBRSxhQUZpQjtBQUd4Qi9FLE1BQUFBLE9BQU8sRUFBRSxLQUFLQSxPQUFMLENBQWFzRCxJQUhFO0FBSXhCcEQsTUFBQUEsYUFBYSxFQUFFLEtBQUtBLGFBQUwsQ0FBbUJvRCxJQUpWO0FBS3hCMEIsTUFBQUEsWUFBWSxFQUFFdUMsZ0JBQWdCLENBQUN2QyxZQUxQO0FBTXhCRSxNQUFBQSxZQUFZLEVBQUVmLE1BQU0sQ0FBQ2dCLFlBTkc7QUFPeEJDLE1BQUFBLGNBQWMsRUFBRWpCLE1BQU0sQ0FBQ2lCO0FBUEMsS0FBMUI7O0FBVUEsUUFBSSxDQUFDdUYsWUFBTCxFQUFtQjtBQUNqQjtBQUNEOztBQUVEeEcsSUFBQUEsTUFBTSxDQUFDMEcsZUFBUCxDQUF1QmpFLE9BQU8sQ0FBQ3hDLFNBQS9COztBQUVBeEQsb0JBQU9DLE9BQVAsQ0FDRyxrQkFBaUJhLGNBQWMsQ0FBQ29DLFFBQVMsb0JBQW1COEMsT0FBTyxDQUFDeEMsU0FBVSxFQURqRjtBQUdEOztBQXJ4QndCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR2NCBmcm9tICd0djQnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAnLi9TdWJzY3JpcHRpb24nO1xuaW1wb3J0IHsgQ2xpZW50IH0gZnJvbSAnLi9DbGllbnQnO1xuaW1wb3J0IHsgUGFyc2VXZWJTb2NrZXRTZXJ2ZXIgfSBmcm9tICcuL1BhcnNlV2ViU29ja2V0U2VydmVyJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCBSZXF1ZXN0U2NoZW1hIGZyb20gJy4vUmVxdWVzdFNjaGVtYSc7XG5pbXBvcnQgeyBtYXRjaGVzUXVlcnksIHF1ZXJ5SGFzaCB9IGZyb20gJy4vUXVlcnlUb29scyc7XG5pbXBvcnQgeyBQYXJzZVB1YlN1YiB9IGZyb20gJy4vUGFyc2VQdWJTdWInO1xuaW1wb3J0IFNjaGVtYUNvbnRyb2xsZXIgZnJvbSAnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5pbXBvcnQge1xuICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzLFxuICBtYXliZVJ1bkNvbm5lY3RUcmlnZ2VyLFxuICBtYXliZVJ1blN1YnNjcmliZVRyaWdnZXIsXG4gIG1heWJlUnVuQWZ0ZXJFdmVudFRyaWdnZXIsXG59IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCB7IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4sIEF1dGggfSBmcm9tICcuLi9BdXRoJztcbmltcG9ydCB7IGdldENhY2hlQ29udHJvbGxlciB9IGZyb20gJy4uL0NvbnRyb2xsZXJzJztcbmltcG9ydCBMUlUgZnJvbSAnbHJ1LWNhY2hlJztcbmltcG9ydCBVc2VyUm91dGVyIGZyb20gJy4uL1JvdXRlcnMvVXNlcnNSb3V0ZXInO1xuXG5jbGFzcyBQYXJzZUxpdmVRdWVyeVNlcnZlciB7XG4gIGNsaWVudHM6IE1hcDtcbiAgLy8gY2xhc3NOYW1lIC0+IChxdWVyeUhhc2ggLT4gc3Vic2NyaXB0aW9uKVxuICBzdWJzY3JpcHRpb25zOiBPYmplY3Q7XG4gIHBhcnNlV2ViU29ja2V0U2VydmVyOiBPYmplY3Q7XG4gIGtleVBhaXJzOiBhbnk7XG4gIC8vIFRoZSBzdWJzY3JpYmVyIHdlIHVzZSB0byBnZXQgb2JqZWN0IHVwZGF0ZSBmcm9tIHB1Ymxpc2hlclxuICBzdWJzY3JpYmVyOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3Ioc2VydmVyOiBhbnksIGNvbmZpZzogYW55ID0ge30sIHBhcnNlU2VydmVyQ29uZmlnOiBhbnkgPSB7fSkge1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuICAgIHRoaXMuY2xpZW50cyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG5cbiAgICBjb25maWcuYXBwSWQgPSBjb25maWcuYXBwSWQgfHwgUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgICBjb25maWcubWFzdGVyS2V5ID0gY29uZmlnLm1hc3RlcktleSB8fCBQYXJzZS5tYXN0ZXJLZXk7XG5cbiAgICAvLyBTdG9yZSBrZXlzLCBjb252ZXJ0IG9iaiB0byBtYXBcbiAgICBjb25zdCBrZXlQYWlycyA9IGNvbmZpZy5rZXlQYWlycyB8fCB7fTtcbiAgICB0aGlzLmtleVBhaXJzID0gbmV3IE1hcCgpO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGtleVBhaXJzKSkge1xuICAgICAgdGhpcy5rZXlQYWlycy5zZXQoa2V5LCBrZXlQYWlyc1trZXldKTtcbiAgICB9XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ1N1cHBvcnQga2V5IHBhaXJzJywgdGhpcy5rZXlQYWlycyk7XG5cbiAgICAvLyBJbml0aWFsaXplIFBhcnNlXG4gICAgUGFyc2UuT2JqZWN0LmRpc2FibGVTaW5nbGVJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHNlcnZlclVSTCA9IGNvbmZpZy5zZXJ2ZXJVUkwgfHwgUGFyc2Uuc2VydmVyVVJMO1xuICAgIFBhcnNlLnNlcnZlclVSTCA9IHNlcnZlclVSTDtcbiAgICBQYXJzZS5pbml0aWFsaXplKGNvbmZpZy5hcHBJZCwgUGFyc2UuamF2YVNjcmlwdEtleSwgY29uZmlnLm1hc3RlcktleSk7XG5cbiAgICAvLyBUaGUgY2FjaGUgY29udHJvbGxlciBpcyBhIHByb3BlciBjYWNoZSBjb250cm9sbGVyXG4gICAgLy8gd2l0aCBhY2Nlc3MgdG8gVXNlciBhbmQgUm9sZXNcbiAgICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGdldENhY2hlQ29udHJvbGxlcihwYXJzZVNlcnZlckNvbmZpZyk7XG5cbiAgICBjb25maWcuY2FjaGVUaW1lb3V0ID0gY29uZmlnLmNhY2hlVGltZW91dCB8fCA1ICogMTAwMDsgLy8gNXNcblxuICAgIC8vIFRoaXMgYXV0aCBjYWNoZSBzdG9yZXMgdGhlIHByb21pc2VzIGZvciBlYWNoIGF1dGggcmVzb2x1dGlvbi5cbiAgICAvLyBUaGUgbWFpbiBiZW5lZml0IGlzIHRvIGJlIGFibGUgdG8gcmV1c2UgdGhlIHNhbWUgdXNlciAvIHNlc3Npb24gdG9rZW4gcmVzb2x1dGlvbi5cbiAgICB0aGlzLmF1dGhDYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiA1MDAsIC8vIDUwMCBjb25jdXJyZW50XG4gICAgICBtYXhBZ2U6IGNvbmZpZy5jYWNoZVRpbWVvdXQsXG4gICAgfSk7XG4gICAgLy8gSW5pdGlhbGl6ZSB3ZWJzb2NrZXQgc2VydmVyXG4gICAgdGhpcy5wYXJzZVdlYlNvY2tldFNlcnZlciA9IG5ldyBQYXJzZVdlYlNvY2tldFNlcnZlcihcbiAgICAgIHNlcnZlcixcbiAgICAgIHBhcnNlV2Vic29ja2V0ID0+IHRoaXMuX29uQ29ubmVjdChwYXJzZVdlYnNvY2tldCksXG4gICAgICBjb25maWdcbiAgICApO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBzdWJzY3JpYmVyXG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICAgIHRoaXMuc3Vic2NyaWJlci5zdWJzY3JpYmUoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUnKTtcbiAgICB0aGlzLnN1YnNjcmliZXIuc3Vic2NyaWJlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUnKTtcbiAgICAvLyBSZWdpc3RlciBtZXNzYWdlIGhhbmRsZXIgZm9yIHN1YnNjcmliZXIuIFdoZW4gcHVibGlzaGVyIGdldCBtZXNzYWdlcywgaXQgd2lsbCBwdWJsaXNoIG1lc3NhZ2VcbiAgICAvLyB0byB0aGUgc3Vic2NyaWJlcnMgYW5kIHRoZSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkLlxuICAgIHRoaXMuc3Vic2NyaWJlci5vbignbWVzc2FnZScsIChjaGFubmVsLCBtZXNzYWdlU3RyKSA9PiB7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnU3Vic2NyaWJlIG1lc3NzYWdlICVqJywgbWVzc2FnZVN0cik7XG4gICAgICBsZXQgbWVzc2FnZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1lc3NhZ2UgPSBKU09OLnBhcnNlKG1lc3NhZ2VTdHIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSBtZXNzYWdlJywgbWVzc2FnZVN0ciwgZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2luZmxhdGVQYXJzZU9iamVjdChtZXNzYWdlKTtcbiAgICAgIGlmIChjaGFubmVsID09PSBQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyU2F2ZScpIHtcbiAgICAgICAgdGhpcy5fb25BZnRlclNhdmUobWVzc2FnZSk7XG4gICAgICB9IGVsc2UgaWYgKGNoYW5uZWwgPT09IFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUnKSB7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJEZWxldGUobWVzc2FnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCBtZXNzYWdlICVzIGZyb20gdW5rbm93biBjaGFubmVsICVqJywgbWVzc2FnZSwgY2hhbm5lbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlci4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IEpTT04gYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdCBKU09OLlxuICBfaW5mbGF0ZVBhcnNlT2JqZWN0KG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIC8vIEluZmxhdGUgbWVyZ2VkIG9iamVjdFxuICAgIGNvbnN0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0O1xuICAgIFVzZXJSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyhjdXJyZW50UGFyc2VPYmplY3QpO1xuICAgIGxldCBjbGFzc05hbWUgPSBjdXJyZW50UGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxldCBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICBwYXJzZU9iamVjdC5fZmluaXNoRmV0Y2goY3VycmVudFBhcnNlT2JqZWN0KTtcbiAgICBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIC8vIEluZmxhdGUgb3JpZ2luYWwgb2JqZWN0XG4gICAgY29uc3Qgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgICBpZiAob3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgVXNlclJvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKG9yaWdpbmFsUGFyc2VPYmplY3QpO1xuICAgICAgY2xhc3NOYW1lID0gb3JpZ2luYWxQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgICBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICAgIHBhcnNlT2JqZWN0Ll9maW5pc2hGZXRjaChvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgIG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIH1cbiAgfVxuXG4gIC8vIE1lc3NhZ2UgaXMgdGhlIEpTT04gb2JqZWN0IGZyb20gcHVibGlzaGVyIGFmdGVyIGluZmxhdGVkLiBNZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCBpcyB0aGUgUGFyc2VPYmplY3QgYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdC5cbiAgX29uQWZ0ZXJEZWxldGUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZSBpcyB0cmlnZ2VyZWQnKTtcblxuICAgIGxldCBkZWxldGVkUGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICBjb25zdCBjbGFzc0xldmVsUGVybWlzc2lvbnMgPSBtZXNzYWdlLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICBjb25zdCBjbGFzc05hbWUgPSBkZWxldGVkUGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDbGFzc05hbWU6ICVqIHwgT2JqZWN0SWQ6ICVzJywgY2xhc3NOYW1lLCBkZWxldGVkUGFyc2VPYmplY3QuaWQpO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXIgOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcblxuICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICBpZiAodHlwZW9mIGNsYXNzU3Vic2NyaXB0aW9ucyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2FuIG5vdCBmaW5kIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcyAnICsgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2YgY2xhc3NTdWJzY3JpcHRpb25zLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBpc1N1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKGRlbGV0ZWRQYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIGlmICghaXNTdWJzY3JpcHRpb25NYXRjaGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICBjb25zdCBhY2wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAvLyBDaGVjayBDTFBcbiAgICAgICAgICBjb25zdCBvcCA9IHRoaXMuX2dldENMUE9wZXJhdGlvbihzdWJzY3JpcHRpb24ucXVlcnkpO1xuICAgICAgICAgIGxldCByZXMgPSB7fTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gQ2hlY2sgQUNMXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXRjaGVzQUNMKGFjbCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKGlzTWF0Y2hlZCA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNNYXRjaGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiAnRGVsZXRlJyxcbiAgICAgICAgICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBkZWxldGVkUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgICAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgc2VuZEV2ZW50OiB0cnVlLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICByZXR1cm4gbWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlcignYWZ0ZXJFdmVudCcsIGNsYXNzTmFtZSwgcmVzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghcmVzLnNlbmRFdmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVzLm9iamVjdCAmJiB0eXBlb2YgcmVzLm9iamVjdC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBkZWxldGVkUGFyc2VPYmplY3QgPSByZXMub2JqZWN0LnRvSlNPTigpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZWRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2xpZW50LnB1c2hEZWxldGUocmVxdWVzdElkLCBkZWxldGVkUGFyc2VPYmplY3QpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgICAgICAgICAgY2xpZW50LnBhcnNlV2ViU29ja2V0LFxuICAgICAgICAgICAgICAgIGVycm9yLmNvZGUgfHwgMTQxLFxuICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTWVzc2FnZSBpcyB0aGUgSlNPTiBvYmplY3QgZnJvbSBwdWJsaXNoZXIgYWZ0ZXIgaW5mbGF0ZWQuIE1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0IGlzIHRoZSBQYXJzZU9iamVjdCBhZnRlciBjaGFuZ2VzLlxuICAvLyBNZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgaXMgdGhlIG9yaWdpbmFsIFBhcnNlT2JqZWN0LlxuICBfb25BZnRlclNhdmUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUgaXMgdHJpZ2dlcmVkJyk7XG5cbiAgICBsZXQgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG51bGw7XG4gICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICB9XG4gICAgY29uc3QgY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gbWVzc2FnZS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgbGV0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LnRvSlNPTigpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0NsYXNzTmFtZTogJXMgfCBPYmplY3RJZDogJXMnLCBjbGFzc05hbWUsIGN1cnJlbnRQYXJzZU9iamVjdC5pZCk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50IG51bWJlciA6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICh0eXBlb2YgY2xhc3NTdWJzY3JpcHRpb25zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9ucyB1bmRlciB0aGlzIGNsYXNzICcgKyBjbGFzc05hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHN1YnNjcmlwdGlvbiBvZiBjbGFzc1N1YnNjcmlwdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkID0gdGhpcy5fbWF0Y2hlc1N1YnNjcmlwdGlvbihcbiAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgY29uc3QgaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCA9IHRoaXMuX21hdGNoZXNTdWJzY3JpcHRpb24oXG4gICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICAvLyBTZXQgb3JpZ25hbCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlO1xuICAgICAgICAgIGlmICghaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG9yaWdpbmFsQUNMO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgICAgICAgICBvcmlnaW5hbEFDTCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gdGhpcy5fbWF0Y2hlc0FDTChvcmlnaW5hbEFDTCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTZXQgY3VycmVudCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2U7XG4gICAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICAgIGlmICghaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCkge1xuICAgICAgICAgICAgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRBQ0wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UgPSB0aGlzLl9tYXRjaGVzQUNMKGN1cnJlbnRBQ0wsIGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgb3AgPSB0aGlzLl9nZXRDTFBPcGVyYXRpb24oc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSwgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKChbaXNPcmlnaW5hbE1hdGNoZWQsIGlzQ3VycmVudE1hdGNoZWRdKSA9PiB7XG4gICAgICAgICAgICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgICAgICdPcmlnaW5hbCAlaiB8IEN1cnJlbnQgJWogfCBNYXRjaDogJXMsICVzLCAlcywgJXMgfCBRdWVyeTogJXMnLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICAgIGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkLFxuICAgICAgICAgICAgICAgIGlzQ3VycmVudFN1YnNjcmlwdGlvbk1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNPcmlnaW5hbE1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNDdXJyZW50TWF0Y2hlZCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uaGFzaFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAvLyBEZWNpZGUgZXZlbnQgdHlwZVxuICAgICAgICAgICAgICBsZXQgdHlwZTtcbiAgICAgICAgICAgICAgaWYgKGlzT3JpZ2luYWxNYXRjaGVkICYmIGlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ1VwZGF0ZSc7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPcmlnaW5hbE1hdGNoZWQgJiYgIWlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ0xlYXZlJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNPcmlnaW5hbE1hdGNoZWQgJiYgaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICB0eXBlID0gJ0VudGVyJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdHlwZSA9ICdDcmVhdGUnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBtZXNzYWdlLmV2ZW50ID0gdHlwZTtcbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiB0eXBlLFxuICAgICAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogY2xpZW50LnNlc3Npb25Ub2tlbixcbiAgICAgICAgICAgICAgICBvYmplY3Q6IGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbDogb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBzZW5kRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHJldHVybiBtYXliZVJ1bkFmdGVyRXZlbnRUcmlnZ2VyKCdhZnRlckV2ZW50JywgY2xhc3NOYW1lLCByZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXMuc2VuZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXMub2JqZWN0ICYmIHR5cGVvZiByZXMub2JqZWN0LnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0ID0gcmVzLm9iamVjdC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSByZXMub2JqZWN0LmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcy5vcmlnaW5hbCAmJiB0eXBlb2YgcmVzLm9yaWdpbmFsLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IHJlcy5vcmlnaW5hbC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QuY2xhc3NOYW1lID0gcmVzLm9yaWdpbmFsLmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9ICdwdXNoJyArIG1lc3NhZ2UuZXZlbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGNsaWVudFtmdW5jdGlvbk5hbWVdKSB7XG4gICAgICAgICAgICAgICAgICBjbGllbnRbZnVuY3Rpb25OYW1lXShyZXF1ZXN0SWQsIGN1cnJlbnRQYXJzZU9iamVjdCwgb3JpZ2luYWxQYXJzZU9iamVjdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgICAgICAgICAgIGNsaWVudC5wYXJzZVdlYlNvY2tldCxcbiAgICAgICAgICAgICAgICAgIGVycm9yLmNvZGUgfHwgMTQxLFxuICAgICAgICAgICAgICAgICAgZXJyb3IubWVzc2FnZSB8fCBlcnJvcixcbiAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVycm9yKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfb25Db25uZWN0KHBhcnNlV2Vic29ja2V0OiBhbnkpOiB2b2lkIHtcbiAgICBwYXJzZVdlYnNvY2tldC5vbignbWVzc2FnZScsIHJlcXVlc3QgPT4ge1xuICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0ID09PSAnc3RyaW5nJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlcXVlc3QgPSBKU09OLnBhcnNlKHJlcXVlc3QpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCd1bmFibGUgdG8gcGFyc2UgcmVxdWVzdCcsIHJlcXVlc3QsIGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ1JlcXVlc3Q6ICVqJywgcmVxdWVzdCk7XG5cbiAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhpcyByZXF1ZXN0IGlzIGEgdmFsaWQgcmVxdWVzdCwgcmV0dXJuIGVycm9yIGRpcmVjdGx5IGlmIG5vdFxuICAgICAgaWYgKFxuICAgICAgICAhdHY0LnZhbGlkYXRlKHJlcXVlc3QsIFJlcXVlc3RTY2hlbWFbJ2dlbmVyYWwnXSkgfHxcbiAgICAgICAgIXR2NC52YWxpZGF0ZShyZXF1ZXN0LCBSZXF1ZXN0U2NoZW1hW3JlcXVlc3Qub3BdKVxuICAgICAgKSB7XG4gICAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDEsIHR2NC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdDb25uZWN0IG1lc3NhZ2UgZXJyb3IgJXMnLCB0djQuZXJyb3IubWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChyZXF1ZXN0Lm9wKSB7XG4gICAgICAgIGNhc2UgJ2Nvbm5lY3QnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZUNvbm5lY3QocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdzdWJzY3JpYmUnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZVN1YnNjcmliZShwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3VwZGF0ZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndW5zdWJzY3JpYmUnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCAzLCAnR2V0IHVua25vd24gb3BlcmF0aW9uJyk7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdHZXQgdW5rbm93biBvcGVyYXRpb24nLCByZXF1ZXN0Lm9wKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHBhcnNlV2Vic29ja2V0Lm9uKCdkaXNjb25uZWN0JywgKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYENsaWVudCBkaXNjb25uZWN0OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfWApO1xuICAgICAgY29uc3QgY2xpZW50SWQgPSBwYXJzZVdlYnNvY2tldC5jbGllbnRJZDtcbiAgICAgIGlmICghdGhpcy5jbGllbnRzLmhhcyhjbGllbnRJZCkpIHtcbiAgICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICAgICAgZXZlbnQ6ICd3c19kaXNjb25uZWN0X2Vycm9yJyxcbiAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICBlcnJvcjogYFVuYWJsZSB0byBmaW5kIGNsaWVudCAke2NsaWVudElkfWAsXG4gICAgICAgIH0pO1xuICAgICAgICBsb2dnZXIuZXJyb3IoYENhbiBub3QgZmluZCBjbGllbnQgJHtjbGllbnRJZH0gb24gZGlzY29ubmVjdGApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIERlbGV0ZSBjbGllbnRcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQoY2xpZW50SWQpO1xuICAgICAgdGhpcy5jbGllbnRzLmRlbGV0ZShjbGllbnRJZCk7XG5cbiAgICAgIC8vIERlbGV0ZSBjbGllbnQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICBmb3IgKGNvbnN0IFtyZXF1ZXN0SWQsIHN1YnNjcmlwdGlvbkluZm9dIG9mIF8uZW50cmllcyhjbGllbnQuc3Vic2NyaXB0aW9uSW5mb3MpKSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHN1YnNjcmlwdGlvbkluZm8uc3Vic2NyaXB0aW9uO1xuICAgICAgICBzdWJzY3JpcHRpb24uZGVsZXRlQ2xpZW50U3Vic2NyaXB0aW9uKGNsaWVudElkLCByZXF1ZXN0SWQpO1xuXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNsaWVudCB3aGljaCBpcyBzdWJzY3JpYmluZyB0aGlzIHN1YnNjcmlwdGlvbiwgcmVtb3ZlIGl0IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgICAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KHN1YnNjcmlwdGlvbi5jbGFzc05hbWUpO1xuICAgICAgICBpZiAoIXN1YnNjcmlwdGlvbi5oYXNTdWJzY3JpYmluZ0NsaWVudCgpKSB7XG4gICAgICAgICAgY2xhc3NTdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uaGFzaCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gc3Vic2NyaXB0aW9ucyB1bmRlciB0aGlzIGNsYXNzLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uLmNsYXNzTmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50cyAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcbiAgICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IHN1YnNjcmlwdGlvbnMgJWQnLCB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSk7XG4gICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgZXZlbnQ6ICd3c19kaXNjb25uZWN0JyxcbiAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgZXZlbnQ6ICd3c19jb25uZWN0JyxcbiAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgfSk7XG4gIH1cblxuICBfbWF0Y2hlc1N1YnNjcmlwdGlvbihwYXJzZU9iamVjdDogYW55LCBzdWJzY3JpcHRpb246IGFueSk6IGJvb2xlYW4ge1xuICAgIC8vIE9iamVjdCBpcyB1bmRlZmluZWQgb3IgbnVsbCwgbm90IG1hdGNoXG4gICAgaWYgKCFwYXJzZU9iamVjdCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hlc1F1ZXJ5KHBhcnNlT2JqZWN0LCBzdWJzY3JpcHRpb24ucXVlcnkpO1xuICB9XG5cbiAgZ2V0QXV0aEZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW46ID9zdHJpbmcpOiBQcm9taXNlPHsgYXV0aDogP0F1dGgsIHVzZXJJZDogP3N0cmluZyB9PiB7XG4gICAgaWYgKCFzZXNzaW9uVG9rZW4pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ2FjaGUgPSB0aGlzLmF1dGhDYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAoZnJvbUNhY2hlKSB7XG4gICAgICByZXR1cm4gZnJvbUNhY2hlO1xuICAgIH1cbiAgICBjb25zdCBhdXRoUHJvbWlzZSA9IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgY2FjaGVDb250cm9sbGVyOiB0aGlzLmNhY2hlQ29udHJvbGxlcixcbiAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgIH0pXG4gICAgICAudGhlbihhdXRoID0+IHtcbiAgICAgICAgcmV0dXJuIHsgYXV0aCwgdXNlcklkOiBhdXRoICYmIGF1dGgudXNlciAmJiBhdXRoLnVzZXIuaWQgfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvLyBUaGVyZSB3YXMgYW4gZXJyb3Igd2l0aCB0aGUgc2Vzc2lvbiB0b2tlblxuICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTikge1xuICAgICAgICAgIHJlc3VsdC5lcnJvciA9IGVycm9yO1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLnNldChzZXNzaW9uVG9rZW4sIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLCB0aGlzLmNvbmZpZy5jYWNoZVRpbWVvdXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLmRlbChzZXNzaW9uVG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB0aGlzLmF1dGhDYWNoZS5zZXQoc2Vzc2lvblRva2VuLCBhdXRoUHJvbWlzZSk7XG4gICAgcmV0dXJuIGF1dGhQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgX21hdGNoZXNDTFAoXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55LFxuICAgIG9iamVjdDogYW55LFxuICAgIGNsaWVudDogYW55LFxuICAgIHJlcXVlc3RJZDogbnVtYmVyLFxuICAgIG9wOiBzdHJpbmdcbiAgKTogYW55IHtcbiAgICAvLyB0cnkgdG8gbWF0Y2ggb24gdXNlciBmaXJzdCwgbGVzcyBleHBlbnNpdmUgdGhhbiB3aXRoIHJvbGVzXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgY29uc3QgYWNsR3JvdXAgPSBbJyonXTtcbiAgICBsZXQgdXNlcklkO1xuICAgIGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSW5mbyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnN0IHsgdXNlcklkIH0gPSBhd2FpdCB0aGlzLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4pO1xuICAgICAgaWYgKHVzZXJJZCkge1xuICAgICAgICBhY2xHcm91cC5wdXNoKHVzZXJJZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBTY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihcbiAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICBvYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgb3BcbiAgICAgICk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZShgRmFpbGVkIG1hdGNoaW5nIENMUCBmb3IgJHtvYmplY3QuaWR9ICR7dXNlcklkfSAke2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFRPRE86IGhhbmRsZSByb2xlcyBwZXJtaXNzaW9uc1xuICAgIC8vIE9iamVjdC5rZXlzKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgLy8gICBjb25zdCBwZXJtID0gY2xhc3NMZXZlbFBlcm1pc3Npb25zW2tleV07XG4gICAgLy8gICBPYmplY3Qua2V5cyhwZXJtKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAvLyAgICAgaWYgKGtleS5pbmRleE9mKCdyb2xlJykpXG4gICAgLy8gICB9KTtcbiAgICAvLyB9KVxuICAgIC8vIC8vIGl0J3MgcmVqZWN0ZWQgaGVyZSwgY2hlY2sgdGhlIHJvbGVzXG4gICAgLy8gdmFyIHJvbGVzUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoUGFyc2UuUm9sZSk7XG4gICAgLy8gcm9sZXNRdWVyeS5lcXVhbFRvKFwidXNlcnNcIiwgdXNlcik7XG4gICAgLy8gcmV0dXJuIHJvbGVzUXVlcnkuZmluZCh7dXNlTWFzdGVyS2V5OnRydWV9KTtcbiAgfVxuXG4gIF9nZXRDTFBPcGVyYXRpb24ocXVlcnk6IGFueSkge1xuICAgIHJldHVybiB0eXBlb2YgcXVlcnkgPT09ICdvYmplY3QnICYmXG4gICAgICBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoID09IDEgJiZcbiAgICAgIHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZydcbiAgICAgID8gJ2dldCdcbiAgICAgIDogJ2ZpbmQnO1xuICB9XG5cbiAgYXN5bmMgX3ZlcmlmeUFDTChhY2w6IGFueSwgdG9rZW46IHN0cmluZykge1xuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGF1dGgsIHVzZXJJZCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHRva2VuKTtcblxuICAgIC8vIEdldHRpbmcgdGhlIHNlc3Npb24gdG9rZW4gZmFpbGVkXG4gICAgLy8gVGhpcyBtZWFucyB0aGF0IG5vIGFkZGl0aW9uYWwgYXV0aCBpcyBhdmFpbGFibGVcbiAgICAvLyBBdCB0aGlzIHBvaW50LCBqdXN0IGJhaWwgb3V0IGFzIG5vIGFkZGl0aW9uYWwgdmlzaWJpbGl0eSBjYW4gYmUgaW5mZXJyZWQuXG4gICAgaWYgKCFhdXRoIHx8ICF1c2VySWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkID0gYWNsLmdldFJlYWRBY2Nlc3ModXNlcklkKTtcbiAgICBpZiAoaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBoYXMgYW55IHJvbGVzIHRoYXQgbWF0Y2ggdGhlIEFDTFxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBSZXNvbHZlIGZhbHNlIHJpZ2h0IGF3YXkgaWYgdGhlIGFjbCBkb2Vzbid0IGhhdmUgYW55IHJvbGVzXG4gICAgICAgIGNvbnN0IGFjbF9oYXNfcm9sZXMgPSBPYmplY3Qua2V5cyhhY2wucGVybWlzc2lvbnNCeUlkKS5zb21lKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgncm9sZTonKSk7XG4gICAgICAgIGlmICghYWNsX2hhc19yb2xlcykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IGF1dGguZ2V0VXNlclJvbGVzKCk7XG4gICAgICAgIC8vIEZpbmFsbHksIHNlZSBpZiBhbnkgb2YgdGhlIHVzZXIncyByb2xlcyBhbGxvdyB0aGVtIHJlYWQgYWNjZXNzXG4gICAgICAgIGZvciAoY29uc3Qgcm9sZSBvZiByb2xlTmFtZXMpIHtcbiAgICAgICAgICAvLyBXZSB1c2UgZ2V0UmVhZEFjY2VzcyBhcyBgcm9sZWAgaXMgaW4gdGhlIGZvcm0gYHJvbGU6cm9sZU5hbWVgXG4gICAgICAgICAgaWYgKGFjbC5nZXRSZWFkQWNjZXNzKHJvbGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgX21hdGNoZXNBQ0woYWNsOiBhbnksIGNsaWVudDogYW55LCByZXF1ZXN0SWQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIC8vIFJldHVybiB0cnVlIGRpcmVjdGx5IGlmIEFDTCBpc24ndCBwcmVzZW50LCBBQ0wgaXMgcHVibGljIHJlYWQsIG9yIGNsaWVudCBoYXMgbWFzdGVyIGtleVxuICAgIGlmICghYWNsIHx8IGFjbC5nZXRQdWJsaWNSZWFkQWNjZXNzKCkgfHwgY2xpZW50Lmhhc01hc3RlcktleSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENoZWNrIHN1YnNjcmlwdGlvbiBzZXNzaW9uVG9rZW4gbWF0Y2hlcyBBQ0wgZmlyc3RcbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uVG9rZW4gPSBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbjtcbiAgICBjb25zdCBjbGllbnRTZXNzaW9uVG9rZW4gPSBjbGllbnQuc2Vzc2lvblRva2VuO1xuXG4gICAgaWYgKGF3YWl0IHRoaXMuX3ZlcmlmeUFDTChhY2wsIHN1YnNjcmlwdGlvblRva2VuKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGF3YWl0IHRoaXMuX3ZlcmlmeUFDTChhY2wsIGNsaWVudFNlc3Npb25Ub2tlbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVDb25uZWN0KHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgaWYgKCF0aGlzLl92YWxpZGF0ZUtleXMocmVxdWVzdCwgdGhpcy5rZXlQYWlycykpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDQsICdLZXkgaW4gcmVxdWVzdCBpcyBub3QgdmFsaWQnKTtcbiAgICAgIGxvZ2dlci5lcnJvcignS2V5IGluIHJlcXVlc3QgaXMgbm90IHZhbGlkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhhc01hc3RlcktleSA9IHRoaXMuX2hhc01hc3RlcktleShyZXF1ZXN0LCB0aGlzLmtleVBhaXJzKTtcbiAgICBjb25zdCBjbGllbnRJZCA9IHV1aWR2NCgpO1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoXG4gICAgICBjbGllbnRJZCxcbiAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgaGFzTWFzdGVyS2V5LFxuICAgICAgcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICByZXF1ZXN0Lmluc3RhbGxhdGlvbklkXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICBjbGllbnQsXG4gICAgICAgIGV2ZW50OiAnY29ubmVjdCcsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiByZXF1ZXN0LnNlc3Npb25Ub2tlbixcbiAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogcmVxdWVzdC5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBhd2FpdCBtYXliZVJ1bkNvbm5lY3RUcmlnZ2VyKCdiZWZvcmVDb25uZWN0JywgcmVxKTtcbiAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkID0gY2xpZW50SWQ7XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkLCBjbGllbnQpO1xuICAgICAgbG9nZ2VyLmluZm8oYENyZWF0ZSBuZXcgY2xpZW50OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfWApO1xuICAgICAgY2xpZW50LnB1c2hDb25uZWN0KCk7XG4gICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHJlcSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIGVycm9yLmNvZGUgfHwgMTQxLCBlcnJvci5tZXNzYWdlIHx8IGVycm9yLCBmYWxzZSk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgcnVubmluZyBiZWZvcmVDb25uZWN0IGZvciBzZXNzaW9uICR7cmVxdWVzdC5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgX2hhc01hc3RlcktleShyZXF1ZXN0OiBhbnksIHZhbGlkS2V5UGFpcnM6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICghdmFsaWRLZXlQYWlycyB8fCB2YWxpZEtleVBhaXJzLnNpemUgPT0gMCB8fCAhdmFsaWRLZXlQYWlycy5oYXMoJ21hc3RlcktleScpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghcmVxdWVzdCB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlcXVlc3QsICdtYXN0ZXJLZXknKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gcmVxdWVzdC5tYXN0ZXJLZXkgPT09IHZhbGlkS2V5UGFpcnMuZ2V0KCdtYXN0ZXJLZXknKTtcbiAgfVxuXG4gIF92YWxpZGF0ZUtleXMocmVxdWVzdDogYW55LCB2YWxpZEtleVBhaXJzOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkS2V5UGFpcnMgfHwgdmFsaWRLZXlQYWlycy5zaXplID09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsZXQgaXNWYWxpZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgW2tleSwgc2VjcmV0XSBvZiB2YWxpZEtleVBhaXJzKSB7XG4gICAgICBpZiAoIXJlcXVlc3Rba2V5XSB8fCByZXF1ZXN0W2tleV0gIT09IHNlY3JldCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBpc1ZhbGlkO1xuICB9XG5cbiAgYXN5bmMgX2hhbmRsZVN1YnNjcmliZShwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIC8vIElmIHdlIGNhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgcmV0dXJuIGVycm9yIHRvIGNsaWVudFxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhcnNlV2Vic29ja2V0LCAnY2xpZW50SWQnKSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHN1YnNjcmliaW5nJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcignQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSBzdWJzY3JpYmluZycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSByZXF1ZXN0LnF1ZXJ5LmNsYXNzTmFtZTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgbWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyKCdiZWZvcmVTdWJzY3JpYmUnLCBjbGFzc05hbWUsIHJlcXVlc3QpO1xuXG4gICAgICAvLyBHZXQgc3Vic2NyaXB0aW9uIGZyb20gc3Vic2NyaXB0aW9ucywgY3JlYXRlIG9uZSBpZiBuZWNlc3NhcnlcbiAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbkhhc2ggPSBxdWVyeUhhc2gocmVxdWVzdC5xdWVyeSk7XG4gICAgICAvLyBBZGQgY2xhc3NOYW1lIHRvIHN1YnNjcmlwdGlvbnMgaWYgbmVjZXNzYXJ5XG5cbiAgICAgIGlmICghdGhpcy5zdWJzY3JpcHRpb25zLmhhcyhjbGFzc05hbWUpKSB7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5zZXQoY2xhc3NOYW1lLCBuZXcgTWFwKCkpO1xuICAgICAgfVxuICAgICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgICAgbGV0IHN1YnNjcmlwdGlvbjtcbiAgICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuaGFzKHN1YnNjcmlwdGlvbkhhc2gpKSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbiA9IGNsYXNzU3Vic2NyaXB0aW9ucy5nZXQoc3Vic2NyaXB0aW9uSGFzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKGNsYXNzTmFtZSwgcmVxdWVzdC5xdWVyeS53aGVyZSwgc3Vic2NyaXB0aW9uSGFzaCk7XG4gICAgICAgIGNsYXNzU3Vic2NyaXB0aW9ucy5zZXQoc3Vic2NyaXB0aW9uSGFzaCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIH1cblxuICAgICAgLy8gQWRkIHN1YnNjcmlwdGlvbkluZm8gdG8gY2xpZW50XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0ge1xuICAgICAgICBzdWJzY3JpcHRpb246IHN1YnNjcmlwdGlvbixcbiAgICAgIH07XG4gICAgICAvLyBBZGQgc2VsZWN0ZWQgZmllbGRzLCBzZXNzaW9uVG9rZW4gYW5kIGluc3RhbGxhdGlvbklkIGZvciB0aGlzIHN1YnNjcmlwdGlvbiBpZiBuZWNlc3NhcnlcbiAgICAgIGlmIChyZXF1ZXN0LnF1ZXJ5LmZpZWxkcykge1xuICAgICAgICBzdWJzY3JpcHRpb25JbmZvLmZpZWxkcyA9IHJlcXVlc3QucXVlcnkuZmllbGRzO1xuICAgICAgfVxuICAgICAgaWYgKHJlcXVlc3Quc2Vzc2lvblRva2VuKSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuID0gcmVxdWVzdC5zZXNzaW9uVG9rZW47XG4gICAgICB9XG4gICAgICBjbGllbnQuYWRkU3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0LnJlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mbyk7XG5cbiAgICAgIC8vIEFkZCBjbGllbnRJZCB0byBzdWJzY3JpcHRpb25cbiAgICAgIHN1YnNjcmlwdGlvbi5hZGRDbGllbnRTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQsIHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgICAgY2xpZW50LnB1c2hTdWJzY3JpYmUocmVxdWVzdC5yZXF1ZXN0SWQpO1xuXG4gICAgICBsb2dnZXIudmVyYm9zZShcbiAgICAgICAgYENyZWF0ZSBjbGllbnQgJHtwYXJzZVdlYnNvY2tldC5jbGllbnRJZH0gbmV3IHN1YnNjcmlwdGlvbjogJHtyZXF1ZXN0LnJlcXVlc3RJZH1gXG4gICAgICApO1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50IG51bWJlcjogJWQnLCB0aGlzLmNsaWVudHMuc2l6ZSk7XG4gICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgY2xpZW50LFxuICAgICAgICBldmVudDogJ3N1YnNjcmliZScsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiByZXF1ZXN0LnNlc3Npb25Ub2tlbixcbiAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgZS5jb2RlIHx8IDE0MSwgZS5tZXNzYWdlIHx8IGUsIGZhbHNlLCByZXF1ZXN0LnJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgcnVubmluZyBiZWZvcmVTdWJzY3JpYmUgb24gJHtjbGFzc05hbWV9IGZvciBzZXNzaW9uICR7cmVxdWVzdC5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShlKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfaGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgdGhpcy5faGFuZGxlVW5zdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QsIGZhbHNlKTtcbiAgICB0aGlzLl9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICB9XG5cbiAgX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSwgbm90aWZ5Q2xpZW50OiBib29sZWFuID0gdHJ1ZSk6IGFueSB7XG4gICAgLy8gSWYgd2UgY2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCByZXR1cm4gZXJyb3IgdG8gY2xpZW50XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGFyc2VXZWJzb2NrZXQsICdjbGllbnRJZCcpKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgdW5zdWJzY3JpYmluZydcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0SWQgPSByZXF1ZXN0LnJlcXVlc3RJZDtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIGNsaWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAyLFxuICAgICAgICAnQ2Fubm90IGZpbmQgY2xpZW50IHdpdGggY2xpZW50SWQgJyArXG4gICAgICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgK1xuICAgICAgICAgICcuIE1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBsaXZlIHF1ZXJ5IHNlcnZlciBiZWZvcmUgdW5zdWJzY3JpYmluZy4nXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQgJyArIHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0Nhbm5vdCBmaW5kIHN1YnNjcmlwdGlvbiB3aXRoIGNsaWVudElkICcgK1xuICAgICAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkICtcbiAgICAgICAgICAnIHN1YnNjcmlwdGlvbklkICcgK1xuICAgICAgICAgIHJlcXVlc3RJZCArXG4gICAgICAgICAgJy4gTWFrZSBzdXJlIHlvdSBzdWJzY3JpYmUgdG8gbGl2ZSBxdWVyeSBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcuJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgJ0NhbiBub3QgZmluZCBzdWJzY3JpcHRpb24gd2l0aCBjbGllbnRJZCAnICtcbiAgICAgICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCArXG4gICAgICAgICAgJyBzdWJzY3JpcHRpb25JZCAnICtcbiAgICAgICAgICByZXF1ZXN0SWRcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHN1YnNjcmlwdGlvbiBmcm9tIGNsaWVudFxuICAgIGNsaWVudC5kZWxldGVTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgLy8gUmVtb3ZlIGNsaWVudCBmcm9tIHN1YnNjcmlwdGlvblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHN1YnNjcmlwdGlvbkluZm8uc3Vic2NyaXB0aW9uO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHN1YnNjcmlwdGlvbi5jbGFzc05hbWU7XG4gICAgc3Vic2NyaXB0aW9uLmRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBjbGllbnQgd2hpY2ggaXMgc3Vic2NyaWJpbmcgdGhpcyBzdWJzY3JpcHRpb24sIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNsYXNzTmFtZSk7XG4gICAgaWYgKCFzdWJzY3JpcHRpb24uaGFzU3Vic2NyaWJpbmdDbGllbnQoKSkge1xuICAgICAgY2xhc3NTdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uaGFzaCk7XG4gICAgfVxuICAgIC8vIElmIHRoZXJlIGlzIG5vIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcywgcmVtb3ZlIGl0IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShjbGFzc05hbWUpO1xuICAgIH1cbiAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgIGNsaWVudCxcbiAgICAgIGV2ZW50OiAndW5zdWJzY3JpYmUnLFxuICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgIHNlc3Npb25Ub2tlbjogc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuXG4gICAgaWYgKCFub3RpZnlDbGllbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjbGllbnQucHVzaFVuc3Vic2NyaWJlKHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYERlbGV0ZSBjbGllbnQ6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9IHwgc3Vic2NyaXB0aW9uOiAke3JlcXVlc3QucmVxdWVzdElkfWBcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCB7IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIH07XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParsePubSub.js b/lib/LiveQuery/ParsePubSub.js new file mode 100644 index 0000000000..87f2438cff --- /dev/null +++ b/lib/LiveQuery/ParsePubSub.js @@ -0,0 +1,49 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParsePubSub = void 0; + +var _AdapterLoader = require("../Adapters/AdapterLoader"); + +var _EventEmitterPubSub = require("../Adapters/PubSub/EventEmitterPubSub"); + +var _RedisPubSub = require("../Adapters/PubSub/RedisPubSub"); + +const ParsePubSub = {}; +exports.ParsePubSub = ParsePubSub; + +function useRedis(config) { + const redisURL = config.redisURL; + return typeof redisURL !== 'undefined' && redisURL !== ''; +} + +ParsePubSub.createPublisher = function (config) { + if (useRedis(config)) { + return _RedisPubSub.RedisPubSub.createPublisher(config); + } else { + const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); + + if (typeof adapter.createPublisher !== 'function') { + throw 'pubSubAdapter should have createPublisher()'; + } + + return adapter.createPublisher(config); + } +}; + +ParsePubSub.createSubscriber = function (config) { + if (useRedis(config)) { + return _RedisPubSub.RedisPubSub.createSubscriber(config); + } else { + const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); + + if (typeof adapter.createSubscriber !== 'function') { + throw 'pubSubAdapter should have createSubscriber()'; + } + + return adapter.createSubscriber(config); + } +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VQdWJTdWIuanMiXSwibmFtZXMiOlsiUGFyc2VQdWJTdWIiLCJ1c2VSZWRpcyIsImNvbmZpZyIsInJlZGlzVVJMIiwiY3JlYXRlUHVibGlzaGVyIiwiUmVkaXNQdWJTdWIiLCJhZGFwdGVyIiwicHViU3ViQWRhcHRlciIsIkV2ZW50RW1pdHRlclB1YlN1YiIsImNyZWF0ZVN1YnNjcmliZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFFQTs7QUFFQSxNQUFNQSxXQUFXLEdBQUcsRUFBcEI7OztBQUVBLFNBQVNDLFFBQVQsQ0FBa0JDLE1BQWxCLEVBQXdDO0FBQ3RDLFFBQU1DLFFBQVEsR0FBR0QsTUFBTSxDQUFDQyxRQUF4QjtBQUNBLFNBQU8sT0FBT0EsUUFBUCxLQUFvQixXQUFwQixJQUFtQ0EsUUFBUSxLQUFLLEVBQXZEO0FBQ0Q7O0FBRURILFdBQVcsQ0FBQ0ksZUFBWixHQUE4QixVQUFVRixNQUFWLEVBQTRCO0FBQ3hELE1BQUlELFFBQVEsQ0FBQ0MsTUFBRCxDQUFaLEVBQXNCO0FBQ3BCLFdBQU9HLHlCQUFZRCxlQUFaLENBQTRCRixNQUE1QixDQUFQO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsVUFBTUksT0FBTyxHQUFHLGdDQUFZSixNQUFNLENBQUNLLGFBQW5CLEVBQWtDQyxzQ0FBbEMsRUFBc0ROLE1BQXRELENBQWhCOztBQUNBLFFBQUksT0FBT0ksT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFlBQU0sNkNBQU47QUFDRDs7QUFDRCxXQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JGLE1BQXhCLENBQVA7QUFDRDtBQUNGLENBVkQ7O0FBWUFGLFdBQVcsQ0FBQ1MsZ0JBQVosR0FBK0IsVUFBVVAsTUFBVixFQUE2QjtBQUMxRCxNQUFJRCxRQUFRLENBQUNDLE1BQUQsQ0FBWixFQUFzQjtBQUNwQixXQUFPRyx5QkFBWUksZ0JBQVosQ0FBNkJQLE1BQTdCLENBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxVQUFNSSxPQUFPLEdBQUcsZ0NBQVlKLE1BQU0sQ0FBQ0ssYUFBbkIsRUFBa0NDLHNDQUFsQyxFQUFzRE4sTUFBdEQsQ0FBaEI7O0FBQ0EsUUFBSSxPQUFPSSxPQUFPLENBQUNHLGdCQUFmLEtBQW9DLFVBQXhDLEVBQW9EO0FBQ2xELFlBQU0sOENBQU47QUFDRDs7QUFDRCxXQUFPSCxPQUFPLENBQUNHLGdCQUFSLENBQXlCUCxNQUF6QixDQUFQO0FBQ0Q7QUFDRixDQVZEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlclB1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9FdmVudEVtaXR0ZXJQdWJTdWInO1xuXG5pbXBvcnQgeyBSZWRpc1B1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9SZWRpc1B1YlN1Yic7XG5cbmNvbnN0IFBhcnNlUHViU3ViID0ge307XG5cbmZ1bmN0aW9uIHVzZVJlZGlzKGNvbmZpZzogYW55KTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlZGlzVVJMID0gY29uZmlnLnJlZGlzVVJMO1xuICByZXR1cm4gdHlwZW9mIHJlZGlzVVJMICE9PSAndW5kZWZpbmVkJyAmJiByZWRpc1VSTCAhPT0gJyc7XG59XG5cblBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGlmICh1c2VSZWRpcyhjb25maWcpKSB7XG4gICAgcmV0dXJuIFJlZGlzUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93ICdwdWJTdWJBZGFwdGVyIHNob3VsZCBoYXZlIGNyZWF0ZVB1Ymxpc2hlcigpJztcbiAgICB9XG4gICAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG4gIH1cbn07XG5cblBhcnNlUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIgPSBmdW5jdGlvbiAoY29uZmlnOiBhbnkpOiB2b2lkIHtcbiAgaWYgKHVzZVJlZGlzKGNvbmZpZykpIHtcbiAgICByZXR1cm4gUmVkaXNQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVTdWJzY3JpYmVyKCknO1xuICAgIH1cbiAgICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IFBhcnNlUHViU3ViIH07XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseWebSocketServer.js b/lib/LiveQuery/ParseWebSocketServer.js new file mode 100644 index 0000000000..b7ab9d6099 --- /dev/null +++ b/lib/LiveQuery/ParseWebSocketServer.js @@ -0,0 +1,80 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseWebSocket = exports.ParseWebSocketServer = void 0; + +var _AdapterLoader = require("../Adapters/AdapterLoader"); + +var _WSAdapter = require("../Adapters/WebSocketServer/WSAdapter"); + +var _logger = _interopRequireDefault(require("../logger")); + +var _events = _interopRequireDefault(require("events")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseWebSocketServer { + constructor(server, onConnect, config) { + config.server = server; + const wss = (0, _AdapterLoader.loadAdapter)(config.wssAdapter, _WSAdapter.WSAdapter, config); + + wss.onListen = () => { + _logger.default.info('Parse LiveQuery Server starts running'); + }; + + wss.onConnection = ws => { + ws.on('error', error => { + _logger.default.error(error.message); + + _logger.default.error(JSON.stringify(ws)); + }); + onConnect(new ParseWebSocket(ws)); // Send ping to client periodically + + const pingIntervalId = setInterval(() => { + if (ws.readyState == ws.OPEN) { + ws.ping(); + } else { + clearInterval(pingIntervalId); + } + }, config.websocketTimeout || 10 * 1000); + }; + + wss.onError = error => { + _logger.default.error(error); + }; + + wss.start(); + this.server = wss; + } + + close() { + if (this.server && this.server.close) { + this.server.close(); + } + } + +} + +exports.ParseWebSocketServer = ParseWebSocketServer; + +class ParseWebSocket extends _events.default.EventEmitter { + constructor(ws) { + super(); + + ws.onmessage = request => this.emit('message', request && request.data ? request.data : request); + + ws.onclose = () => this.emit('disconnect'); + + this.ws = ws; + } + + send(message) { + this.ws.send(message); + } + +} + +exports.ParseWebSocket = ParseWebSocket; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VXZWJTb2NrZXRTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsIm9uQ29ubmVjdCIsImNvbmZpZyIsIndzcyIsIndzc0FkYXB0ZXIiLCJXU0FkYXB0ZXIiLCJvbkxpc3RlbiIsImxvZ2dlciIsImluZm8iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uIiwiZXJyb3IiLCJtZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsIlBhcnNlV2ViU29ja2V0IiwicGluZ0ludGVydmFsSWQiLCJzZXRJbnRlcnZhbCIsInJlYWR5U3RhdGUiLCJPUEVOIiwicGluZyIsImNsZWFySW50ZXJ2YWwiLCJ3ZWJzb2NrZXRUaW1lb3V0Iiwib25FcnJvciIsInN0YXJ0IiwiY2xvc2UiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJvbm1lc3NhZ2UiLCJyZXF1ZXN0IiwiZW1pdCIsImRhdGEiLCJvbmNsb3NlIiwic2VuZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsb0JBQU4sQ0FBMkI7QUFHaENDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFjQyxTQUFkLEVBQW1DQyxNQUFuQyxFQUEyQztBQUNwREEsSUFBQUEsTUFBTSxDQUFDRixNQUFQLEdBQWdCQSxNQUFoQjtBQUNBLFVBQU1HLEdBQUcsR0FBRyxnQ0FBWUQsTUFBTSxDQUFDRSxVQUFuQixFQUErQkMsb0JBQS9CLEVBQTBDSCxNQUExQyxDQUFaOztBQUNBQyxJQUFBQSxHQUFHLENBQUNHLFFBQUosR0FBZSxNQUFNO0FBQ25CQyxzQkFBT0MsSUFBUCxDQUFZLHVDQUFaO0FBQ0QsS0FGRDs7QUFHQUwsSUFBQUEsR0FBRyxDQUFDTSxZQUFKLEdBQW1CQyxFQUFFLElBQUk7QUFDdkJBLE1BQUFBLEVBQUUsQ0FBQ0MsRUFBSCxDQUFNLE9BQU4sRUFBZUMsS0FBSyxJQUFJO0FBQ3RCTCx3QkFBT0ssS0FBUCxDQUFhQSxLQUFLLENBQUNDLE9BQW5COztBQUNBTix3QkFBT0ssS0FBUCxDQUFhRSxJQUFJLENBQUNDLFNBQUwsQ0FBZUwsRUFBZixDQUFiO0FBQ0QsT0FIRDtBQUlBVCxNQUFBQSxTQUFTLENBQUMsSUFBSWUsY0FBSixDQUFtQk4sRUFBbkIsQ0FBRCxDQUFULENBTHVCLENBTXZCOztBQUNBLFlBQU1PLGNBQWMsR0FBR0MsV0FBVyxDQUFDLE1BQU07QUFDdkMsWUFBSVIsRUFBRSxDQUFDUyxVQUFILElBQWlCVCxFQUFFLENBQUNVLElBQXhCLEVBQThCO0FBQzVCVixVQUFBQSxFQUFFLENBQUNXLElBQUg7QUFDRCxTQUZELE1BRU87QUFDTEMsVUFBQUEsYUFBYSxDQUFDTCxjQUFELENBQWI7QUFDRDtBQUNGLE9BTmlDLEVBTS9CZixNQUFNLENBQUNxQixnQkFBUCxJQUEyQixLQUFLLElBTkQsQ0FBbEM7QUFPRCxLQWREOztBQWVBcEIsSUFBQUEsR0FBRyxDQUFDcUIsT0FBSixHQUFjWixLQUFLLElBQUk7QUFDckJMLHNCQUFPSyxLQUFQLENBQWFBLEtBQWI7QUFDRCxLQUZEOztBQUdBVCxJQUFBQSxHQUFHLENBQUNzQixLQUFKO0FBQ0EsU0FBS3pCLE1BQUwsR0FBY0csR0FBZDtBQUNEOztBQUVEdUIsRUFBQUEsS0FBSyxHQUFHO0FBQ04sUUFBSSxLQUFLMUIsTUFBTCxJQUFlLEtBQUtBLE1BQUwsQ0FBWTBCLEtBQS9CLEVBQXNDO0FBQ3BDLFdBQUsxQixNQUFMLENBQVkwQixLQUFaO0FBQ0Q7QUFDRjs7QUFuQytCOzs7O0FBc0MzQixNQUFNVixjQUFOLFNBQTZCVyxnQkFBT0MsWUFBcEMsQ0FBaUQ7QUFHdEQ3QixFQUFBQSxXQUFXLENBQUNXLEVBQUQsRUFBVTtBQUNuQjs7QUFDQUEsSUFBQUEsRUFBRSxDQUFDbUIsU0FBSCxHQUFlQyxPQUFPLElBQ3BCLEtBQUtDLElBQUwsQ0FBVSxTQUFWLEVBQXFCRCxPQUFPLElBQUlBLE9BQU8sQ0FBQ0UsSUFBbkIsR0FBMEJGLE9BQU8sQ0FBQ0UsSUFBbEMsR0FBeUNGLE9BQTlELENBREY7O0FBRUFwQixJQUFBQSxFQUFFLENBQUN1QixPQUFILEdBQWEsTUFBTSxLQUFLRixJQUFMLENBQVUsWUFBVixDQUFuQjs7QUFDQSxTQUFLckIsRUFBTCxHQUFVQSxFQUFWO0FBQ0Q7O0FBRUR3QixFQUFBQSxJQUFJLENBQUNyQixPQUFELEVBQXFCO0FBQ3ZCLFNBQUtILEVBQUwsQ0FBUXdCLElBQVIsQ0FBYXJCLE9BQWI7QUFDRDs7QUFicUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsb2FkQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgV1NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvV2ViU29ja2V0U2VydmVyL1dTQWRhcHRlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZVdlYlNvY2tldFNlcnZlciB7XG4gIHNlcnZlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBvbkNvbm5lY3Q6IEZ1bmN0aW9uLCBjb25maWcpIHtcbiAgICBjb25maWcuc2VydmVyID0gc2VydmVyO1xuICAgIGNvbnN0IHdzcyA9IGxvYWRBZGFwdGVyKGNvbmZpZy53c3NBZGFwdGVyLCBXU0FkYXB0ZXIsIGNvbmZpZyk7XG4gICAgd3NzLm9uTGlzdGVuID0gKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oJ1BhcnNlIExpdmVRdWVyeSBTZXJ2ZXIgc3RhcnRzIHJ1bm5pbmcnKTtcbiAgICB9O1xuICAgIHdzcy5vbkNvbm5lY3Rpb24gPSB3cyA9PiB7XG4gICAgICB3cy5vbignZXJyb3InLCBlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKEpTT04uc3RyaW5naWZ5KHdzKSk7XG4gICAgICB9KTtcbiAgICAgIG9uQ29ubmVjdChuZXcgUGFyc2VXZWJTb2NrZXQod3MpKTtcbiAgICAgIC8vIFNlbmQgcGluZyB0byBjbGllbnQgcGVyaW9kaWNhbGx5XG4gICAgICBjb25zdCBwaW5nSW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT0gd3MuT1BFTikge1xuICAgICAgICAgIHdzLnBpbmcoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbElkKTtcbiAgICAgICAgfVxuICAgICAgfSwgY29uZmlnLndlYnNvY2tldFRpbWVvdXQgfHwgMTAgKiAxMDAwKTtcbiAgICB9O1xuICAgIHdzcy5vbkVycm9yID0gZXJyb3IgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICB9O1xuICAgIHdzcy5zdGFydCgpO1xuICAgIHRoaXMuc2VydmVyID0gd3NzO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuc2VydmVyICYmIHRoaXMuc2VydmVyLmNsb3NlKSB7XG4gICAgICB0aGlzLnNlcnZlci5jbG9zZSgpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VXZWJTb2NrZXQgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgd3M6IGFueTtcblxuICBjb25zdHJ1Y3Rvcih3czogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB3cy5vbm1lc3NhZ2UgPSByZXF1ZXN0ID0+XG4gICAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCByZXF1ZXN0ICYmIHJlcXVlc3QuZGF0YSA/IHJlcXVlc3QuZGF0YSA6IHJlcXVlc3QpO1xuICAgIHdzLm9uY2xvc2UgPSAoKSA9PiB0aGlzLmVtaXQoJ2Rpc2Nvbm5lY3QnKTtcbiAgICB0aGlzLndzID0gd3M7XG4gIH1cblxuICBzZW5kKG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIHRoaXMud3Muc2VuZChtZXNzYWdlKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/QueryTools.js b/lib/LiveQuery/QueryTools.js new file mode 100644 index 0000000000..58b13135f2 --- /dev/null +++ b/lib/LiveQuery/QueryTools.js @@ -0,0 +1,407 @@ +"use strict"; + +var equalObjects = require('./equalObjects'); + +var Id = require('./Id'); + +var Parse = require('parse/node'); +/** + * Query Hashes are deterministic hashes for Parse Queries. + * Any two queries that have the same set of constraints will produce the same + * hash. This lets us reliably group components by the queries they depend upon, + * and quickly determine if a query has changed. + */ + +/** + * Convert $or queries into an array of where conditions + */ + + +function flattenOrQueries(where) { + if (!Object.prototype.hasOwnProperty.call(where, '$or')) { + return where; + } + + var accum = []; + + for (var i = 0; i < where.$or.length; i++) { + accum = accum.concat(where.$or[i]); + } + + return accum; +} +/** + * Deterministically turns an object into a string. Disregards ordering + */ + + +function stringify(object) { + if (typeof object !== 'object' || object === null) { + if (typeof object === 'string') { + return '"' + object.replace(/\|/g, '%|') + '"'; + } + + return object + ''; + } + + if (Array.isArray(object)) { + var copy = object.map(stringify); + copy.sort(); + return '[' + copy.join(',') + ']'; + } + + var sections = []; + var keys = Object.keys(object); + keys.sort(); + + for (var k = 0; k < keys.length; k++) { + sections.push(stringify(keys[k]) + ':' + stringify(object[keys[k]])); + } + + return '{' + sections.join(',') + '}'; +} +/** + * Generate a hash from a query, with unique fields for columns, values, order, + * skip, and limit. + */ + + +function queryHash(query) { + if (query instanceof Parse.Query) { + query = { + className: query.className, + where: query._where + }; + } + + var where = flattenOrQueries(query.where || {}); + var columns = []; + var values = []; + var i; + + if (Array.isArray(where)) { + var uniqueColumns = {}; + + for (i = 0; i < where.length; i++) { + var subValues = {}; + var keys = Object.keys(where[i]); + keys.sort(); + + for (var j = 0; j < keys.length; j++) { + subValues[keys[j]] = where[i][keys[j]]; + uniqueColumns[keys[j]] = true; + } + + values.push(subValues); + } + + columns = Object.keys(uniqueColumns); + columns.sort(); + } else { + columns = Object.keys(where); + columns.sort(); + + for (i = 0; i < columns.length; i++) { + values.push(where[columns[i]]); + } + } + + var sections = [columns.join(','), stringify(values)]; + return query.className + ':' + sections.join('|'); +} +/** + * contains -- Determines if an object is contained in a list with special handling for Parse pointers. + */ + + +function contains(haystack, needle) { + if (needle && needle.__type && needle.__type === 'Pointer') { + for (const i in haystack) { + const ptr = haystack[i]; + + if (typeof ptr === 'string' && ptr === needle.objectId) { + return true; + } + + if (ptr.className === needle.className && ptr.objectId === needle.objectId) { + return true; + } + } + + return false; + } + + return haystack.indexOf(needle) > -1; +} +/** + * matchesQuery -- Determines if an object would be returned by a Parse Query + * It's a lightweight, where-clause only implementation of a full query engine. + * Since we find queries that match objects, rather than objects that match + * queries, we can avoid building a full-blown query tool. + */ + + +function matchesQuery(object, query) { + if (query instanceof Parse.Query) { + var className = object.id instanceof Id ? object.id.className : object.className; + + if (className !== query.className) { + return false; + } + + return matchesQuery(object, query._where); + } + + for (var field in query) { + if (!matchesKeyConstraints(object, field, query[field])) { + return false; + } + } + + return true; +} + +function equalObjectsGeneric(obj, compareTo, eqlFn) { + if (Array.isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + if (eqlFn(obj[i], compareTo)) { + return true; + } + } + + return false; + } + + return eqlFn(obj, compareTo); +} +/** + * Determines whether an object matches a single key's constraints + */ + + +function matchesKeyConstraints(object, key, constraints) { + if (constraints === null) { + return false; + } + + if (key.indexOf('.') >= 0) { + // Key references a subobject + var keyComponents = key.split('.'); + var subObjectKey = keyComponents[0]; + var keyRemainder = keyComponents.slice(1).join('.'); + return matchesKeyConstraints(object[subObjectKey] || {}, keyRemainder, constraints); + } + + var i; + + if (key === '$or') { + for (i = 0; i < constraints.length; i++) { + if (matchesQuery(object, constraints[i])) { + return true; + } + } + + return false; + } + + if (key === '$relatedTo') { + // Bail! We can't handle relational queries locally + return false; + } // Decode Date JSON value + + + if (object[key] && object[key].__type == 'Date') { + object[key] = new Date(object[key].iso); + } // Equality (or Array contains) cases + + + if (typeof constraints !== 'object') { + if (Array.isArray(object[key])) { + return object[key].indexOf(constraints) > -1; + } + + return object[key] === constraints; + } + + var compareTo; + + if (constraints.__type) { + if (constraints.__type === 'Pointer') { + return equalObjectsGeneric(object[key], constraints, function (obj, ptr) { + return typeof obj !== 'undefined' && ptr.className === obj.className && ptr.objectId === obj.objectId; + }); + } + + return equalObjectsGeneric(object[key], Parse._decode(key, constraints), equalObjects); + } // More complex cases + + + for (var condition in constraints) { + compareTo = constraints[condition]; + + if (compareTo.__type) { + compareTo = Parse._decode(key, compareTo); + } + + switch (condition) { + case '$lt': + if (object[key] >= compareTo) { + return false; + } + + break; + + case '$lte': + if (object[key] > compareTo) { + return false; + } + + break; + + case '$gt': + if (object[key] <= compareTo) { + return false; + } + + break; + + case '$gte': + if (object[key] < compareTo) { + return false; + } + + break; + + case '$ne': + if (equalObjects(object[key], compareTo)) { + return false; + } + + break; + + case '$in': + if (!contains(compareTo, object[key])) { + return false; + } + + break; + + case '$nin': + if (contains(compareTo, object[key])) { + return false; + } + + break; + + case '$all': + for (i = 0; i < compareTo.length; i++) { + if (object[key].indexOf(compareTo[i]) < 0) { + return false; + } + } + + break; + + case '$exists': + { + const propertyExists = typeof object[key] !== 'undefined'; + const existenceIsRequired = constraints['$exists']; + + if (typeof constraints['$exists'] !== 'boolean') { + // The SDK will never submit a non-boolean for $exists, but if someone + // tries to submit a non-boolean for $exits outside the SDKs, just ignore it. + break; + } + + if (!propertyExists && existenceIsRequired || propertyExists && !existenceIsRequired) { + return false; + } + + break; + } + + case '$regex': + if (typeof compareTo === 'object') { + return compareTo.test(object[key]); + } // JS doesn't support perl-style escaping + + + var expString = ''; + var escapeEnd = -2; + var escapeStart = compareTo.indexOf('\\Q'); + + while (escapeStart > -1) { + // Add the unescaped portion + expString += compareTo.substring(escapeEnd + 2, escapeStart); + escapeEnd = compareTo.indexOf('\\E', escapeStart); + + if (escapeEnd > -1) { + expString += compareTo.substring(escapeStart + 2, escapeEnd).replace(/\\\\\\\\E/g, '\\E').replace(/\W/g, '\\$&'); + } + + escapeStart = compareTo.indexOf('\\Q', escapeEnd); + } + + expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2)); + var exp = new RegExp(expString, constraints.$options || ''); + + if (!exp.test(object[key])) { + return false; + } + + break; + + case '$nearSphere': + if (!compareTo || !object[key]) { + return false; + } + + var distance = compareTo.radiansTo(object[key]); + var max = constraints.$maxDistance || Infinity; + return distance <= max; + + case '$within': + if (!compareTo || !object[key]) { + return false; + } + + var southWest = compareTo.$box[0]; + var northEast = compareTo.$box[1]; + + if (southWest.latitude > northEast.latitude || southWest.longitude > northEast.longitude) { + // Invalid box, crosses the date line + return false; + } + + return object[key].latitude > southWest.latitude && object[key].latitude < northEast.latitude && object[key].longitude > southWest.longitude && object[key].longitude < northEast.longitude; + + case '$options': + // Not a query type, but a way to add options to $regex. Ignore and + // avoid the default + break; + + case '$maxDistance': + // Not a query type, but a way to add a cap to $nearSphere. Ignore and + // avoid the default + break; + + case '$select': + return false; + + case '$dontSelect': + return false; + + default: + return false; + } + } + + return true; +} + +var QueryTools = { + queryHash: queryHash, + matchesQuery: matchesQuery +}; +module.exports = QueryTools; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUXVlcnlUb29scy5qcyJdLCJuYW1lcyI6WyJlcXVhbE9iamVjdHMiLCJyZXF1aXJlIiwiSWQiLCJQYXJzZSIsImZsYXR0ZW5PclF1ZXJpZXMiLCJ3aGVyZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFjY3VtIiwiaSIsIiRvciIsImxlbmd0aCIsImNvbmNhdCIsInN0cmluZ2lmeSIsIm9iamVjdCIsInJlcGxhY2UiLCJBcnJheSIsImlzQXJyYXkiLCJjb3B5IiwibWFwIiwic29ydCIsImpvaW4iLCJzZWN0aW9ucyIsImtleXMiLCJrIiwicHVzaCIsInF1ZXJ5SGFzaCIsInF1ZXJ5IiwiUXVlcnkiLCJjbGFzc05hbWUiLCJfd2hlcmUiLCJjb2x1bW5zIiwidmFsdWVzIiwidW5pcXVlQ29sdW1ucyIsInN1YlZhbHVlcyIsImoiLCJjb250YWlucyIsImhheXN0YWNrIiwibmVlZGxlIiwiX190eXBlIiwicHRyIiwib2JqZWN0SWQiLCJpbmRleE9mIiwibWF0Y2hlc1F1ZXJ5IiwiaWQiLCJmaWVsZCIsIm1hdGNoZXNLZXlDb25zdHJhaW50cyIsImVxdWFsT2JqZWN0c0dlbmVyaWMiLCJvYmoiLCJjb21wYXJlVG8iLCJlcWxGbiIsImtleSIsImNvbnN0cmFpbnRzIiwia2V5Q29tcG9uZW50cyIsInNwbGl0Iiwic3ViT2JqZWN0S2V5Iiwia2V5UmVtYWluZGVyIiwic2xpY2UiLCJEYXRlIiwiaXNvIiwiX2RlY29kZSIsImNvbmRpdGlvbiIsInByb3BlcnR5RXhpc3RzIiwiZXhpc3RlbmNlSXNSZXF1aXJlZCIsInRlc3QiLCJleHBTdHJpbmciLCJlc2NhcGVFbmQiLCJlc2NhcGVTdGFydCIsInN1YnN0cmluZyIsIk1hdGgiLCJtYXgiLCJleHAiLCJSZWdFeHAiLCIkb3B0aW9ucyIsImRpc3RhbmNlIiwicmFkaWFuc1RvIiwiJG1heERpc3RhbmNlIiwiSW5maW5pdHkiLCJzb3V0aFdlc3QiLCIkYm94Iiwibm9ydGhFYXN0IiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJRdWVyeVRvb2xzIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxFQUFFLEdBQUdELE9BQU8sQ0FBQyxNQUFELENBQWhCOztBQUNBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBbkI7QUFFQTs7Ozs7OztBQU9BOzs7OztBQUdBLFNBQVNHLGdCQUFULENBQTBCQyxLQUExQixFQUFpQztBQUMvQixNQUFJLENBQUNDLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDSixLQUFyQyxFQUE0QyxLQUE1QyxDQUFMLEVBQXlEO0FBQ3ZELFdBQU9BLEtBQVA7QUFDRDs7QUFDRCxNQUFJSyxLQUFLLEdBQUcsRUFBWjs7QUFDQSxPQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdOLEtBQUssQ0FBQ08sR0FBTixDQUFVQyxNQUE5QixFQUFzQ0YsQ0FBQyxFQUF2QyxFQUEyQztBQUN6Q0QsSUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNJLE1BQU4sQ0FBYVQsS0FBSyxDQUFDTyxHQUFOLENBQVVELENBQVYsQ0FBYixDQUFSO0FBQ0Q7O0FBQ0QsU0FBT0QsS0FBUDtBQUNEO0FBRUQ7Ozs7O0FBR0EsU0FBU0ssU0FBVCxDQUFtQkMsTUFBbkIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQWxCLElBQThCQSxNQUFNLEtBQUssSUFBN0MsRUFBbUQ7QUFDakQsUUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQXRCLEVBQWdDO0FBQzlCLGFBQU8sTUFBTUEsTUFBTSxDQUFDQyxPQUFQLENBQWUsS0FBZixFQUFzQixJQUF0QixDQUFOLEdBQW9DLEdBQTNDO0FBQ0Q7O0FBQ0QsV0FBT0QsTUFBTSxHQUFHLEVBQWhCO0FBQ0Q7O0FBQ0QsTUFB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ZXF1YWxPYmplY3RzJyk7XG52YXIgSWQgPSByZXF1aXJlKCcuL0lkJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5cbi8qKlxuICogUXVlcnkgSGFzaGVzIGFyZSBkZXRlcm1pbmlzdGljIGhhc2hlcyBmb3IgUGFyc2UgUXVlcmllcy5cbiAqIEFueSB0d28gcXVlcmllcyB0aGF0IGhhdmUgdGhlIHNhbWUgc2V0IG9mIGNvbnN0cmFpbnRzIHdpbGwgcHJvZHVjZSB0aGUgc2FtZVxuICogaGFzaC4gVGhpcyBsZXRzIHVzIHJlbGlhYmx5IGdyb3VwIGNvbXBvbmVudHMgYnkgdGhlIHF1ZXJpZXMgdGhleSBkZXBlbmQgdXBvbixcbiAqIGFuZCBxdWlja2x5IGRldGVybWluZSBpZiBhIHF1ZXJ5IGhhcyBjaGFuZ2VkLlxuICovXG5cbi8qKlxuICogQ29udmVydCAkb3IgcXVlcmllcyBpbnRvIGFuIGFycmF5IG9mIHdoZXJlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZmxhdHRlbk9yUXVlcmllcyh3aGVyZSkge1xuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh3aGVyZSwgJyRvcicpKSB7XG4gICAgcmV0dXJuIHdoZXJlO1xuICB9XG4gIHZhciBhY2N1bSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHdoZXJlLiRvci5sZW5ndGg7IGkrKykge1xuICAgIGFjY3VtID0gYWNjdW0uY29uY2F0KHdoZXJlLiRvcltpXSk7XG4gIH1cbiAgcmV0dXJuIGFjY3VtO1xufVxuXG4vKipcbiAqIERldGVybWluaXN0aWNhbGx5IHR1cm5zIGFuIG9iamVjdCBpbnRvIGEgc3RyaW5nLiBEaXNyZWdhcmRzIG9yZGVyaW5nXG4gKi9cbmZ1bmN0aW9uIHN0cmluZ2lmeShvYmplY3QpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcgfHwgb2JqZWN0ID09PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gJ1wiJyArIG9iamVjdC5yZXBsYWNlKC9cXHwvZywgJyV8JykgKyAnXCInO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0ICsgJyc7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgIHZhciBjb3B5ID0gb2JqZWN0Lm1hcChzdHJpbmdpZnkpO1xuICAgIGNvcHkuc29ydCgpO1xuICAgIHJldHVybiAnWycgKyBjb3B5LmpvaW4oJywnKSArICddJztcbiAgfVxuICB2YXIgc2VjdGlvbnMgPSBbXTtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICBrZXlzLnNvcnQoKTtcbiAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgc2VjdGlvbnMucHVzaChzdHJpbmdpZnkoa2V5c1trXSkgKyAnOicgKyBzdHJpbmdpZnkob2JqZWN0W2tleXNba11dKSk7XG4gIH1cbiAgcmV0dXJuICd7JyArIHNlY3Rpb25zLmpvaW4oJywnKSArICd9Jztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIGhhc2ggZnJvbSBhIHF1ZXJ5LCB3aXRoIHVuaXF1ZSBmaWVsZHMgZm9yIGNvbHVtbnMsIHZhbHVlcywgb3JkZXIsXG4gKiBza2lwLCBhbmQgbGltaXQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5SGFzaChxdWVyeSkge1xuICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgIHF1ZXJ5ID0ge1xuICAgICAgY2xhc3NOYW1lOiBxdWVyeS5jbGFzc05hbWUsXG4gICAgICB3aGVyZTogcXVlcnkuX3doZXJlLFxuICAgIH07XG4gIH1cbiAgdmFyIHdoZXJlID0gZmxhdHRlbk9yUXVlcmllcyhxdWVyeS53aGVyZSB8fCB7fSk7XG4gIHZhciBjb2x1bW5zID0gW107XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIGk7XG4gIGlmIChBcnJheS5pc0FycmF5KHdoZXJlKSkge1xuICAgIHZhciB1bmlxdWVDb2x1bW5zID0ge307XG4gICAgZm9yIChpID0gMDsgaSA8IHdoZXJlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc3ViVmFsdWVzID0ge307XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHdoZXJlW2ldKTtcbiAgICAgIGtleXMuc29ydCgpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHN1YlZhbHVlc1trZXlzW2pdXSA9IHdoZXJlW2ldW2tleXNbal1dO1xuICAgICAgICB1bmlxdWVDb2x1bW5zW2tleXNbal1dID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhbHVlcy5wdXNoKHN1YlZhbHVlcyk7XG4gICAgfVxuICAgIGNvbHVtbnMgPSBPYmplY3Qua2V5cyh1bmlxdWVDb2x1bW5zKTtcbiAgICBjb2x1bW5zLnNvcnQoKTtcbiAgfSBlbHNlIHtcbiAgICBjb2x1bW5zID0gT2JqZWN0LmtleXMod2hlcmUpO1xuICAgIGNvbHVtbnMuc29ydCgpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb2x1bW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZXMucHVzaCh3aGVyZVtjb2x1bW5zW2ldXSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNlY3Rpb25zID0gW2NvbHVtbnMuam9pbignLCcpLCBzdHJpbmdpZnkodmFsdWVzKV07XG5cbiAgcmV0dXJuIHF1ZXJ5LmNsYXNzTmFtZSArICc6JyArIHNlY3Rpb25zLmpvaW4oJ3wnKTtcbn1cblxuLyoqXG4gKiBjb250YWlucyAtLSBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBpcyBjb250YWluZWQgaW4gYSBsaXN0IHdpdGggc3BlY2lhbCBoYW5kbGluZyBmb3IgUGFyc2UgcG9pbnRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5zKGhheXN0YWNrOiBBcnJheSwgbmVlZGxlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKG5lZWRsZSAmJiBuZWVkbGUuX190eXBlICYmIG5lZWRsZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgIGZvciAoY29uc3QgaSBpbiBoYXlzdGFjaykge1xuICAgICAgY29uc3QgcHRyID0gaGF5c3RhY2tbaV07XG4gICAgICBpZiAodHlwZW9mIHB0ciA9PT0gJ3N0cmluZycgJiYgcHRyID09PSBuZWVkbGUub2JqZWN0SWQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAocHRyLmNsYXNzTmFtZSA9PT0gbmVlZGxlLmNsYXNzTmFtZSAmJiBwdHIub2JqZWN0SWQgPT09IG5lZWRsZS5vYmplY3RJZCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBoYXlzdGFjay5pbmRleE9mKG5lZWRsZSkgPiAtMTtcbn1cbi8qKlxuICogbWF0Y2hlc1F1ZXJ5IC0tIERldGVybWluZXMgaWYgYW4gb2JqZWN0IHdvdWxkIGJlIHJldHVybmVkIGJ5IGEgUGFyc2UgUXVlcnlcbiAqIEl0J3MgYSBsaWdodHdlaWdodCwgd2hlcmUtY2xhdXNlIG9ubHkgaW1wbGVtZW50YXRpb24gb2YgYSBmdWxsIHF1ZXJ5IGVuZ2luZS5cbiAqIFNpbmNlIHdlIGZpbmQgcXVlcmllcyB0aGF0IG1hdGNoIG9iamVjdHMsIHJhdGhlciB0aGFuIG9iamVjdHMgdGhhdCBtYXRjaFxuICogcXVlcmllcywgd2UgY2FuIGF2b2lkIGJ1aWxkaW5nIGEgZnVsbC1ibG93biBxdWVyeSB0b29sLlxuICovXG5mdW5jdGlvbiBtYXRjaGVzUXVlcnkob2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKHF1ZXJ5IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gb2JqZWN0LmlkIGluc3RhbmNlb2YgSWQgPyBvYmplY3QuaWQuY2xhc3NOYW1lIDogb2JqZWN0LmNsYXNzTmFtZTtcbiAgICBpZiAoY2xhc3NOYW1lICE9PSBxdWVyeS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShvYmplY3QsIHF1ZXJ5Ll93aGVyZSk7XG4gIH1cbiAgZm9yICh2YXIgZmllbGQgaW4gcXVlcnkpIHtcbiAgICBpZiAoIW1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGZpZWxkLCBxdWVyeVtmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBlcXVhbE9iamVjdHNHZW5lcmljKG9iaiwgY29tcGFyZVRvLCBlcWxGbikge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcWxGbihvYmpbaV0sIGNvbXBhcmVUbykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBlcWxGbihvYmosIGNvbXBhcmVUbyk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9iamVjdCBtYXRjaGVzIGEgc2luZ2xlIGtleSdzIGNvbnN0cmFpbnRzXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGtleSwgY29uc3RyYWludHMpIHtcbiAgaWYgKGNvbnN0cmFpbnRzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkuaW5kZXhPZignLicpID49IDApIHtcbiAgICAvLyBLZXkgcmVmZXJlbmNlcyBhIHN1Ym9iamVjdFxuICAgIHZhciBrZXlDb21wb25lbnRzID0ga2V5LnNwbGl0KCcuJyk7XG4gICAgdmFyIHN1Yk9iamVjdEtleSA9IGtleUNvbXBvbmVudHNbMF07XG4gICAgdmFyIGtleVJlbWFpbmRlciA9IGtleUNvbXBvbmVudHMuc2xpY2UoMSkuam9pbignLicpO1xuICAgIHJldHVybiBtYXRjaGVzS2V5Q29uc3RyYWludHMob2JqZWN0W3N1Yk9iamVjdEtleV0gfHwge30sIGtleVJlbWFpbmRlciwgY29uc3RyYWludHMpO1xuICB9XG4gIHZhciBpO1xuICBpZiAoa2V5ID09PSAnJG9yJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1hdGNoZXNRdWVyeShvYmplY3QsIGNvbnN0cmFpbnRzW2ldKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkgPT09ICckcmVsYXRlZFRvJykge1xuICAgIC8vIEJhaWwhIFdlIGNhbid0IGhhbmRsZSByZWxhdGlvbmFsIHF1ZXJpZXMgbG9jYWxseVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBEZWNvZGUgRGF0ZSBKU09OIHZhbHVlXG4gIGlmIChvYmplY3Rba2V5XSAmJiBvYmplY3Rba2V5XS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgb2JqZWN0W2tleV0gPSBuZXcgRGF0ZShvYmplY3Rba2V5XS5pc28pO1xuICB9XG4gIC8vIEVxdWFsaXR5IChvciBBcnJheSBjb250YWlucykgY2FzZXNcbiAgaWYgKHR5cGVvZiBjb25zdHJhaW50cyAhPT0gJ29iamVjdCcpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3Rba2V5XSkpIHtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XS5pbmRleE9mKGNvbnN0cmFpbnRzKSA+IC0xO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IGNvbnN0cmFpbnRzO1xuICB9XG4gIHZhciBjb21wYXJlVG87XG4gIGlmIChjb25zdHJhaW50cy5fX3R5cGUpIHtcbiAgICBpZiAoY29uc3RyYWludHMuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiBlcXVhbE9iamVjdHNHZW5lcmljKG9iamVjdFtrZXldLCBjb25zdHJhaW50cywgZnVuY3Rpb24gKG9iaiwgcHRyKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgdHlwZW9mIG9iaiAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICBwdHIuY2xhc3NOYW1lID09PSBvYmouY2xhc3NOYW1lICYmXG4gICAgICAgICAgcHRyLm9iamVjdElkID09PSBvYmoub2JqZWN0SWRcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBlcXVhbE9iamVjdHNHZW5lcmljKG9iamVjdFtrZXldLCBQYXJzZS5fZGVjb2RlKGtleSwgY29uc3RyYWludHMpLCBlcXVhbE9iamVjdHMpO1xuICB9XG4gIC8vIE1vcmUgY29tcGxleCBjYXNlc1xuICBmb3IgKHZhciBjb25kaXRpb24gaW4gY29uc3RyYWludHMpIHtcbiAgICBjb21wYXJlVG8gPSBjb25zdHJhaW50c1tjb25kaXRpb25dO1xuICAgIGlmIChjb21wYXJlVG8uX190eXBlKSB7XG4gICAgICBjb21wYXJlVG8gPSBQYXJzZS5fZGVjb2RlKGtleSwgY29tcGFyZVRvKTtcbiAgICB9XG4gICAgc3dpdGNoIChjb25kaXRpb24pIHtcbiAgICAgIGNhc2UgJyRsdCc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA+PSBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbHRlJzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldID4gY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGd0JzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldIDw9IGNvbXBhcmVUbykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRndGUnOlxuICAgICAgICBpZiAob2JqZWN0W2tleV0gPCBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbmUnOlxuICAgICAgICBpZiAoZXF1YWxPYmplY3RzKG9iamVjdFtrZXldLCBjb21wYXJlVG8pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGluJzpcbiAgICAgICAgaWYgKCFjb250YWlucyhjb21wYXJlVG8sIG9iamVjdFtrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRuaW4nOlxuICAgICAgICBpZiAoY29udGFpbnMoY29tcGFyZVRvLCBvYmplY3Rba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckYWxsJzpcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvbXBhcmVUby5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChvYmplY3Rba2V5XS5pbmRleE9mKGNvbXBhcmVUb1tpXSkgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGV4aXN0cyc6IHtcbiAgICAgICAgY29uc3QgcHJvcGVydHlFeGlzdHMgPSB0eXBlb2Ygb2JqZWN0W2tleV0gIT09ICd1bmRlZmluZWQnO1xuICAgICAgICBjb25zdCBleGlzdGVuY2VJc1JlcXVpcmVkID0gY29uc3RyYWludHNbJyRleGlzdHMnXTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zdHJhaW50c1snJGV4aXN0cyddICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAvLyBUaGUgU0RLIHdpbGwgbmV2ZXIgc3VibWl0IGEgbm9uLWJvb2xlYW4gZm9yICRleGlzdHMsIGJ1dCBpZiBzb21lb25lXG4gICAgICAgICAgLy8gdHJpZXMgdG8gc3VibWl0IGEgbm9uLWJvb2xlYW4gZm9yICRleGl0cyBvdXRzaWRlIHRoZSBTREtzLCBqdXN0IGlnbm9yZSBpdC5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoKCFwcm9wZXJ0eUV4aXN0cyAmJiBleGlzdGVuY2VJc1JlcXVpcmVkKSB8fCAocHJvcGVydHlFeGlzdHMgJiYgIWV4aXN0ZW5jZUlzUmVxdWlyZWQpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJHJlZ2V4JzpcbiAgICAgICAgaWYgKHR5cGVvZiBjb21wYXJlVG8gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbXBhcmVUby50ZXN0KG9iamVjdFtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBKUyBkb2Vzbid0IHN1cHBvcnQgcGVybC1zdHlsZSBlc2NhcGluZ1xuICAgICAgICB2YXIgZXhwU3RyaW5nID0gJyc7XG4gICAgICAgIHZhciBlc2NhcGVFbmQgPSAtMjtcbiAgICAgICAgdmFyIGVzY2FwZVN0YXJ0ID0gY29tcGFyZVRvLmluZGV4T2YoJ1xcXFxRJyk7XG4gICAgICAgIHdoaWxlIChlc2NhcGVTdGFydCA+IC0xKSB7XG4gICAgICAgICAgLy8gQWRkIHRoZSB1bmVzY2FwZWQgcG9ydGlvblxuICAgICAgICAgIGV4cFN0cmluZyArPSBjb21wYXJlVG8uc3Vic3RyaW5nKGVzY2FwZUVuZCArIDIsIGVzY2FwZVN0YXJ0KTtcbiAgICAgICAgICBlc2NhcGVFbmQgPSBjb21wYXJlVG8uaW5kZXhPZignXFxcXEUnLCBlc2NhcGVTdGFydCk7XG4gICAgICAgICAgaWYgKGVzY2FwZUVuZCA+IC0xKSB7XG4gICAgICAgICAgICBleHBTdHJpbmcgKz0gY29tcGFyZVRvXG4gICAgICAgICAgICAgIC5zdWJzdHJpbmcoZXNjYXBlU3RhcnQgKyAyLCBlc2NhcGVFbmQpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXFxcXFxcXFxcXFxcRS9nLCAnXFxcXEUnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFxXL2csICdcXFxcJCYnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlc2NhcGVTdGFydCA9IGNvbXBhcmVUby5pbmRleE9mKCdcXFxcUScsIGVzY2FwZUVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwU3RyaW5nICs9IGNvbXBhcmVUby5zdWJzdHJpbmcoTWF0aC5tYXgoZXNjYXBlU3RhcnQsIGVzY2FwZUVuZCArIDIpKTtcbiAgICAgICAgdmFyIGV4cCA9IG5ldyBSZWdFeHAoZXhwU3RyaW5nLCBjb25zdHJhaW50cy4kb3B0aW9ucyB8fCAnJyk7XG4gICAgICAgIGlmICghZXhwLnRlc3Qob2JqZWN0W2tleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG5lYXJTcGhlcmUnOlxuICAgICAgICBpZiAoIWNvbXBhcmVUbyB8fCAhb2JqZWN0W2tleV0pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRpc3RhbmNlID0gY29tcGFyZVRvLnJhZGlhbnNUbyhvYmplY3Rba2V5XSk7XG4gICAgICAgIHZhciBtYXggPSBjb25zdHJhaW50cy4kbWF4RGlzdGFuY2UgfHwgSW5maW5pdHk7XG4gICAgICAgIHJldHVybiBkaXN0YW5jZSA8PSBtYXg7XG4gICAgICBjYXNlICckd2l0aGluJzpcbiAgICAgICAgaWYgKCFjb21wYXJlVG8gfHwgIW9iamVjdFtrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzb3V0aFdlc3QgPSBjb21wYXJlVG8uJGJveFswXTtcbiAgICAgICAgdmFyIG5vcnRoRWFzdCA9IGNvbXBhcmVUby4kYm94WzFdO1xuICAgICAgICBpZiAoc291dGhXZXN0LmxhdGl0dWRlID4gbm9ydGhFYXN0LmxhdGl0dWRlIHx8IHNvdXRoV2VzdC5sb25naXR1ZGUgPiBub3J0aEVhc3QubG9uZ2l0dWRlKSB7XG4gICAgICAgICAgLy8gSW52YWxpZCBib3gsIGNyb3NzZXMgdGhlIGRhdGUgbGluZVxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIG9iamVjdFtrZXldLmxhdGl0dWRlID4gc291dGhXZXN0LmxhdGl0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubGF0aXR1ZGUgPCBub3J0aEVhc3QubGF0aXR1ZGUgJiZcbiAgICAgICAgICBvYmplY3Rba2V5XS5sb25naXR1ZGUgPiBzb3V0aFdlc3QubG9uZ2l0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubG9uZ2l0dWRlIDwgbm9ydGhFYXN0LmxvbmdpdHVkZVxuICAgICAgICApO1xuICAgICAgY2FzZSAnJG9wdGlvbnMnOlxuICAgICAgICAvLyBOb3QgYSBxdWVyeSB0eXBlLCBidXQgYSB3YXkgdG8gYWRkIG9wdGlvbnMgdG8gJHJlZ2V4LiBJZ25vcmUgYW5kXG4gICAgICAgIC8vIGF2b2lkIHRoZSBkZWZhdWx0XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG1heERpc3RhbmNlJzpcbiAgICAgICAgLy8gTm90IGEgcXVlcnkgdHlwZSwgYnV0IGEgd2F5IHRvIGFkZCBhIGNhcCB0byAkbmVhclNwaGVyZS4gSWdub3JlIGFuZFxuICAgICAgICAvLyBhdm9pZCB0aGUgZGVmYXVsdFxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRzZWxlY3QnOlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBjYXNlICckZG9udFNlbGVjdCc6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbnZhciBRdWVyeVRvb2xzID0ge1xuICBxdWVyeUhhc2g6IHF1ZXJ5SGFzaCxcbiAgbWF0Y2hlc1F1ZXJ5OiBtYXRjaGVzUXVlcnksXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFF1ZXJ5VG9vbHM7XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/RequestSchema.js b/lib/LiveQuery/RequestSchema.js new file mode 100644 index 0000000000..08cb08c4c0 --- /dev/null +++ b/lib/LiveQuery/RequestSchema.js @@ -0,0 +1,146 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +const general = { + title: 'General request schema', + type: 'object', + properties: { + op: { + type: 'string', + enum: ['connect', 'subscribe', 'unsubscribe', 'update'] + } + }, + required: ['op'] +}; +const connect = { + title: 'Connect operation schema', + type: 'object', + properties: { + op: 'connect', + applicationId: { + type: 'string' + }, + javascriptKey: { + type: 'string' + }, + masterKey: { + type: 'string' + }, + clientKey: { + type: 'string' + }, + windowsKey: { + type: 'string' + }, + restAPIKey: { + type: 'string' + }, + sessionToken: { + type: 'string' + }, + installationId: { + type: 'string' + } + }, + required: ['op', 'applicationId'], + additionalProperties: false +}; +const subscribe = { + title: 'Subscribe operation schema', + type: 'object', + properties: { + op: 'subscribe', + requestId: { + type: 'number' + }, + query: { + title: 'Query field schema', + type: 'object', + properties: { + className: { + type: 'string' + }, + where: { + type: 'object' + }, + fields: { + type: 'array', + items: { + type: 'string' + }, + minItems: 1, + uniqueItems: true + } + }, + required: ['where', 'className'], + additionalProperties: false + }, + sessionToken: { + type: 'string' + } + }, + required: ['op', 'requestId', 'query'], + additionalProperties: false +}; +const update = { + title: 'Update operation schema', + type: 'object', + properties: { + op: 'update', + requestId: { + type: 'number' + }, + query: { + title: 'Query field schema', + type: 'object', + properties: { + className: { + type: 'string' + }, + where: { + type: 'object' + }, + fields: { + type: 'array', + items: { + type: 'string' + }, + minItems: 1, + uniqueItems: true + } + }, + required: ['where', 'className'], + additionalProperties: false + }, + sessionToken: { + type: 'string' + } + }, + required: ['op', 'requestId', 'query'], + additionalProperties: false +}; +const unsubscribe = { + title: 'Unsubscribe operation schema', + type: 'object', + properties: { + op: 'unsubscribe', + requestId: { + type: 'number' + } + }, + required: ['op', 'requestId'], + additionalProperties: false +}; +const RequestSchema = { + general: general, + connect: connect, + subscribe: subscribe, + update: update, + unsubscribe: unsubscribe +}; +var _default = RequestSchema; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUmVxdWVzdFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJnZW5lcmFsIiwidGl0bGUiLCJ0eXBlIiwicHJvcGVydGllcyIsIm9wIiwiZW51bSIsInJlcXVpcmVkIiwiY29ubmVjdCIsImFwcGxpY2F0aW9uSWQiLCJqYXZhc2NyaXB0S2V5IiwibWFzdGVyS2V5IiwiY2xpZW50S2V5Iiwid2luZG93c0tleSIsInJlc3RBUElLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwic3Vic2NyaWJlIiwicmVxdWVzdElkIiwicXVlcnkiLCJjbGFzc05hbWUiLCJ3aGVyZSIsImZpZWxkcyIsIml0ZW1zIiwibWluSXRlbXMiLCJ1bmlxdWVJdGVtcyIsInVwZGF0ZSIsInVuc3Vic2NyaWJlIiwiUmVxdWVzdFNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2RDLEVBQUFBLEtBQUssRUFBRSx3QkFETztBQUVkQyxFQUFBQSxJQUFJLEVBQUUsUUFGUTtBQUdkQyxFQUFBQSxVQUFVLEVBQUU7QUFDVkMsSUFBQUEsRUFBRSxFQUFFO0FBQ0ZGLE1BQUFBLElBQUksRUFBRSxRQURKO0FBRUZHLE1BQUFBLElBQUksRUFBRSxDQUFDLFNBQUQsRUFBWSxXQUFaLEVBQXlCLGFBQXpCLEVBQXdDLFFBQXhDO0FBRko7QUFETSxHQUhFO0FBU2RDLEVBQUFBLFFBQVEsRUFBRSxDQUFDLElBQUQ7QUFUSSxDQUFoQjtBQVlBLE1BQU1DLE9BQU8sR0FBRztBQUNkTixFQUFBQSxLQUFLLEVBQUUsMEJBRE87QUFFZEMsRUFBQUEsSUFBSSxFQUFFLFFBRlE7QUFHZEMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxTQURNO0FBRVZJLElBQUFBLGFBQWEsRUFBRTtBQUNiTixNQUFBQSxJQUFJLEVBQUU7QUFETyxLQUZMO0FBS1ZPLElBQUFBLGFBQWEs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LENBTEo7QUFNTkMsVUFBQUEsV0FBVyxFQUFFO0FBTlA7QUFQRSxPQUhQO0FBbUJMbkIsTUFBQUEsUUFBUSxFQUFFLENBQUMsT0FBRCxFQUFVLFdBQVYsQ0FuQkw7QUFvQkxVLE1BQUFBLG9CQUFvQixFQUFFO0FBcEJqQixLQUxHO0FBMkJWRixJQUFBQSxZQUFZLEVBQUU7QUFDWlosTUFBQUEsSUFBSSxFQUFFO0FBRE07QUEzQkosR0FIQztBQWtDYkksRUFBQUEsUUFBUSxFQUFFLENBQUMsSUFBRCxFQUFPLFdBQVAsRUFBb0IsT0FBcEIsQ0FsQ0c7QUFtQ2JVLEVBQUFBLG9CQUFvQixFQUFFO0FBbkNULENBQWY7QUFzQ0EsTUFBTVcsV0FBVyxHQUFHO0FBQ2xCMUIsRUFBQUEsS0FBSyxFQUFFLDhCQURXO0FBRWxCQyxFQUFBQSxJQUFJLEVBQUUsUUFGWTtBQUdsQkMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxhQURNO0FBRVZjLElBQUFBLFNBQVMsRUFBRTtBQUNUaEIsTUFBQUEsSUFBSSxFQUFFO0FBREc7QUFGRCxHQUhNO0FBU2xCSSxFQUFBQSxRQUFRLEVBQUUsQ0FBQyxJQUFELEVBQU8sV0FBUCxDQVRRO0FBVWxCVSxFQUFBQSxvQkFBb0IsRUFBRTtBQVZKLENBQXBCO0FBYUEsTUFBTVksYUFBYSxHQUFHO0FBQ3BCNUIsRUFBQUEsT0FBTyxFQUFFQSxPQURXO0FBRXBCTyxFQUFBQSxPQUFPLEVBQUVBLE9BRlc7QUFHcEJVLEVBQUFBLFNBQVMsRUFBRUEsU0FIUztBQUlwQlMsRUFBQUEsTUFBTSxFQUFFQSxNQUpZO0FBS3BCQyxFQUFBQSxXQUFXLEVBQUVBO0FBTE8sQ0FBdEI7ZUFRZUMsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGdlbmVyYWwgPSB7XG4gIHRpdGxlOiAnR2VuZXJhbCByZXF1ZXN0IHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW51bTogWydjb25uZWN0JywgJ3N1YnNjcmliZScsICd1bnN1YnNjcmliZScsICd1cGRhdGUnXSxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCddLFxufTtcblxuY29uc3QgY29ubmVjdCA9IHtcbiAgdGl0bGU6ICdDb25uZWN0IG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnY29ubmVjdCcsXG4gICAgYXBwbGljYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBqYXZhc2NyaXB0S2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIG1hc3RlcktleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBjbGllbnRLZXk6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIH0sXG4gICAgd2luZG93c0tleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICByZXN0QVBJS2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBpbnN0YWxsYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAnYXBwbGljYXRpb25JZCddLFxuICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG59O1xuXG5jb25zdCBzdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnU3Vic2NyaWJlIG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnc3Vic2NyaWJlJyxcbiAgICByZXF1ZXN0SWQ6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgIH0sXG4gICAgcXVlcnk6IHtcbiAgICAgIHRpdGxlOiAnUXVlcnkgZmllbGQgc2NoZW1hJyxcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBjbGFzc05hbWU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgfSxcbiAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgfSxcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczoge1xuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtaW5JdGVtczogMSxcbiAgICAgICAgICB1bmlxdWVJdGVtczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWyd3aGVyZScsICdjbGFzc05hbWUnXSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAncmVxdWVzdElkJywgJ3F1ZXJ5J10sXG4gIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbn07XG5cbmNvbnN0IHVwZGF0ZSA9IHtcbiAgdGl0bGU6ICdVcGRhdGUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1cGRhdGUnLFxuICAgIHJlcXVlc3RJZDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgfSxcbiAgICBxdWVyeToge1xuICAgICAgdGl0bGU6ICdRdWVyeSBmaWVsZCBzY2hlbWEnLFxuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGNsYXNzTmFtZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICB9LFxuICAgICAgICB3aGVyZToge1xuICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICB9LFxuICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1pbkl0ZW1zOiAxLFxuICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3doZXJlJywgJ2NsYXNzTmFtZSddLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIH0sXG4gICAgc2Vzc2lvblRva2VuOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnLCAncXVlcnknXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgdW5zdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnVW5zdWJzY3JpYmUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1bnN1YnNjcmliZScsXG4gICAgcmVxdWVzdElkOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgUmVxdWVzdFNjaGVtYSA9IHtcbiAgZ2VuZXJhbDogZ2VuZXJhbCxcbiAgY29ubmVjdDogY29ubmVjdCxcbiAgc3Vic2NyaWJlOiBzdWJzY3JpYmUsXG4gIHVwZGF0ZTogdXBkYXRlLFxuICB1bnN1YnNjcmliZTogdW5zdWJzY3JpYmUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0U2NoZW1hO1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/SessionTokenCache.js b/lib/LiveQuery/SessionTokenCache.js new file mode 100644 index 0000000000..07a9a06965 --- /dev/null +++ b/lib/LiveQuery/SessionTokenCache.js @@ -0,0 +1,67 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SessionTokenCache = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _lruCache = _interopRequireDefault(require("lru-cache")); + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function userForSessionToken(sessionToken) { + var q = new _node.default.Query('_Session'); + q.equalTo('sessionToken', sessionToken); + return q.first({ + useMasterKey: true + }).then(function (session) { + if (!session) { + return Promise.reject('No session found for session token'); + } + + return session.get('user'); + }); +} + +class SessionTokenCache { + constructor(timeout = 30 * 24 * 60 * 60 * 1000, maxSize = 10000) { + this.cache = new _lruCache.default({ + max: maxSize, + maxAge: timeout + }); + } + + getUserId(sessionToken) { + if (!sessionToken) { + return Promise.reject('Empty sessionToken'); + } + + const userId = this.cache.get(sessionToken); + + if (userId) { + _logger.default.verbose('Fetch userId %s of sessionToken %s from Cache', userId, sessionToken); + + return Promise.resolve(userId); + } + + return userForSessionToken(sessionToken).then(user => { + _logger.default.verbose('Fetch userId %s of sessionToken %s from Parse', user.id, sessionToken); + + const userId = user.id; + this.cache.set(sessionToken, userId); + return Promise.resolve(userId); + }, error => { + _logger.default.error('Can not fetch userId for sessionToken %j, error %j', sessionToken, error); + + return Promise.reject(error); + }); + } + +} + +exports.SessionTokenCache = SessionTokenCache; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU2Vzc2lvblRva2VuQ2FjaGUuanMiXSwibmFtZXMiOlsidXNlckZvclNlc3Npb25Ub2tlbiIsInNlc3Npb25Ub2tlbiIsInEiLCJQYXJzZSIsIlF1ZXJ5IiwiZXF1YWxUbyIsImZpcnN0IiwidXNlTWFzdGVyS2V5IiwidGhlbiIsInNlc3Npb24iLCJQcm9taXNlIiwicmVqZWN0IiwiZ2V0IiwiU2Vzc2lvblRva2VuQ2FjaGUiLCJjb25zdHJ1Y3RvciIsInRpbWVvdXQiLCJtYXhTaXplIiwiY2FjaGUiLCJMUlUiLCJtYXgiLCJtYXhBZ2UiLCJnZXRVc2VySWQiLCJ1c2VySWQiLCJsb2dnZXIiLCJ2ZXJib3NlIiwicmVzb2x2ZSIsInVzZXIiLCJpZCIsInNldCIsImVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxTQUFTQSxtQkFBVCxDQUE2QkMsWUFBN0IsRUFBMkM7QUFDekMsTUFBSUMsQ0FBQyxHQUFHLElBQUlDLGNBQU1DLEtBQVYsQ0FBZ0IsVUFBaEIsQ0FBUjtBQUNBRixFQUFBQSxDQUFDLENBQUNHLE9BQUYsQ0FBVSxjQUFWLEVBQTBCSixZQUExQjtBQUNBLFNBQU9DLENBQUMsQ0FBQ0ksS0FBRixDQUFRO0FBQUVDLElBQUFBLFlBQVksRUFBRTtBQUFoQixHQUFSLEVBQWdDQyxJQUFoQyxDQUFxQyxVQUFVQyxPQUFWLEVBQW1CO0FBQzdELFFBQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osYUFBT0MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0NBQWYsQ0FBUDtBQUNEOztBQUNELFdBQU9GLE9BQU8sQ0FBQ0csR0FBUixDQUFZLE1BQVosQ0FBUDtBQUNELEdBTE0sQ0FBUDtBQU1EOztBQUVELE1BQU1DLGlCQUFOLENBQXdCO0FBR3RCQyxFQUFBQSxXQUFXLENBQUNDLE9BQWUsR0FBRyxLQUFLLEVBQUwsR0FBVSxFQUFWLEdBQWUsRUFBZixHQUFvQixJQUF2QyxFQUE2Q0MsT0FBZSxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxpQkFBSixDQUFRO0FBQ25CQyxNQUFBQSxHQUFHLEVBQUVILE9BRGM7QUFFbkJJLE1BQUFBLE1BQU0sRUFBRUw7QUFGVyxLQUFSLENBQWI7QUFJRDs7QUFFRE0sRUFBQUEsU0FBUyxDQUFDcEIsWUFBRCxFQUE0QjtBQUNuQyxRQUFJLENBQUNBLFlBQUwsRUFBbUI7QUFDakIsYUFBT1MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0JBQWYsQ0FBUDtBQUNEOztBQUNELFVBQU1XLE1BQU0sR0FBRyxLQUFLTCxLQUFMLENBQVdMLEdBQVgsQ0FBZVgsWUFBZixDQUFmOztBQUNBLFFBQUlxQixNQUFKLEVBQVk7QUFDVkMsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUYsTUFBaEUsRUFBd0VyQixZQUF4RTs7QUFDQSxhQUFPUyxPQUFPLENBQUNlLE9BQVIsQ0FBZ0JILE1BQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPdEIsbUJBQW1CLENBQUNDLFlBQUQsQ0FBbkIsQ0FBa0NPLElBQWxDLENBQ0xrQixJQUFJLElBQUk7QUFDTkgsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUUsSUFBSSxDQUFDQyxFQUFyRSxFQUF5RTFCLFlBQXpFOztBQUNBLFlBQU1xQixNQUFNLEdBQUdJLElBQUksQ0FBQ0MsRUFBcEI7QUFDQSxXQUFLVixLQUFMLENBQVdXLEdBQVgsQ0FBZTNCLFlBQWYsRUFBNkJxQixNQUE3QjtBQUNBLGFBQU9aLE9BQU8sQ0FBQ2UsT0FBUixDQUFnQkgsTUFBaEIsQ0FBUDtBQUNELEtBTkksRUFPTE8sS0FBSyxJQUFJO0FBQ1BOLHNCQUFPTSxLQUFQLENBQWEsb0RBQWIsRUFBbUU1QixZQUFuRSxFQUFpRjRCLEtBQWpGOztBQUNBLGFBQU9uQixPQUFPLENBQUNDLE1BQVIsQ0FBZWtCLEtBQWYsQ0FBUDtBQUNELEtBVkksQ0FBUDtBQVlEOztBQS9CcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgTFJVIGZyb20gJ2xydS1jYWNoZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIHVzZXJGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuKSB7XG4gIHZhciBxID0gbmV3IFBhcnNlLlF1ZXJ5KCdfU2Vzc2lvbicpO1xuICBxLmVxdWFsVG8oJ3Nlc3Npb25Ub2tlbicsIHNlc3Npb25Ub2tlbik7XG4gIHJldHVybiBxLmZpcnN0KHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pLnRoZW4oZnVuY3Rpb24gKHNlc3Npb24pIHtcbiAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnTm8gc2Vzc2lvbiBmb3VuZCBmb3Igc2Vzc2lvbiB0b2tlbicpO1xuICAgIH1cbiAgICByZXR1cm4gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbiAgfSk7XG59XG5cbmNsYXNzIFNlc3Npb25Ub2tlbkNhY2hlIHtcbiAgY2FjaGU6IE9iamVjdDtcblxuICBjb25zdHJ1Y3Rvcih0aW1lb3V0OiBudW1iZXIgPSAzMCAqIDI0ICogNjAgKiA2MCAqIDEwMDAsIG1heFNpemU6IG51bWJlciA9IDEwMDAwKSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0aW1lb3V0LFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklkKHNlc3Npb25Ub2tlbjogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoIXNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdFbXB0eSBzZXNzaW9uVG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy5jYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlcklkKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnRmV0Y2ggdXNlcklkICVzIG9mIHNlc3Npb25Ub2tlbiAlcyBmcm9tIENhY2hlJywgdXNlcklkLCBzZXNzaW9uVG9rZW4pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgIH1cbiAgICByZXR1cm4gdXNlckZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pLnRoZW4oXG4gICAgICB1c2VyID0+IHtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0ZldGNoIHVzZXJJZCAlcyBvZiBzZXNzaW9uVG9rZW4gJXMgZnJvbSBQYXJzZScsIHVzZXIuaWQsIHNlc3Npb25Ub2tlbik7XG4gICAgICAgIGNvbnN0IHVzZXJJZCA9IHVzZXIuaWQ7XG4gICAgICAgIHRoaXMuY2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgdXNlcklkKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZldGNoIHVzZXJJZCBmb3Igc2Vzc2lvblRva2VuICVqLCBlcnJvciAlaicsIHNlc3Npb25Ub2tlbiwgZXJyb3IpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IHsgU2Vzc2lvblRva2VuQ2FjaGUgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Subscription.js b/lib/LiveQuery/Subscription.js new file mode 100644 index 0000000000..a424955752 --- /dev/null +++ b/lib/LiveQuery/Subscription.js @@ -0,0 +1,61 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Subscription = void 0; + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Subscription { + // It is query condition eg query.where + constructor(className, query, queryHash) { + this.className = className; + this.query = query; + this.hash = queryHash; + this.clientRequestIds = new Map(); + } + + addClientSubscription(clientId, requestId) { + if (!this.clientRequestIds.has(clientId)) { + this.clientRequestIds.set(clientId, []); + } + + const requestIds = this.clientRequestIds.get(clientId); + requestIds.push(requestId); + } + + deleteClientSubscription(clientId, requestId) { + const requestIds = this.clientRequestIds.get(clientId); + + if (typeof requestIds === 'undefined') { + _logger.default.error('Can not find client %d to delete', clientId); + + return; + } + + const index = requestIds.indexOf(requestId); + + if (index < 0) { + _logger.default.error('Can not find client %d subscription %d to delete', clientId, requestId); + + return; + } + + requestIds.splice(index, 1); // Delete client reference if it has no subscription + + if (requestIds.length == 0) { + this.clientRequestIds.delete(clientId); + } + } + + hasSubscribingClient() { + return this.clientRequestIds.size > 0; + } + +} + +exports.Subscription = Subscription; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU3Vic2NyaXB0aW9uLmpzIl0sIm5hbWVzIjpbIlN1YnNjcmlwdGlvbiIsImNvbnN0cnVjdG9yIiwiY2xhc3NOYW1lIiwicXVlcnkiLCJxdWVyeUhhc2giLCJoYXNoIiwiY2xpZW50UmVxdWVzdElkcyIsIk1hcCIsImFkZENsaWVudFN1YnNjcmlwdGlvbiIsImNsaWVudElkIiwicmVxdWVzdElkIiwiaGFzIiwic2V0IiwicmVxdWVzdElkcyIsImdldCIsInB1c2giLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJsb2dnZXIiLCJlcnJvciIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsImxlbmd0aCIsImRlbGV0ZSIsImhhc1N1YnNjcmliaW5nQ2xpZW50Iiwic2l6ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBS0EsTUFBTUEsWUFBTixDQUFtQjtBQUNqQjtBQU1BQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLEtBQXBCLEVBQXNDQyxTQUF0QyxFQUF5RDtBQUNsRSxTQUFLRixTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLFNBQUtDLEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtFLElBQUwsR0FBWUQsU0FBWjtBQUNBLFNBQUtFLGdCQUFMLEdBQXdCLElBQUlDLEdBQUosRUFBeEI7QUFDRDs7QUFFREMsRUFBQUEscUJBQXFCLENBQUNDLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQy9ELFFBQUksQ0FBQyxLQUFLSixnQkFBTCxDQUFzQkssR0FBdEIsQ0FBMEJGLFFBQTFCLENBQUwsRUFBMEM7QUFDeEMsV0FBS0gsZ0JBQUwsQ0FBc0JNLEdBQXRCLENBQTBCSCxRQUExQixFQUFvQyxFQUFwQztBQUNEOztBQUNELFVBQU1JLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5CO0FBQ0FJLElBQUFBLFVBQVUsQ0FBQ0UsSUFBWCxDQUFnQkwsU0FBaEI7QUFDRDs7QUFFRE0sRUFBQUEsd0JBQXdCLENBQUNQLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQ2xFLFVBQU1HLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5COztBQUNBLFFBQUksT0FBT0ksVUFBUCxLQUFzQixXQUExQixFQUF1QztBQUNyQ0ksc0JBQU9DLEtBQVAsQ0FBYSxrQ0FBYixFQUFpRFQsUUFBakQ7O0FBQ0E7QUFDRDs7QUFFRCxVQUFNVSxLQUFLLEdBQUdOLFVBQVUsQ0FBQ08sT0FBWCxDQUFtQlYsU0FBbkIsQ0FBZDs7QUFDQSxRQUFJUyxLQUFLLEdBQUcsQ0FBWixFQUFlO0FBQ2JGLHNCQUFPQyxLQUFQLENBQWEsa0RBQWIsRUFBaUVULFFBQWpFLEVBQTJFQyxTQUEzRTs7QUFDQTtBQUNEOztBQUNERyxJQUFBQSxVQUFVLENBQUNRLE1BQVgsQ0FBa0JGLEtBQWxCLEVBQXlCLENBQXpCLEVBWmtFLENBYWxFOztBQUNBLFFBQUlOLFVBQVUsQ0FBQ1MsTUFBWCxJQUFxQixDQUF6QixFQUE0QjtBQUMxQixXQUFLaEIsZ0JBQUwsQ0FBc0JpQixNQUF0QixDQUE2QmQsUUFBN0I7QUFDRDtBQUNGOztBQUVEZSxFQUFBQSxvQkFBb0IsR0FBWTtBQUM5QixXQUFPLEtBQUtsQixnQkFBTCxDQUFzQm1CLElBQXRCLEdBQTZCLENBQXBDO0FBQ0Q7O0FBM0NnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcblxuZXhwb3J0IHR5cGUgRmxhdHRlbmVkT2JqZWN0RGF0YSA9IHsgW2F0dHI6IHN0cmluZ106IGFueSB9O1xuZXhwb3J0IHR5cGUgUXVlcnlEYXRhID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNsYXNzIFN1YnNjcmlwdGlvbiB7XG4gIC8vIEl0IGlzIHF1ZXJ5IGNvbmRpdGlvbiBlZyBxdWVyeS53aGVyZVxuICBxdWVyeTogUXVlcnlEYXRhO1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgaGFzaDogc3RyaW5nO1xuICBjbGllbnRSZXF1ZXN0SWRzOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBRdWVyeURhdGEsIHF1ZXJ5SGFzaDogc3RyaW5nKSB7XG4gICAgdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgdGhpcy5xdWVyeSA9IHF1ZXJ5O1xuICAgIHRoaXMuaGFzaCA9IHF1ZXJ5SGFzaDtcbiAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBhZGRDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQ6IG51bWJlciwgcmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50UmVxdWVzdElkcy5oYXMoY2xpZW50SWQpKSB7XG4gICAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMuc2V0KGNsaWVudElkLCBbXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICByZXF1ZXN0SWRzLnB1c2gocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihjbGllbnRJZDogbnVtYmVyLCByZXF1ZXN0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RJZHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCBjbGllbnQgJWQgdG8gZGVsZXRlJywgY2xpZW50SWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gcmVxdWVzdElkcy5pbmRleE9mKHJlcXVlc3RJZCk7XG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgY2xpZW50ICVkIHN1YnNjcmlwdGlvbiAlZCB0byBkZWxldGUnLCBjbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmVxdWVzdElkcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIC8vIERlbGV0ZSBjbGllbnQgcmVmZXJlbmNlIGlmIGl0IGhhcyBubyBzdWJzY3JpcHRpb25cbiAgICBpZiAocmVxdWVzdElkcy5sZW5ndGggPT0gMCkge1xuICAgICAgdGhpcy5jbGllbnRSZXF1ZXN0SWRzLmRlbGV0ZShjbGllbnRJZCk7XG4gICAgfVxuICB9XG5cbiAgaGFzU3Vic2NyaWJpbmdDbGllbnQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50UmVxdWVzdElkcy5zaXplID4gMDtcbiAgfVxufVxuXG5leHBvcnQgeyBTdWJzY3JpcHRpb24gfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/equalObjects.js b/lib/LiveQuery/equalObjects.js new file mode 100644 index 0000000000..028cc134ac --- /dev/null +++ b/lib/LiveQuery/equalObjects.js @@ -0,0 +1,62 @@ +"use strict"; + +var toString = Object.prototype.toString; +/** + * Determines whether two objects represent the same primitive, special Parse + * type, or full Parse Object. + */ + +function equalObjects(a, b) { + if (typeof a !== typeof b) { + return false; + } + + if (typeof a !== 'object') { + return a === b; + } + + if (a === b) { + return true; + } + + if (toString.call(a) === '[object Date]') { + if (toString.call(b) === '[object Date]') { + return +a === +b; + } + + return false; + } + + if (Array.isArray(a)) { + if (Array.isArray(b)) { + if (a.length !== b.length) { + return false; + } + + for (var i = 0; i < a.length; i++) { + if (!equalObjects(a[i], b[i])) { + return false; + } + } + + return true; + } + + return false; + } + + if (Object.keys(a).length !== Object.keys(b).length) { + return false; + } + + for (var key in a) { + if (!equalObjects(a[key], b[key])) { + return false; + } + } + + return true; +} + +module.exports = equalObjects; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvZXF1YWxPYmplY3RzLmpzIl0sIm5hbWVzIjpbInRvU3RyaW5nIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiZXF1YWxPYmplY3RzIiwiYSIsImIiLCJjYWxsIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiaSIsImtleXMiLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxTQUFQLENBQWlCRixRQUFoQztBQUVBOzs7OztBQUlBLFNBQVNHLFlBQVQsQ0FBc0JDLENBQXRCLEVBQXlCQyxDQUF6QixFQUE0QjtBQUMxQixNQUFJLE9BQU9ELENBQVAsS0FBYSxPQUFPQyxDQUF4QixFQUEyQjtBQUN6QixXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJLE9BQU9ELENBQVAsS0FBYSxRQUFqQixFQUEyQjtBQUN6QixXQUFPQSxDQUFDLEtBQUtDLENBQWI7QUFDRDs7QUFDRCxNQUFJRCxDQUFDLEtBQUtDLENBQVYsRUFBYTtBQUNYLFdBQU8sSUFBUDtBQUNEOztBQUNELE1BQUlMLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRixDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLFFBQUlKLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRCxDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLGFBQU8sQ0FBQ0QsQ0FBRCxLQUFPLENBQUNDLENBQWY7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJRSxLQUFLLENBQUNDLE9BQU4sQ0FBY0osQ0FBZCxDQUFKLEVBQXNCO0FBQ3BCLFFBQUlHLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxDQUFkLENBQUosRUFBc0I7QUFDcEIsVUFBSUQsQ0FBQyxDQUFDSyxNQUFGLEtBQWFKLENBQUMsQ0FBQ0ksTUFBbkIsRUFBMkI7QUFDekIsZUFBTyxLQUFQO0FBQ0Q7O0FBQ0QsV0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHTixDQUFDLENBQUNLLE1BQXRCLEVBQThCQyxDQUFDLEVBQS9CLEVBQW1DO0FBQ2pDLFlBQUksQ0FBQ1AsWUFBWSxDQUFDQyxDQUFDLENBQUNNLENBQUQsQ0FBRixFQUFPTCxDQUFDLENBQUNLLENBQUQsQ0FBUixDQUFqQixFQUErQjtBQUM3QixpQkFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPLElBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJVCxNQUFNLENBQUNVLElBQVAsQ0FBWVAsQ0FBWixFQUFlSyxNQUFmLEtBQTBCUixNQUFNLENBQUNVLElBQVAsQ0FBWU4sQ0FBWixFQUFlSSxNQUE3QyxFQUFxRDtBQUNuRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxPQUFLLElBQUlHLEdBQVQsSUFBZ0JSLENBQWhCLEVBQW1CO0FBQ2pCLFFBQUksQ0FBQ0QsWUFBWSxDQUFDQyxDQUFDLENBQUNRLEdBQUQsQ0FBRixFQUFTUCxDQUFDLENBQUNPLEdBQUQsQ0FBVixDQUFqQixFQUFtQztBQUNqQyxhQUFPLEtBQVA7QUFDRDtBQUNGOztBQUNELFNBQU8sSUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLFlBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdHdvIG9iamVjdHMgcmVwcmVzZW50IHRoZSBzYW1lIHByaW1pdGl2ZSwgc3BlY2lhbCBQYXJzZVxuICogdHlwZSwgb3IgZnVsbCBQYXJzZSBPYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhhLCBiKSB7XG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBhICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBhID09PSBiO1xuICB9XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHRvU3RyaW5nLmNhbGwoYSkgPT09ICdbb2JqZWN0IERhdGVdJykge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKGIpID09PSAnW29iamVjdCBEYXRlXScpIHtcbiAgICAgIHJldHVybiArYSA9PT0gK2I7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGIpKSB7XG4gICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2ldLCBiW2ldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yICh2YXIga2V5IGluIGEpIHtcbiAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2tleV0sIGJba2V5XSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxPYmplY3RzO1xuIl19 \ No newline at end of file diff --git a/lib/Options/Definitions.js b/lib/Options/Definitions.js new file mode 100644 index 0000000000..37d5b1bcd7 --- /dev/null +++ b/lib/Options/Definitions.js @@ -0,0 +1,531 @@ +"use strict"; + +/* +**** GENERATED CODE **** +This code has been generated by resources/buildConfigDefinitions.js +Do not edit manually, but update Options/index.js +*/ +var parsers = require('./parsers'); + +module.exports.ParseServerOptions = { + accountLockout: { + env: 'PARSE_SERVER_ACCOUNT_LOCKOUT', + help: 'account lockout policy for failed login attempts', + action: parsers.objectParser + }, + allowClientClassCreation: { + env: 'PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION', + help: 'Enable (or disable) client class creation, defaults to true', + action: parsers.booleanParser, + default: true + }, + allowCustomObjectId: { + env: 'PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID', + help: 'Enable (or disable) custom objectId', + action: parsers.booleanParser, + default: false + }, + allowHeaders: { + env: 'PARSE_SERVER_ALLOW_HEADERS', + help: 'Add headers to Access-Control-Allow-Headers', + action: parsers.arrayParser + }, + allowOrigin: { + env: 'PARSE_SERVER_ALLOW_ORIGIN', + help: 'Sets the origin to Access-Control-Allow-Origin' + }, + analyticsAdapter: { + env: 'PARSE_SERVER_ANALYTICS_ADAPTER', + help: 'Adapter module for the analytics', + action: parsers.moduleOrObjectParser + }, + appId: { + env: 'PARSE_SERVER_APPLICATION_ID', + help: 'Your Parse Application ID', + required: true + }, + appName: { + env: 'PARSE_SERVER_APP_NAME', + help: 'Sets the app name' + }, + auth: { + env: 'PARSE_SERVER_AUTH_PROVIDERS', + help: 'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication', + action: parsers.objectParser + }, + cacheAdapter: { + env: 'PARSE_SERVER_CACHE_ADAPTER', + help: 'Adapter module for the cache', + action: parsers.moduleOrObjectParser + }, + cacheMaxSize: { + env: 'PARSE_SERVER_CACHE_MAX_SIZE', + help: 'Sets the maximum size for the in memory cache, defaults to 10000', + action: parsers.numberParser('cacheMaxSize'), + default: 10000 + }, + cacheTTL: { + env: 'PARSE_SERVER_CACHE_TTL', + help: 'Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds)', + action: parsers.numberParser('cacheTTL'), + default: 5000 + }, + clientKey: { + env: 'PARSE_SERVER_CLIENT_KEY', + help: 'Key for iOS, MacOS, tvOS clients' + }, + cloud: { + env: 'PARSE_SERVER_CLOUD', + help: 'Full path to your cloud code main.js' + }, + cluster: { + env: 'PARSE_SERVER_CLUSTER', + help: 'Run with cluster, optionally set the number of processes default to os.cpus().length', + action: parsers.numberOrBooleanParser + }, + collectionPrefix: { + env: 'PARSE_SERVER_COLLECTION_PREFIX', + help: 'A collection prefix for the classes', + default: '' + }, + customPages: { + env: 'PARSE_SERVER_CUSTOM_PAGES', + help: 'custom pages for password validation and reset', + action: parsers.objectParser, + default: {} + }, + databaseAdapter: { + env: 'PARSE_SERVER_DATABASE_ADAPTER', + help: 'Adapter module for the database', + action: parsers.moduleOrObjectParser + }, + databaseOptions: { + env: 'PARSE_SERVER_DATABASE_OPTIONS', + help: 'Options to pass to the mongodb client', + action: parsers.objectParser + }, + databaseURI: { + env: 'PARSE_SERVER_DATABASE_URI', + help: 'The full URI to your database. Supported databases are mongodb or postgres.', + required: true, + default: 'mongodb://localhost:27017/parse' + }, + directAccess: { + env: 'PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS', + help: 'Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production.', + action: parsers.booleanParser, + default: false + }, + dotNetKey: { + env: 'PARSE_SERVER_DOT_NET_KEY', + help: 'Key for Unity and .Net SDK' + }, + emailAdapter: { + env: 'PARSE_SERVER_EMAIL_ADAPTER', + help: 'Adapter module for email sending', + action: parsers.moduleOrObjectParser + }, + emailVerifyTokenValidityDuration: { + env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_VALIDITY_DURATION', + help: 'Email verification token validity duration, in seconds', + action: parsers.numberParser('emailVerifyTokenValidityDuration') + }, + enableAnonymousUsers: { + env: 'PARSE_SERVER_ENABLE_ANON_USERS', + help: 'Enable (or disable) anonymous users, defaults to true', + action: parsers.booleanParser, + default: true + }, + enableExpressErrorHandler: { + env: 'PARSE_SERVER_ENABLE_EXPRESS_ERROR_HANDLER', + help: 'Enables the default express error handler for all errors', + action: parsers.booleanParser, + default: false + }, + enableSingleSchemaCache: { + env: 'PARSE_SERVER_ENABLE_SINGLE_SCHEMA_CACHE', + help: 'Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request.', + action: parsers.booleanParser, + default: false + }, + encryptionKey: { + env: 'PARSE_SERVER_ENCRYPTION_KEY', + help: 'Key for encrypting your files' + }, + expireInactiveSessions: { + env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', + help: 'Sets wether we should expire the inactive sessions, defaults to true', + action: parsers.booleanParser, + default: true + }, + fileKey: { + env: 'PARSE_SERVER_FILE_KEY', + help: 'Key for your files' + }, + filesAdapter: { + env: 'PARSE_SERVER_FILES_ADAPTER', + help: 'Adapter module for the files sub-system', + action: parsers.moduleOrObjectParser + }, + graphQLPath: { + env: 'PARSE_SERVER_GRAPHQL_PATH', + help: 'Mount path for the GraphQL endpoint, defaults to /graphql', + default: '/graphql' + }, + graphQLSchema: { + env: 'PARSE_SERVER_GRAPH_QLSCHEMA', + help: 'Full path to your GraphQL custom schema.graphql file' + }, + host: { + env: 'PARSE_SERVER_HOST', + help: 'The host to serve ParseServer on, defaults to 0.0.0.0', + default: '0.0.0.0' + }, + idempotencyOptions: { + env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_OPTIONS', + help: 'Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production.', + action: parsers.objectParser, + default: {} + }, + javascriptKey: { + env: 'PARSE_SERVER_JAVASCRIPT_KEY', + help: 'Key for the Javascript SDK' + }, + jsonLogs: { + env: 'JSON_LOGS', + help: 'Log as structured JSON objects', + action: parsers.booleanParser + }, + liveQuery: { + env: 'PARSE_SERVER_LIVE_QUERY', + help: "parse-server's LiveQuery configuration object", + action: parsers.objectParser + }, + liveQueryServerOptions: { + env: 'PARSE_SERVER_LIVE_QUERY_SERVER_OPTIONS', + help: 'Live query server configuration options (will start the liveQuery server)', + action: parsers.objectParser + }, + loggerAdapter: { + env: 'PARSE_SERVER_LOGGER_ADAPTER', + help: 'Adapter module for the logging sub-system', + action: parsers.moduleOrObjectParser + }, + logLevel: { + env: 'PARSE_SERVER_LOG_LEVEL', + help: 'Sets the level for logs' + }, + logsFolder: { + env: 'PARSE_SERVER_LOGS_FOLDER', + help: "Folder for the logs (defaults to './logs'); set to null to disable file based logging", + default: './logs' + }, + masterKey: { + env: 'PARSE_SERVER_MASTER_KEY', + help: 'Your Parse Master Key', + required: true + }, + masterKeyIps: { + env: 'PARSE_SERVER_MASTER_KEY_IPS', + help: 'Restrict masterKey to be used by only these ips, defaults to [] (allow all ips)', + action: parsers.arrayParser, + default: [] + }, + maxLimit: { + env: 'PARSE_SERVER_MAX_LIMIT', + help: 'Max value for limit option on queries, defaults to unlimited', + action: parsers.numberParser('maxLimit') + }, + maxLogFiles: { + env: 'PARSE_SERVER_MAX_LOG_FILES', + help: "Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null)", + action: parsers.objectParser + }, + maxUploadSize: { + env: 'PARSE_SERVER_MAX_UPLOAD_SIZE', + help: 'Max file size for uploads, defaults to 20mb', + default: '20mb' + }, + middleware: { + env: 'PARSE_SERVER_MIDDLEWARE', + help: 'middleware for express server, can be string or function' + }, + mountGraphQL: { + env: 'PARSE_SERVER_MOUNT_GRAPHQL', + help: 'Mounts the GraphQL endpoint', + action: parsers.booleanParser, + default: false + }, + mountPath: { + env: 'PARSE_SERVER_MOUNT_PATH', + help: 'Mount path for the server, defaults to /parse', + default: '/parse' + }, + mountPlayground: { + env: 'PARSE_SERVER_MOUNT_PLAYGROUND', + help: 'Mounts the GraphQL Playground - never use this option in production', + action: parsers.booleanParser, + default: false + }, + objectIdSize: { + env: 'PARSE_SERVER_OBJECT_ID_SIZE', + help: "Sets the number of characters in generated object id's, default 10", + action: parsers.numberParser('objectIdSize'), + default: 10 + }, + passwordPolicy: { + env: 'PARSE_SERVER_PASSWORD_POLICY', + help: 'Password policy for enforcing password related rules', + action: parsers.objectParser + }, + playgroundPath: { + env: 'PARSE_SERVER_PLAYGROUND_PATH', + help: 'Mount path for the GraphQL Playground, defaults to /playground', + default: '/playground' + }, + port: { + env: 'PORT', + help: 'The port to run the ParseServer, defaults to 1337.', + action: parsers.numberParser('port'), + default: 1337 + }, + preserveFileName: { + env: 'PARSE_SERVER_PRESERVE_FILE_NAME', + help: 'Enable (or disable) the addition of a unique hash to the file names', + action: parsers.booleanParser, + default: false + }, + preventLoginWithUnverifiedEmail: { + env: 'PARSE_SERVER_PREVENT_LOGIN_WITH_UNVERIFIED_EMAIL', + help: 'Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false', + action: parsers.booleanParser, + default: false + }, + protectedFields: { + env: 'PARSE_SERVER_PROTECTED_FIELDS', + help: 'Protected fields that should be treated with extra security when fetching details.', + action: parsers.objectParser, + default: { + _User: { + '*': ['email'] + } + } + }, + publicServerURL: { + env: 'PARSE_PUBLIC_SERVER_URL', + help: 'Public URL to your parse server with http:// or https://.' + }, + push: { + env: 'PARSE_SERVER_PUSH', + help: 'Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications', + action: parsers.objectParser + }, + readOnlyMasterKey: { + env: 'PARSE_SERVER_READ_ONLY_MASTER_KEY', + help: 'Read-only key, which has the same capabilities as MasterKey without writes' + }, + restAPIKey: { + env: 'PARSE_SERVER_REST_API_KEY', + help: 'Key for REST calls' + }, + revokeSessionOnPasswordReset: { + env: 'PARSE_SERVER_REVOKE_SESSION_ON_PASSWORD_RESET', + help: "When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions.", + action: parsers.booleanParser, + default: true + }, + scheduledPush: { + env: 'PARSE_SERVER_SCHEDULED_PUSH', + help: 'Configuration for push scheduling, defaults to false.', + action: parsers.booleanParser, + default: false + }, + schemaCacheTTL: { + env: 'PARSE_SERVER_SCHEMA_CACHE_TTL', + help: 'The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable.', + action: parsers.numberParser('schemaCacheTTL'), + default: 5000 + }, + serverCloseComplete: { + env: 'PARSE_SERVER_SERVER_CLOSE_COMPLETE', + help: 'Callback when server has closed' + }, + serverStartComplete: { + env: 'PARSE_SERVER_SERVER_START_COMPLETE', + help: 'Callback when server has started' + }, + serverURL: { + env: 'PARSE_SERVER_URL', + help: 'URL to your parse server with http:// or https://.', + required: true + }, + sessionLength: { + env: 'PARSE_SERVER_SESSION_LENGTH', + help: 'Session duration, in seconds, defaults to 1 year', + action: parsers.numberParser('sessionLength'), + default: 31536000 + }, + silent: { + env: 'SILENT', + help: 'Disables console output', + action: parsers.booleanParser + }, + startLiveQueryServer: { + env: 'PARSE_SERVER_START_LIVE_QUERY_SERVER', + help: 'Starts the liveQuery server', + action: parsers.booleanParser + }, + userSensitiveFields: { + env: 'PARSE_SERVER_USER_SENSITIVE_FIELDS', + help: 'Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields', + action: parsers.arrayParser + }, + verbose: { + env: 'VERBOSE', + help: 'Set the logging to verbose', + action: parsers.booleanParser + }, + verifyUserEmails: { + env: 'PARSE_SERVER_VERIFY_USER_EMAILS', + help: 'Enable (or disable) user email validation, defaults to false', + action: parsers.booleanParser, + default: false + }, + webhookKey: { + env: 'PARSE_SERVER_WEBHOOK_KEY', + help: 'Key sent with outgoing webhook calls' + } +}; +module.exports.CustomPagesOptions = { + choosePassword: { + env: 'PARSE_SERVER_CUSTOM_PAGES_CHOOSE_PASSWORD', + help: 'choose password page path' + }, + invalidLink: { + env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_LINK', + help: 'invalid link page path' + }, + invalidVerificationLink: { + env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_VERIFICATION_LINK', + help: 'invalid verification link page path' + }, + linkSendFail: { + env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_FAIL', + help: 'verification link send fail page path' + }, + linkSendSuccess: { + env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_SUCCESS', + help: 'verification link send success page path' + }, + parseFrameURL: { + env: 'PARSE_SERVER_CUSTOM_PAGES_PARSE_FRAME_URL', + help: 'for masking user-facing pages' + }, + passwordResetSuccess: { + env: 'PARSE_SERVER_CUSTOM_PAGES_PASSWORD_RESET_SUCCESS', + help: 'password reset success page path' + }, + verifyEmailSuccess: { + env: 'PARSE_SERVER_CUSTOM_PAGES_VERIFY_EMAIL_SUCCESS', + help: 'verify email success page path' + } +}; +module.exports.LiveQueryOptions = { + classNames: { + env: 'PARSE_SERVER_LIVEQUERY_CLASSNAMES', + help: "parse-server's LiveQuery classNames", + action: parsers.arrayParser + }, + pubSubAdapter: { + env: 'PARSE_SERVER_LIVEQUERY_PUB_SUB_ADAPTER', + help: 'LiveQuery pubsub adapter', + action: parsers.moduleOrObjectParser + }, + redisOptions: { + env: 'PARSE_SERVER_LIVEQUERY_REDIS_OPTIONS', + help: "parse-server's LiveQuery redisOptions", + action: parsers.objectParser + }, + redisURL: { + env: 'PARSE_SERVER_LIVEQUERY_REDIS_URL', + help: "parse-server's LiveQuery redisURL" + }, + wssAdapter: { + env: 'PARSE_SERVER_LIVEQUERY_WSS_ADAPTER', + help: 'Adapter module for the WebSocketServer', + action: parsers.moduleOrObjectParser + } +}; +module.exports.LiveQueryServerOptions = { + appId: { + env: 'PARSE_LIVE_QUERY_SERVER_APP_ID', + help: 'This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId.' + }, + cacheTimeout: { + env: 'PARSE_LIVE_QUERY_SERVER_CACHE_TIMEOUT', + help: "Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds).", + action: parsers.numberParser('cacheTimeout') + }, + keyPairs: { + env: 'PARSE_LIVE_QUERY_SERVER_KEY_PAIRS', + help: 'A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details.', + action: parsers.objectParser + }, + logLevel: { + env: 'PARSE_LIVE_QUERY_SERVER_LOG_LEVEL', + help: 'This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO.' + }, + masterKey: { + env: 'PARSE_LIVE_QUERY_SERVER_MASTER_KEY', + help: 'This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey.' + }, + port: { + env: 'PARSE_LIVE_QUERY_SERVER_PORT', + help: 'The port to run the LiveQuery server, defaults to 1337.', + action: parsers.numberParser('port'), + default: 1337 + }, + pubSubAdapter: { + env: 'PARSE_LIVE_QUERY_SERVER_PUB_SUB_ADAPTER', + help: 'LiveQuery pubsub adapter', + action: parsers.moduleOrObjectParser + }, + redisOptions: { + env: 'PARSE_LIVE_QUERY_SERVER_REDIS_OPTIONS', + help: "parse-server's LiveQuery redisOptions", + action: parsers.objectParser + }, + redisURL: { + env: 'PARSE_LIVE_QUERY_SERVER_REDIS_URL', + help: "parse-server's LiveQuery redisURL" + }, + serverURL: { + env: 'PARSE_LIVE_QUERY_SERVER_SERVER_URL', + help: 'This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL.' + }, + websocketTimeout: { + env: 'PARSE_LIVE_QUERY_SERVER_WEBSOCKET_TIMEOUT', + help: 'Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s).', + action: parsers.numberParser('websocketTimeout') + }, + wssAdapter: { + env: 'PARSE_LIVE_QUERY_SERVER_WSS_ADAPTER', + help: 'Adapter module for the WebSocketServer', + action: parsers.moduleOrObjectParser + } +}; +module.exports.IdempotencyOptions = { + paths: { + env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_PATHS', + help: 'An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths.', + action: parsers.arrayParser, + default: [] + }, + ttl: { + env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_TTL', + help: 'The duration in seconds after which a request record is discarded from the database, defaults to 300s.', + action: parsers.numberParser('ttl'), + default: 300 + } +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL0RlZmluaXRpb25zLmpzIl0sIm5hbWVzIjpbInBhcnNlcnMiLCJyZXF1aXJlIiwibW9kdWxlIiwiZXhwb3J0cyIsIlBhcnNlU2VydmVyT3B0aW9ucyIsImFjY291bnRMb2Nrb3V0IiwiZW52IiwiaGVscCIsImFjdGlvbiIsIm9iamVjdFBhcnNlciIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsImJvb2xlYW5QYXJzZXIiLCJkZWZhdWx0IiwiYWxsb3dDdXN0b21PYmplY3RJZCIsImFsbG93SGVhZGVycyIsImFycmF5UGFyc2VyIiwiYWxsb3dPcmlnaW4iLCJhbmFseXRpY3NBZGFwdGVyIiwibW9kdWxlT3JPYmplY3RQYXJzZXIiLCJhcHBJZCIsInJlcXVpcmVkIiwiYXBwTmFtZSIsImF1dGgiLCJjYWNoZUFkYXB0ZXIiLCJjYWNoZU1heFNpemUiLCJudW1iZXJQYXJzZXIiLCJjYWNoZVRUTCIsImNsaWVudEtleSIsImNsb3VkIiwiY2x1c3RlciIsIm51bWJlck9yQm9vbGVhblBhcnNlciIsImNvbGxlY3Rpb25QcmVmaXgiLCJjdXN0b21QYWdlcyIsImRhdGFiYXNlQWRhcHRlciIsImRhdGFiYXNlT3B0aW9ucyIsImRhdGFiYXNlVVJJIiwiZGlyZWN0QWNjZXNzIiwiZG90TmV0S2V5IiwiZW1haWxBZGFwdGVyIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJlbmFibGVBbm9ueW1vdXNVc2VycyIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSIsImVuY3J5cHRpb25LZXkiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwiZmlsZUtleSIsImZpbGVzQWRhcHRlciIsImdyYXBoUUxQYXRoIiwiZ3JhcGhRTFNjaGVtYSIsImhvc3QiLCJpZGVtcG90ZW5jeU9wdGlvbnMiLCJqYXZhc2NyaXB0S2V5IiwianNvbkxvZ3MiLCJsaXZlUXVlcnkiLCJsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIiwibG9nZ2VyQWRhcHRlciIsImxvZ0xldmVsIiwibG9nc0ZvbGRlciIsIm1hc3RlcktleSIsIm1hc3RlcktleUlwcyIsIm1heExpbWl0IiwibWF4TG9nRmlsZXMiLCJtYXhVcGxvYWRTaXplIiwibWlkZGxld2FyZSIsIm1vdW50R3JhcGhRTCIsIm1vdW50UGF0aCIsIm1vdW50UGxheWdyb3VuZCIsIm9iamVjdElkU2l6ZSIsInBhc3N3b3JkUG9saWN5IiwicGxheWdyb3VuZFBhdGgiLCJwb3J0IiwicHJlc2VydmVGaWxlTmFtZSIsInByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwiLCJwcm90ZWN0ZWRGaWVsZHMiLCJfVXNlciIsInB1YmxpY1NlcnZlclVSTCIsInB1c2giLCJyZWFkT25seU1hc3RlcktleSIsInJlc3RBUElLZXkiLCJyZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0Iiwic2NoZWR1bGVkUHVzaCIsInNjaGVtYUNhY2hlVFRMIiwic2VydmVyQ2xvc2VDb21wbGV0ZSIsInNlcnZlclN0YXJ0Q29tcGxldGUiLCJzZXJ2ZXJVUkwiLCJzZXNzaW9uTGVuZ3RoIiwic2lsZW50Iiwic3RhcnRMaXZlUXVlcnlTZXJ2ZXIiLCJ1c2VyU2Vuc2l0aXZlRmllbGRzIiwidmVyYm9zZSIsInZlcmlmeVVzZXJFbWFpbHMiLCJ3ZWJob29rS2V5IiwiQ3VzdG9tUGFnZXNPcHRpb25zIiwiY2hvb3NlUGFzc3dvcmQiLCJpbnZhbGlkTGluayIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRGYWlsIiwibGlua1NlbmRTdWNjZXNzIiwicGFyc2VGcmFtZVVSTCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzIiwidmVyaWZ5RW1haWxTdWNjZXNzIiwiTGl2ZVF1ZXJ5T3B0aW9ucyIsImNsYXNzTmFtZXMiLCJwdWJTdWJBZGFwdGVyIiwicmVkaXNPcHRpb25zIiwicmVkaXNVUkwiLCJ3c3NBZGFwdGVyIiwiTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsImNhY2hlVGltZW91dCIsImtleVBhaXJzIiwid2Vic29ja2V0VGltZW91dCIsIklkZW1wb3RlbmN5T3B0aW9ucyIsInBhdGhzIiwidHRsIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7OztBQUtBLElBQUlBLE9BQU8sR0FBR0MsT0FBTyxDQUFDLFdBQUQsQ0FBckI7O0FBRUFDLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlQyxrQkFBZixHQUFvQztBQUNsQ0MsRUFBQUEsY0FBYyxFQUFFO0FBQ2RDLElBQUFBLEdBQUcsRUFBRSw4QkFEUztBQUVkQyxJQUFBQSxJQUFJLEVBQUUsa0RBRlE7QUFHZEMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUNTO0FBSEYsR0FEa0I7QUFNbENDLEVBQUFBLHdCQUF3QixFQUFFO0FBQ3hCSixJQUFBQSxHQUFHLEVBQUUsMENBRG1CO0FBRXhCQyxJQUFBQSxJQUFJLEVBQUUsNkRBRmtCO0FBR3hCQyxJQUFBQSxNQUFNLEVBQUVSLE9BQU8sQ0FBQ1csYUFIUTtBQUl4QkMsSUFBQUEsT0FBTyxFQUFFO0FBSmUsR0FOUTtBQVlsQ0MsRUFBQUEsbUJBQW1CLEVBQUU7QUFDbkJQLElBQUFBLEdBQUcsRUFBRSxxQ0FEYztBQUVuQkMsSUFBQUEsSUFBSSxFQUFFLHFDQUZhO0FBR25CQyxJQUFBQSxNQUFNLEVBQUVSLE9BQU8sQ0FBQ1csYUFIRztBQUluQkMsSUFBQUEsT0FBTyxFQUFFO0FBSlUsR0FaYTtBQWtCbENFLEVBQUFBLFlBQVksRUFBRTtBQUNaUixJQUFBQSxHQUFHLEVBQUUsNEJBRE87QUFFWkMsSUFBQUEsSUFBSSxFQUFFLDZDQUZNO0FBR1pDLElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDZTtBQUhKLEdBbEJvQjtBQXVCbENDLEVBQUFBLFdBQVcsRUFBRTtBQUNYVixJQUFBQSxHQUFHLEVBQUUsMkJBRE07QUFFWEMsSUFBQUEsSUFBSSxFQUFFO0FBRkssR0F2QnFCO0FBMkJsQ1UsRUFBQUEsZ0JBQWdCLEVBQUU7QUFDaEJYLElBQUFBLEdBQUcsRUFBRSxnQ0FEVztBQUVoQkMsSUFBQUEsSUFBSSxF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LElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDeUIsWUFBUixDQUFxQixrQkFBckI7QUFKUSxHQXJEb0I7QUEyRHRDaUYsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZwRyxJQUFBQSxHQUFHLEVBQUUscUNBREs7QUFFVkMsSUFBQUEsSUFBSSxFQUFFLHdDQUZJO0FBR1ZDLElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDa0I7QUFITjtBQTNEMEIsQ0FBeEM7QUFpRUFoQixNQUFNLENBQUNDLE9BQVAsQ0FBZTRHLGtCQUFmLEdBQW9DO0FBQ2xDQyxFQUFBQSxLQUFLLEVBQUU7QUFDTDFHLElBQUFBLEdBQUcsRUFBRSw2Q0FEQTtBQUVMQyxJQUFBQSxJQUFJLEVBQ0Ysa1hBSEc7QUFJTEMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUNlLFdBSlg7QUFLTEgsSUFBQUEsT0FBTyxFQUFFO0FBTEosR0FEMkI7QUFRbENxRyxFQUFBQSxHQUFHLEVBQUU7QUFDSDNHLElBQUFBLEdBQUcsRUFBRSwyQ0FERjtBQUVIQyxJQUFBQSxJQUFJLEVBQ0Ysd0dBSEM7QUFJSEMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUN5QixZQUFSLENBQXFCLEtBQXJCLENBSkw7QUFLSGIsSUFBQUEsT0FBTyxFQUFFO0FBTE47QUFSNkIsQ0FBcEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuKioqKiBHRU5FUkFURUQgQ09ERSAqKioqXG5UaGlzIGNvZGUgaGFzIGJlZW4gZ2VuZXJhdGVkIGJ5IHJlc291cmNlcy9idWlsZENvbmZpZ0RlZmluaXRpb25zLmpzXG5EbyBub3QgZWRpdCBtYW51YWxseSwgYnV0IHVwZGF0ZSBPcHRpb25zL2luZGV4LmpzXG4qL1xudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxubW9kdWxlLmV4cG9ydHMuUGFyc2VTZXJ2ZXJPcHRpb25zID0ge1xuICBhY2NvdW50TG9ja291dDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BQ0NPVU5UX0xPQ0tPVVQnLFxuICAgIGhlbHA6ICdhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DTElFTlRfQ0xBU1NfQ1JFQVRJT04nLFxuICAgIGhlbHA6ICdFbmFibGUgKG9yIGRpc2FibGUpIGNsaWVudCBjbGFzcyBjcmVhdGlvbiwgZGVmYXVsdHMgdG8gdHJ1ZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgYWxsb3dDdXN0b21PYmplY3RJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DVVNUT01fT0JKRUNUX0lEJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSBjdXN0b20gb2JqZWN0SWQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBhbGxvd0hlYWRlcnM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfSEVBREVSUycsXG4gICAgaGVscDogJ0FkZCBoZWFkZXJzIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgfSxcbiAgYWxsb3dPcmlnaW46IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfT1JJR0lOJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgb3JpZ2luIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsXG4gIH0sXG4gIGFuYWx5dGljc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQU5BTFlUSUNTX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBhcHBJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BUFBMSUNBVElPTl9JRCcsXG4gICAgaGVscDogJ1lvdXIgUGFyc2UgQXBwbGljYXRpb24gSUQnLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBhcHBOYW1lOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FQUF9OQU1FJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgYXBwIG5hbWUnLFxuICB9LFxuICBhdXRoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FVVEhfUFJPVklERVJTJyxcbiAgICBoZWxwOlxuICAgICAgJ0NvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBjYWNoZUFkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0FDSEVfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgY2FjaGVNYXhTaXplOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX01BWF9TSVpFJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignY2FjaGVNYXhTaXplJyksXG4gICAgZGVmYXVsdDogMTAwMDAsXG4gIH0sXG4gIGNhY2hlVFRMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX1RUTCcsXG4gICAgaGVscDogJ1NldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdjYWNoZVRUTCcpLFxuICAgIGRlZmF1bHQ6IDUwMDAsXG4gIH0sXG4gIGNsaWVudEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTElFTlRfS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMnLFxuICB9LFxuICBjbG91ZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTE9VRCcsXG4gICAgaGVscDogJ0Z1bGwgcGF0aCB0byB5b3VyIGNsb3VkIGNvZGUgbWFpbi5qcycsXG4gIH0sXG4gIGNsdXN0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0xVU1RFUicsXG4gICAgaGVscDogJ1J1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlck9yQm9vbGVhblBhcnNlcixcbiAgfSxcbiAgY29sbGVjdGlvblByZWZpeDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DT0xMRUNUSU9OX1BSRUZJWCcsXG4gICAgaGVscDogJ0EgY29sbGVjdGlvbiBwcmVmaXggZm9yIHRoZSBjbGFzc2VzJyxcbiAgICBkZWZhdWx0OiAnJyxcbiAgfSxcbiAgY3VzdG9tUGFnZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTJyxcbiAgICBoZWxwOiAnY3VzdG9tIHBhZ2VzIGZvciBwYXNzd29yZCB2YWxpZGF0aW9uIGFuZCByZXNldCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZGF0YWJhc2VBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0RBVEFCQVNFX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGRhdGFiYXNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIGRhdGFiYXNlT3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9EQVRBQkFTRV9PUFRJT05TJyxcbiAgICBoZWxwOiAnT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBtb25nb2RiIGNsaWVudCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgZGF0YWJhc2VVUkk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfREFUQUJBU0VfVVJJJyxcbiAgICBoZWxwOiAnVGhlIGZ1bGwgVVJJIHRvIHlvdXIgZGF0YWJhc2UuIFN1cHBvcnRlZCBkYXRhYmFzZXMgYXJlIG1vbmdvZGIgb3IgcG9zdGdyZXMuJyxcbiAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICBkZWZhdWx0OiAnbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZScsXG4gIH0sXG4gIGRpcmVjdEFjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MnLFxuICAgIGhlbHA6XG4gICAgICAnUmVwbGFjZSBIVFRQIEludGVyZmFjZSB3aGVuIHVzaW5nIEpTIFNESyBpbiBjdXJyZW50IG5vZGUgcnVudGltZSwgZGVmYXVsdHMgdG8gZmFsc2UuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGRvdE5ldEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9ET1RfTkVUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgVW5pdHkgYW5kIC5OZXQgU0RLJyxcbiAgfSxcbiAgZW1haWxBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VNQUlMX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTUFJTF9WRVJJRllfVE9LRU5fVkFMSURJVFlfRFVSQVRJT04nLFxuICAgIGhlbHA6ICdFbWFpbCB2ZXJpZmljYXRpb24gdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24sIGluIHNlY29uZHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ2VtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uJyksXG4gIH0sXG4gIGVuYWJsZUFub255bW91c1VzZXJzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQUJMRV9BTk9OX1VTRVJTJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSBhbm9ueW1vdXMgdXNlcnMsIGRlZmF1bHRzIHRvIHRydWUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG4gIGVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRU5BQkxFX0VYUFJFU1NfRVJST1JfSEFORExFUicsXG4gICAgaGVscDogJ0VuYWJsZXMgdGhlIGRlZmF1bHQgZXhwcmVzcyBlcnJvciBoYW5kbGVyIGZvciBhbGwgZXJyb3JzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRU5BQkxFX1NJTkdMRV9TQ0hFTUFfQ0FDSEUnLFxuICAgIGhlbHA6XG4gICAgICAnVXNlIGEgc2luZ2xlIHNjaGVtYSBjYWNoZSBzaGFyZWQgYWNyb3NzIHJlcXVlc3RzLiBSZWR1Y2VzIG51bWJlciBvZiBxdWVyaWVzIG1hZGUgdG8gX1NDSEVNQSwgZGVmYXVsdHMgdG8gZmFsc2UsIGkuZS4gdW5pcXVlIHNjaGVtYSBjYWNoZSBwZXIgcmVxdWVzdC4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBlbmNyeXB0aW9uS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQ1JZUFRJT05fS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciBlbmNyeXB0aW5nIHlvdXIgZmlsZXMnLFxuICB9LFxuICBleHBpcmVJbmFjdGl2ZVNlc3Npb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VYUElSRV9JTkFDVElWRV9TRVNTSU9OUycsXG4gICAgaGVscDogJ1NldHMgd2V0aGVyIHdlIHNob3VsZCBleHBpcmUgdGhlIGluYWN0aXZlIHNlc3Npb25zLCBkZWZhdWx0cyB0byB0cnVlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiB0cnVlLFxuICB9LFxuICBmaWxlS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVfS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciB5b3VyIGZpbGVzJyxcbiAgfSxcbiAgZmlsZXNBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVTX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGZpbGVzIHN1Yi1zeXN0ZW0nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgZ3JhcGhRTFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIJyxcbiAgICBoZWxwOiAnTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgZW5kcG9pbnQsIGRlZmF1bHRzIHRvIC9ncmFwaHFsJyxcbiAgICBkZWZhdWx0OiAnL2dyYXBocWwnLFxuICB9LFxuICBncmFwaFFMU2NoZW1hOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0dSQVBIX1FMU0NIRU1BJyxcbiAgICBoZWxwOiAnRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZScsXG4gIH0sXG4gIGhvc3Q6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfSE9TVCcsXG4gICAgaGVscDogJ1RoZSBob3N0IHRvIHNlcnZlIFBhcnNlU2VydmVyIG9uLCBkZWZhdWx0cyB0byAwLjAuMC4wJyxcbiAgICBkZWZhdWx0OiAnMC4wLjAuMCcsXG4gIH0sXG4gIGlkZW1wb3RlbmN5T3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfT1BUSU9OUycsXG4gICAgaGVscDpcbiAgICAgICdPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgamF2YXNjcmlwdEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9KQVZBU0NSSVBUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgdGhlIEphdmFzY3JpcHQgU0RLJyxcbiAgfSxcbiAganNvbkxvZ3M6IHtcbiAgICBlbnY6ICdKU09OX0xPR1MnLFxuICAgIGhlbHA6ICdMb2cgYXMgc3RydWN0dXJlZCBKU09OIG9iamVjdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRV9RVUVSWScsXG4gICAgaGVscDogXCJwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY29uZmlndXJhdGlvbiBvYmplY3RcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVfUVVFUllfU0VSVkVSX09QVElPTlMnLFxuICAgIGhlbHA6ICdMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsb2dnZXJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR0dFUl9BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTE9HX0xFVkVMJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbGV2ZWwgZm9yIGxvZ3MnLFxuICB9LFxuICBsb2dzRm9sZGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSJyxcbiAgICBoZWxwOiBcIkZvbGRlciBmb3IgdGhlIGxvZ3MgKGRlZmF1bHRzIHRvICcuL2xvZ3MnKTsgc2V0IHRvIG51bGwgdG8gZGlzYWJsZSBmaWxlIGJhc2VkIGxvZ2dpbmdcIixcbiAgICBkZWZhdWx0OiAnLi9sb2dzJyxcbiAgfSxcbiAgbWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BU1RFUl9LRVknLFxuICAgIGhlbHA6ICdZb3VyIFBhcnNlIE1hc3RlciBLZXknLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBtYXN0ZXJLZXlJcHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFTVEVSX0tFWV9JUFMnLFxuICAgIGhlbHA6ICdSZXN0cmljdCBtYXN0ZXJLZXkgdG8gYmUgdXNlZCBieSBvbmx5IHRoZXNlIGlwcywgZGVmYXVsdHMgdG8gW10gKGFsbG93IGFsbCBpcHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYXJyYXlQYXJzZXIsXG4gICAgZGVmYXVsdDogW10sXG4gIH0sXG4gIG1heExpbWl0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BWF9MSU1JVCcsXG4gICAgaGVscDogJ01heCB2YWx1ZSBmb3IgbGltaXQgb3B0aW9uIG9uIHF1ZXJpZXMsIGRlZmF1bHRzIHRvIHVubGltaXRlZCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignbWF4TGltaXQnKSxcbiAgfSxcbiAgbWF4TG9nRmlsZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFYX0xPR19GSUxFUycsXG4gICAgaGVscDpcbiAgICAgIFwiTWF4aW11bSBudW1iZXIgb2YgbG9ncyB0byBrZWVwLiBJZiBub3Qgc2V0LCBubyBsb2dzIHdpbGwgYmUgcmVtb3ZlZC4gVGhpcyBjYW4gYmUgYSBudW1iZXIgb2YgZmlsZXMgb3IgbnVtYmVyIG9mIGRheXMuIElmIHVzaW5nIGRheXMsIGFkZCAnZCcgYXMgdGhlIHN1ZmZpeC4gKGRlZmF1bHQ6IG51bGwpXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgbWF4VXBsb2FkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NQVhfVVBMT0FEX1NJWkUnLFxuICAgIGhlbHA6ICdNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iJyxcbiAgICBkZWZhdWx0OiAnMjBtYicsXG4gIH0sXG4gIG1pZGRsZXdhcmU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUlERExFV0FSRScsXG4gICAgaGVscDogJ21pZGRsZXdhcmUgZm9yIGV4cHJlc3Mgc2VydmVyLCBjYW4gYmUgc3RyaW5nIG9yIGZ1bmN0aW9uJyxcbiAgfSxcbiAgbW91bnRHcmFwaFFMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUwnLFxuICAgIGhlbHA6ICdNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBtb3VudFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTU9VTlRfUEFUSCcsXG4gICAgaGVscDogJ01vdW50IHBhdGggZm9yIHRoZSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIC9wYXJzZScsXG4gICAgZGVmYXVsdDogJy9wYXJzZScsXG4gIH0sXG4gIG1vdW50UGxheWdyb3VuZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NT1VOVF9QTEFZR1JPVU5EJyxcbiAgICBoZWxwOiAnTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvbicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIG9iamVjdElkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9PQkpFQ1RfSURfU0laRScsXG4gICAgaGVscDogXCJTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcIixcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdvYmplY3RJZFNpemUnKSxcbiAgICBkZWZhdWx0OiAxMCxcbiAgfSxcbiAgcGFzc3dvcmRQb2xpY3k6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFTU1dPUkRfUE9MSUNZJyxcbiAgICBoZWxwOiAnUGFzc3dvcmQgcG9saWN5IGZvciBlbmZvcmNpbmcgcGFzc3dvcmQgcmVsYXRlZCBydWxlcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgcGxheWdyb3VuZFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUExBWUdST1VORF9QQVRIJyxcbiAgICBoZWxwOiAnTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmQnLFxuICAgIGRlZmF1bHQ6ICcvcGxheWdyb3VuZCcsXG4gIH0sXG4gIHBvcnQ6IHtcbiAgICBlbnY6ICdQT1JUJyxcbiAgICBoZWxwOiAnVGhlIHBvcnQgdG8gcnVuIHRoZSBQYXJzZVNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3BvcnQnKSxcbiAgICBkZWZhdWx0OiAxMzM3LFxuICB9LFxuICBwcmVzZXJ2ZUZpbGVOYW1lOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BSRVNFUlZFX0ZJTEVfTkFNRScsXG4gICAgaGVscDogJ0VuYWJsZSAob3IgZGlzYWJsZSkgdGhlIGFkZGl0aW9uIG9mIGEgdW5pcXVlIGhhc2ggdG8gdGhlIGZpbGUgbmFtZXMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BSRVZFTlRfTE9HSU5fV0lUSF9VTlZFUklGSUVEX0VNQUlMJyxcbiAgICBoZWxwOlxuICAgICAgJ1ByZXZlbnQgdXNlciBmcm9tIGxvZ2luIGlmIGVtYWlsIGlzIG5vdCB2ZXJpZmllZCBhbmQgUEFSU0VfU0VSVkVSX1ZFUklGWV9VU0VSX0VNQUlMUyBpcyB0cnVlLCBkZWZhdWx0cyB0byBmYWxzZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIHByb3RlY3RlZEZpZWxkczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QUk9URUNURURfRklFTERTJyxcbiAgICBoZWxwOiAnUHJvdGVjdGVkIGZpZWxkcyB0aGF0IHNob3VsZCBiZSB0cmVhdGVkIHdpdGggZXh0cmEgc2VjdXJpdHkgd2hlbiBmZXRjaGluZyBkZXRhaWxzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7XG4gICAgICBfVXNlcjoge1xuICAgICAgICAnKic6IFsnZW1haWwnXSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAgcHVibGljU2VydmVyVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfUFVCTElDX1NFUlZFUl9VUkwnLFxuICAgIGhlbHA6ICdQdWJsaWMgVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy4nLFxuICB9LFxuICBwdXNoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BVU0gnLFxuICAgIGhlbHA6XG4gICAgICAnQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWFkT25seU1hc3RlcktleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9SRUFEX09OTFlfTUFTVEVSX0tFWScsXG4gICAgaGVscDogJ1JlYWQtb25seSBrZXksIHdoaWNoIGhhcyB0aGUgc2FtZSBjYXBhYmlsaXRpZXMgYXMgTWFzdGVyS2V5IHdpdGhvdXQgd3JpdGVzJyxcbiAgfSxcbiAgcmVzdEFQSUtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9SRVNUX0FQSV9LRVknLFxuICAgIGhlbHA6ICdLZXkgZm9yIFJFU1QgY2FsbHMnLFxuICB9LFxuICByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1JFVk9LRV9TRVNTSU9OX09OX1BBU1NXT1JEX1JFU0VUJyxcbiAgICBoZWxwOlxuICAgICAgXCJXaGVuIGEgdXNlciBjaGFuZ2VzIHRoZWlyIHBhc3N3b3JkLCBlaXRoZXIgdGhyb3VnaCB0aGUgcmVzZXQgcGFzc3dvcmQgZW1haWwgb3Igd2hpbGUgbG9nZ2VkIGluLCBhbGwgc2Vzc2lvbnMgYXJlIHJldm9rZWQgaWYgdGhpcyBpcyB0cnVlLiBTZXQgdG8gZmFsc2UgaWYgeW91IGRvbid0IHdhbnQgdG8gcmV2b2tlIHNlc3Npb25zLlwiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG4gIHNjaGVkdWxlZFB1c2g6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0NIRURVTEVEX1BVU0gnLFxuICAgIGhlbHA6ICdDb25maWd1cmF0aW9uIGZvciBwdXNoIHNjaGVkdWxpbmcsIGRlZmF1bHRzIHRvIGZhbHNlLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIHNjaGVtYUNhY2hlVFRMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NDSEVNQV9DQUNIRV9UVEwnLFxuICAgIGhlbHA6XG4gICAgICAnVGhlIFRUTCBmb3IgY2FjaGluZyB0aGUgc2NoZW1hIGZvciBvcHRpbWl6aW5nIHJlYWQvd3JpdGUgb3BlcmF0aW9ucy4gWW91IHNob3VsZCBwdXQgYSBsb25nIFRUTCB3aGVuIHlvdXIgREIgaXMgaW4gcHJvZHVjdGlvbi4gZGVmYXVsdCB0byA1MDAwOyBzZXQgMCB0byBkaXNhYmxlLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignc2NoZW1hQ2FjaGVUVEwnKSxcbiAgICBkZWZhdWx0OiA1MDAwLFxuICB9LFxuICBzZXJ2ZXJDbG9zZUNvbXBsZXRlOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NFUlZFUl9DTE9TRV9DT01QTEVURScsXG4gICAgaGVscDogJ0NhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBjbG9zZWQnLFxuICB9LFxuICBzZXJ2ZXJTdGFydENvbXBsZXRlOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NFUlZFUl9TVEFSVF9DT01QTEVURScsXG4gICAgaGVscDogJ0NhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBzdGFydGVkJyxcbiAgfSxcbiAgc2VydmVyVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1VSTCcsXG4gICAgaGVscDogJ1VSTCB0byB5b3VyIHBhcnNlIHNlcnZlciB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8uJyxcbiAgICByZXF1aXJlZDogdHJ1ZSxcbiAgfSxcbiAgc2Vzc2lvbkxlbmd0aDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9TRVNTSU9OX0xFTkdUSCcsXG4gICAgaGVscDogJ1Nlc3Npb24gZHVyYXRpb24sIGluIHNlY29uZHMsIGRlZmF1bHRzIHRvIDEgeWVhcicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignc2Vzc2lvbkxlbmd0aCcpLFxuICAgIGRlZmF1bHQ6IDMxNTM2MDAwLFxuICB9LFxuICBzaWxlbnQ6IHtcbiAgICBlbnY6ICdTSUxFTlQnLFxuICAgIGhlbHA6ICdEaXNhYmxlcyBjb25zb2xlIG91dHB1dCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gIH0sXG4gIHN0YXJ0TGl2ZVF1ZXJ5U2VydmVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NUQVJUX0xJVkVfUVVFUllfU0VSVkVSJyxcbiAgICBoZWxwOiAnU3RhcnRzIHRoZSBsaXZlUXVlcnkgc2VydmVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgdXNlclNlbnNpdGl2ZUZpZWxkczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9VU0VSX1NFTlNJVElWRV9GSUVMRFMnLFxuICAgIGhlbHA6XG4gICAgICAnUGVyc29uYWxseSBpZGVudGlmaWFibGUgaW5mb3JtYXRpb24gZmllbGRzIGluIHRoZSB1c2VyIHRhYmxlIHRoZSBzaG91bGQgYmUgcmVtb3ZlZCBmb3Igbm9uLWF1dGhvcml6ZWQgdXNlcnMuIERlcHJlY2F0ZWQgQHNlZSBwcm90ZWN0ZWRGaWVsZHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgfSxcbiAgdmVyYm9zZToge1xuICAgIGVudjogJ1ZFUkJPU0UnLFxuICAgIGhlbHA6ICdTZXQgdGhlIGxvZ2dpbmcgdG8gdmVyYm9zZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gIH0sXG4gIHZlcmlmeVVzZXJFbWFpbHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSB1c2VyIGVtYWlsIHZhbGlkYXRpb24sIGRlZmF1bHRzIHRvIGZhbHNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgd2ViaG9va0tleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9XRUJIT09LX0tFWScsXG4gICAgaGVscDogJ0tleSBzZW50IHdpdGggb3V0Z29pbmcgd2ViaG9vayBjYWxscycsXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuQ3VzdG9tUGFnZXNPcHRpb25zID0ge1xuICBjaG9vc2VQYXNzd29yZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfQ0hPT1NFX1BBU1NXT1JEJyxcbiAgICBoZWxwOiAnY2hvb3NlIHBhc3N3b3JkIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIGludmFsaWRMaW5rOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19JTlZBTElEX0xJTksnLFxuICAgIGhlbHA6ICdpbnZhbGlkIGxpbmsgcGFnZSBwYXRoJyxcbiAgfSxcbiAgaW52YWxpZFZlcmlmaWNhdGlvbkxpbms6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0lOVkFMSURfVkVSSUZJQ0FUSU9OX0xJTksnLFxuICAgIGhlbHA6ICdpbnZhbGlkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIGxpbmtTZW5kRmFpbDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfTElOS19TRU5EX0ZBSUwnLFxuICAgIGhlbHA6ICd2ZXJpZmljYXRpb24gbGluayBzZW5kIGZhaWwgcGFnZSBwYXRoJyxcbiAgfSxcbiAgbGlua1NlbmRTdWNjZXNzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19MSU5LX1NFTkRfU1VDQ0VTUycsXG4gICAgaGVscDogJ3ZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgc3VjY2VzcyBwYWdlIHBhdGgnLFxuICB9LFxuICBwYXJzZUZyYW1lVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19QQVJTRV9GUkFNRV9VUkwnLFxuICAgIGhlbHA6ICdmb3IgbWFza2luZyB1c2VyLWZhY2luZyBwYWdlcycsXG4gIH0sXG4gIHBhc3N3b3JkUmVzZXRTdWNjZXNzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19QQVNTV09SRF9SRVNFVF9TVUNDRVNTJyxcbiAgICBoZWxwOiAncGFzc3dvcmQgcmVzZXQgc3VjY2VzcyBwYWdlIHBhdGgnLFxuICB9LFxuICB2ZXJpZnlFbWFpbFN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX1ZFUklGWV9FTUFJTF9TVUNDRVNTJyxcbiAgICBoZWxwOiAndmVyaWZ5IGVtYWlsIHN1Y2Nlc3MgcGFnZSBwYXRoJyxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5MaXZlUXVlcnlPcHRpb25zID0ge1xuICBjbGFzc05hbWVzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9DTEFTU05BTUVTJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjbGFzc05hbWVzXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmFycmF5UGFyc2VyLFxuICB9LFxuICBwdWJTdWJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9QVUJfU1VCX0FEQVBURVInLFxuICAgIGhlbHA6ICdMaXZlUXVlcnkgcHVic3ViIGFkYXB0ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgcmVkaXNPcHRpb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9SRURJU19PUFRJT05TJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc1VSTDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9MSVZFUVVFUllfUkVESVNfVVJMJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc1VSTFwiLFxuICB9LFxuICB3c3NBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9XU1NfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyA9IHtcbiAgYXBwSWQ6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9BUFBfSUQnLFxuICAgIGhlbHA6XG4gICAgICAnVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBhcHBJZCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIGFwcElkLicsXG4gIH0sXG4gIGNhY2hlVGltZW91dDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0NBQ0hFX1RJTUVPVVQnLFxuICAgIGhlbHA6XG4gICAgICBcIk51bWJlciBpbiBtaWxsaXNlY29uZHMuIFdoZW4gY2xpZW50cyBwcm92aWRlIHRoZSBzZXNzaW9uVG9rZW4gdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIGZldGNoIGl0cyBQYXJzZVVzZXIncyBvYmplY3RJZCBmcm9tIHBhcnNlIHNlcnZlciBhbmQgc3RvcmUgaXQgaW4gdGhlIGNhY2hlLiBUaGUgdmFsdWUgZGVmaW5lcyB0aGUgZHVyYXRpb24gb2YgdGhlIGNhY2hlLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLCBkZWZhdWx0cyB0byA1ICogMTAwMCBtcyAoNSBzZWNvbmRzKS5cIixcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdjYWNoZVRpbWVvdXQnKSxcbiAgfSxcbiAga2V5UGFpcnM6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9LRVlfUEFJUlMnLFxuICAgIGhlbHA6XG4gICAgICAnQSBKU09OIG9iamVjdCB0aGF0IHNlcnZlcyBhcyBhIHdoaXRlbGlzdCBvZiBrZXlzLiBJdCBpcyB1c2VkIGZvciB2YWxpZGF0aW5nIGNsaWVudHMgd2hlbiB0aGV5IHRyeSB0byBjb25uZWN0IHRvIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9MT0dfTEVWRUwnLFxuICAgIGhlbHA6XG4gICAgICAnVGhpcyBzdHJpbmcgZGVmaW5lcyB0aGUgbG9nIGxldmVsIG9mIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBXZSBzdXBwb3J0IFZFUkJPU0UsIElORk8sIEVSUk9SLCBOT05FLCBkZWZhdWx0cyB0byBJTkZPLicsXG4gIH0sXG4gIG1hc3RlcktleToge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX01BU1RFUl9LRVknLFxuICAgIGhlbHA6XG4gICAgICAnVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBtYXN0ZXJLZXkgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBtYXN0ZXJLZXkuJyxcbiAgfSxcbiAgcG9ydDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1BPUlQnLFxuICAgIGhlbHA6ICdUaGUgcG9ydCB0byBydW4gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdwb3J0JyksXG4gICAgZGVmYXVsdDogMTMzNyxcbiAgfSxcbiAgcHViU3ViQWRhcHRlcjoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1BVQl9TVUJfQURBUFRFUicsXG4gICAgaGVscDogJ0xpdmVRdWVyeSBwdWJzdWIgYWRhcHRlcicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc09wdGlvbnM6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9SRURJU19PUFRJT05TJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc1VSTDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1JFRElTX1VSTCcsXG4gICAgaGVscDogXCJwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkxcIixcbiAgfSxcbiAgc2VydmVyVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfU0VSVkVSX1VSTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIHNlcnZlclVSTCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIHNlcnZlclVSTC4nLFxuICB9LFxuICB3ZWJzb2NrZXRUaW1lb3V0OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfV0VCU09DS0VUX1RJTUVPVVQnLFxuICAgIGhlbHA6XG4gICAgICAnTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHBpbmcvcG9uZyBmcmFtZXMuIFRoZSBXZWJTb2NrZXQgc2VydmVyIHNlbmRzIHBpbmcvcG9uZyBmcmFtZXMgdG8gdGhlIGNsaWVudHMgdG8ga2VlcCB0aGUgV2ViU29ja2V0IGFsaXZlLiBUaGlzIHZhbHVlIGRlZmluZXMgdGhlIGludGVydmFsIG9mIHRoZSBwaW5nL3BvbmcgZnJhbWUgZnJvbSB0aGUgc2VydmVyIHRvIGNsaWVudHMsIGRlZmF1bHRzIHRvIDEwICogMTAwMCBtcyAoMTAgcykuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCd3ZWJzb2NrZXRUaW1lb3V0JyksXG4gIH0sXG4gIHdzc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9XU1NfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuSWRlbXBvdGVuY3lPcHRpb25zID0ge1xuICBwYXRoczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfUEFUSFMnLFxuICAgIGhlbHA6XG4gICAgICAnQW4gYXJyYXkgb2YgcGF0aHMgZm9yIHdoaWNoIHRoZSBmZWF0dXJlIHNob3VsZCBiZSBlbmFibGVkLiBUaGUgbW91bnQgcGF0aCBtdXN0IG5vdCBiZSBpbmNsdWRlZCwgZm9yIGV4YW1wbGUgaW5zdGVhZCBvZiBgL3BhcnNlL2Z1bmN0aW9ucy9teUZ1bmN0aW9uYCBzcGVjaWZpeSBgZnVuY3Rpb25zL215RnVuY3Rpb25gLiBUaGUgZW50cmllcyBhcmUgaW50ZXJwcmV0ZWQgYXMgcmVndWxhciBleHByZXNzaW9uLCBmb3IgZXhhbXBsZSBgZnVuY3Rpb25zLy4qYCBtYXRjaGVzIGFsbCBmdW5jdGlvbnMsIGBqb2JzLy4qYCBtYXRjaGVzIGFsbCBqb2JzLCBgY2xhc3Nlcy8uKmAgbWF0Y2hlcyBhbGwgY2xhc3NlcywgYC4qYCBtYXRjaGVzIGFsbCBwYXRocy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgICBkZWZhdWx0OiBbXSxcbiAgfSxcbiAgdHRsOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VYUEVSSU1FTlRBTF9JREVNUE9URU5DWV9UVEwnLFxuICAgIGhlbHA6XG4gICAgICAnVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgYWZ0ZXIgd2hpY2ggYSByZXF1ZXN0IHJlY29yZCBpcyBkaXNjYXJkZWQgZnJvbSB0aGUgZGF0YWJhc2UsIGRlZmF1bHRzIHRvIDMwMHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCd0dGwnKSxcbiAgICBkZWZhdWx0OiAzMDAsXG4gIH0sXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Options/docs.js b/lib/Options/docs.js new file mode 100644 index 0000000000..2e40b21790 --- /dev/null +++ b/lib/Options/docs.js @@ -0,0 +1,122 @@ +/** + * @interface ParseServerOptions + * @property {Any} accountLockout account lockout policy for failed login attempts + * @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true + * @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId + * @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers + * @property {String} allowOrigin Sets the origin to Access-Control-Allow-Origin + * @property {Adapter} analyticsAdapter Adapter module for the analytics + * @property {String} appId Your Parse Application ID + * @property {String} appName Sets the app name + * @property {Any} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication + * @property {Adapter} cacheAdapter Adapter module for the cache + * @property {Number} cacheMaxSize Sets the maximum size for the in memory cache, defaults to 10000 + * @property {Number} cacheTTL Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds) + * @property {String} clientKey Key for iOS, MacOS, tvOS clients + * @property {String} cloud Full path to your cloud code main.js + * @property {Number|Boolean} cluster Run with cluster, optionally set the number of processes default to os.cpus().length + * @property {String} collectionPrefix A collection prefix for the classes + * @property {CustomPagesOptions} customPages custom pages for password validation and reset + * @property {Adapter} databaseAdapter Adapter module for the database + * @property {Any} databaseOptions Options to pass to the mongodb client + * @property {String} databaseURI The full URI to your database. Supported databases are mongodb or postgres. + * @property {Boolean} directAccess Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production. + * @property {String} dotNetKey Key for Unity and .Net SDK + * @property {Adapter} emailAdapter Adapter module for email sending + * @property {Number} emailVerifyTokenValidityDuration Email verification token validity duration, in seconds + * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true + * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors + * @property {Boolean} enableSingleSchemaCache Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request. + * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true + * @property {String} fileKey Key for your files + * @property {Adapter} filesAdapter Adapter module for the files sub-system + * @property {String} graphQLPath Mount path for the GraphQL endpoint, defaults to /graphql + * @property {String} graphQLSchema Full path to your GraphQL custom schema.graphql file + * @property {String} host The host to serve ParseServer on, defaults to 0.0.0.0 + * @property {IdempotencyOptions} idempotencyOptions Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production. + * @property {String} javascriptKey Key for the Javascript SDK + * @property {Boolean} jsonLogs Log as structured JSON objects + * @property {LiveQueryOptions} liveQuery parse-server's LiveQuery configuration object + * @property {LiveQueryServerOptions} liveQueryServerOptions Live query server configuration options (will start the liveQuery server) + * @property {Adapter} loggerAdapter Adapter module for the logging sub-system + * @property {String} logLevel Sets the level for logs + * @property {String} logsFolder Folder for the logs (defaults to './logs'); set to null to disable file based logging + * @property {String} masterKey Your Parse Master Key + * @property {String[]} masterKeyIps Restrict masterKey to be used by only these ips, defaults to [] (allow all ips) + * @property {Number} maxLimit Max value for limit option on queries, defaults to unlimited + * @property {Number|String} maxLogFiles Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null) + * @property {String} maxUploadSize Max file size for uploads, defaults to 20mb + * @property {Union} middleware middleware for express server, can be string or function + * @property {Boolean} mountGraphQL Mounts the GraphQL endpoint + * @property {String} mountPath Mount path for the server, defaults to /parse + * @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production + * @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10 + * @property {Any} passwordPolicy Password policy for enforcing password related rules + * @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground + * @property {Number} port The port to run the ParseServer, defaults to 1337. + * @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names + * @property {Boolean} preventLoginWithUnverifiedEmail Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false + * @property {ProtectedFields} protectedFields Protected fields that should be treated with extra security when fetching details. + * @property {String} publicServerURL Public URL to your parse server with http:// or https://. + * @property {Any} push Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications + * @property {String} readOnlyMasterKey Read-only key, which has the same capabilities as MasterKey without writes + * @property {String} restAPIKey Key for REST calls + * @property {Boolean} revokeSessionOnPasswordReset When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions. + * @property {Boolean} scheduledPush Configuration for push scheduling, defaults to false. + * @property {Number} schemaCacheTTL The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable. + * @property {Function} serverCloseComplete Callback when server has closed + * @property {Function} serverStartComplete Callback when server has started + * @property {String} serverURL URL to your parse server with http:// or https://. + * @property {Number} sessionLength Session duration, in seconds, defaults to 1 year + * @property {Boolean} silent Disables console output + * @property {Boolean} startLiveQueryServer Starts the liveQuery server + * @property {String[]} userSensitiveFields Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields + * @property {Boolean} verbose Set the logging to verbose + * @property {Boolean} verifyUserEmails Enable (or disable) user email validation, defaults to false + * @property {String} webhookKey Key sent with outgoing webhook calls + */ + +/** + * @interface CustomPagesOptions + * @property {String} choosePassword choose password page path + * @property {String} invalidLink invalid link page path + * @property {String} invalidVerificationLink invalid verification link page path + * @property {String} linkSendFail verification link send fail page path + * @property {String} linkSendSuccess verification link send success page path + * @property {String} parseFrameURL for masking user-facing pages + * @property {String} passwordResetSuccess password reset success page path + * @property {String} verifyEmailSuccess verify email success page path + */ + +/** + * @interface LiveQueryOptions + * @property {String[]} classNames parse-server's LiveQuery classNames + * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter + * @property {Any} redisOptions parse-server's LiveQuery redisOptions + * @property {String} redisURL parse-server's LiveQuery redisURL + * @property {Adapter} wssAdapter Adapter module for the WebSocketServer + */ + +/** + * @interface LiveQueryServerOptions + * @property {String} appId This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId. + * @property {Number} cacheTimeout Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds). + * @property {Any} keyPairs A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details. + * @property {String} logLevel This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO. + * @property {String} masterKey This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey. + * @property {Number} port The port to run the LiveQuery server, defaults to 1337. + * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter + * @property {Any} redisOptions parse-server's LiveQuery redisOptions + * @property {String} redisURL parse-server's LiveQuery redisURL + * @property {String} serverURL This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL. + * @property {Number} websocketTimeout Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s). + * @property {Adapter} wssAdapter Adapter module for the WebSocketServer + */ + +/** + * @interface IdempotencyOptions + * @property {String[]} paths An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths. + * @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s. + */ +"use strict"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2RvY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQThFQTs7Ozs7Ozs7Ozs7O0FBWUE7Ozs7Ozs7OztBQVNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlU2VydmVyT3B0aW9uc1xuICogQHByb3BlcnR5IHtBbnl9IGFjY291bnRMb2Nrb3V0IGFjY291bnQgbG9ja291dCBwb2xpY3kgZm9yIGZhaWxlZCBsb2dpbiBhdHRlbXB0c1xuICogQHByb3BlcnR5IHtCb29sZWFufSBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gRW5hYmxlIChvciBkaXNhYmxlKSBjbGllbnQgY2xhc3MgY3JlYXRpb24sIGRlZmF1bHRzIHRvIHRydWVcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gYWxsb3dDdXN0b21PYmplY3RJZCBFbmFibGUgKG9yIGRpc2FibGUpIGN1c3RvbSBvYmplY3RJZFxuICogQHByb3BlcnR5IHtTdHJpbmdbXX0gYWxsb3dIZWFkZXJzIEFkZCBoZWFkZXJzIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBhbGxvd09yaWdpbiBTZXRzIHRoZSBvcmlnaW4gdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8QW5hbHl0aWNzQWRhcHRlcj59IGFuYWx5dGljc0FkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBhbmFseXRpY3NcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBhcHBJZCBZb3VyIFBhcnNlIEFwcGxpY2F0aW9uIElEXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYXBwTmFtZSBTZXRzIHRoZSBhcHAgbmFtZVxuICogQHByb3BlcnR5IHtBbnl9IGF1dGggQ29uZmlndXJhdGlvbiBmb3IgeW91ciBhdXRoZW50aWNhdGlvbiBwcm92aWRlcnMsIGFzIHN0cmluZ2lmaWVkIEpTT04uIFNlZSBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvI29hdXRoLWFuZC0zcmQtcGFydHktYXV0aGVudGljYXRpb25cbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxDYWNoZUFkYXB0ZXI+fSBjYWNoZUFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBjYWNoZVxuICogQHByb3BlcnR5IHtOdW1iZXJ9IGNhY2hlTWF4U2l6ZSBTZXRzIHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBpbiBtZW1vcnkgY2FjaGUsIGRlZmF1bHRzIHRvIDEwMDAwXG4gKiBAcHJvcGVydHkge051bWJlcn0gY2FjaGVUVEwgU2V0cyB0aGUgVFRMIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlIChpbiBtcyksIGRlZmF1bHRzIHRvIDUwMDAgKDUgc2Vjb25kcylcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBjbGllbnRLZXkgS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBjbG91ZCBGdWxsIHBhdGggdG8geW91ciBjbG91ZCBjb2RlIG1haW4uanNcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfEJvb2xlYW59IGNsdXN0ZXIgUnVuIHdpdGggY2x1c3Rlciwgb3B0aW9uYWxseSBzZXQgdGhlIG51bWJlciBvZiBwcm9jZXNzZXMgZGVmYXVsdCB0byBvcy5jcHVzKCkubGVuZ3RoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gY29sbGVjdGlvblByZWZpeCBBIGNvbGxlY3Rpb24gcHJlZml4IGZvciB0aGUgY2xhc3Nlc1xuICogQHByb3BlcnR5IHtDdXN0b21QYWdlc09wdGlvbnN9IGN1c3RvbVBhZ2VzIGN1c3RvbSBwYWdlcyBmb3IgcGFzc3dvcmQgdmFsaWRhdGlvbiBhbmQgcmVzZXRcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxTdG9yYWdlQWRhcHRlcj59IGRhdGFiYXNlQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGRhdGFiYXNlXG4gKiBAcHJvcGVydHkge0FueX0gZGF0YWJhc2VPcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgbW9uZ29kYiBjbGllbnRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBkYXRhYmFzZVVSSSBUaGUgZnVsbCBVUkkgdG8geW91ciBkYXRhYmFzZS4gU3VwcG9ydGVkIGRhdGFiYXNlcyBhcmUgbW9uZ29kYiBvciBwb3N0Z3Jlcy5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZGlyZWN0QWNjZXNzIFJlcGxhY2UgSFRUUCBJbnRlcmZhY2Ugd2hlbiB1c2luZyBKUyBTREsgaW4gY3VycmVudCBub2RlIHJ1bnRpbWUsIGRlZmF1bHRzIHRvIGZhbHNlLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBkb3ROZXRLZXkgS2V5IGZvciBVbml0eSBhbmQgLk5ldCBTREtcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxNYWlsQWRhcHRlcj59IGVtYWlsQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZ1xuICogQHByb3BlcnR5IHtOdW1iZXJ9IGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIEVtYWlsIHZlcmlmaWNhdGlvbiB0b2tlbiB2YWxpZGl0eSBkdXJhdGlvbiwgaW4gc2Vjb25kc1xuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVBbm9ueW1vdXNVc2VycyBFbmFibGUgKG9yIGRpc2FibGUpIGFub255bW91cyB1c2VycywgZGVmYXVsdHMgdG8gdHJ1ZVxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyIEVuYWJsZXMgdGhlIGRlZmF1bHQgZXhwcmVzcyBlcnJvciBoYW5kbGVyIGZvciBhbGwgZXJyb3JzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIFVzZSBhIHNpbmdsZSBzY2hlbWEgY2FjaGUgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cy4gUmVkdWNlcyBudW1iZXIgb2YgcXVlcmllcyBtYWRlIHRvIF9TQ0hFTUEsIGRlZmF1bHRzIHRvIGZhbHNlLCBpLmUuIHVuaXF1ZSBzY2hlbWEgY2FjaGUgcGVyIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMgU2V0cyB3ZXRoZXIgd2Ugc2hvdWxkIGV4cGlyZSB0aGUgaW5hY3RpdmUgc2Vzc2lvbnMsIGRlZmF1bHRzIHRvIHRydWVcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWxlS2V5IEtleSBmb3IgeW91ciBmaWxlc1xuICogQHByb3BlcnR5IHtBZGFwdGVyPEZpbGVzQWRhcHRlcj59IGZpbGVzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGZpbGVzIHN1Yi1zeXN0ZW1cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBncmFwaFFMUGF0aCBNb3VudCBwYXRoIGZvciB0aGUgR3JhcGhRTCBlbmRwb2ludCwgZGVmYXVsdHMgdG8gL2dyYXBocWxcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBncmFwaFFMU2NoZW1hIEZ1bGwgcGF0aCB0byB5b3VyIEdyYXBoUUwgY3VzdG9tIHNjaGVtYS5ncmFwaHFsIGZpbGVcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBob3N0IFRoZSBob3N0IHRvIHNlcnZlIFBhcnNlU2VydmVyIG9uLCBkZWZhdWx0cyB0byAwLjAuMC4wXG4gKiBAcHJvcGVydHkge0lkZW1wb3RlbmN5T3B0aW9uc30gaWRlbXBvdGVuY3lPcHRpb25zIE9wdGlvbnMgZm9yIHJlcXVlc3QgaWRlbXBvdGVuY3kgdG8gZGVkdXBsaWNhdGUgaWRlbnRpY2FsIHJlcXVlc3RzIHRoYXQgbWF5IGJlIGNhdXNlZCBieSBuZXR3b3JrIGlzc3Vlcy4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gKiBAcHJvcGVydHkge1N0cmluZ30gamF2YXNjcmlwdEtleSBLZXkgZm9yIHRoZSBKYXZhc2NyaXB0IFNES1xuICogQHByb3BlcnR5IHtCb29sZWFufSBqc29uTG9ncyBMb2cgYXMgc3RydWN0dXJlZCBKU09OIG9iamVjdHNcbiAqIEBwcm9wZXJ0eSB7TGl2ZVF1ZXJ5T3B0aW9uc30gbGl2ZVF1ZXJ5IHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjb25maWd1cmF0aW9uIG9iamVjdFxuICogQHByb3BlcnR5IHtMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zfSBsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIExpdmUgcXVlcnkgc2VydmVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyAod2lsbCBzdGFydCB0aGUgbGl2ZVF1ZXJ5IHNlcnZlcilcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxMb2dnZXJBZGFwdGVyPn0gbG9nZ2VyQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGxvZ2dpbmcgc3ViLXN5c3RlbVxuICogQHByb3BlcnR5IHtTdHJpbmd9IGxvZ0xldmVsIFNldHMgdGhlIGxldmVsIGZvciBsb2dzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbG9nc0ZvbGRlciBGb2xkZXIgZm9yIHRoZSBsb2dzIChkZWZhdWx0cyB0byAnLi9sb2dzJyk7IHNldCB0byBudWxsIHRvIGRpc2FibGUgZmlsZSBiYXNlZCBsb2dnaW5nXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWFzdGVyS2V5IFlvdXIgUGFyc2UgTWFzdGVyIEtleVxuICogQHByb3BlcnR5IHtTdHJpbmdbXX0gbWFzdGVyS2V5SXBzIFJlc3RyaWN0IG1hc3RlcktleSB0byBiZSB1c2VkIGJ5IG9ubHkgdGhlc2UgaXBzLCBkZWZhdWx0cyB0byBbXSAoYWxsb3cgYWxsIGlwcylcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBtYXhMaW1pdCBNYXggdmFsdWUgZm9yIGxpbWl0IG9wdGlvbiBvbiBxdWVyaWVzLCBkZWZhdWx0cyB0byB1bmxpbWl0ZWRcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfFN0cmluZ30gbWF4TG9nRmlsZXMgTWF4aW11bSBudW1iZXIgb2YgbG9ncyB0byBrZWVwLiBJZiBub3Qgc2V0LCBubyBsb2dzIHdpbGwgYmUgcmVtb3ZlZC4gVGhpcyBjYW4gYmUgYSBudW1iZXIgb2YgZmlsZXMgb3IgbnVtYmVyIG9mIGRheXMuIElmIHVzaW5nIGRheXMsIGFkZCAnZCcgYXMgdGhlIHN1ZmZpeC4gKGRlZmF1bHQ6IG51bGwpXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWF4VXBsb2FkU2l6ZSBNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iXG4gKiBAcHJvcGVydHkge1VuaW9ufSBtaWRkbGV3YXJlIG1pZGRsZXdhcmUgZm9yIGV4cHJlc3Mgc2VydmVyLCBjYW4gYmUgc3RyaW5nIG9yIGZ1bmN0aW9uXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1vdW50R3JhcGhRTCBNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBtb3VudFBhdGggTW91bnQgcGF0aCBmb3IgdGhlIHNlcnZlciwgZGVmYXVsdHMgdG8gL3BhcnNlXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1vdW50UGxheWdyb3VuZCBNb3VudHMgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCAtIG5ldmVyIHVzZSB0aGlzIG9wdGlvbiBpbiBwcm9kdWN0aW9uXG4gKiBAcHJvcGVydHkge051bWJlcn0gb2JqZWN0SWRTaXplIFNldHMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIGdlbmVyYXRlZCBvYmplY3QgaWQncywgZGVmYXVsdCAxMFxuICogQHByb3BlcnR5IHtBbnl9IHBhc3N3b3JkUG9saWN5IFBhc3N3b3JkIHBvbGljeSBmb3IgZW5mb3JjaW5nIHBhc3N3b3JkIHJlbGF0ZWQgcnVsZXNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwbGF5Z3JvdW5kUGF0aCBNb3VudCBwYXRoIGZvciB0aGUgR3JhcGhRTCBQbGF5Z3JvdW5kLCBkZWZhdWx0cyB0byAvcGxheWdyb3VuZFxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHBvcnQgVGhlIHBvcnQgdG8gcnVuIHRoZSBQYXJzZVNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gcHJlc2VydmVGaWxlTmFtZSBFbmFibGUgKG9yIGRpc2FibGUpIHRoZSBhZGRpdGlvbiBvZiBhIHVuaXF1ZSBoYXNoIHRvIHRoZSBmaWxlIG5hbWVzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwgUHJldmVudCB1c2VyIGZyb20gbG9naW4gaWYgZW1haWwgaXMgbm90IHZlcmlmaWVkIGFuZCBQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTIGlzIHRydWUsIGRlZmF1bHRzIHRvIGZhbHNlXG4gKiBAcHJvcGVydHkge1Byb3RlY3RlZEZpZWxkc30gcHJvdGVjdGVkRmllbGRzIFByb3RlY3RlZCBmaWVsZHMgdGhhdCBzaG91bGQgYmUgdHJlYXRlZCB3aXRoIGV4dHJhIHNlY3VyaXR5IHdoZW4gZmV0Y2hpbmcgZGV0YWlscy5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwdWJsaWNTZXJ2ZXJVUkwgUHVibGljIFVSTCB0byB5b3VyIHBhcnNlIHNlcnZlciB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8uXG4gKiBAcHJvcGVydHkge0FueX0gcHVzaCBDb25maWd1cmF0aW9uIGZvciBwdXNoLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNwdXNoLW5vdGlmaWNhdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWFkT25seU1hc3RlcktleSBSZWFkLW9ubHkga2V5LCB3aGljaCBoYXMgdGhlIHNhbWUgY2FwYWJpbGl0aWVzIGFzIE1hc3RlcktleSB3aXRob3V0IHdyaXRlc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlc3RBUElLZXkgS2V5IGZvciBSRVNUIGNhbGxzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQgV2hlbiBhIHVzZXIgY2hhbmdlcyB0aGVpciBwYXNzd29yZCwgZWl0aGVyIHRocm91Z2ggdGhlIHJlc2V0IHBhc3N3b3JkIGVtYWlsIG9yIHdoaWxlIGxvZ2dlZCBpbiwgYWxsIHNlc3Npb25zIGFyZSByZXZva2VkIGlmIHRoaXMgaXMgdHJ1ZS4gU2V0IHRvIGZhbHNlIGlmIHlvdSBkb24ndCB3YW50IHRvIHJldm9rZSBzZXNzaW9ucy5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2NoZWR1bGVkUHVzaCBDb25maWd1cmF0aW9uIGZvciBwdXNoIHNjaGVkdWxpbmcsIGRlZmF1bHRzIHRvIGZhbHNlLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHNjaGVtYUNhY2hlVFRMIFRoZSBUVEwgZm9yIGNhY2hpbmcgdGhlIHNjaGVtYSBmb3Igb3B0aW1pemluZyByZWFkL3dyaXRlIG9wZXJhdGlvbnMuIFlvdSBzaG91bGQgcHV0IGEgbG9uZyBUVEwgd2hlbiB5b3VyIERCIGlzIGluIHByb2R1Y3Rpb24uIGRlZmF1bHQgdG8gNTAwMDsgc2V0IDAgdG8gZGlzYWJsZS5cbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IHNlcnZlckNsb3NlQ29tcGxldGUgQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZFxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gc2VydmVyU3RhcnRDb21wbGV0ZSBDYWxsYmFjayB3aGVuIHNlcnZlciBoYXMgc3RhcnRlZFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHNlcnZlclVSTCBVUkwgdG8geW91ciBwYXJzZSBzZXJ2ZXIgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHNlc3Npb25MZW5ndGggU2Vzc2lvbiBkdXJhdGlvbiwgaW4gc2Vjb25kcywgZGVmYXVsdHMgdG8gMSB5ZWFyXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNpbGVudCBEaXNhYmxlcyBjb25zb2xlIG91dHB1dFxuICogQHByb3BlcnR5IHtCb29sZWFufSBzdGFydExpdmVRdWVyeVNlcnZlciBTdGFydHMgdGhlIGxpdmVRdWVyeSBzZXJ2ZXJcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IHVzZXJTZW5zaXRpdmVGaWVsZHMgUGVyc29uYWxseSBpZGVudGlmaWFibGUgaW5mb3JtYXRpb24gZmllbGRzIGluIHRoZSB1c2VyIHRhYmxlIHRoZSBzaG91bGQgYmUgcmVtb3ZlZCBmb3Igbm9uLWF1dGhvcml6ZWQgdXNlcnMuIERlcHJlY2F0ZWQgQHNlZSBwcm90ZWN0ZWRGaWVsZHNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdmVyYm9zZSBTZXQgdGhlIGxvZ2dpbmcgdG8gdmVyYm9zZVxuICogQHByb3BlcnR5IHtCb29sZWFufSB2ZXJpZnlVc2VyRW1haWxzIEVuYWJsZSAob3IgZGlzYWJsZSkgdXNlciBlbWFpbCB2YWxpZGF0aW9uLCBkZWZhdWx0cyB0byBmYWxzZVxuICogQHByb3BlcnR5IHtTdHJpbmd9IHdlYmhvb2tLZXkgS2V5IHNlbnQgd2l0aCBvdXRnb2luZyB3ZWJob29rIGNhbGxzXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIEN1c3RvbVBhZ2VzT3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGNob29zZVBhc3N3b3JkIGNob29zZSBwYXNzd29yZCBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnZhbGlkTGluayBpbnZhbGlkIGxpbmsgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsgaW52YWxpZCB2ZXJpZmljYXRpb24gbGluayBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsaW5rU2VuZEZhaWwgdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBmYWlsIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGxpbmtTZW5kU3VjY2VzcyB2ZXJpZmljYXRpb24gbGluayBzZW5kIHN1Y2Nlc3MgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFyc2VGcmFtZVVSTCBmb3IgbWFza2luZyB1c2VyLWZhY2luZyBwYWdlc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IHBhc3N3b3JkUmVzZXRTdWNjZXNzIHBhc3N3b3JkIHJlc2V0IHN1Y2Nlc3MgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdmVyaWZ5RW1haWxTdWNjZXNzIHZlcmlmeSBlbWFpbCBzdWNjZXNzIHBhZ2UgcGF0aFxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBMaXZlUXVlcnlPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ1tdfSBjbGFzc05hbWVzIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjbGFzc05hbWVzXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8UHViU3ViQWRhcHRlcj59IHB1YlN1YkFkYXB0ZXIgTGl2ZVF1ZXJ5IHB1YnN1YiBhZGFwdGVyXG4gKiBAcHJvcGVydHkge0FueX0gcmVkaXNPcHRpb25zIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWRpc1VSTCBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkxcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxXU1NBZGFwdGVyPn0gd3NzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIFdlYlNvY2tldFNlcnZlclxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYXBwSWQgVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBhcHBJZCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIGFwcElkLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IGNhY2hlVGltZW91dCBOdW1iZXIgaW4gbWlsbGlzZWNvbmRzLiBXaGVuIGNsaWVudHMgcHJvdmlkZSB0aGUgc2Vzc2lvblRva2VuIHRvIHRoZSBMaXZlUXVlcnkgc2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byBmZXRjaCBpdHMgUGFyc2VVc2VyJ3Mgb2JqZWN0SWQgZnJvbSBwYXJzZSBzZXJ2ZXIgYW5kIHN0b3JlIGl0IGluIHRoZSBjYWNoZS4gVGhlIHZhbHVlIGRlZmluZXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBjYWNoZS4gQ2hlY2sgdGhlIGZvbGxvd2luZyBTZWN1cml0eSBzZWN0aW9uIGFuZCBvdXIgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscywgZGVmYXVsdHMgdG8gNSAqIDEwMDAgbXMgKDUgc2Vjb25kcykuXG4gKiBAcHJvcGVydHkge0FueX0ga2V5UGFpcnMgQSBKU09OIG9iamVjdCB0aGF0IHNlcnZlcyBhcyBhIHdoaXRlbGlzdCBvZiBrZXlzLiBJdCBpcyB1c2VkIGZvciB2YWxpZGF0aW5nIGNsaWVudHMgd2hlbiB0aGV5IHRyeSB0byBjb25uZWN0IHRvIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGxvZ0xldmVsIFRoaXMgc3RyaW5nIGRlZmluZXMgdGhlIGxvZyBsZXZlbCBvZiB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gV2Ugc3VwcG9ydCBWRVJCT1NFLCBJTkZPLCBFUlJPUiwgTk9ORSwgZGVmYXVsdHMgdG8gSU5GTy5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBtYXN0ZXJLZXkgVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBtYXN0ZXJLZXkgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBtYXN0ZXJLZXkuXG4gKiBAcHJvcGVydHkge051bWJlcn0gcG9ydCBUaGUgcG9ydCB0byBydW4gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8UHViU3ViQWRhcHRlcj59IHB1YlN1YkFkYXB0ZXIgTGl2ZVF1ZXJ5IHB1YnN1YiBhZGFwdGVyXG4gKiBAcHJvcGVydHkge0FueX0gcmVkaXNPcHRpb25zIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWRpc1VSTCBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkxcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBzZXJ2ZXJVUkwgVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBzZXJ2ZXJVUkwgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBzZXJ2ZXJVUkwuXG4gKiBAcHJvcGVydHkge051bWJlcn0gd2Vic29ja2V0VGltZW91dCBOdW1iZXIgb2YgbWlsbGlzZWNvbmRzIGJldHdlZW4gcGluZy9wb25nIGZyYW1lcy4gVGhlIFdlYlNvY2tldCBzZXJ2ZXIgc2VuZHMgcGluZy9wb25nIGZyYW1lcyB0byB0aGUgY2xpZW50cyB0byBrZWVwIHRoZSBXZWJTb2NrZXQgYWxpdmUuIFRoaXMgdmFsdWUgZGVmaW5lcyB0aGUgaW50ZXJ2YWwgb2YgdGhlIHBpbmcvcG9uZyBmcmFtZSBmcm9tIHRoZSBzZXJ2ZXIgdG8gY2xpZW50cywgZGVmYXVsdHMgdG8gMTAgKiAxMDAwIG1zICgxMCBzKS5cbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxXU1NBZGFwdGVyPn0gd3NzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIFdlYlNvY2tldFNlcnZlclxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBJZGVtcG90ZW5jeU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IHBhdGhzIEFuIGFycmF5IG9mIHBhdGhzIGZvciB3aGljaCB0aGUgZmVhdHVyZSBzaG91bGQgYmUgZW5hYmxlZC4gVGhlIG1vdW50IHBhdGggbXVzdCBub3QgYmUgaW5jbHVkZWQsIGZvciBleGFtcGxlIGluc3RlYWQgb2YgYC9wYXJzZS9mdW5jdGlvbnMvbXlGdW5jdGlvbmAgc3BlY2lmaXkgYGZ1bmN0aW9ucy9teUZ1bmN0aW9uYC4gVGhlIGVudHJpZXMgYXJlIGludGVycHJldGVkIGFzIHJlZ3VsYXIgZXhwcmVzc2lvbiwgZm9yIGV4YW1wbGUgYGZ1bmN0aW9ucy8uKmAgbWF0Y2hlcyBhbGwgZnVuY3Rpb25zLCBgam9icy8uKmAgbWF0Y2hlcyBhbGwgam9icywgYGNsYXNzZXMvLipgIG1hdGNoZXMgYWxsIGNsYXNzZXMsIGAuKmAgbWF0Y2hlcyBhbGwgcGF0aHMuXG4gKiBAcHJvcGVydHkge051bWJlcn0gdHRsIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFmdGVyIHdoaWNoIGEgcmVxdWVzdCByZWNvcmQgaXMgZGlzY2FyZGVkIGZyb20gdGhlIGRhdGFiYXNlLCBkZWZhdWx0cyB0byAzMDBzLlxuICovXG4iXX0= \ No newline at end of file diff --git a/lib/Options/index.js b/lib/Options/index.js new file mode 100644 index 0000000000..75d7985142 --- /dev/null +++ b/lib/Options/index.js @@ -0,0 +1,18 @@ +"use strict"; + +var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); + +var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); + +var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); + +var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); + +var _CacheAdapter = require("../Adapters/Cache/CacheAdapter"); + +var _MailAdapter = require("../Adapters/Email/MailAdapter"); + +var _PubSubAdapter = require("../Adapters/PubSub/PubSubAdapter"); + +var _WSSAdapter = require("../Adapters/WebSocketServer/WSSAdapter"); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IHsgRmlsZXNBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRmlsZXMvRmlsZXNBZGFwdGVyJztcbmltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlcic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHsgQ2FjaGVBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQ2FjaGUvQ2FjaGVBZGFwdGVyJztcbmltcG9ydCB7IE1haWxBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRW1haWwvTWFpbEFkYXB0ZXInO1xuaW1wb3J0IHsgUHViU3ViQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9QdWJTdWJBZGFwdGVyJztcbmltcG9ydCB7IFdTU0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlcic7XG5cbi8vIEBmbG93XG50eXBlIEFkYXB0ZXI8VD4gPSBzdHJpbmcgfCBhbnkgfCBUO1xudHlwZSBOdW1iZXJPckJvb2xlYW4gPSBudW1iZXIgfCBib29sZWFuO1xudHlwZSBOdW1iZXJPclN0cmluZyA9IG51bWJlciB8IHN0cmluZztcbnR5cGUgUHJvdGVjdGVkRmllbGRzID0gYW55O1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlU2VydmVyT3B0aW9ucyB7XG4gIC8qIFlvdXIgUGFyc2UgQXBwbGljYXRpb24gSURcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FQUExJQ0FUSU9OX0lEICovXG4gIGFwcElkOiBzdHJpbmc7XG4gIC8qIFlvdXIgUGFyc2UgTWFzdGVyIEtleSAqL1xuICBtYXN0ZXJLZXk6IHN0cmluZztcbiAgLyogVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAgOkVOVjogUEFSU0VfU0VSVkVSX1VSTCAqL1xuICBzZXJ2ZXJVUkw6IHN0cmluZztcbiAgLyogUmVzdHJpY3QgbWFzdGVyS2V5IHRvIGJlIHVzZWQgYnkgb25seSB0aGVzZSBpcHMsIGRlZmF1bHRzIHRvIFtdIChhbGxvdyBhbGwgaXBzKVxuICA6REVGQVVMVDogW10gKi9cbiAgbWFzdGVyS2V5SXBzOiA/KHN0cmluZ1tdKTtcbiAgLyogU2V0cyB0aGUgYXBwIG5hbWUgKi9cbiAgYXBwTmFtZTogP3N0cmluZztcbiAgLyogQWRkIGhlYWRlcnMgdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyAqL1xuICBhbGxvd0hlYWRlcnM6ID8oc3RyaW5nW10pO1xuICAvKiBTZXRzIHRoZSBvcmlnaW4gdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luICovXG4gIGFsbG93T3JpZ2luOiA/c3RyaW5nO1xuICAvKiBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcyAqL1xuICBhbmFseXRpY3NBZGFwdGVyOiA/QWRhcHRlcjxBbmFseXRpY3NBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBmaWxlcyBzdWItc3lzdGVtICovXG4gIGZpbGVzQWRhcHRlcjogP0FkYXB0ZXI8RmlsZXNBZGFwdGVyPjtcbiAgLyogQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zICovXG4gIHB1c2g6ID9hbnk7XG4gIC8qIENvbmZpZ3VyYXRpb24gZm9yIHB1c2ggc2NoZWR1bGluZywgZGVmYXVsdHMgdG8gZmFsc2UuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBzY2hlZHVsZWRQdXNoOiA/Ym9vbGVhbjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0gKi9cbiAgbG9nZ2VyQWRhcHRlcjogP0FkYXB0ZXI8TG9nZ2VyQWRhcHRlcj47XG4gIC8qIExvZyBhcyBzdHJ1Y3R1cmVkIEpTT04gb2JqZWN0c1xuICA6RU5WOiBKU09OX0xPR1MgKi9cbiAganNvbkxvZ3M6ID9ib29sZWFuO1xuICAvKiBGb2xkZXIgZm9yIHRoZSBsb2dzIChkZWZhdWx0cyB0byAnLi9sb2dzJyk7IHNldCB0byBudWxsIHRvIGRpc2FibGUgZmlsZSBiYXNlZCBsb2dnaW5nXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9MT0dTX0ZPTERFUlxuICA6REVGQVVMVDogLi9sb2dzICovXG4gIGxvZ3NGb2xkZXI6ID9zdHJpbmc7XG4gIC8qIFNldCB0aGUgbG9nZ2luZyB0byB2ZXJib3NlXG4gIDpFTlY6IFZFUkJPU0UgKi9cbiAgdmVyYm9zZTogP2Jvb2xlYW47XG4gIC8qIFNldHMgdGhlIGxldmVsIGZvciBsb2dzICovXG4gIGxvZ0xldmVsOiA/c3RyaW5nO1xuICAvKiBNYXhpbXVtIG51bWJlciBvZiBsb2dzIHRvIGtlZXAuIElmIG5vdCBzZXQsIG5vIGxvZ3Mgd2lsbCBiZSByZW1vdmVkLiBUaGlzIGNhbiBiZSBhIG51bWJlciBvZiBmaWxlcyBvciBudW1iZXIgb2YgZGF5cy4gSWYgdXNpbmcgZGF5cywgYWRkICdkJyBhcyB0aGUgc3VmZml4LiAoZGVmYXVsdDogbnVsbCkgKi9cbiAgbWF4TG9nRmlsZXM6ID9OdW1iZXJPclN0cmluZztcbiAgLyogRGlzYWJsZXMgY29uc29sZSBvdXRwdXRcbiAgOkVOVjogU0lMRU5UICovXG4gIHNpbGVudDogP2Jvb2xlYW47XG4gIC8qIFRoZSBmdWxsIFVSSSB0byB5b3VyIGRhdGFiYXNlLiBTdXBwb3J0ZWQgZGF0YWJhc2VzIGFyZSBtb25nb2RiIG9yIHBvc3RncmVzLlxuICA6REVGQVVMVDogbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZSAqL1xuICBkYXRhYmFzZVVSSTogc3RyaW5nO1xuICAvKiBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIG1vbmdvZGIgY2xpZW50ICovXG4gIGRhdGFiYXNlT3B0aW9uczogP2FueTtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBkYXRhYmFzZSAqL1xuICBkYXRhYmFzZUFkYXB0ZXI6ID9BZGFwdGVyPFN0b3JhZ2VBZGFwdGVyPjtcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgY2xvdWQgY29kZSBtYWluLmpzICovXG4gIGNsb3VkOiA/c3RyaW5nO1xuICAvKiBBIGNvbGxlY3Rpb24gcHJlZml4IGZvciB0aGUgY2xhc3Nlc1xuICA6REVGQVVMVDogJycgKi9cbiAgY29sbGVjdGlvblByZWZpeDogP3N0cmluZztcbiAgLyogS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMgKi9cbiAgY2xpZW50S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIHRoZSBKYXZhc2NyaXB0IFNESyAqL1xuICBqYXZhc2NyaXB0S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIFVuaXR5IGFuZCAuTmV0IFNESyAqL1xuICBkb3ROZXRLZXk6ID9zdHJpbmc7XG4gIC8qIEtleSBmb3IgUkVTVCBjYWxsc1xuICA6RU5WOiBQQVJTRV9TRVJWRVJfUkVTVF9BUElfS0VZICovXG4gIHJlc3RBUElLZXk6ID9zdHJpbmc7XG4gIC8qIFJlYWQtb25seSBrZXksIHdoaWNoIGhhcyB0aGUgc2FtZSBjYXBhYmlsaXRpZXMgYXMgTWFzdGVyS2V5IHdpdGhvdXQgd3JpdGVzICovXG4gIHJlYWRPbmx5TWFzdGVyS2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgc2VudCB3aXRoIG91dGdvaW5nIHdlYmhvb2sgY2FsbHMgKi9cbiAgd2ViaG9va0tleTogP3N0cmluZztcbiAgLyogS2V5IGZvciB5b3VyIGZpbGVzICovXG4gIGZpbGVLZXk6ID9zdHJpbmc7XG4gIC8qIEVuYWJsZSAob3IgZGlzYWJsZSkgdGhlIGFkZGl0aW9uIG9mIGEgdW5pcXVlIGhhc2ggdG8gdGhlIGZpbGUgbmFtZXNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1BSRVNFUlZFX0ZJTEVfTkFNRVxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgcHJlc2VydmVGaWxlTmFtZTogP2Jvb2xlYW47XG4gIC8qIFBlcnNvbmFsbHkgaWRlbnRpZmlhYmxlIGluZm9ybWF0aW9uIGZpZWxkcyBpbiB0aGUgdXNlciB0YWJsZSB0aGUgc2hvdWxkIGJlIHJlbW92ZWQgZm9yIG5vbi1hdXRob3JpemVkIHVzZXJzLiBEZXByZWNhdGVkIEBzZWUgcHJvdGVjdGVkRmllbGRzICovXG4gIHVzZXJTZW5zaXRpdmVGaWVsZHM6ID8oc3RyaW5nW10pO1xuICAvKiBQcm90ZWN0ZWQgZmllbGRzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgd2l0aCBleHRyYSBzZWN1cml0eSB3aGVuIGZldGNoaW5nIGRldGFpbHMuXG4gIDpERUZBVUxUOiB7XCJfVXNlclwiOiB7XCIqXCI6IFtcImVtYWlsXCJdfX0gKi9cbiAgcHJvdGVjdGVkRmllbGRzOiA/UHJvdGVjdGVkRmllbGRzO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIGFub255bW91cyB1c2VycywgZGVmYXVsdHMgdG8gdHJ1ZVxuICA6RU5WOiBQQVJTRV9TRVJWRVJfRU5BQkxFX0FOT05fVVNFUlNcbiAgOkRFRkFVTFQ6IHRydWUgKi9cbiAgZW5hYmxlQW5vbnltb3VzVXNlcnM6ID9ib29sZWFuO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIGNsaWVudCBjbGFzcyBjcmVhdGlvbiwgZGVmYXVsdHMgdG8gdHJ1ZVxuICA6RU5WOiBQQVJTRV9TRVJWRVJfQUxMT1dfQ0xJRU5UX0NMQVNTX0NSRUFUSU9OXG4gIDpERUZBVUxUOiB0cnVlICovXG4gIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbjogP2Jvb2xlYW47XG4gIC8qIEVuYWJsZSAob3IgZGlzYWJsZSkgY3VzdG9tIG9iamVjdElkXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9BTExPV19DVVNUT01fT0JKRUNUX0lEXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBhbGxvd0N1c3RvbU9iamVjdElkOiA/Ym9vbGVhbjtcbiAgLyogQ29uZmlndXJhdGlvbiBmb3IgeW91ciBhdXRoZW50aWNhdGlvbiBwcm92aWRlcnMsIGFzIHN0cmluZ2lmaWVkIEpTT04uIFNlZSBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvI29hdXRoLWFuZC0zcmQtcGFydHktYXV0aGVudGljYXRpb25cbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FVVEhfUFJPVklERVJTICovXG4gIGF1dGg6ID9hbnk7XG4gIC8qIE1heCBmaWxlIHNpemUgZm9yIHVwbG9hZHMsIGRlZmF1bHRzIHRvIDIwbWJcbiAgOkRFRkFVTFQ6IDIwbWIgKi9cbiAgbWF4VXBsb2FkU2l6ZTogP3N0cmluZztcbiAgLyogRW5hYmxlIChvciBkaXNhYmxlKSB1c2VyIGVtYWlsIHZhbGlkYXRpb24sIGRlZmF1bHRzIHRvIGZhbHNlXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICB2ZXJpZnlVc2VyRW1haWxzOiA/Ym9vbGVhbjtcbiAgLyogUHJldmVudCB1c2VyIGZyb20gbG9naW4gaWYgZW1haWwgaXMgbm90IHZlcmlmaWVkIGFuZCBQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTIGlzIHRydWUsIGRlZmF1bHRzIHRvIGZhbHNlXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsOiA/Ym9vbGVhbjtcbiAgLyogRW1haWwgdmVyaWZpY2F0aW9uIHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uLCBpbiBzZWNvbmRzICovXG4gIGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uOiA/bnVtYmVyO1xuICAvKiBhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHMgKi9cbiAgYWNjb3VudExvY2tvdXQ6ID9hbnk7XG4gIC8qIFBhc3N3b3JkIHBvbGljeSBmb3IgZW5mb3JjaW5nIHBhc3N3b3JkIHJlbGF0ZWQgcnVsZXMgKi9cbiAgcGFzc3dvcmRQb2xpY3k6ID9hbnk7XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGUgKi9cbiAgY2FjaGVBZGFwdGVyOiA/QWRhcHRlcjxDYWNoZUFkYXB0ZXI+O1xuICAvKiBBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZyAqL1xuICBlbWFpbEFkYXB0ZXI6ID9BZGFwdGVyPE1haWxBZGFwdGVyPjtcbiAgLyogUHVibGljIFVSTCB0byB5b3VyIHBhcnNlIHNlcnZlciB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8uXG4gIDpFTlY6IFBBUlNFX1BVQkxJQ19TRVJWRVJfVVJMICovXG4gIHB1YmxpY1NlcnZlclVSTDogP3N0cmluZztcbiAgLyogY3VzdG9tIHBhZ2VzIGZvciBwYXNzd29yZCB2YWxpZGF0aW9uIGFuZCByZXNldFxuICA6REVGQVVMVDoge30gKi9cbiAgY3VzdG9tUGFnZXM6ID9DdXN0b21QYWdlc09wdGlvbnM7XG4gIC8qIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjb25maWd1cmF0aW9uIG9iamVjdCAqL1xuICBsaXZlUXVlcnk6ID9MaXZlUXVlcnlPcHRpb25zO1xuICAvKiBTZXNzaW9uIGR1cmF0aW9uLCBpbiBzZWNvbmRzLCBkZWZhdWx0cyB0byAxIHllYXJcbiAgOkRFRkFVTFQ6IDMxNTM2MDAwICovXG4gIHNlc3Npb25MZW5ndGg6ID9udW1iZXI7XG4gIC8qIE1heCB2YWx1ZSBmb3IgbGltaXQgb3B0aW9uIG9uIHF1ZXJpZXMsIGRlZmF1bHRzIHRvIHVubGltaXRlZCAqL1xuICBtYXhMaW1pdDogP251bWJlcjtcbiAgLyogU2V0cyB3ZXRoZXIgd2Ugc2hvdWxkIGV4cGlyZSB0aGUgaW5hY3RpdmUgc2Vzc2lvbnMsIGRlZmF1bHRzIHRvIHRydWVcbiAgOkRFRkFVTFQ6IHRydWUgKi9cbiAgZXhwaXJlSW5hY3RpdmVTZXNzaW9uczogP2Jvb2xlYW47XG4gIC8qIFdoZW4gYSB1c2VyIGNoYW5nZXMgdGhlaXIgcGFzc3dvcmQsIGVpdGhlciB0aHJvdWdoIHRoZSByZXNldCBwYXNzd29yZCBlbWFpbCBvciB3aGlsZSBsb2dnZWQgaW4sIGFsbCBzZXNzaW9ucyBhcmUgcmV2b2tlZCBpZiB0aGlzIGlzIHRydWUuIFNldCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudCB0byByZXZva2Ugc2Vzc2lvbnMuXG4gIDpERUZBVUxUOiB0cnVlICovXG4gIHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQ6ID9ib29sZWFuO1xuICAvKiBUaGUgVFRMIGZvciBjYWNoaW5nIHRoZSBzY2hlbWEgZm9yIG9wdGltaXppbmcgcmVhZC93cml0ZSBvcGVyYXRpb25zLiBZb3Ugc2hvdWxkIHB1dCBhIGxvbmcgVFRMIHdoZW4geW91ciBEQiBpcyBpbiBwcm9kdWN0aW9uLiBkZWZhdWx0IHRvIDUwMDA7IHNldCAwIHRvIGRpc2FibGUuXG4gIDpERUZBVUxUOiA1MDAwICovXG4gIHNjaGVtYUNhY2hlVFRMOiA/bnVtYmVyO1xuICAvKiBTZXRzIHRoZSBUVEwgZm9yIHRoZSBpbiBtZW1vcnkgY2FjaGUgKGluIG1zKSwgZGVmYXVsdHMgdG8gNTAwMCAoNSBzZWNvbmRzKVxuICA6REVGQVVMVDogNTAwMCAqL1xuICBjYWNoZVRUTDogP251bWJlcjtcbiAgLyogU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMFxuICA6REVGQVVMVDogMTAwMDAgKi9cbiAgY2FjaGVNYXhTaXplOiA/bnVtYmVyO1xuICAvKiBSZXBsYWNlIEhUVFAgSW50ZXJmYWNlIHdoZW4gdXNpbmcgSlMgU0RLIGluIGN1cnJlbnQgbm9kZSBydW50aW1lLCBkZWZhdWx0cyB0byBmYWxzZS4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1NcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGRpcmVjdEFjY2VzczogP2Jvb2xlYW47XG4gIC8qIFVzZSBhIHNpbmdsZSBzY2hlbWEgY2FjaGUgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cy4gUmVkdWNlcyBudW1iZXIgb2YgcXVlcmllcyBtYWRlIHRvIF9TQ0hFTUEsIGRlZmF1bHRzIHRvIGZhbHNlLCBpLmUuIHVuaXF1ZSBzY2hlbWEgY2FjaGUgcGVyIHJlcXVlc3QuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZTogP2Jvb2xlYW47XG4gIC8qIEVuYWJsZXMgdGhlIGRlZmF1bHQgZXhwcmVzcyBlcnJvciBoYW5kbGVyIGZvciBhbGwgZXJyb3JzXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyOiA/Ym9vbGVhbjtcbiAgLyogU2V0cyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gZ2VuZXJhdGVkIG9iamVjdCBpZCdzLCBkZWZhdWx0IDEwXG4gIDpERUZBVUxUOiAxMCAqL1xuICBvYmplY3RJZFNpemU6ID9udW1iZXI7XG4gIC8qIFRoZSBwb3J0IHRvIHJ1biB0aGUgUGFyc2VTZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gIDpFTlY6IFBPUlRcbiAgOkRFRkFVTFQ6IDEzMzcgKi9cbiAgcG9ydDogP251bWJlcjtcbiAgLyogVGhlIGhvc3QgdG8gc2VydmUgUGFyc2VTZXJ2ZXIgb24sIGRlZmF1bHRzIHRvIDAuMC4wLjBcbiAgOkRFRkFVTFQ6IDAuMC4wLjAgKi9cbiAgaG9zdDogP3N0cmluZztcbiAgLyogTW91bnQgcGF0aCBmb3IgdGhlIHNlcnZlciwgZGVmYXVsdHMgdG8gL3BhcnNlXG4gIDpERUZBVUxUOiAvcGFyc2UgKi9cbiAgbW91bnRQYXRoOiA/c3RyaW5nO1xuICAvKiBSdW4gd2l0aCBjbHVzdGVyLCBvcHRpb25hbGx5IHNldCB0aGUgbnVtYmVyIG9mIHByb2Nlc3NlcyBkZWZhdWx0IHRvIG9zLmNwdXMoKS5sZW5ndGggKi9cbiAgY2x1c3RlcjogP051bWJlck9yQm9vbGVhbjtcbiAgLyogbWlkZGxld2FyZSBmb3IgZXhwcmVzcyBzZXJ2ZXIsIGNhbiBiZSBzdHJpbmcgb3IgZnVuY3Rpb24gKi9cbiAgbWlkZGxld2FyZTogPygoKCkgPT4gdm9pZCkgfCBzdHJpbmcpO1xuICAvKiBTdGFydHMgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIgKi9cbiAgc3RhcnRMaXZlUXVlcnlTZXJ2ZXI6ID9ib29sZWFuO1xuICAvKiBMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpICovXG4gIGxpdmVRdWVyeVNlcnZlck9wdGlvbnM6ID9MaXZlUXVlcnlTZXJ2ZXJPcHRpb25zO1xuICAvKiBPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLlxuICA6RU5WOiBQQVJTRV9TRVJWRVJfRVhQRVJJTUVOVEFMX0lERU1QT1RFTkNZX09QVElPTlNcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGlkZW1wb3RlbmN5T3B0aW9uczogP0lkZW1wb3RlbmN5T3B0aW9ucztcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZSAqL1xuICBncmFwaFFMU2NoZW1hOiA/c3RyaW5nO1xuICAvKiBNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUxcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIG1vdW50R3JhcGhRTDogP2Jvb2xlYW47XG4gIC8qIE1vdW50IHBhdGggZm9yIHRoZSBHcmFwaFFMIGVuZHBvaW50LCBkZWZhdWx0cyB0byAvZ3JhcGhxbFxuICA6RU5WOiBQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIXG4gIDpERUZBVUxUOiAvZ3JhcGhxbCAqL1xuICBncmFwaFFMUGF0aDogP3N0cmluZztcbiAgLyogTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvblxuICA6RU5WOiBQQVJTRV9TRVJWRVJfTU9VTlRfUExBWUdST1VORFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgbW91bnRQbGF5Z3JvdW5kOiA/Ym9vbGVhbjtcbiAgLyogTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1BMQVlHUk9VTkRfUEFUSFxuICA6REVGQVVMVDogL3BsYXlncm91bmQgKi9cbiAgcGxheWdyb3VuZFBhdGg6ID9zdHJpbmc7XG4gIC8qIENhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBzdGFydGVkICovXG4gIHNlcnZlclN0YXJ0Q29tcGxldGU6ID8oZXJyb3I6ID9FcnJvcikgPT4gdm9pZDtcbiAgLyogQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZCAqL1xuICBzZXJ2ZXJDbG9zZUNvbXBsZXRlOiA/KCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21QYWdlc09wdGlvbnMge1xuICAvKiBpbnZhbGlkIGxpbmsgcGFnZSBwYXRoICovXG4gIGludmFsaWRMaW5rOiA/c3RyaW5nO1xuICAvKiB2ZXJpZnkgZW1haWwgc3VjY2VzcyBwYWdlIHBhdGggKi9cbiAgdmVyaWZ5RW1haWxTdWNjZXNzOiA/c3RyaW5nO1xuICAvKiBpbnZhbGlkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aCAqL1xuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluazogP3N0cmluZztcbiAgLyogdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICBsaW5rU2VuZFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIHZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgZmFpbCBwYWdlIHBhdGggKi9cbiAgbGlua1NlbmRGYWlsOiA/c3RyaW5nO1xuICAvKiBjaG9vc2UgcGFzc3dvcmQgcGFnZSBwYXRoICovXG4gIGNob29zZVBhc3N3b3JkOiA/c3RyaW5nO1xuICAvKiBwYXNzd29yZCByZXNldCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICBwYXNzd29yZFJlc2V0U3VjY2VzczogP3N0cmluZztcbiAgLyogZm9yIG1hc2tpbmcgdXNlci1mYWNpbmcgcGFnZXMgKi9cbiAgcGFyc2VGcmFtZVVSTDogP3N0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXZlUXVlcnlPcHRpb25zIHtcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IGNsYXNzTmFtZXNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9DTEFTU05BTUVTICovXG4gIGNsYXNzTmFtZXM6ID8oc3RyaW5nW10pO1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zICovXG4gIHJlZGlzT3B0aW9uczogP2FueTtcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMICovXG4gIHJlZGlzVVJMOiA/c3RyaW5nO1xuICAvKiBMaXZlUXVlcnkgcHVic3ViIGFkYXB0ZXIgKi9cbiAgcHViU3ViQWRhcHRlcjogP0FkYXB0ZXI8UHViU3ViQWRhcHRlcj47XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyICovXG4gIHdzc0FkYXB0ZXI6ID9BZGFwdGVyPFdTU0FkYXB0ZXI+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpdmVRdWVyeVNlcnZlck9wdGlvbnMge1xuICAvKiBUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIGFwcElkIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgYXBwSWQuKi9cbiAgYXBwSWQ6ID9zdHJpbmc7XG4gIC8qIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgbWFzdGVyS2V5IGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgbWFzdGVyS2V5LiovXG4gIG1hc3RlcktleTogP3N0cmluZztcbiAgLyogVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBzZXJ2ZXJVUkwgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBzZXJ2ZXJVUkwuKi9cbiAgc2VydmVyVVJMOiA/c3RyaW5nO1xuICAvKiBBIEpTT04gb2JqZWN0IHRoYXQgc2VydmVzIGFzIGEgd2hpdGVsaXN0IG9mIGtleXMuIEl0IGlzIHVzZWQgZm9yIHZhbGlkYXRpbmcgY2xpZW50cyB3aGVuIHRoZXkgdHJ5IHRvIGNvbm5lY3QgdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMuKi9cbiAga2V5UGFpcnM6ID9hbnk7XG4gIC8qIE51bWJlciBvZiBtaWxsaXNlY29uZHMgYmV0d2VlbiBwaW5nL3BvbmcgZnJhbWVzLiBUaGUgV2ViU29ja2V0IHNlcnZlciBzZW5kcyBwaW5nL3BvbmcgZnJhbWVzIHRvIHRoZSBjbGllbnRzIHRvIGtlZXAgdGhlIFdlYlNvY2tldCBhbGl2ZS4gVGhpcyB2YWx1ZSBkZWZpbmVzIHRoZSBpbnRlcnZhbCBvZiB0aGUgcGluZy9wb25nIGZyYW1lIGZyb20gdGhlIHNlcnZlciB0byBjbGllbnRzLCBkZWZhdWx0cyB0byAxMCAqIDEwMDAgbXMgKDEwIHMpLiovXG4gIHdlYnNvY2tldFRpbWVvdXQ6ID9udW1iZXI7XG4gIC8qIE51bWJlciBpbiBtaWxsaXNlY29uZHMuIFdoZW4gY2xpZW50cyBwcm92aWRlIHRoZSBzZXNzaW9uVG9rZW4gdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIGZldGNoIGl0cyBQYXJzZVVzZXIncyBvYmplY3RJZCBmcm9tIHBhcnNlIHNlcnZlciBhbmQgc3RvcmUgaXQgaW4gdGhlIGNhY2hlLiBUaGUgdmFsdWUgZGVmaW5lcyB0aGUgZHVyYXRpb24gb2YgdGhlIGNhY2hlLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLCBkZWZhdWx0cyB0byA1ICogMTAwMCBtcyAoNSBzZWNvbmRzKS4qL1xuICBjYWNoZVRpbWVvdXQ6ID9udW1iZXI7XG4gIC8qIFRoaXMgc3RyaW5nIGRlZmluZXMgdGhlIGxvZyBsZXZlbCBvZiB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gV2Ugc3VwcG9ydCBWRVJCT1NFLCBJTkZPLCBFUlJPUiwgTk9ORSwgZGVmYXVsdHMgdG8gSU5GTy4qL1xuICBsb2dMZXZlbDogP3N0cmluZztcbiAgLyogVGhlIHBvcnQgdG8gcnVuIHRoZSBMaXZlUXVlcnkgc2VydmVyLCBkZWZhdWx0cyB0byAxMzM3LlxuICA6REVGQVVMVDogMTMzNyAqL1xuICBwb3J0OiA/bnVtYmVyO1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zICovXG4gIHJlZGlzT3B0aW9uczogP2FueTtcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMICovXG4gIHJlZGlzVVJMOiA/c3RyaW5nO1xuICAvKiBMaXZlUXVlcnkgcHVic3ViIGFkYXB0ZXIgKi9cbiAgcHViU3ViQWRhcHRlcjogP0FkYXB0ZXI8UHViU3ViQWRhcHRlcj47XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyICovXG4gIHdzc0FkYXB0ZXI6ID9BZGFwdGVyPFdTU0FkYXB0ZXI+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElkZW1wb3RlbmN5T3B0aW9ucyB7XG4gIC8qIEFuIGFycmF5IG9mIHBhdGhzIGZvciB3aGljaCB0aGUgZmVhdHVyZSBzaG91bGQgYmUgZW5hYmxlZC4gVGhlIG1vdW50IHBhdGggbXVzdCBub3QgYmUgaW5jbHVkZWQsIGZvciBleGFtcGxlIGluc3RlYWQgb2YgYC9wYXJzZS9mdW5jdGlvbnMvbXlGdW5jdGlvbmAgc3BlY2lmaXkgYGZ1bmN0aW9ucy9teUZ1bmN0aW9uYC4gVGhlIGVudHJpZXMgYXJlIGludGVycHJldGVkIGFzIHJlZ3VsYXIgZXhwcmVzc2lvbiwgZm9yIGV4YW1wbGUgYGZ1bmN0aW9ucy8uKmAgbWF0Y2hlcyBhbGwgZnVuY3Rpb25zLCBgam9icy8uKmAgbWF0Y2hlcyBhbGwgam9icywgYGNsYXNzZXMvLipgIG1hdGNoZXMgYWxsIGNsYXNzZXMsIGAuKmAgbWF0Y2hlcyBhbGwgcGF0aHMuXG4gIDpERUZBVUxUOiBbXSAqL1xuICBwYXRoczogPyhzdHJpbmdbXSk7XG4gIC8qIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFmdGVyIHdoaWNoIGEgcmVxdWVzdCByZWNvcmQgaXMgZGlzY2FyZGVkIGZyb20gdGhlIGRhdGFiYXNlLCBkZWZhdWx0cyB0byAzMDBzLlxuICA6REVGQVVMVDogMzAwICovXG4gIHR0bDogP251bWJlcjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Options/parsers.js b/lib/Options/parsers.js new file mode 100644 index 0000000000..d5bc65c7d4 --- /dev/null +++ b/lib/Options/parsers.js @@ -0,0 +1,90 @@ +"use strict"; + +function numberParser(key) { + return function (opt) { + const intOpt = parseInt(opt); + + if (!Number.isInteger(intOpt)) { + throw new Error(`Key ${key} has invalid value ${opt}`); + } + + return intOpt; + }; +} + +function numberOrBoolParser(key) { + return function (opt) { + if (typeof opt === 'boolean') { + return opt; + } + + if (opt === 'true') { + return true; + } + + if (opt === 'false') { + return false; + } + + return numberParser(key)(opt); + }; +} + +function objectParser(opt) { + if (typeof opt == 'object') { + return opt; + } + + return JSON.parse(opt); +} + +function arrayParser(opt) { + if (Array.isArray(opt)) { + return opt; + } else if (typeof opt === 'string') { + return opt.split(','); + } else { + throw new Error(`${opt} should be a comma separated string or an array`); + } +} + +function moduleOrObjectParser(opt) { + if (typeof opt == 'object') { + return opt; + } + + try { + return JSON.parse(opt); + } catch (e) { + /* */ + } + + return opt; +} + +function booleanParser(opt) { + if (opt == true || opt == 'true' || opt == '1') { + return true; + } + + return false; +} + +function nullParser(opt) { + if (opt == 'null') { + return null; + } + + return opt; +} + +module.exports = { + numberParser, + numberOrBoolParser, + nullParser, + booleanParser, + moduleOrObjectParser, + arrayParser, + objectParser +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL3BhcnNlcnMuanMiXSwibmFtZXMiOlsibnVtYmVyUGFyc2VyIiwia2V5Iiwib3B0IiwiaW50T3B0IiwicGFyc2VJbnQiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJFcnJvciIsIm51bWJlck9yQm9vbFBhcnNlciIsIm9iamVjdFBhcnNlciIsIkpTT04iLCJwYXJzZSIsImFycmF5UGFyc2VyIiwiQXJyYXkiLCJpc0FycmF5Iiwic3BsaXQiLCJtb2R1bGVPck9iamVjdFBhcnNlciIsImUiLCJib29sZWFuUGFyc2VyIiwibnVsbFBhcnNlciIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkI7QUFDekIsU0FBTyxVQUFVQyxHQUFWLEVBQWU7QUFDcEIsVUFBTUMsTUFBTSxHQUFHQyxRQUFRLENBQUNGLEdBQUQsQ0FBdkI7O0FBQ0EsUUFBSSxDQUFDRyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJILE1BQWpCLENBQUwsRUFBK0I7QUFDN0IsWUFBTSxJQUFJSSxLQUFKLENBQVcsT0FBTU4sR0FBSSxzQkFBcUJDLEdBQUksRUFBOUMsQ0FBTjtBQUNEOztBQUNELFdBQU9DLE1BQVA7QUFDRCxHQU5EO0FBT0Q7O0FBRUQsU0FBU0ssa0JBQVQsQ0FBNEJQLEdBQTVCLEVBQWlDO0FBQy9CLFNBQU8sVUFBVUMsR0FBVixFQUFlO0FBQ3BCLFFBQUksT0FBT0EsR0FBUCxLQUFlLFNBQW5CLEVBQThCO0FBQzVCLGFBQU9BLEdBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssTUFBWixFQUFvQjtBQUNsQixhQUFPLElBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssT0FBWixFQUFxQjtBQUNuQixhQUFPLEtBQVA7QUFDRDs7QUFDRCxXQUFPRixZQUFZLENBQUNDLEdBQUQsQ0FBWixDQUFrQkMsR0FBbEIsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTTyxZQUFULENBQXNCUCxHQUF0QixFQUEyQjtBQUN6QixNQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFPQSxHQUFQO0FBQ0Q7O0FBQ0QsU0FBT1EsSUFBSSxDQUFDQyxLQUFMLENBQVdULEdBQVgsQ0FBUDtBQUNEOztBQUVELFNBQVNVLFdBQVQsQ0FBcUJWLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlXLEtBQUssQ0FBQ0MsT0FBTixDQUFjWixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBUDtBQUNELEdBRkQsTUFFTyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUNsQyxXQUFPQSxHQUFHLENBQUNhLEtBQUosQ0FBVSxHQUFWLENBQVA7QUFDRCxHQUZNLE1BRUE7QUFDTCxVQUFNLElBQUlSLEtBQUosQ0FBVyxHQUFFTCxHQUFJLGlEQUFqQixDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTYyxvQkFBVCxDQUE4QmQsR0FBOUIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxHQUFQLElBQWMsUUFBbEIsRUFBNEI7QUFDMUIsV0FBT0EsR0FBUDtBQUNEOztBQUNELE1BQUk7QUFDRixXQUFPUSxJQUFJLENBQUNDLEtBQUwsQ0FBV1QsR0FBWCxDQUFQO0FBQ0QsR0FGRCxDQUVFLE9BQU9lLENBQVAsRUFBVTtBQUNWO0FBQ0Q7O0FBQ0QsU0FBT2YsR0FBUDtBQUNEOztBQUVELFNBQVNnQixhQUFULENBQXVCaEIsR0FBdkIsRUFBNEI7QUFDMUIsTUFBSUEsR0FBRyxJQUFJLElBQVAsSUFBZUEsR0FBRyxJQUFJLE1BQXRCLElBQWdDQSxHQUFHLElBQUksR0FBM0MsRUFBZ0Q7QUFDOUMsV0FBTyxJQUFQO0FBQ0Q7O0FBQ0QsU0FBTyxLQUFQO0FBQ0Q7O0FBRUQsU0FBU2lCLFVBQVQsQ0FBb0JqQixHQUFwQixFQUF5QjtBQUN2QixNQUFJQSxHQUFHLElBQUksTUFBWCxFQUFtQjtBQUNqQixXQUFPLElBQVA7QUFDRDs7QUFDRCxTQUFPQSxHQUFQO0FBQ0Q7O0FBRURrQixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZnJCLEVBQUFBLFlBRGU7QUFFZlEsRUFBQUEsa0JBRmU7QUFHZlcsRUFBQUEsVUFIZTtBQUlmRCxFQUFBQSxhQUplO0FBS2ZGLEVBQUFBLG9CQUxlO0FBTWZKLEVBQUFBLFdBTmU7QUFPZkgsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIG51bWJlclBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBjb25zdCBpbnRPcHQgPSBwYXJzZUludChvcHQpO1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbnRPcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEtleSAke2tleX0gaGFzIGludmFsaWQgdmFsdWUgJHtvcHR9YCk7XG4gICAgfVxuICAgIHJldHVybiBpbnRPcHQ7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG51bWJlck9yQm9vbFBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gb3B0O1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAnZmFsc2UnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBudW1iZXJQYXJzZXIoa2V5KShvcHQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvYmplY3RQYXJzZXIob3B0KSB7XG4gIGlmICh0eXBlb2Ygb3B0ID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9wdDtcbiAgfVxuICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xufVxuXG5mdW5jdGlvbiBhcnJheVBhcnNlcihvcHQpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0KSkge1xuICAgIHJldHVybiBvcHQ7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gb3B0LnNwbGl0KCcsJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke29wdH0gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGVkIHN0cmluZyBvciBhbiBhcnJheWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vZHVsZU9yT2JqZWN0UGFyc2VyKG9wdCkge1xuICBpZiAodHlwZW9mIG9wdCA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvcHQ7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICByZXR1cm4gb3B0O1xufVxuXG5mdW5jdGlvbiBib29sZWFuUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09IHRydWUgfHwgb3B0ID09ICd0cnVlJyB8fCBvcHQgPT0gJzEnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBudWxsUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09ICdudWxsJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBvcHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBudW1iZXJQYXJzZXIsXG4gIG51bWJlck9yQm9vbFBhcnNlcixcbiAgbnVsbFBhcnNlcixcbiAgYm9vbGVhblBhcnNlcixcbiAgbW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIGFycmF5UGFyc2VyLFxuICBvYmplY3RQYXJzZXIsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/ParseMessageQueue.js b/lib/ParseMessageQueue.js new file mode 100644 index 0000000000..3bf0e42236 --- /dev/null +++ b/lib/ParseMessageQueue.js @@ -0,0 +1,34 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseMessageQueue = void 0; + +var _AdapterLoader = require("./Adapters/AdapterLoader"); + +var _EventEmitterMQ = require("./Adapters/MessageQueue/EventEmitterMQ"); + +const ParseMessageQueue = {}; +exports.ParseMessageQueue = ParseMessageQueue; + +ParseMessageQueue.createPublisher = function (config) { + const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); + + if (typeof adapter.createPublisher !== 'function') { + throw 'pubSubAdapter should have createPublisher()'; + } + + return adapter.createPublisher(config); +}; + +ParseMessageQueue.createSubscriber = function (config) { + const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); + + if (typeof adapter.createSubscriber !== 'function') { + throw 'messageQueueAdapter should have createSubscriber()'; + } + + return adapter.createSubscriber(config); +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZU1lc3NhZ2VRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQYXJzZU1lc3NhZ2VRdWV1ZSIsImNyZWF0ZVB1Ymxpc2hlciIsImNvbmZpZyIsImFkYXB0ZXIiLCJtZXNzYWdlUXVldWVBZGFwdGVyIiwiRXZlbnRFbWl0dGVyTVEiLCJjcmVhdGVTdWJzY3JpYmVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBRUEsTUFBTUEsaUJBQWlCLEdBQUcsRUFBMUI7OztBQUVBQSxpQkFBaUIsQ0FBQ0MsZUFBbEIsR0FBb0MsVUFBVUMsTUFBVixFQUE0QjtBQUM5RCxRQUFNQyxPQUFPLEdBQUcsZ0NBQVlELE1BQU0sQ0FBQ0UsbUJBQW5CLEVBQXdDQyw4QkFBeEMsRUFBd0RILE1BQXhELENBQWhCOztBQUNBLE1BQUksT0FBT0MsT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFVBQU0sNkNBQU47QUFDRDs7QUFDRCxTQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JDLE1BQXhCLENBQVA7QUFDRCxDQU5EOztBQVFBRixpQkFBaUIsQ0FBQ00sZ0JBQWxCLEdBQXFDLFVBQVVKLE1BQVYsRUFBNkI7QUFDaEUsUUFBTUMsT0FBTyxHQUFHLGdDQUFZRCxNQUFNLENBQUNFLG1CQUFuQixFQUF3Q0MsOEJBQXhDLEVBQXdESCxNQUF4RCxDQUFoQjs7QUFDQSxNQUFJLE9BQU9DLE9BQU8sQ0FBQ0csZ0JBQWYsS0FBb0MsVUFBeEMsRUFBb0Q7QUFDbEQsVUFBTSxvREFBTjtBQUNEOztBQUNELFNBQU9ILE9BQU8sQ0FBQ0csZ0JBQVIsQ0FBeUJKLE1BQXpCLENBQVA7QUFDRCxDQU5EIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyTVEgfSBmcm9tICcuL0FkYXB0ZXJzL01lc3NhZ2VRdWV1ZS9FdmVudEVtaXR0ZXJNUSc7XG5cbmNvbnN0IFBhcnNlTWVzc2FnZVF1ZXVlID0ge307XG5cblBhcnNlTWVzc2FnZVF1ZXVlLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVQdWJsaXNoZXIoKSc7XG4gIH1cbiAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG59O1xuXG5QYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVTdWJzY3JpYmVyID0gZnVuY3Rpb24gKGNvbmZpZzogYW55KTogdm9pZCB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgJ21lc3NhZ2VRdWV1ZUFkYXB0ZXIgc2hvdWxkIGhhdmUgY3JlYXRlU3Vic2NyaWJlcigpJztcbiAgfVxuICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG59O1xuXG5leHBvcnQgeyBQYXJzZU1lc3NhZ2VRdWV1ZSB9O1xuIl19 \ No newline at end of file diff --git a/lib/ParseServer.js b/lib/ParseServer.js new file mode 100644 index 0000000000..59d9a823a6 --- /dev/null +++ b/lib/ParseServer.js @@ -0,0 +1,495 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _Options = require("./Options"); + +var _defaults = _interopRequireDefault(require("./defaults")); + +var logging = _interopRequireWildcard(require("./logger")); + +var _Config = _interopRequireDefault(require("./Config")); + +var _PromiseRouter = _interopRequireDefault(require("./PromiseRouter")); + +var _requiredParameter = _interopRequireDefault(require("./requiredParameter")); + +var _AnalyticsRouter = require("./Routers/AnalyticsRouter"); + +var _ClassesRouter = require("./Routers/ClassesRouter"); + +var _FeaturesRouter = require("./Routers/FeaturesRouter"); + +var _FilesRouter = require("./Routers/FilesRouter"); + +var _FunctionsRouter = require("./Routers/FunctionsRouter"); + +var _GlobalConfigRouter = require("./Routers/GlobalConfigRouter"); + +var _GraphQLRouter = require("./Routers/GraphQLRouter"); + +var _HooksRouter = require("./Routers/HooksRouter"); + +var _IAPValidationRouter = require("./Routers/IAPValidationRouter"); + +var _InstallationsRouter = require("./Routers/InstallationsRouter"); + +var _LogsRouter = require("./Routers/LogsRouter"); + +var _ParseLiveQueryServer = require("./LiveQuery/ParseLiveQueryServer"); + +var _PublicAPIRouter = require("./Routers/PublicAPIRouter"); + +var _PushRouter = require("./Routers/PushRouter"); + +var _CloudCodeRouter = require("./Routers/CloudCodeRouter"); + +var _RolesRouter = require("./Routers/RolesRouter"); + +var _SchemasRouter = require("./Routers/SchemasRouter"); + +var _SessionsRouter = require("./Routers/SessionsRouter"); + +var _UsersRouter = require("./Routers/UsersRouter"); + +var _PurgeRouter = require("./Routers/PurgeRouter"); + +var _AudiencesRouter = require("./Routers/AudiencesRouter"); + +var _AggregateRouter = require("./Routers/AggregateRouter"); + +var _ParseServerRESTController = require("./ParseServerRESTController"); + +var controllers = _interopRequireWildcard(require("./Controllers")); + +var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// ParseServer - open-source compatible API Server for Parse apps +var batch = require('./batch'), + bodyParser = require('body-parser'), + express = require('express'), + middlewares = require('./middlewares'), + Parse = require('parse/node').Parse, + { + parse +} = require('graphql'), + path = require('path'), + fs = require('fs'); + +// Mutate the Parse object to add the Cloud Code handlers +addParseCloud(); // ParseServer works like a constructor of an express app. +// https://parseplatform.org/parse-server/api/master/ParseServerOptions.html + +class ParseServer { + /** + * @constructor + * @param {ParseServerOptions} options the parse server initialization options + */ + constructor(options) { + injectDefaults(options); + const { + appId = (0, _requiredParameter.default)('You must provide an appId!'), + masterKey = (0, _requiredParameter.default)('You must provide a masterKey!'), + cloud, + javascriptKey, + serverURL = (0, _requiredParameter.default)('You must provide a serverURL!'), + serverStartComplete + } = options; // Initialize the node client SDK automatically + + Parse.initialize(appId, javascriptKey || 'unused', masterKey); + Parse.serverURL = serverURL; + const allControllers = controllers.getControllers(options); + const { + loggerController, + databaseController, + hooksController + } = allControllers; + this.config = _Config.default.put(Object.assign({}, options, allControllers)); + logging.setLogger(loggerController); + const dbInitPromise = databaseController.performInitialization(); + const hooksLoadPromise = hooksController.load(); // Note: Tests will start to fail if any validation happens after this is called. + + Promise.all([dbInitPromise, hooksLoadPromise]).then(() => { + if (serverStartComplete) { + serverStartComplete(); + } + }).catch(error => { + if (serverStartComplete) { + serverStartComplete(error); + } else { + console.error(error); + process.exit(1); + } + }); + + if (cloud) { + addParseCloud(); + + if (typeof cloud === 'function') { + cloud(Parse); + } else if (typeof cloud === 'string') { + require(path.resolve(process.cwd(), cloud)); + } else { + throw "argument 'cloud' must either be a string or a function"; + } + } + } + + get app() { + if (!this._app) { + this._app = ParseServer.app(this.config); + } + + return this._app; + } + + handleShutdown() { + const promises = []; + const { + adapter: databaseAdapter + } = this.config.databaseController; + + if (databaseAdapter && typeof databaseAdapter.handleShutdown === 'function') { + promises.push(databaseAdapter.handleShutdown()); + } + + const { + adapter: fileAdapter + } = this.config.filesController; + + if (fileAdapter && typeof fileAdapter.handleShutdown === 'function') { + promises.push(fileAdapter.handleShutdown()); + } + + const { + adapter: cacheAdapter + } = this.config.cacheController; + + if (cacheAdapter && typeof cacheAdapter.handleShutdown === 'function') { + promises.push(cacheAdapter.handleShutdown()); + } + + return (promises.length > 0 ? Promise.all(promises) : Promise.resolve()).then(() => { + if (this.config.serverCloseComplete) { + this.config.serverCloseComplete(); + } + }); + } + /** + * @static + * Create an express app for the parse server + * @param {Object} options let you specify the maxUploadSize when creating the express app */ + + + static app({ + maxUploadSize = '20mb', + appId, + directAccess + }) { + // This app serves the Parse API directly. + // It's the equivalent of https://api.parse.com/1 in the hosted Parse API. + var api = express(); //api.use("/apps", express.static(__dirname + "/public")); + + api.use(middlewares.allowCrossDomain(appId)); // File handling needs to be before default middlewares are applied + + api.use('/', new _FilesRouter.FilesRouter().expressRouter({ + maxUploadSize: maxUploadSize + })); + api.use('/health', function (req, res) { + res.json({ + status: 'ok' + }); + }); + api.use('/', bodyParser.urlencoded({ + extended: false + }), new _PublicAPIRouter.PublicAPIRouter().expressRouter()); + api.use(bodyParser.json({ + type: '*/*', + limit: maxUploadSize + })); + api.use(middlewares.allowMethodOverride); + api.use(middlewares.handleParseHeaders); + const appRouter = ParseServer.promiseRouter({ + appId + }); + api.use(appRouter.expressRouter()); + api.use(middlewares.handleParseErrors); // run the following when not testing + + if (!process.env.TESTING) { + //This causes tests to spew some useless warnings, so disable in test + + /* istanbul ignore next */ + process.on('uncaughtException', err => { + if (err.code === 'EADDRINUSE') { + // user-friendly message for this common error + process.stderr.write(`Unable to listen on port ${err.port}. The port is already in use.`); + process.exit(0); + } else { + throw err; + } + }); // verify the server url after a 'mount' event is received + + /* istanbul ignore next */ + + api.on('mount', function () { + ParseServer.verifyServerUrl(); + }); + } + + if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1' || directAccess) { + Parse.CoreManager.setRESTController((0, _ParseServerRESTController.ParseServerRESTController)(appId, appRouter)); + } + + return api; + } + + static promiseRouter({ + appId + }) { + const routers = [new _ClassesRouter.ClassesRouter(), new _UsersRouter.UsersRouter(), new _SessionsRouter.SessionsRouter(), new _RolesRouter.RolesRouter(), new _AnalyticsRouter.AnalyticsRouter(), new _InstallationsRouter.InstallationsRouter(), new _FunctionsRouter.FunctionsRouter(), new _SchemasRouter.SchemasRouter(), new _PushRouter.PushRouter(), new _LogsRouter.LogsRouter(), new _IAPValidationRouter.IAPValidationRouter(), new _FeaturesRouter.FeaturesRouter(), new _GlobalConfigRouter.GlobalConfigRouter(), new _GraphQLRouter.GraphQLRouter(), new _PurgeRouter.PurgeRouter(), new _HooksRouter.HooksRouter(), new _CloudCodeRouter.CloudCodeRouter(), new _AudiencesRouter.AudiencesRouter(), new _AggregateRouter.AggregateRouter()]; + const routes = routers.reduce((memo, router) => { + return memo.concat(router.routes); + }, []); + const appRouter = new _PromiseRouter.default(routes, appId); + batch.mountOnto(appRouter); + return appRouter; + } + /** + * starts the parse server's express app + * @param {ParseServerOptions} options to use to start the server + * @param {Function} callback called when the server has started + * @returns {ParseServer} the parse server instance + */ + + + start(options, callback) { + const app = express(); + + if (options.middleware) { + let middleware; + + if (typeof options.middleware == 'string') { + middleware = require(path.resolve(process.cwd(), options.middleware)); + } else { + middleware = options.middleware; // use as-is let express fail + } + + app.use(middleware); + } + + app.use(options.mountPath, this.app); + + if (options.mountGraphQL === true || options.mountPlayground === true) { + let graphQLCustomTypeDefs = undefined; + + if (typeof options.graphQLSchema === 'string') { + graphQLCustomTypeDefs = parse(fs.readFileSync(options.graphQLSchema, 'utf8')); + } else if (typeof options.graphQLSchema === 'object' || typeof options.graphQLSchema === 'function') { + graphQLCustomTypeDefs = options.graphQLSchema; + } + + const parseGraphQLServer = new _ParseGraphQLServer.ParseGraphQLServer(this, { + graphQLPath: options.graphQLPath, + playgroundPath: options.playgroundPath, + graphQLCustomTypeDefs + }); + + if (options.mountGraphQL) { + parseGraphQLServer.applyGraphQL(app); + } + + if (options.mountPlayground) { + parseGraphQLServer.applyPlayground(app); + } + } + + const server = app.listen(options.port, options.host, callback); + this.server = server; + + if (options.startLiveQueryServer || options.liveQueryServerOptions) { + this.liveQueryServer = ParseServer.createLiveQueryServer(server, options.liveQueryServerOptions, options); + } + /* istanbul ignore next */ + + + if (!process.env.TESTING) { + configureListeners(this); + } + + this.expressApp = app; + return this; + } + /** + * Creates a new ParseServer and starts it. + * @param {ParseServerOptions} options used to start the server + * @param {Function} callback called when the server has started + * @returns {ParseServer} the parse server instance + */ + + + static start(options, callback) { + const parseServer = new ParseServer(options); + return parseServer.start(options, callback); + } + /** + * Helper method to create a liveQuery server + * @static + * @param {Server} httpServer an optional http server to pass + * @param {LiveQueryServerOptions} config options for the liveQueryServer + * @param {ParseServerOptions} options options for the ParseServer + * @returns {ParseLiveQueryServer} the live query server instance + */ + + + static createLiveQueryServer(httpServer, config, options) { + if (!httpServer || config && config.port) { + var app = express(); + httpServer = require('http').createServer(app); + httpServer.listen(config.port); + } + + return new _ParseLiveQueryServer.ParseLiveQueryServer(httpServer, config, options); + } + + static verifyServerUrl(callback) { + // perform a health check on the serverURL value + if (Parse.serverURL) { + const request = require('./request'); + + request({ + url: Parse.serverURL.replace(/\/$/, '') + '/health' + }).catch(response => response).then(response => { + const json = response.data || null; + + if (response.status !== 200 || !json || json && json.status !== 'ok') { + /* eslint-disable no-console */ + console.warn(`\nWARNING, Unable to connect to '${Parse.serverURL}'.` + ` Cloud code and push notifications may be unavailable!\n`); + /* eslint-enable no-console */ + + if (callback) { + callback(false); + } + } else { + if (callback) { + callback(true); + } + } + }); + } + } + +} + +function addParseCloud() { + const ParseCloud = require('./cloud-code/Parse.Cloud'); + + Object.assign(Parse.Cloud, ParseCloud); + global.Parse = Parse; +} + +function injectDefaults(options) { + Object.keys(_defaults.default).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(options, key)) { + options[key] = _defaults.default[key]; + } + }); + + if (!Object.prototype.hasOwnProperty.call(options, 'serverURL')) { + options.serverURL = `http://localhost:${options.port}${options.mountPath}`; + } // Reserved Characters + + + if (options.appId) { + const regex = /[!#$%'()*+&/:;=?@[\]{}^,|<>]/g; + + if (options.appId.match(regex)) { + console.warn(`\nWARNING, appId that contains special characters can cause issues while using with urls.\n`); + } + } // Backwards compatibility + + + if (options.userSensitiveFields) { + /* eslint-disable no-console */ + !process.env.TESTING && console.warn(`\nDEPRECATED: userSensitiveFields has been replaced by protectedFields allowing the ability to protect fields in all classes with CLP. \n`); + /* eslint-enable no-console */ + + const userSensitiveFields = Array.from(new Set([...(_defaults.default.userSensitiveFields || []), ...(options.userSensitiveFields || [])])); // If the options.protectedFields is unset, + // it'll be assigned the default above. + // Here, protect against the case where protectedFields + // is set, but doesn't have _User. + + if (!('_User' in options.protectedFields)) { + options.protectedFields = Object.assign({ + _User: [] + }, options.protectedFields); + } + + options.protectedFields['_User']['*'] = Array.from(new Set([...(options.protectedFields['_User']['*'] || []), ...userSensitiveFields])); + } // Merge protectedFields options with defaults. + + + Object.keys(_defaults.default.protectedFields).forEach(c => { + const cur = options.protectedFields[c]; + + if (!cur) { + options.protectedFields[c] = _defaults.default.protectedFields[c]; + } else { + Object.keys(_defaults.default.protectedFields[c]).forEach(r => { + const unq = new Set([...(options.protectedFields[c][r] || []), ..._defaults.default.protectedFields[c][r]]); + options.protectedFields[c][r] = Array.from(unq); + }); + } + }); + options.masterKeyIps = Array.from(new Set(options.masterKeyIps.concat(_defaults.default.masterKeyIps, options.masterKeyIps))); +} // Those can't be tested as it requires a subprocess + +/* istanbul ignore next */ + + +function configureListeners(parseServer) { + const server = parseServer.server; + const sockets = {}; + /* Currently, express doesn't shut down immediately after receiving SIGINT/SIGTERM if it has client connections that haven't timed out. (This is a known issue with node - https://github.com/nodejs/node/issues/2642) + This function, along with `destroyAliveConnections()`, intend to fix this behavior such that parse server will close all open connections and initiate the shutdown process as soon as it receives a SIGINT/SIGTERM signal. */ + + server.on('connection', socket => { + const socketId = socket.remoteAddress + ':' + socket.remotePort; + sockets[socketId] = socket; + socket.on('close', () => { + delete sockets[socketId]; + }); + }); + + const destroyAliveConnections = function () { + for (const socketId in sockets) { + try { + sockets[socketId].destroy(); + } catch (e) { + /* */ + } + } + }; + + const handleShutdown = function () { + process.stdout.write('Termination signal received. Shutting down.'); + destroyAliveConnections(); + server.close(); + parseServer.handleShutdown(); + }; + + process.on('SIGTERM', handleShutdown); + process.on('SIGINT', handleShutdown); +} + +var _default = ParseServer; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlci5qcyJdLCJuYW1lcyI6WyJiYXRjaCIsInJlcXVpcmUiLCJib2R5UGFyc2VyIiwiZXhwcmVzcyIsIm1pZGRsZXdhcmVzIiwiUGFyc2UiLCJwYXJzZSIsInBhdGgiLCJmcyIsImFkZFBhcnNlQ2xvdWQiLCJQYXJzZVNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImluamVjdERlZmF1bHRzIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJjbG91ZCIsImphdmFzY3JpcHRLZXkiLCJzZXJ2ZXJVUkwiLCJzZXJ2ZXJTdGFydENvbXBsZXRlIiwiaW5pdGlhbGl6ZSIsImFsbENvbnRyb2xsZXJzIiwiY29udHJvbGxlcnMiLCJnZXRDb250cm9sbGVycyIsImxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJob29rc0NvbnRyb2xsZXIiLCJjb25maWciLCJDb25maWciLCJwdXQiLCJPYmplY3QiLCJhc3NpZ24iLCJsb2dnaW5nIiwic2V0TG9nZ2VyIiwiZGJJbml0UHJvbWlzZSIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsImhvb2tzTG9hZFByb21pc2UiLCJsb2FkIiwiUHJvbWlzZSIsImFsbCIsInRoZW4iLCJjYXRjaCIsImVycm9yIiwiY29uc29sZSIsInByb2Nlc3MiLCJleGl0IiwicmVzb2x2ZSIsImN3ZCIsImFwcCIsIl9hcHAiLCJoYW5kbGVTaHV0ZG93biIsInByb21pc2VzIiwiYWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInB1c2giLCJmaWxlQWRhcHRlciIsImZpbGVzQ29udHJvbGxlciIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsImxlbmd0aCIsInNlcnZlckNsb3NlQ29tcGxldGUiLCJtYXhVcGxvYWRTaXplIiwiZGlyZWN0QWNjZXNzIiwiYXBpIiwidXNlIiwiYWxsb3dDcm9zc0RvbWFpbiIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsInJlcSIsInJlcyIsImpzb24iLCJzdGF0dXMiLCJ1cmxlbmNvZGVkIiwiZXh0ZW5kZWQiLCJQdWJsaWNBUElSb3V0ZXIiLCJ0eXBlIiwibGltaXQiLCJhbGxvd01ldGhvZE92ZXJyaWRlIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiYXBwUm91dGVyIiwicHJvbWlzZVJvdXRlciIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZW52IiwiVEVTVElORyIsIm9uIiwiZXJyIiwiY29kZSIsInN0ZGVyciIsIndyaXRlIiwicG9ydCIsInZlcmlmeVNlcnZlclVybCIsIlBBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MiLCJDb3JlTWFuYWdlciIsInNldFJFU1RDb250cm9sbGVyIiwicm91dGVycyIsIkNsYXNzZXNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsIlNlc3Npb25zUm91dGVyIiwiUm9sZXNSb3V0ZXIiLCJBbmFseXRpY3NSb3V0ZXIiLCJJbnN0YWxsYXRpb25zUm91dGVyIiwiRnVuY3Rpb25zUm91dGVyIiwiU2NoZW1hc1JvdXRlciIsIlB1c2hSb3V0ZXIiLCJMb2dzUm91dGVyIiwiSUFQVmFsaWRhdGlvblJvdXRlciIsIkZlYXR1cmVzUm91dGVyIiwiR2xvYmFsQ29uZmlnUm91dGVyIiwiR3JhcGhRTFJvdXRlciIsIlB1cmdlUm91dGVyIiwiSG9va3NSb3V0ZXIiLCJDbG91ZENvZGVSb3V0ZXIiLCJBdWRpZW5jZXNSb3V0ZXIiLCJBZ2dyZWdhdGVSb3V0ZXIiLCJyb3V0ZXMiLCJyZWR1Y2UiLCJtZW1vIiwicm91dGVyIiwiY29uY2F0IiwiUHJvbWlzZVJvdXRlciIsIm1vdW50T250byIsInN0YXJ0IiwiY2FsbGJhY2siLCJtaWRkbGV3YXJlIiwibW91bnRQYXRoIiwibW91bnRHcmFwaFFMIiwibW91bnRQbGF5Z3JvdW5kIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWZzIiwidW5kZWZpbmVkIiwiZ3JhcGhRTFNjaGVtYSIsInJlYWRGaWxlU3luYyIsInBhcnNlR3JhcGhRTFNlcnZlciIsIlBhcnNlR3JhcGhRTFNlcnZlciIsImdyYXBoUUxQYXRoIiwicGxheWdyb3VuZFBhdGgiLCJhcHBseUdyYXBoUUwiLCJhcHBseVBsYXlncm91bmQiLCJzZXJ2ZXIiLCJsaXN0ZW4iLCJob3N0Iiwic3RhcnRMaXZlUXVlcnlTZXJ2ZXIiLCJsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIiwibGl2ZVF1ZXJ5U2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwiY29uZmlndXJlTGlzdGVuZXJzIiwiZXhwcmVzc0FwcCIsInBhcnNlU2VydmVyIiwiaHR0cFNlcnZlciIsImNyZWF0ZVNlcnZlciIsIlBhcnNlTGl2ZVF1ZXJ5U2VydmVyIiwicmVxdWVzdCIsInVybCIsInJlcGxhY2UiLCJyZXNwb25zZSIsImRhdGEiLCJ3YXJuIiwiUGFyc2VDbG91ZCIsIkNsb3VkIiwiZ2xvYmFsIiwia2V5cyIsImRlZmF1bHRzIiwiZm9yRWFjaCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlZ2V4IiwibWF0Y2giLCJ1c2VyU2Vuc2l0aXZlRmllbGRzIiwiQXJyYXkiLCJmcm9tIiwiU2V0IiwicHJvdGVjdGVkRmllbGRzIiwiX1VzZXIiLCJjIiwiY3VyIiwiciIsInVucSIsIm1hc3RlcktleUlwcyIsInNvY2tldHMiLCJzb2NrZXQiLCJzb2NrZXRJZCIsInJlbW90ZUFkZHJlc3MiLCJyZW1vdGVQb3J0IiwiZGVzdHJveUFsaXZlQ29ubmVjdGlvbnMiLCJkZXN0cm95IiwiZSIsInN0ZG91dCIsImNsb3NlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBV0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBekNBO0FBRUEsSUFBSUEs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QmxDLGNBQXRCO0FBQ0FOLEVBQUFBLE9BQU8sQ0FBQ3dDLEVBQVIsQ0FBVyxRQUFYLEVBQXFCbEMsY0FBckI7QUFDRDs7ZUFFY3hDLFciLCJzb3VyY2VzQ29udGVudCI6WyIvLyBQYXJzZVNlcnZlciAtIG9wZW4tc291cmNlIGNvbXBhdGlibGUgQVBJIFNlcnZlciBmb3IgUGFyc2UgYXBwc1xuXG52YXIgYmF0Y2ggPSByZXF1aXJlKCcuL2JhdGNoJyksXG4gIGJvZHlQYXJzZXIgPSByZXF1aXJlKCdib2R5LXBhcnNlcicpLFxuICBleHByZXNzID0gcmVxdWlyZSgnZXhwcmVzcycpLFxuICBtaWRkbGV3YXJlcyA9IHJlcXVpcmUoJy4vbWlkZGxld2FyZXMnKSxcbiAgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2UsXG4gIHsgcGFyc2UgfSA9IHJlcXVpcmUoJ2dyYXBocWwnKSxcbiAgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKSxcbiAgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5pbXBvcnQgeyBQYXJzZVNlcnZlck9wdGlvbnMsIExpdmVRdWVyeVNlcnZlck9wdGlvbnMgfSBmcm9tICcuL09wdGlvbnMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4vZGVmYXVsdHMnO1xuaW1wb3J0ICogYXMgbG9nZ2luZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vQ29uZmlnJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi9yZXF1aXJlZFBhcmFtZXRlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQW5hbHl0aWNzUm91dGVyJztcbmltcG9ydCB7IENsYXNzZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgeyBGZWF0dXJlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9GZWF0dXJlc1JvdXRlcic7XG5pbXBvcnQgeyBGaWxlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9GaWxlc1JvdXRlcic7XG5pbXBvcnQgeyBGdW5jdGlvbnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRnVuY3Rpb25zUm91dGVyJztcbmltcG9ydCB7IEdsb2JhbENvbmZpZ1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9HbG9iYWxDb25maWdSb3V0ZXInO1xuaW1wb3J0IHsgR3JhcGhRTFJvdXRlciB9IGZyb20gJy4vUm91dGVycy9HcmFwaFFMUm91dGVyJztcbmltcG9ydCB7IEhvb2tzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0hvb2tzUm91dGVyJztcbmltcG9ydCB7IElBUFZhbGlkYXRpb25Sb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvSUFQVmFsaWRhdGlvblJvdXRlcic7XG5pbXBvcnQgeyBJbnN0YWxsYXRpb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0luc3RhbGxhdGlvbnNSb3V0ZXInO1xuaW1wb3J0IHsgTG9nc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Mb2dzUm91dGVyJztcbmltcG9ydCB7IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIH0gZnJvbSAnLi9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXInO1xuaW1wb3J0IHsgUHVibGljQVBJUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1YmxpY0FQSVJvdXRlcic7XG5pbXBvcnQgeyBQdXNoUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1c2hSb3V0ZXInO1xuaW1wb3J0IHsgQ2xvdWRDb2RlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0Nsb3VkQ29kZVJvdXRlcic7XG5pbXBvcnQgeyBSb2xlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Sb2xlc1JvdXRlcic7XG5pbXBvcnQgeyBTY2hlbWFzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1NjaGVtYXNSb3V0ZXInO1xuaW1wb3J0IHsgU2Vzc2lvbnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvU2Vzc2lvbnNSb3V0ZXInO1xuaW1wb3J0IHsgVXNlcnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvVXNlcnNSb3V0ZXInO1xuaW1wb3J0IHsgUHVyZ2VSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUHVyZ2VSb3V0ZXInO1xuaW1wb3J0IHsgQXVkaWVuY2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0F1ZGllbmNlc1JvdXRlcic7XG5pbXBvcnQgeyBBZ2dyZWdhdGVSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQWdncmVnYXRlUm91dGVyJztcbmltcG9ydCB7IFBhcnNlU2VydmVyUkVTVENvbnRyb2xsZXIgfSBmcm9tICcuL1BhcnNlU2VydmVyUkVTVENvbnRyb2xsZXInO1xuaW1wb3J0ICogYXMgY29udHJvbGxlcnMgZnJvbSAnLi9Db250cm9sbGVycyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxTZXJ2ZXIgfSBmcm9tICcuL0dyYXBoUUwvUGFyc2VHcmFwaFFMU2VydmVyJztcblxuLy8gTXV0YXRlIHRoZSBQYXJzZSBvYmplY3QgdG8gYWRkIHRoZSBDbG91ZCBDb2RlIGhhbmRsZXJzXG5hZGRQYXJzZUNsb3VkKCk7XG5cbi8vIFBhcnNlU2VydmVyIHdvcmtzIGxpa2UgYSBjb25zdHJ1Y3RvciBvZiBhbiBleHByZXNzIGFwcC5cbi8vIGh0dHBzOi8vcGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2FwaS9tYXN0ZXIvUGFyc2VTZXJ2ZXJPcHRpb25zLmh0bWxcbmNsYXNzIFBhcnNlU2VydmVyIHtcbiAgLyoqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1BhcnNlU2VydmVyT3B0aW9uc30gb3B0aW9ucyB0aGUgcGFyc2Ugc2VydmVyIGluaXRpYWxpemF0aW9uIG9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICAgIGluamVjdERlZmF1bHRzKG9wdGlvbnMpO1xuICAgIGNvbnN0IHtcbiAgICAgIGFwcElkID0gcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYW4gYXBwSWQhJyksXG4gICAgICBtYXN0ZXJLZXkgPSByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIG1hc3RlcktleSEnKSxcbiAgICAgIGNsb3VkLFxuICAgICAgamF2YXNjcmlwdEtleSxcbiAgICAgIHNlcnZlclVSTCA9IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgc2VydmVyVVJMIScpLFxuICAgICAgc2VydmVyU3RhcnRDb21wbGV0ZSxcbiAgICB9ID0gb3B0aW9ucztcbiAgICAvLyBJbml0aWFsaXplIHRoZSBub2RlIGNsaWVudCBTREsgYXV0b21hdGljYWxseVxuICAgIFBhcnNlLmluaXRpYWxpemUoYXBwSWQsIGphdmFzY3JpcHRLZXkgfHwgJ3VudXNlZCcsIG1hc3RlcktleSk7XG4gICAgUGFyc2Uuc2VydmVyVVJMID0gc2VydmVyVVJMO1xuXG4gICAgY29uc3QgYWxsQ29udHJvbGxlcnMgPSBjb250cm9sbGVycy5nZXRDb250cm9sbGVycyhvcHRpb25zKTtcblxuICAgIGNvbnN0IHsgbG9nZ2VyQ29udHJvbGxlciwgZGF0YWJhc2VDb250cm9sbGVyLCBob29rc0NvbnRyb2xsZXIgfSA9IGFsbENvbnRyb2xsZXJzO1xuICAgIHRoaXMuY29uZmlnID0gQ29uZmlnLnB1dChPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCBhbGxDb250cm9sbGVycykpO1xuXG4gICAgbG9nZ2luZy5zZXRMb2dnZXIobG9nZ2VyQ29udHJvbGxlcik7XG4gICAgY29uc3QgZGJJbml0UHJvbWlzZSA9IGRhdGFiYXNlQ29udHJvbGxlci5wZXJmb3JtSW5pdGlhbGl6YXRpb24oKTtcbiAgICBjb25zdCBob29rc0xvYWRQcm9taXNlID0gaG9va3NDb250cm9sbGVyLmxvYWQoKTtcblxuICAgIC8vIE5vdGU6IFRlc3RzIHdpbGwgc3RhcnQgdG8gZmFpbCBpZiBhbnkgdmFsaWRhdGlvbiBoYXBwZW5zIGFmdGVyIHRoaXMgaXMgY2FsbGVkLlxuICAgIFByb21pc2UuYWxsKFtkYkluaXRQcm9taXNlLCBob29rc0xvYWRQcm9taXNlXSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHNlcnZlclN0YXJ0Q29tcGxldGUpIHtcbiAgICAgICAgICBzZXJ2ZXJTdGFydENvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoc2VydmVyU3RhcnRDb21wbGV0ZSkge1xuICAgICAgICAgIHNlcnZlclN0YXJ0Q29tcGxldGUoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZiAoY2xvdWQpIHtcbiAgICAgIGFkZFBhcnNlQ2xvdWQoKTtcbiAgICAgIGlmICh0eXBlb2YgY2xvdWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY2xvdWQoUGFyc2UpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY2xvdWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlcXVpcmUocGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGNsb3VkKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBcImFyZ3VtZW50ICdjbG91ZCcgbXVzdCBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvblwiO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBhcHAoKSB7XG4gICAgaWYgKCF0aGlzLl9hcHApIHtcbiAgICAgIHRoaXMuX2FwcCA9IFBhcnNlU2VydmVyLmFwcCh0aGlzLmNvbmZpZyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hcHA7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgIGNvbnN0IHsgYWRhcHRlcjogZGF0YWJhc2VBZGFwdGVyIH0gPSB0aGlzLmNvbmZpZy5kYXRhYmFzZUNvbnRyb2xsZXI7XG4gICAgaWYgKGRhdGFiYXNlQWRhcHRlciAmJiB0eXBlb2YgZGF0YWJhc2VBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGRhdGFiYXNlQWRhcHRlci5oYW5kbGVTaHV0ZG93bigpKTtcbiAgICB9XG4gICAgY29uc3QgeyBhZGFwdGVyOiBmaWxlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuZmlsZXNDb250cm9sbGVyO1xuICAgIGlmIChmaWxlQWRhcHRlciAmJiB0eXBlb2YgZmlsZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHByb21pc2VzLnB1c2goZmlsZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgYWRhcHRlcjogY2FjaGVBZGFwdGVyIH0gPSB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXI7XG4gICAgaWYgKGNhY2hlQWRhcHRlciAmJiB0eXBlb2YgY2FjaGVBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGNhY2hlQWRhcHRlci5oYW5kbGVTaHV0ZG93bigpKTtcbiAgICB9XG4gICAgcmV0dXJuIChwcm9taXNlcy5sZW5ndGggPiAwID8gUHJvbWlzZS5hbGwocHJvbWlzZXMpIDogUHJvbWlzZS5yZXNvbHZlKCkpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY29uZmlnLnNlcnZlckNsb3NlQ29tcGxldGUpIHtcbiAgICAgICAgdGhpcy5jb25maWcuc2VydmVyQ2xvc2VDb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQ3JlYXRlIGFuIGV4cHJlc3MgYXBwIGZvciB0aGUgcGFyc2Ugc2VydmVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGxldCB5b3Ugc3BlY2lmeSB0aGUgbWF4VXBsb2FkU2l6ZSB3aGVuIGNyZWF0aW5nIHRoZSBleHByZXNzIGFwcCAgKi9cbiAgc3RhdGljIGFwcCh7IG1heFVwbG9hZFNpemUgPSAnMjBtYicsIGFwcElkLCBkaXJlY3RBY2Nlc3MgfSkge1xuICAgIC8vIFRoaXMgYXBwIHNlcnZlcyB0aGUgUGFyc2UgQVBJIGRpcmVjdGx5LlxuICAgIC8vIEl0J3MgdGhlIGVxdWl2YWxlbnQgb2YgaHR0cHM6Ly9hcGkucGFyc2UuY29tLzEgaW4gdGhlIGhvc3RlZCBQYXJzZSBBUEkuXG4gICAgdmFyIGFwaSA9IGV4cHJlc3MoKTtcbiAgICAvL2FwaS51c2UoXCIvYXBwc1wiLCBleHByZXNzLnN0YXRpYyhfX2Rpcm5hbWUgKyBcIi9wdWJsaWNcIikpO1xuICAgIGFwaS51c2UobWlkZGxld2FyZXMuYWxsb3dDcm9zc0RvbWFpbihhcHBJZCkpO1xuICAgIC8vIEZpbGUgaGFuZGxpbmcgbmVlZHMgdG8gYmUgYmVmb3JlIGRlZmF1bHQgbWlkZGxld2FyZXMgYXJlIGFwcGxpZWRcbiAgICBhcGkudXNlKFxuICAgICAgJy8nLFxuICAgICAgbmV3IEZpbGVzUm91dGVyKCkuZXhwcmVzc1JvdXRlcih7XG4gICAgICAgIG1heFVwbG9hZFNpemU6IG1heFVwbG9hZFNpemUsXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBhcGkudXNlKCcvaGVhbHRoJywgZnVuY3Rpb24gKHJlcSwgcmVzKSB7XG4gICAgICByZXMuanNvbih7XG4gICAgICAgIHN0YXR1czogJ29rJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYXBpLnVzZSgnLycsIGJvZHlQYXJzZXIudXJsZW5jb2RlZCh7IGV4dGVuZGVkOiBmYWxzZSB9KSwgbmV3IFB1YmxpY0FQSVJvdXRlcigpLmV4cHJlc3NSb3V0ZXIoKSk7XG5cbiAgICBhcGkudXNlKGJvZHlQYXJzZXIuanNvbih7IHR5cGU6ICcqLyonLCBsaW1pdDogbWF4VXBsb2FkU2l6ZSB9KSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5hbGxvd01ldGhvZE92ZXJyaWRlKTtcbiAgICBhcGkudXNlKG1pZGRsZXdhcmVzLmhhbmRsZVBhcnNlSGVhZGVycyk7XG5cbiAgICBjb25zdCBhcHBSb3V0ZXIgPSBQYXJzZVNlcnZlci5wcm9taXNlUm91dGVyKHsgYXBwSWQgfSk7XG4gICAgYXBpLnVzZShhcHBSb3V0ZXIuZXhwcmVzc1JvdXRlcigpKTtcblxuICAgIGFwaS51c2UobWlkZGxld2FyZXMuaGFuZGxlUGFyc2VFcnJvcnMpO1xuXG4gICAgLy8gcnVuIHRoZSBmb2xsb3dpbmcgd2hlbiBub3QgdGVzdGluZ1xuICAgIGlmICghcHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgICAgLy9UaGlzIGNhdXNlcyB0ZXN0cyB0byBzcGV3IHNvbWUgdXNlbGVzcyB3YXJuaW5ncywgc28gZGlzYWJsZSBpbiB0ZXN0XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09ICdFQUREUklOVVNFJykge1xuICAgICAgICAgIC8vIHVzZXItZnJpZW5kbHkgbWVzc2FnZSBmb3IgdGhpcyBjb21tb24gZXJyb3JcbiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgVW5hYmxlIHRvIGxpc3RlbiBvbiBwb3J0ICR7ZXJyLnBvcnR9LiBUaGUgcG9ydCBpcyBhbHJlYWR5IGluIHVzZS5gKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIHZlcmlmeSB0aGUgc2VydmVyIHVybCBhZnRlciBhICdtb3VudCcgZXZlbnQgaXMgcmVjZWl2ZWRcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBhcGkub24oJ21vdW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBQYXJzZVNlcnZlci52ZXJpZnlTZXJ2ZXJVcmwoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBFUklNRU5UQUxfRElSRUNUX0FDQ0VTUyA9PT0gJzEnIHx8IGRpcmVjdEFjY2Vzcykge1xuICAgICAgUGFyc2UuQ29yZU1hbmFnZXIuc2V0UkVTVENvbnRyb2xsZXIoUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcihhcHBJZCwgYXBwUm91dGVyKSk7XG4gICAgfVxuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBzdGF0aWMgcHJvbWlzZVJvdXRlcih7IGFwcElkIH0pIHtcbiAgICBjb25zdCByb3V0ZXJzID0gW1xuICAgICAgbmV3IENsYXNzZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBVc2Vyc1JvdXRlcigpLFxuICAgICAgbmV3IFNlc3Npb25zUm91dGVyKCksXG4gICAgICBuZXcgUm9sZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBBbmFseXRpY3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBJbnN0YWxsYXRpb25zUm91dGVyKCksXG4gICAgICBuZXcgRnVuY3Rpb25zUm91dGVyKCksXG4gICAgICBuZXcgU2NoZW1hc1JvdXRlcigpLFxuICAgICAgbmV3IFB1c2hSb3V0ZXIoKSxcbiAgICAgIG5ldyBMb2dzUm91dGVyKCksXG4gICAgICBuZXcgSUFQVmFsaWRhdGlvblJvdXRlcigpLFxuICAgICAgbmV3IEZlYXR1cmVzUm91dGVyKCksXG4gICAgICBuZXcgR2xvYmFsQ29uZmlnUm91dGVyKCksXG4gICAgICBuZXcgR3JhcGhRTFJvdXRlcigpLFxuICAgICAgbmV3IFB1cmdlUm91dGVyKCksXG4gICAgICBuZXcgSG9va3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBDbG91ZENvZGVSb3V0ZXIoKSxcbiAgICAgIG5ldyBBdWRpZW5jZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBBZ2dyZWdhdGVSb3V0ZXIoKSxcbiAgICBdO1xuXG4gICAgY29uc3Qgcm91dGVzID0gcm91dGVycy5yZWR1Y2UoKG1lbW8sIHJvdXRlcikgPT4ge1xuICAgICAgcmV0dXJuIG1lbW8uY29uY2F0KHJvdXRlci5yb3V0ZXMpO1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IGFwcFJvdXRlciA9IG5ldyBQcm9taXNlUm91dGVyKHJvdXRlcywgYXBwSWQpO1xuXG4gICAgYmF0Y2gubW91bnRPbnRvKGFwcFJvdXRlcik7XG4gICAgcmV0dXJuIGFwcFJvdXRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBzdGFydHMgdGhlIHBhcnNlIHNlcnZlcidzIGV4cHJlc3MgYXBwXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIHRvIHVzZSB0byBzdGFydCB0aGUgc2VydmVyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGNhbGxlZCB3aGVuIHRoZSBzZXJ2ZXIgaGFzIHN0YXJ0ZWRcbiAgICogQHJldHVybnMge1BhcnNlU2VydmVyfSB0aGUgcGFyc2Ugc2VydmVyIGluc3RhbmNlXG4gICAqL1xuICBzdGFydChvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsIGNhbGxiYWNrOiA/KCkgPT4gdm9pZCkge1xuICAgIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcbiAgICBpZiAob3B0aW9ucy5taWRkbGV3YXJlKSB7XG4gICAgICBsZXQgbWlkZGxld2FyZTtcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5taWRkbGV3YXJlID09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1pZGRsZXdhcmUgPSByZXF1aXJlKHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBvcHRpb25zLm1pZGRsZXdhcmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pZGRsZXdhcmUgPSBvcHRpb25zLm1pZGRsZXdhcmU7IC8vIHVzZSBhcy1pcyBsZXQgZXhwcmVzcyBmYWlsXG4gICAgICB9XG4gICAgICBhcHAudXNlKG1pZGRsZXdhcmUpO1xuICAgIH1cblxuICAgIGFwcC51c2Uob3B0aW9ucy5tb3VudFBhdGgsIHRoaXMuYXBwKTtcblxuICAgIGlmIChvcHRpb25zLm1vdW50R3JhcGhRTCA9PT0gdHJ1ZSB8fCBvcHRpb25zLm1vdW50UGxheWdyb3VuZCA9PT0gdHJ1ZSkge1xuICAgICAgbGV0IGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5ncmFwaFFMU2NoZW1hID09PSAnc3RyaW5nJykge1xuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSBwYXJzZShmcy5yZWFkRmlsZVN5bmMob3B0aW9ucy5ncmFwaFFMU2NoZW1hLCAndXRmOCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdvYmplY3QnIHx8XG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSBvcHRpb25zLmdyYXBoUUxTY2hlbWE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcnNlR3JhcGhRTFNlcnZlciA9IG5ldyBQYXJzZUdyYXBoUUxTZXJ2ZXIodGhpcywge1xuICAgICAgICBncmFwaFFMUGF0aDogb3B0aW9ucy5ncmFwaFFMUGF0aCxcbiAgICAgICAgcGxheWdyb3VuZFBhdGg6IG9wdGlvbnMucGxheWdyb3VuZFBhdGgsXG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2VydmVyLmFwcGx5R3JhcGhRTChhcHApO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5tb3VudFBsYXlncm91bmQpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2VydmVyLmFwcGx5UGxheWdyb3VuZChhcHApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNlcnZlciA9IGFwcC5saXN0ZW4ob3B0aW9ucy5wb3J0LCBvcHRpb25zLmhvc3QsIGNhbGxiYWNrKTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcblxuICAgIGlmIChvcHRpb25zLnN0YXJ0TGl2ZVF1ZXJ5U2VydmVyIHx8IG9wdGlvbnMubGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucykge1xuICAgICAgdGhpcy5saXZlUXVlcnlTZXJ2ZXIgPSBQYXJzZVNlcnZlci5jcmVhdGVMaXZlUXVlcnlTZXJ2ZXIoXG4gICAgICAgIHNlcnZlcixcbiAgICAgICAgb3B0aW9ucy5saXZlUXVlcnlTZXJ2ZXJPcHRpb25zLFxuICAgICAgICBvcHRpb25zXG4gICAgICApO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmICghcHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgICAgY29uZmlndXJlTGlzdGVuZXJzKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLmV4cHJlc3NBcHAgPSBhcHA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBQYXJzZVNlcnZlciBhbmQgc3RhcnRzIGl0LlxuICAgKiBAcGFyYW0ge1BhcnNlU2VydmVyT3B0aW9uc30gb3B0aW9ucyB1c2VkIHRvIHN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHNlcnZlciBoYXMgc3RhcnRlZFxuICAgKiBAcmV0dXJucyB7UGFyc2VTZXJ2ZXJ9IHRoZSBwYXJzZSBzZXJ2ZXIgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBzdGFydChvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsIGNhbGxiYWNrOiA/KCkgPT4gdm9pZCkge1xuICAgIGNvbnN0IHBhcnNlU2VydmVyID0gbmV3IFBhcnNlU2VydmVyKG9wdGlvbnMpO1xuICAgIHJldHVybiBwYXJzZVNlcnZlci5zdGFydChvcHRpb25zLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIG1ldGhvZCB0byBjcmVhdGUgYSBsaXZlUXVlcnkgc2VydmVyXG4gICAqIEBzdGF0aWNcbiAgICogQHBhcmFtIHtTZXJ2ZXJ9IGh0dHBTZXJ2ZXIgYW4gb3B0aW9uYWwgaHR0cCBzZXJ2ZXIgdG8gcGFzc1xuICAgKiBAcGFyYW0ge0xpdmVRdWVyeVNlcnZlck9wdGlvbnN9IGNvbmZpZyBvcHRpb25zIGZvciB0aGUgbGl2ZVF1ZXJ5U2VydmVyXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIG9wdGlvbnMgZm9yIHRoZSBQYXJzZVNlcnZlclxuICAgKiBAcmV0dXJucyB7UGFyc2VMaXZlUXVlcnlTZXJ2ZXJ9IHRoZSBsaXZlIHF1ZXJ5IHNlcnZlciBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZUxpdmVRdWVyeVNlcnZlcihcbiAgICBodHRwU2VydmVyLFxuICAgIGNvbmZpZzogTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyxcbiAgICBvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnNcbiAgKSB7XG4gICAgaWYgKCFodHRwU2VydmVyIHx8IChjb25maWcgJiYgY29uZmlnLnBvcnQpKSB7XG4gICAgICB2YXIgYXBwID0gZXhwcmVzcygpO1xuICAgICAgaHR0cFNlcnZlciA9IHJlcXVpcmUoJ2h0dHAnKS5jcmVhdGVTZXJ2ZXIoYXBwKTtcbiAgICAgIGh0dHBTZXJ2ZXIubGlzdGVuKGNvbmZpZy5wb3J0KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQYXJzZUxpdmVRdWVyeVNlcnZlcihodHRwU2VydmVyLCBjb25maWcsIG9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIHZlcmlmeVNlcnZlclVybChjYWxsYmFjaykge1xuICAgIC8vIHBlcmZvcm0gYSBoZWFsdGggY2hlY2sgb24gdGhlIHNlcnZlclVSTCB2YWx1ZVxuICAgIGlmIChQYXJzZS5zZXJ2ZXJVUkwpIHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSByZXF1aXJlKCcuL3JlcXVlc3QnKTtcbiAgICAgIHJlcXVlc3QoeyB1cmw6IFBhcnNlLnNlcnZlclVSTC5yZXBsYWNlKC9cXC8kLywgJycpICsgJy9oZWFsdGgnIH0pXG4gICAgICAgIC5jYXRjaChyZXNwb25zZSA9PiByZXNwb25zZSlcbiAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgIGNvbnN0IGpzb24gPSByZXNwb25zZS5kYXRhIHx8IG51bGw7XG4gICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwIHx8ICFqc29uIHx8IChqc29uICYmIGpzb24uc3RhdHVzICE9PSAnb2snKSkge1xuICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgXFxuV0FSTklORywgVW5hYmxlIHRvIGNvbm5lY3QgdG8gJyR7UGFyc2Uuc2VydmVyVVJMfScuYCArXG4gICAgICAgICAgICAgICAgYCBDbG91ZCBjb2RlIGFuZCBwdXNoIG5vdGlmaWNhdGlvbnMgbWF5IGJlIHVuYXZhaWxhYmxlIVxcbmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICBjYWxsYmFjayhmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICBjYWxsYmFjayh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRQYXJzZUNsb3VkKCkge1xuICBjb25zdCBQYXJzZUNsb3VkID0gcmVxdWlyZSgnLi9jbG91ZC1jb2RlL1BhcnNlLkNsb3VkJyk7XG4gIE9iamVjdC5hc3NpZ24oUGFyc2UuQ2xvdWQsIFBhcnNlQ2xvdWQpO1xuICBnbG9iYWwuUGFyc2UgPSBQYXJzZTtcbn1cblxuZnVuY3Rpb24gaW5qZWN0RGVmYXVsdHMob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKSB7XG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywga2V5KSkge1xuICAgICAgb3B0aW9uc1trZXldID0gZGVmYXVsdHNba2V5XTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMsICdzZXJ2ZXJVUkwnKSkge1xuICAgIG9wdGlvbnMuc2VydmVyVVJMID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRpb25zLnBvcnR9JHtvcHRpb25zLm1vdW50UGF0aH1gO1xuICB9XG5cbiAgLy8gUmVzZXJ2ZWQgQ2hhcmFjdGVyc1xuICBpZiAob3B0aW9ucy5hcHBJZCkge1xuICAgIGNvbnN0IHJlZ2V4ID0gL1shIyQlJygpKismLzo7PT9AW1xcXXt9Xix8PD5dL2c7XG4gICAgaWYgKG9wdGlvbnMuYXBwSWQubWF0Y2gocmVnZXgpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBcXG5XQVJOSU5HLCBhcHBJZCB0aGF0IGNvbnRhaW5zIHNwZWNpYWwgY2hhcmFjdGVycyBjYW4gY2F1c2UgaXNzdWVzIHdoaWxlIHVzaW5nIHdpdGggdXJscy5cXG5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gIGlmIChvcHRpb25zLnVzZXJTZW5zaXRpdmVGaWVsZHMpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgIXByb2Nlc3MuZW52LlRFU1RJTkcgJiZcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFxcbkRFUFJFQ0FURUQ6IHVzZXJTZW5zaXRpdmVGaWVsZHMgaGFzIGJlZW4gcmVwbGFjZWQgYnkgcHJvdGVjdGVkRmllbGRzIGFsbG93aW5nIHRoZSBhYmlsaXR5IHRvIHByb3RlY3QgZmllbGRzIGluIGFsbCBjbGFzc2VzIHdpdGggQ0xQLiBcXG5gXG4gICAgICApO1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuXG4gICAgY29uc3QgdXNlclNlbnNpdGl2ZUZpZWxkcyA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4oZGVmYXVsdHMudXNlclNlbnNpdGl2ZUZpZWxkcyB8fCBbXSksIC4uLihvcHRpb25zLnVzZXJTZW5zaXRpdmVGaWVsZHMgfHwgW10pXSlcbiAgICApO1xuXG4gICAgLy8gSWYgdGhlIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzIGlzIHVuc2V0LFxuICAgIC8vIGl0J2xsIGJlIGFzc2lnbmVkIHRoZSBkZWZhdWx0IGFib3ZlLlxuICAgIC8vIEhlcmUsIHByb3RlY3QgYWdhaW5zdCB0aGUgY2FzZSB3aGVyZSBwcm90ZWN0ZWRGaWVsZHNcbiAgICAvLyBpcyBzZXQsIGJ1dCBkb2Vzbid0IGhhdmUgX1VzZXIuXG4gICAgaWYgKCEoJ19Vc2VyJyBpbiBvcHRpb25zLnByb3RlY3RlZEZpZWxkcykpIHtcbiAgICAgIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzID0gT2JqZWN0LmFzc2lnbih7IF9Vc2VyOiBbXSB9LCBvcHRpb25zLnByb3RlY3RlZEZpZWxkcyk7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbJ19Vc2VyJ11bJyonXSA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4ob3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbJ19Vc2VyJ11bJyonXSB8fCBbXSksIC4uLnVzZXJTZW5zaXRpdmVGaWVsZHNdKVxuICAgICk7XG4gIH1cblxuICAvLyBNZXJnZSBwcm90ZWN0ZWRGaWVsZHMgb3B0aW9ucyB3aXRoIGRlZmF1bHRzLlxuICBPYmplY3Qua2V5cyhkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHMpLmZvckVhY2goYyA9PiB7XG4gICAgY29uc3QgY3VyID0gb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY107XG4gICAgaWYgKCFjdXIpIHtcbiAgICAgIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzW2NdID0gZGVmYXVsdHMucHJvdGVjdGVkRmllbGRzW2NdO1xuICAgIH0gZWxzZSB7XG4gICAgICBPYmplY3Qua2V5cyhkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY10pLmZvckVhY2gociA9PiB7XG4gICAgICAgIGNvbnN0IHVucSA9IG5ldyBTZXQoW1xuICAgICAgICAgIC4uLihvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXVtyXSB8fCBbXSksXG4gICAgICAgICAgLi4uZGVmYXVsdHMucHJvdGVjdGVkRmllbGRzW2NdW3JdLFxuICAgICAgICBdKTtcbiAgICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY11bcl0gPSBBcnJheS5mcm9tKHVucSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIG9wdGlvbnMubWFzdGVyS2V5SXBzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KG9wdGlvbnMubWFzdGVyS2V5SXBzLmNvbmNhdChkZWZhdWx0cy5tYXN0ZXJLZXlJcHMsIG9wdGlvbnMubWFzdGVyS2V5SXBzKSlcbiAgKTtcbn1cblxuLy8gVGhvc2UgY2FuJ3QgYmUgdGVzdGVkIGFzIGl0IHJlcXVpcmVzIGEgc3VicHJvY2Vzc1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGNvbmZpZ3VyZUxpc3RlbmVycyhwYXJzZVNlcnZlcikge1xuICBjb25zdCBzZXJ2ZXIgPSBwYXJzZVNlcnZlci5zZXJ2ZXI7XG4gIGNvbnN0IHNvY2tldHMgPSB7fTtcbiAgLyogQ3VycmVudGx5LCBleHByZXNzIGRvZXNuJ3Qgc2h1dCBkb3duIGltbWVkaWF0ZWx5IGFmdGVyIHJlY2VpdmluZyBTSUdJTlQvU0lHVEVSTSBpZiBpdCBoYXMgY2xpZW50IGNvbm5lY3Rpb25zIHRoYXQgaGF2ZW4ndCB0aW1lZCBvdXQuIChUaGlzIGlzIGEga25vd24gaXNzdWUgd2l0aCBub2RlIC0gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2lzc3Vlcy8yNjQyKVxuICAgIFRoaXMgZnVuY3Rpb24sIGFsb25nIHdpdGggYGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zKClgLCBpbnRlbmQgdG8gZml4IHRoaXMgYmVoYXZpb3Igc3VjaCB0aGF0IHBhcnNlIHNlcnZlciB3aWxsIGNsb3NlIGFsbCBvcGVuIGNvbm5lY3Rpb25zIGFuZCBpbml0aWF0ZSB0aGUgc2h1dGRvd24gcHJvY2VzcyBhcyBzb29uIGFzIGl0IHJlY2VpdmVzIGEgU0lHSU5UL1NJR1RFUk0gc2lnbmFsLiAqL1xuICBzZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCBzb2NrZXQgPT4ge1xuICAgIGNvbnN0IHNvY2tldElkID0gc29ja2V0LnJlbW90ZUFkZHJlc3MgKyAnOicgKyBzb2NrZXQucmVtb3RlUG9ydDtcbiAgICBzb2NrZXRzW3NvY2tldElkXSA9IHNvY2tldDtcbiAgICBzb2NrZXQub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgZGVsZXRlIHNvY2tldHNbc29ja2V0SWRdO1xuICAgIH0pO1xuICB9KTtcblxuICBjb25zdCBkZXN0cm95QWxpdmVDb25uZWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKGNvbnN0IHNvY2tldElkIGluIHNvY2tldHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNvY2tldHNbc29ja2V0SWRdLmRlc3Ryb3koKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogKi9cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlU2h1dGRvd24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoJ1Rlcm1pbmF0aW9uIHNpZ25hbCByZWNlaXZlZC4gU2h1dHRpbmcgZG93bi4nKTtcbiAgICBkZXN0cm95QWxpdmVDb25uZWN0aW9ucygpO1xuICAgIHNlcnZlci5jbG9zZSgpO1xuICAgIHBhcnNlU2VydmVyLmhhbmRsZVNodXRkb3duKCk7XG4gIH07XG4gIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBoYW5kbGVTaHV0ZG93bik7XG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsIGhhbmRsZVNodXRkb3duKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/ParseServerRESTController.js b/lib/ParseServerRESTController.js new file mode 100644 index 0000000000..9602de13a6 --- /dev/null +++ b/lib/ParseServerRESTController.js @@ -0,0 +1,184 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseServerRESTController = ParseServerRESTController; +exports.default = void 0; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const Config = require('./Config'); + +const Auth = require('./Auth'); + +const RESTController = require('parse/lib/node/RESTController'); + +const URL = require('url'); + +const Parse = require('parse/node'); + +function getSessionToken(options) { + if (options && typeof options.sessionToken === 'string') { + return Promise.resolve(options.sessionToken); + } + + return Promise.resolve(null); +} + +function getAuth(options = {}, config) { + const installationId = options.installationId || 'cloud'; + + if (options.useMasterKey) { + return Promise.resolve(new Auth.Auth({ + config, + isMaster: true, + installationId + })); + } + + return getSessionToken(options).then(sessionToken => { + if (sessionToken) { + options.sessionToken = sessionToken; + return Auth.getAuthForSessionToken({ + config, + sessionToken: sessionToken, + installationId + }); + } else { + return Promise.resolve(new Auth.Auth({ + config, + installationId + })); + } + }); +} + +function ParseServerRESTController(applicationId, router) { + function handleRequest(method, path, data = {}, options = {}, config) { + // Store the arguments, for later use if internal fails + const args = arguments; + + if (!config) { + config = Config.get(applicationId); + } + + const serverURL = URL.parse(config.serverURL); + + if (path.indexOf(serverURL.path) === 0) { + path = path.slice(serverURL.path.length, path.length); + } + + if (path[0] !== '/') { + path = '/' + path; + } + + if (path === '/batch') { + let initialPromise = Promise.resolve(); + + if (data.transaction === true) { + initialPromise = config.database.createTransactionalSession(); + } + + return initialPromise.then(() => { + const promises = data.requests.map(request => { + return handleRequest(request.method, request.path, request.body, options, config).then(response => { + if (options.returnStatus) { + const status = response._status; + delete response._status; + return { + success: response, + _status: status + }; + } + + return { + success: response + }; + }, error => { + return { + error: { + code: error.code, + error: error.message + } + }; + }); + }); + return Promise.all(promises).then(result => { + if (data.transaction === true) { + if (result.find(resultItem => typeof resultItem.error === 'object')) { + return config.database.abortTransactionalSession().then(() => { + return Promise.reject(result); + }); + } else { + return config.database.commitTransactionalSession().then(() => { + return result; + }); + } + } else { + return result; + } + }); + }); + } + + let query; + + if (method === 'GET') { + query = data; + } + + return new Promise((resolve, reject) => { + getAuth(options, config).then(auth => { + const request = { + body: data, + config, + auth, + info: { + applicationId: applicationId, + sessionToken: options.sessionToken, + installationId: options.installationId, + context: options.context || {} // Add context + + }, + query + }; + return Promise.resolve().then(() => { + return router.tryRouteRequest(method, path, request); + }).then(resp => { + const { + response, + status + } = resp; + + if (options.returnStatus) { + resolve(_objectSpread(_objectSpread({}, response), {}, { + _status: status + })); + } else { + resolve(response); + } + }, err => { + if (err instanceof Parse.Error && err.code == Parse.Error.INVALID_JSON && err.message == `cannot route ${method} ${path}`) { + RESTController.request.apply(null, args).then(resolve, reject); + } else { + reject(err); + } + }); + }, reject); + }); + } + + return { + request: handleRequest, + ajax: RESTController.ajax + }; +} + +var _default = ParseServerRESTController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkNvbmZpZyIsInJlcXVpcmUiLCJBdXRoIiwiUkVTVENvbnRyb2xsZXIiLCJVUkwiLCJQYXJzZSIsImdldFNlc3Npb25Ub2tlbiIsIm9wdGlvbnMiLCJzZXNzaW9uVG9rZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldEF1dGgiLCJjb25maWciLCJpbnN0YWxsYXRpb25JZCIsInVzZU1hc3RlcktleSIsImlzTWFzdGVyIiwidGhlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIiwiYXBwbGljYXRpb25JZCIsInJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJtZXRob2QiLCJwYXRoIiwiZGF0YSIsImFyZ3MiLCJhcmd1bWVudHMiLCJnZXQiLCJzZXJ2ZXJVUkwiLCJwYXJzZSIsImluZGV4T2YiLCJzbGljZSIsImxlbmd0aCIsImluaXRpYWxQcm9taXNlIiwidHJhbnNhY3Rpb24iLCJkYXRhYmFzZSIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwicHJvbWlzZXMiLCJyZXF1ZXN0cyIsIm1hcCIsInJlcXVlc3QiLCJib2R5IiwicmVzcG9uc2UiLCJyZXR1cm5TdGF0dXMiLCJzdGF0dXMiLCJfc3RhdHVzIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHQiLCJmaW5kIiwicmVzdWx0SXRlbSIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInF1ZXJ5IiwiYXV0aCIsImluZm8iLCJjb250ZXh0IiwidHJ5Um91dGVSZXF1ZXN0IiwicmVzcCIsImVyciIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiYXBwbHkiLCJhamF4Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBdEI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsUUFBRCxDQUFwQjs7QUFDQSxNQUFNRSxjQUFjLEdBQUdGLE9BQU8sQ0FBQywrQkFBRCxDQUE5Qjs7QUFDQSxNQUFNRyxHQUFHLEdBQUdILE9BQU8sQ0FBQyxLQUFELENBQW5COztBQUNBLE1BQU1JLEtBQUssR0FBR0osT0FBTyxDQUFDLFlBQUQsQ0FBckI7O0FBRUEsU0FBU0ssZUFBVCxDQUF5QkMsT0FBekIsRUFBa0M7QUFDaEMsTUFBSUEsT0FBTyxJQUFJLE9BQU9BLE9BQU8sQ0FBQ0MsWUFBZixLQUFnQyxRQUEvQyxFQUF5RDtBQUN2RCxXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JILE9BQU8sQ0FBQ0MsWUFBeEIsQ0FBUDtBQUNEOztBQUNELFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0MsT0FBVCxDQUFpQkosT0FBTyxHQUFHLEVBQTNCLEVBQStCSyxNQUEvQixFQUF1QztBQUNyQyxRQUFNQyxjQUFjLEdBQUdOLE9BQU8sQ0FBQ00sY0FBUixJQUEwQixPQUFqRDs7QUFDQSxNQUFJTixPQUFPLENBQUNPLFlBQVosRUFBMEI7QUFDeEIsV0FBT0wsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQUlSLElBQUksQ0FBQ0EsSUFBVCxDQUFjO0FBQUVVLE1BQUFBLE1BQUY7QUFBVUcsTUFBQUEsUUFBUSxFQUFFLElBQXBCO0FBQTBCRixNQUFBQTtBQUExQixLQUFkLENBQWhCLENBQVA7QUFDRDs7QUFDRCxTQUFPUCxlQUFlLENBQUNDLE9BQUQsQ0FBZixDQUF5QlMsSUFBekIsQ0FBOEJSLFlBQVksSUFBSTtBQUNuRCxRQUFJQSxZQUFKLEVBQWtCO0FBQ2hCRCxNQUFBQSxPQUFPLENBQUNDLFlBQVIsR0FBdUJBLFlBQXZCO0FBQ0EsYUFBT04sSUFBSSxDQUFDZSxzQkFBTCxDQUE0QjtBQUNqQ0wsUUFBQUEsTUFEaUM7QUFFakNKLFFBQUFBLFlBQVksRUFBRUEsWUFGbUI7QUFHakNLLFFBQUFBO0FBSGlDLE9BQTVCLENBQVA7QUFLRCxLQVBELE1BT087QUFDTCxhQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBSVIsSUFBSSxDQUFDQSxJQUFULENBQWM7QUFBRVUsUUFBQUEsTUFBRjtBQUFVQyxRQUFBQTtBQUFWLE9BQWQsQ0FBaEIsQ0FBUDtBQUNEO0FBQ0YsR0FYTSxDQUFQO0FBWUQ7O0FBRUQsU0FBU0sseUJBQVQsQ0FBbUNDLGFBQW5DLEVBQWtEQyxNQUFsRCxFQUEwRDtBQUN4RCxXQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQkMsSUFBL0IsRUFBcUNDLElBQUksR0FBRyxFQUE1QyxFQUFnRGpCLE9BQU8sR0FBRyxFQUExRCxFQUE4REssTUFBOUQsRUFBc0U7QUFDcEU7QUFDQSxVQUFNYSxJQUFJLEdBQUdDLFNBQWI7O0FBRUEsUUFBSSxDQUFDZCxNQUFMLEVBQWE7QUFDWEEsTUFBQUEsTUFBTSxHQUFHWixNQUFNLENBQUMyQixHQUFQLENBQVdSLGFBQVgsQ0FBVDtBQUNEOztBQUNELFVBQU1TLFNBQVMsR0FBR3hCLEdBQUcsQ0FBQ3lCLEtBQUosQ0FBVWpCLE1BQU0sQ0FBQ2dCLFNBQWpCLENBQWxCOztBQUNBLFFBQUlMLElBQUksQ0FBQ08sT0FBTCxDQUFhRixTQUFTLENBQUNMLElBQXZCLE1BQWlDLENBQXJDLEVBQXdDO0FBQ3RDQSxNQUFBQSxJQUFJLEdBQUdBLElBQUksQ0FBQ1EsS0FBTCxDQUFXSCxTQUFTLENBQUNMLElBQVYsQ0FBZVMsTUFBMUIsRUFBa0NULElBQUksQ0FBQ1MsTUFBdkMsQ0FBUDtBQUNEOztBQUVELFFBQUlULElBQUksQ0FBQyxDQUFELENBQUosS0FBWSxHQUFoQixFQUFxQjtBQUNuQkEsTUFBQUEsSUFBSSxHQUFHLE1BQU1BLElBQWI7QUFDRDs7QUFFRCxRQUFJQSxJQUFJLEtBQUssUUFBYixFQUF1QjtBQUNyQixVQUFJVSxjQUFjLEdBQUd4QixPQUFPLENBQUNDLE9BQVIsRUFBckI7O0FBQ0EsVUFBSWMsSUFBSSxDQUFDVSxXQUFMLEtBQXFCLElBQXpCLEVBQStCO0FBQzdCRCxRQUFBQSxjQUFjLEdBQUdyQixNQUFNLENBQUN1QixRQUFQLENBQWdCQywwQkFBaEIsRUFBakI7QUFDRDs7QUFDRCxhQUFPSCxjQUFjLENBQUNqQixJQUFmLENBQW9CLE1BQU07QUFDL0IsY0FBTXFCLFFBQVEsR0FBR2IsSUFBSSxDQUFDYyxRQUFMLENBQWNDLEdBQWQsQ0FBa0JDLE9BQU8sSUFBSTtBQUM1QyxpQkFBT25CLGFBQWEsQ0FBQ21CLE9BQU8sQ0FBQ2xCLE1BQVQsRUFBaUJrQixPQUFPLENBQUNqQixJQUF6QixFQUErQmlCLE9BQU8sQ0FBQ0MsSUFBdkMsRUFBNkNsQyxPQUE3QyxFQUFzREssTUFBdEQsQ0FBYixDQUEyRUksSUFBM0UsQ0FDTDBCLFFBQVEsSUFBSTtBQUNWLGdCQUFJbkMsT0FBTyxDQUFDb0MsWUFBWixFQUEwQjtBQUN4QixvQkFBTUMsTUFBTSxHQUFHRixRQUFRLENBQUNHLE9BQXhCO0FBQ0EscUJBQU9ILFFBQVEsQ0FBQ0csT0FBaEI7QUFDQSxxQkFBTztBQUFFQyxnQkFBQUEsT0FBTyxFQUFFSixRQUFYO0FBQXFCRyxnQkFBQUEsT0FBTyxFQUFFRDtBQUE5QixlQUFQO0FBQ0Q7O0FBQ0QsbUJBQU87QUFBRUUsY0FBQUEsT0FBTyxFQUFFSjtBQUFYLGFBQVA7QUFDRCxXQVJJLEVBU0xLLEtBQUssSUFBSTtBQUNQLG1CQUFPO0FBQ0xBLGNBQUFBLEtBQUssRUFBRTtBQUFFQyxnQkFBQUEsSUFBSSxFQUFFRCxLQUFLLENBQUNDLElBQWQ7QUFBb0JELGdCQUFBQSxLQUFLLEVBQUVBLEtBQUssQ0FBQ0U7QUFBakM7QUFERixhQUFQO0FBR0QsV0FiSSxDQUFQO0FBZUQsU0FoQmdCLENBQWpCO0FBaUJBLGVBQU94QyxPQUFPLENBQUN5QyxHQUFSLENBQVliLFFBQVosRUFBc0JyQixJQUF0QixDQUEyQm1DLE1BQU0sSUFBSTtBQUMxQyxjQUFJM0IsSUFBSSxDQUFDVSxXQUFMLEtBQXFCLElBQXpCLEVBQStCO0FBQzdCLGdCQUFJaUIsTUFBTSxDQUFDQyxJQUFQLENBQVlDLFVBQVUsSUFBSSxPQUFPQSxVQUFVLENBQUNOLEtBQWxCLEtBQTRCLFFBQXRELENBQUosRUFBcUU7QUFDbkUscUJBQU9uQyxNQUFNLENBQUN1QixRQUFQLENBQWdCbUIseUJBQWhCLEdBQTRDdEMsSUFBNUMsQ0FBaUQsTUFBTTtBQUM1RCx1QkFBT1AsT0FBTyxDQUFDOEMsTUFBUixDQUFlSixNQUFmLENBQVA7QUFDRCxlQUZNLENBQVA7QUFHRCxhQUpELE1BSU87QUFDTCxxQkFBT3ZDLE1BQU0sQ0FBQ3VCLFFBQVAsQ0FBZ0JxQiwwQkFBaEIsR0FBNkN4QyxJQUE3QyxDQUFrRCxNQUFNO0FBQzdELHVCQUFPbUMsTUFBUDtBQUNELGVBRk0sQ0FBUDtBQUdEO0FBQ0YsV0FWRCxNQVVPO0FBQ0wsbUJBQU9BLE1BQVA7QUFDRDtBQUNGLFNBZE0sQ0FBUDtBQWVELE9BakNNLENBQVA7QUFrQ0Q7O0FBRUQsUUFBSU0sS0FBSjs7QUFDQSxRQUFJbkMsTUFBTSxLQUFLLEtBQWYsRUFBc0I7QUFDcEJtQyxNQUFBQSxLQUFLLEdBQUdqQyxJQUFSO0FBQ0Q7O0FBRUQsV0FBTyxJQUFJZixPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVNkMsTUFBVixLQUFxQjtBQUN0QzVDLE1BQUFBLE9BQU8sQ0FBQ0osT0FBRCxFQUFVSyxNQUFWLENBQVAsQ0FBeUJJLElBQXpCLENBQThCMEMsSUFBSSxJQUFJO0FBQ3BDLGNBQU1sQixPQUFPLEdBQUc7QUFDZEMsVUFBQUEsSUFBSSxFQUFFakIsSUFEUTtBQUVkWixVQUFBQSxNQUZjO0FBR2Q4QyxVQUFBQSxJQUhjO0FBSWRDLFVBQUFBLElBQUksRUFBRTtBQUNKeEMsWUFBQUEsYUFBYSxFQUFFQSxhQURYO0FBRUpYLFlBQUFBLFlBQVksRUFBRUQsT0FBTyxDQUFDQyxZQUZsQjtBQUdKSyxZQUFBQSxjQUFjLEVBQUVOLE9BQU8sQ0FBQ00sY0FIcEI7QUFJSitDLFlBQUFBLE9BQU8sRUFBRXJELE9BQU8sQ0FBQ3FELE9BQVIsSUFBbUIsRUFKeEIsQ0FJNEI7O0FBSjVCLFdBSlE7QUFVZEgsVUFBQUE7QUFWYyxTQUFoQjtBQVlBLGVBQU9oRCxPQUFPLENBQUNDLE9BQVIsR0FDSk0sSUFESSxDQUNDLE1BQU07QUFDVixpQkFBT0ksTUFBTSxDQUFDeUMsZUFBUCxDQUF1QnZDLE1BQXZCLEVBQStCQyxJQUEvQixFQUFxQ2lCLE9BQXJDLENBQVA7QUFDRCxTQUhJLEVBSUp4QixJQUpJLENBS0g4QyxJQUFJLElBQUk7QUFDTixnQkFBTTtBQUFFcEIsWUFBQUEsUUFBRjtBQUFZRSxZQUFBQTtBQUFaLGNBQXVCa0IsSUFBN0I7O0FBQ0EsY0FBSXZELE9BQU8sQ0FBQ29DLFlBQVosRUFBMEI7QUFDeEJqQyxZQUFBQSxPQUFPLGlDQUFNZ0MsUUFBTjtBQUFnQkcsY0FBQUEsT0FBTyxFQUFFRDtBQUF6QixlQUFQO0FBQ0QsV0FGRCxNQUVPO0FBQ0xsQyxZQUFBQSxPQUFPLENBQUNnQyxRQUFELENBQVA7QUFDRDtBQUNGLFNBWkUsRUFhSHFCLEdBQUcsSUFBSTtBQUNMLGNBQ0VBLEdBQUcsWUFBWTFELEtBQUssQ0FBQzJELEtBQXJCLElBQ0FELEdBQUcsQ0FBQ2YsSUFBSixJQUFZM0MsS0FBSyxDQUFDMkQsS0FBTixDQUFZQyxZQUR4QixJQUVBRixHQUFHLENBQUNkLE9BQUosSUFBZ0IsZ0JBQWUzQixNQUFPLElBQUdDLElBQUssRUFIaEQsRUFJRTtBQUNBcEIsWUFBQUEsY0FBYyxDQUFDcUMsT0FBZixDQUF1QjBCLEtBQXZCLENBQTZCLElBQTdCLEVBQW1DekMsSUFBbkMsRUFBeUNULElBQXpDLENBQThDTixPQUE5QyxFQUF1RDZDLE1BQXZEO0FBQ0QsV0FORCxNQU1PO0FBQ0xBLFlBQUFBLE1BQU0sQ0FBQ1EsR0FBRCxDQUFOO0FBQ0Q7QUFDRixTQXZCRSxDQUFQO0FBeUJELE9BdENELEVBc0NHUixNQXRDSDtBQXVDRCxLQXhDTSxDQUFQO0FBeUNEOztBQUVELFNBQU87QUFDTGYsSUFBQUEsT0FBTyxFQUFFbkIsYUFESjtBQUVMOEMsSUFBQUEsSUFBSSxFQUFFaEUsY0FBYyxDQUFDZ0U7QUFGaEIsR0FBUDtBQUlEOztlQUVjakQseUIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBDb25maWcgPSByZXF1aXJlKCcuL0NvbmZpZycpO1xuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xuY29uc3QgUkVTVENvbnRyb2xsZXIgPSByZXF1aXJlKCdwYXJzZS9saWIvbm9kZS9SRVNUQ29udHJvbGxlcicpO1xuY29uc3QgVVJMID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcblxuZnVuY3Rpb24gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuc2Vzc2lvblRva2VuID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUob3B0aW9ucy5zZXNzaW9uVG9rZW4pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG59XG5cbmZ1bmN0aW9uIGdldEF1dGgob3B0aW9ucyA9IHt9LCBjb25maWcpIHtcbiAgY29uc3QgaW5zdGFsbGF0aW9uSWQgPSBvcHRpb25zLmluc3RhbGxhdGlvbklkIHx8ICdjbG91ZCc7XG4gIGlmIChvcHRpb25zLnVzZU1hc3RlcktleSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEF1dGguQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgfVxuICByZXR1cm4gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpLnRoZW4oc2Vzc2lvblRva2VuID0+IHtcbiAgICBpZiAoc2Vzc2lvblRva2VuKSB7XG4gICAgICBvcHRpb25zLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICAgIHJldHVybiBBdXRoLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgICBjb25maWcsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBBdXRoLkF1dGgoeyBjb25maWcsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcGxpY2F0aW9uSWQsIHJvdXRlcikge1xuICBmdW5jdGlvbiBoYW5kbGVSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgZGF0YSA9IHt9LCBvcHRpb25zID0ge30sIGNvbmZpZykge1xuICAgIC8vIFN0b3JlIHRoZSBhcmd1bWVudHMsIGZvciBsYXRlciB1c2UgaWYgaW50ZXJuYWwgZmFpbHNcbiAgICBjb25zdCBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgfVxuICAgIGNvbnN0IHNlcnZlclVSTCA9IFVSTC5wYXJzZShjb25maWcuc2VydmVyVVJMKTtcbiAgICBpZiAocGF0aC5pbmRleE9mKHNlcnZlclVSTC5wYXRoKSA9PT0gMCkge1xuICAgICAgcGF0aCA9IHBhdGguc2xpY2Uoc2VydmVyVVJMLnBhdGgubGVuZ3RoLCBwYXRoLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKHBhdGhbMF0gIT09ICcvJykge1xuICAgICAgcGF0aCA9ICcvJyArIHBhdGg7XG4gICAgfVxuXG4gICAgaWYgKHBhdGggPT09ICcvYmF0Y2gnKSB7XG4gICAgICBsZXQgaW5pdGlhbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgIGluaXRpYWxQcm9taXNlID0gY29uZmlnLmRhdGFiYXNlLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW5pdGlhbFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gZGF0YS5yZXF1ZXN0cy5tYXAocmVxdWVzdCA9PiB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZVJlcXVlc3QocmVxdWVzdC5tZXRob2QsIHJlcXVlc3QucGF0aCwgcmVxdWVzdC5ib2R5LCBvcHRpb25zLCBjb25maWcpLnRoZW4oXG4gICAgICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLnJldHVyblN0YXR1cykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogcmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHJlc3BvbnNlIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVycm9yOiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0sXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmZpbmQocmVzdWx0SXRlbSA9PiB0eXBlb2YgcmVzdWx0SXRlbS5lcnJvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHF1ZXJ5O1xuICAgIGlmIChtZXRob2QgPT09ICdHRVQnKSB7XG4gICAgICBxdWVyeSA9IGRhdGE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGdldEF1dGgob3B0aW9ucywgY29uZmlnKS50aGVuKGF1dGggPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgaW5mbzoge1xuICAgICAgICAgICAgYXBwbGljYXRpb25JZDogYXBwbGljYXRpb25JZCxcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogb3B0aW9ucy5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICBpbnN0YWxsYXRpb25JZDogb3B0aW9ucy5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIGNvbnRleHQ6IG9wdGlvbnMuY29udGV4dCB8fCB7fSwgLy8gQWRkIGNvbnRleHRcbiAgICAgICAgICB9LFxuICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcm91dGVyLnRyeVJvdXRlUmVxdWVzdChtZXRob2QsIHBhdGgsIHJlcXVlc3QpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICByZXNwID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgeyByZXNwb25zZSwgc3RhdHVzIH0gPSByZXNwO1xuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5yZXR1cm5TdGF0dXMpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHsgLi4ucmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBQYXJzZS5FcnJvciAmJlxuICAgICAgICAgICAgICAgIGVyci5jb2RlID09IFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiAmJlxuICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IGBjYW5ub3Qgcm91dGUgJHttZXRob2R9ICR7cGF0aH1gXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIFJFU1RDb250cm9sbGVyLnJlcXVlc3QuYXBwbHkobnVsbCwgYXJncykudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgIH0sIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHJlcXVlc3Q6IGhhbmRsZVJlcXVlc3QsXG4gICAgYWpheDogUkVTVENvbnRyb2xsZXIuYWpheCxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcjtcbmV4cG9ydCB7IFBhcnNlU2VydmVyUkVTVENvbnRyb2xsZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/PromiseRouter.js b/lib/PromiseRouter.js new file mode 100644 index 0000000000..71f2d5ea39 --- /dev/null +++ b/lib/PromiseRouter.js @@ -0,0 +1,255 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _express = _interopRequireDefault(require("express")); + +var _logger = _interopRequireDefault(require("./logger")); + +var _util = require("util"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// A router that is based on promises rather than req/res/next. +// This is intended to replace the use of express.Router to handle +// subsections of the API surface. +// This will make it easier to have methods like 'batch' that +// themselves use our routing information, without disturbing express +// components that external developers may be modifying. +const Layer = require('express/lib/router/layer'); + +function validateParameter(key, value) { + if (key == 'className') { + if (value.match(/_?[A-Za-z][A-Za-z_0-9]*/)) { + return value; + } + } else if (key == 'objectId') { + if (value.match(/[A-Za-z0-9]+/)) { + return value; + } + } else { + return value; + } +} + +class PromiseRouter { + // Each entry should be an object with: + // path: the path to route, in express format + // method: the HTTP method that this route handles. + // Must be one of: POST, GET, PUT, DELETE + // handler: a function that takes request, and returns a promise. + // Successful handlers should resolve to an object with fields: + // status: optional. the http status code. defaults to 200 + // response: a json object with the content of the response + // location: optional. a location header + constructor(routes = [], appId) { + this.routes = routes; + this.appId = appId; + this.mountRoutes(); + } // Leave the opportunity to + // subclasses to mount their routes by overriding + + + mountRoutes() {} // Merge the routes into this one + + + merge(router) { + for (var route of router.routes) { + this.routes.push(route); + } + } + + route(method, path, ...handlers) { + switch (method) { + case 'POST': + case 'GET': + case 'PUT': + case 'DELETE': + break; + + default: + throw 'cannot route method: ' + method; + } + + let handler = handlers[0]; + + if (handlers.length > 1) { + handler = function (req) { + return handlers.reduce((promise, handler) => { + return promise.then(() => { + return handler(req); + }); + }, Promise.resolve()); + }; + } + + this.routes.push({ + path: path, + method: method, + handler: handler, + layer: new Layer(path, null, handler) + }); + } // Returns an object with: + // handler: the handler that should deal with this request + // params: any :-params that got parsed from the path + // Returns undefined if there is no match. + + + match(method, path) { + for (var route of this.routes) { + if (route.method != method) { + continue; + } + + const layer = route.layer || new Layer(route.path, null, route.handler); + const match = layer.match(path); + + if (match) { + const params = layer.params; + Object.keys(params).forEach(key => { + params[key] = validateParameter(key, params[key]); + }); + return { + params: params, + handler: route.handler + }; + } + } + } // Mount the routes on this router onto an express app (or express router) + + + mountOnto(expressApp) { + this.routes.forEach(route => { + const method = route.method.toLowerCase(); + const handler = makeExpressHandler(this.appId, route.handler); + expressApp[method].call(expressApp, route.path, handler); + }); + return expressApp; + } + + expressRouter() { + return this.mountOnto(_express.default.Router()); + } + + tryRouteRequest(method, path, request) { + var match = this.match(method, path); + + if (!match) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'cannot route ' + method + ' ' + path); + } + + request.params = match.params; + return new Promise((resolve, reject) => { + match.handler(request).then(resolve, reject); + }); + } + +} // A helper function to make an express handler out of a a promise +// handler. +// Express handlers should never throw; if a promise handler throws we +// just treat it like it resolved to an error. + + +exports.default = PromiseRouter; + +function makeExpressHandler(appId, promiseHandler) { + return function (req, res, next) { + try { + const url = maskSensitiveUrl(req); + const body = Object.assign({}, req.body); + const method = req.method; + const headers = req.headers; + + _logger.default.logRequest({ + method, + url, + headers, + body + }); + + promiseHandler(req).then(result => { + clearSchemaCache(req); + + if (!result.response && !result.location && !result.text) { + _logger.default.error('the handler did not include a "response" or a "location" field'); + + throw 'control should not get here'; + } + + _logger.default.logResponse({ + method, + url, + result + }); + + var status = result.status || 200; + res.status(status); + + if (result.text) { + res.send(result.text); + return; + } + + if (result.location) { + res.set('Location', result.location); // Override the default expressjs response + // as it double encodes %encoded chars in URL + + if (!result.response) { + res.send('Found. Redirecting to ' + result.location); + return; + } + } + + if (result.headers) { + Object.keys(result.headers).forEach(header => { + res.set(header, result.headers[header]); + }); + } + + res.json(result.response); + }, error => { + clearSchemaCache(req); + next(error); + }).catch(e => { + clearSchemaCache(req); + + _logger.default.error(`Error generating response. ${(0, _util.inspect)(e)}`, { + error: e + }); + + next(e); + }); + } catch (e) { + clearSchemaCache(req); + + _logger.default.error(`Error handling request: ${(0, _util.inspect)(e)}`, { + error: e + }); + + next(e); + } + }; +} + +function maskSensitiveUrl(req) { + let maskUrl = req.originalUrl.toString(); + const shouldMaskUrl = req.method === 'GET' && req.originalUrl.includes('/login') && !req.originalUrl.includes('classes'); + + if (shouldMaskUrl) { + maskUrl = _logger.default.maskSensitiveUrl(maskUrl); + } + + return maskUrl; +} + +function clearSchemaCache(req) { + if (req.config && !req.config.enableSingleSchemaCache) { + req.config.database.schemaCache.clear(); + } +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Qcm9taXNlUm91dGVyLmpzIl0sIm5hbWVzIjpbIkxheWVyIiwicmVxdWlyZSIsInZhbGlkYXRlUGFyYW1ldGVyIiwia2V5IiwidmFsdWUiLCJtYXRjaCIsIlByb21pc2VSb3V0ZXIiLCJjb25zdHJ1Y3RvciIsInJvdXRlcyIsImFwcElkIiwibW91bnRSb3V0ZXMiLCJtZXJnZSIsInJvdXRlciIsInJvdXRlIiwicHVzaCIsIm1ldGhvZCIsInBhdGgiLCJoYW5kbGVycyIsImhhbmRsZXIiLCJsZW5ndGgiLCJyZXEiLCJyZWR1Y2UiLCJwcm9taXNlIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwibGF5ZXIiLCJwYXJhbXMiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsIm1vdW50T250byIsImV4cHJlc3NBcHAiLCJ0b0xvd2VyQ2FzZSIsIm1ha2VFeHByZXNzSGFuZGxlciIsImNhbGwiLCJleHByZXNzUm91dGVyIiwiZXhwcmVzcyIsIlJvdXRlciIsInRyeVJvdXRlUmVxdWVzdCIsInJlcXVlc3QiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicmVqZWN0IiwicHJvbWlzZUhhbmRsZXIiLCJyZXMiLCJuZXh0IiwidXJsIiwibWFza1NlbnNpdGl2ZVVybCIsImJvZHkiLCJhc3NpZ24iLCJoZWFkZXJzIiwibG9nIiwibG9nUmVxdWVzdCIsInJlc3VsdCIsImNsZWFyU2NoZW1hQ2FjaGUiLCJyZXNwb25zZSIsImxvY2F0aW9uIiwidGV4dCIsImVycm9yIiwibG9nUmVzcG9uc2UiLCJzdGF0dXMiLCJzZW5kIiwic2V0IiwiaGVhZGVyIiwianNvbiIsImNhdGNoIiwiZSIsIm1hc2tVcmwiLCJvcmlnaW5hbFVybCIsInRvU3RyaW5nIiwic2hvdWxkTWFza1VybCIsImluY2x1ZGVzIiwiY29uZmlnIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkYXRhYmFzZSIsInNjaGVtYUNhY2hlIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7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Z0JHLFFBQWhCLENBQXlCLFNBQXpCLENBSEg7O0FBSUEsTUFBSUQsYUFBSixFQUFtQjtBQUNqQkgsSUFBQUEsT0FBTyxHQUFHaEIsZ0JBQUlKLGdCQUFKLENBQXFCb0IsT0FBckIsQ0FBVjtBQUNEOztBQUNELFNBQU9BLE9BQVA7QUFDRDs7QUFFRCxTQUFTYixnQkFBVCxDQUEwQnBDLEdBQTFCLEVBQStCO0FBQzdCLE1BQUlBLEdBQUcsQ0FBQ3NELE1BQUosSUFBYyxDQUFDdEQsR0FBRyxDQUFDc0QsTUFBSixDQUFXQyx1QkFBOUIsRUFBdUQ7QUFDckR2RCxJQUFBQSxHQUFHLENBQUNzRCxNQUFKLENBQVdFLFFBQVgsQ0FBb0JDLFdBQXBCLENBQWdDQyxLQUFoQztBQUNEO0FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIHJvdXRlciB0aGF0IGlzIGJhc2VkIG9uIHByb21pc2VzIHJhdGhlciB0aGFuIHJlcS9yZXMvbmV4dC5cbi8vIFRoaXMgaXMgaW50ZW5kZWQgdG8gcmVwbGFjZSB0aGUgdXNlIG9mIGV4cHJlc3MuUm91dGVyIHRvIGhhbmRsZVxuLy8gc3Vic2VjdGlvbnMgb2YgdGhlIEFQSSBzdXJmYWNlLlxuLy8gVGhpcyB3aWxsIG1ha2UgaXQgZWFzaWVyIHRvIGhhdmUgbWV0aG9kcyBsaWtlICdiYXRjaCcgdGhhdFxuLy8gdGhlbXNlbHZlcyB1c2Ugb3VyIHJvdXRpbmcgaW5mb3JtYXRpb24sIHdpdGhvdXQgZGlzdHVyYmluZyBleHByZXNzXG4vLyBjb21wb25lbnRzIHRoYXQgZXh0ZXJuYWwgZGV2ZWxvcGVycyBtYXkgYmUgbW9kaWZ5aW5nLlxuXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgaW5zcGVjdCB9IGZyb20gJ3V0aWwnO1xuY29uc3QgTGF5ZXIgPSByZXF1aXJlKCdleHByZXNzL2xpYi9yb3V0ZXIvbGF5ZXInKTtcblxuZnVuY3Rpb24gdmFsaWRhdGVQYXJhbWV0ZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5ID09ICdjbGFzc05hbWUnKSB7XG4gICAgaWYgKHZhbHVlLm1hdGNoKC9fP1tBLVphLXpdW0EtWmEtel8wLTldKi8pKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9IGVsc2UgaWYgKGtleSA9PSAnb2JqZWN0SWQnKSB7XG4gICAgaWYgKHZhbHVlLm1hdGNoKC9bQS1aYS16MC05XSsvKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvbWlzZVJvdXRlciB7XG4gIC8vIEVhY2ggZW50cnkgc2hvdWxkIGJlIGFuIG9iamVjdCB3aXRoOlxuICAvLyBwYXRoOiB0aGUgcGF0aCB0byByb3V0ZSwgaW4gZXhwcmVzcyBmb3JtYXRcbiAgLy8gbWV0aG9kOiB0aGUgSFRUUCBtZXRob2QgdGhhdCB0aGlzIHJvdXRlIGhhbmRsZXMuXG4gIC8vICAgTXVzdCBiZSBvbmUgb2Y6IFBPU1QsIEdFVCwgUFVULCBERUxFVEVcbiAgLy8gaGFuZGxlcjogYSBmdW5jdGlvbiB0aGF0IHRha2VzIHJlcXVlc3QsIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAgLy8gICBTdWNjZXNzZnVsIGhhbmRsZXJzIHNob3VsZCByZXNvbHZlIHRvIGFuIG9iamVjdCB3aXRoIGZpZWxkczpcbiAgLy8gICAgIHN0YXR1czogb3B0aW9uYWwuIHRoZSBodHRwIHN0YXR1cyBjb2RlLiBkZWZhdWx0cyB0byAyMDBcbiAgLy8gICAgIHJlc3BvbnNlOiBhIGpzb24gb2JqZWN0IHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIHJlc3BvbnNlXG4gIC8vICAgICBsb2NhdGlvbjogb3B0aW9uYWwuIGEgbG9jYXRpb24gaGVhZGVyXG4gIGNvbnN0cnVjdG9yKHJvdXRlcyA9IFtdLCBhcHBJZCkge1xuICAgIHRoaXMucm91dGVzID0gcm91dGVzO1xuICAgIHRoaXMuYXBwSWQgPSBhcHBJZDtcbiAgICB0aGlzLm1vdW50Um91dGVzKCk7XG4gIH1cblxuICAvLyBMZWF2ZSB0aGUgb3Bwb3J0dW5pdHkgdG9cbiAgLy8gc3ViY2xhc3NlcyB0byBtb3VudCB0aGVpciByb3V0ZXMgYnkgb3ZlcnJpZGluZ1xuICBtb3VudFJvdXRlcygpIHt9XG5cbiAgLy8gTWVyZ2UgdGhlIHJvdXRlcyBpbnRvIHRoaXMgb25lXG4gIG1lcmdlKHJvdXRlcikge1xuICAgIGZvciAodmFyIHJvdXRlIG9mIHJvdXRlci5yb3V0ZXMpIHtcbiAgICAgIHRoaXMucm91dGVzLnB1c2gocm91dGUpO1xuICAgIH1cbiAgfVxuXG4gIHJvdXRlKG1ldGhvZCwgcGF0aCwgLi4uaGFuZGxlcnMpIHtcbiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgY2FzZSAnUE9TVCc6XG4gICAgICBjYXNlICdHRVQnOlxuICAgICAgY2FzZSAnUFVUJzpcbiAgICAgIGNhc2UgJ0RFTEVURSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgJ2Nhbm5vdCByb3V0ZSBtZXRob2Q6ICcgKyBtZXRob2Q7XG4gICAgfVxuXG4gICAgbGV0IGhhbmRsZXIgPSBoYW5kbGVyc1swXTtcblxuICAgIGlmIChoYW5kbGVycy5sZW5ndGggPiAxKSB7XG4gICAgICBoYW5kbGVyID0gZnVuY3Rpb24gKHJlcSkge1xuICAgICAgICByZXR1cm4gaGFuZGxlcnMucmVkdWNlKChwcm9taXNlLCBoYW5kbGVyKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXEpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9LCBQcm9taXNlLnJlc29sdmUoKSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucm91dGVzLnB1c2goe1xuICAgICAgcGF0aDogcGF0aCxcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgaGFuZGxlcjogaGFuZGxlcixcbiAgICAgIGxheWVyOiBuZXcgTGF5ZXIocGF0aCwgbnVsbCwgaGFuZGxlciksXG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGFuIG9iamVjdCB3aXRoOlxuICAvLyAgIGhhbmRsZXI6IHRoZSBoYW5kbGVyIHRoYXQgc2hvdWxkIGRlYWwgd2l0aCB0aGlzIHJlcXVlc3RcbiAgLy8gICBwYXJhbXM6IGFueSA6LXBhcmFtcyB0aGF0IGdvdCBwYXJzZWQgZnJvbSB0aGUgcGF0aFxuICAvLyBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBubyBtYXRjaC5cbiAgbWF0Y2gobWV0aG9kLCBwYXRoKSB7XG4gICAgZm9yICh2YXIgcm91dGUgb2YgdGhpcy5yb3V0ZXMpIHtcbiAgICAgIGlmIChyb3V0ZS5tZXRob2QgIT0gbWV0aG9kKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbGF5ZXIgPSByb3V0ZS5sYXllciB8fCBuZXcgTGF5ZXIocm91dGUucGF0aCwgbnVsbCwgcm91dGUuaGFuZGxlcik7XG4gICAgICBjb25zdCBtYXRjaCA9IGxheWVyLm1hdGNoKHBhdGgpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IGxheWVyLnBhcmFtcztcbiAgICAgICAgT2JqZWN0LmtleXMocGFyYW1zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWxpZGF0ZVBhcmFtZXRlcihrZXksIHBhcmFtc1trZXldKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IHBhcmFtczogcGFyYW1zLCBoYW5kbGVyOiByb3V0ZS5oYW5kbGVyIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTW91bnQgdGhlIHJvdXRlcyBvbiB0aGlzIHJvdXRlciBvbnRvIGFuIGV4cHJlc3MgYXBwIChvciBleHByZXNzIHJvdXRlcilcbiAgbW91bnRPbnRvKGV4cHJlc3NBcHApIHtcbiAgICB0aGlzLnJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IHtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IHJvdXRlLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgaGFuZGxlciA9IG1ha2VFeHByZXNzSGFuZGxlcih0aGlzLmFwcElkLCByb3V0ZS5oYW5kbGVyKTtcbiAgICAgIGV4cHJlc3NBcHBbbWV0aG9kXS5jYWxsKGV4cHJlc3NBcHAsIHJvdXRlLnBhdGgsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiBleHByZXNzQXBwO1xuICB9XG5cbiAgZXhwcmVzc1JvdXRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5tb3VudE9udG8oZXhwcmVzcy5Sb3V0ZXIoKSk7XG4gIH1cblxuICB0cnlSb3V0ZVJlcXVlc3QobWV0aG9kLCBwYXRoLCByZXF1ZXN0KSB7XG4gICAgdmFyIG1hdGNoID0gdGhpcy5tYXRjaChtZXRob2QsIHBhdGgpO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdjYW5ub3Qgcm91dGUgJyArIG1ldGhvZCArICcgJyArIHBhdGgpO1xuICAgIH1cbiAgICByZXF1ZXN0LnBhcmFtcyA9IG1hdGNoLnBhcmFtcztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgbWF0Y2guaGFuZGxlcihyZXF1ZXN0KS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLy8gQSBoZWxwZXIgZnVuY3Rpb24gdG8gbWFrZSBhbiBleHByZXNzIGhhbmRsZXIgb3V0IG9mIGEgYSBwcm9taXNlXG4vLyBoYW5kbGVyLlxuLy8gRXhwcmVzcyBoYW5kbGVycyBzaG91bGQgbmV2ZXIgdGhyb3c7IGlmIGEgcHJvbWlzZSBoYW5kbGVyIHRocm93cyB3ZVxuLy8ganVzdCB0cmVhdCBpdCBsaWtlIGl0IHJlc29sdmVkIHRvIGFuIGVycm9yLlxuZnVuY3Rpb24gbWFrZUV4cHJlc3NIYW5kbGVyKGFwcElkLCBwcm9taXNlSGFuZGxlcikge1xuICByZXR1cm4gZnVuY3Rpb24gKHJlcSwgcmVzLCBuZXh0KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVybCA9IG1hc2tTZW5zaXRpdmVVcmwocmVxKTtcbiAgICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHt9LCByZXEuYm9keSk7XG4gICAgICBjb25zdCBtZXRob2QgPSByZXEubWV0aG9kO1xuICAgICAgY29uc3QgaGVhZGVycyA9IHJlcS5oZWFkZXJzO1xuICAgICAgbG9nLmxvZ1JlcXVlc3Qoe1xuICAgICAgICBtZXRob2QsXG4gICAgICAgIHVybCxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYm9keSxcbiAgICAgIH0pO1xuICAgICAgcHJvbWlzZUhhbmRsZXIocmVxKVxuICAgICAgICAudGhlbihcbiAgICAgICAgICByZXN1bHQgPT4ge1xuICAgICAgICAgICAgY2xlYXJTY2hlbWFDYWNoZShyZXEpO1xuICAgICAgICAgICAgaWYgKCFyZXN1bHQucmVzcG9uc2UgJiYgIXJlc3VsdC5sb2NhdGlvbiAmJiAhcmVzdWx0LnRleHQpIHtcbiAgICAgICAgICAgICAgbG9nLmVycm9yKCd0aGUgaGFuZGxlciBkaWQgbm90IGluY2x1ZGUgYSBcInJlc3BvbnNlXCIgb3IgYSBcImxvY2F0aW9uXCIgZmllbGQnKTtcbiAgICAgICAgICAgICAgdGhyb3cgJ2NvbnRyb2wgc2hvdWxkIG5vdCBnZXQgaGVyZSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvZy5sb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSk7XG5cbiAgICAgICAgICAgIHZhciBzdGF0dXMgPSByZXN1bHQuc3RhdHVzIHx8IDIwMDtcbiAgICAgICAgICAgIHJlcy5zdGF0dXMoc3RhdHVzKTtcblxuICAgICAgICAgICAgaWYgKHJlc3VsdC50ZXh0KSB7XG4gICAgICAgICAgICAgIHJlcy5zZW5kKHJlc3VsdC50ZXh0KTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzdWx0LmxvY2F0aW9uKSB7XG4gICAgICAgICAgICAgIHJlcy5zZXQoJ0xvY2F0aW9uJywgcmVzdWx0LmxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgLy8gT3ZlcnJpZGUgdGhlIGRlZmF1bHQgZXhwcmVzc2pzIHJlc3BvbnNlXG4gICAgICAgICAgICAgIC8vIGFzIGl0IGRvdWJsZSBlbmNvZGVzICVlbmNvZGVkIGNoYXJzIGluIFVSTFxuICAgICAgICAgICAgICBpZiAoIXJlc3VsdC5yZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIHJlcy5zZW5kKCdGb3VuZC4gUmVkaXJlY3RpbmcgdG8gJyArIHJlc3VsdC5sb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0LmhlYWRlcnMpLmZvckVhY2goaGVhZGVyID0+IHtcbiAgICAgICAgICAgICAgICByZXMuc2V0KGhlYWRlciwgcmVzdWx0LmhlYWRlcnNbaGVhZGVyXSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLmpzb24ocmVzdWx0LnJlc3BvbnNlKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAgIGNsZWFyU2NoZW1hQ2FjaGUocmVxKTtcbiAgICAgICAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgY2xlYXJTY2hlbWFDYWNoZShyZXEpO1xuICAgICAgICAgIGxvZy5lcnJvcihgRXJyb3IgZ2VuZXJhdGluZyByZXNwb25zZS4gJHtpbnNwZWN0KGUpfWAsIHsgZXJyb3I6IGUgfSk7XG4gICAgICAgICAgbmV4dChlKTtcbiAgICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY2xlYXJTY2hlbWFDYWNoZShyZXEpO1xuICAgICAgbG9nLmVycm9yKGBFcnJvciBoYW5kbGluZyByZXF1ZXN0OiAke2luc3BlY3QoZSl9YCwgeyBlcnJvcjogZSB9KTtcbiAgICAgIG5leHQoZSk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBtYXNrU2Vuc2l0aXZlVXJsKHJlcSkge1xuICBsZXQgbWFza1VybCA9IHJlcS5vcmlnaW5hbFVybC50b1N0cmluZygpO1xuICBjb25zdCBzaG91bGRNYXNrVXJsID1cbiAgICByZXEubWV0aG9kID09PSAnR0VUJyAmJlxuICAgIHJlcS5vcmlnaW5hbFVybC5pbmNsdWRlcygnL2xvZ2luJykgJiZcbiAgICAhcmVxLm9yaWdpbmFsVXJsLmluY2x1ZGVzKCdjbGFzc2VzJyk7XG4gIGlmIChzaG91bGRNYXNrVXJsKSB7XG4gICAgbWFza1VybCA9IGxvZy5tYXNrU2Vuc2l0aXZlVXJsKG1hc2tVcmwpO1xuICB9XG4gIHJldHVybiBtYXNrVXJsO1xufVxuXG5mdW5jdGlvbiBjbGVhclNjaGVtYUNhY2hlKHJlcSkge1xuICBpZiAocmVxLmNvbmZpZyAmJiAhcmVxLmNvbmZpZy5lbmFibGVTaW5nbGVTY2hlbWFDYWNoZSkge1xuICAgIHJlcS5jb25maWcuZGF0YWJhc2Uuc2NoZW1hQ2FjaGUuY2xlYXIoKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Push/PushQueue.js b/lib/Push/PushQueue.js new file mode 100644 index 0000000000..f3e2d1d755 --- /dev/null +++ b/lib/Push/PushQueue.js @@ -0,0 +1,79 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PushQueue = void 0; + +var _ParseMessageQueue = require("../ParseMessageQueue"); + +var _rest = _interopRequireDefault(require("../rest")); + +var _utils = require("./utils"); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PUSH_CHANNEL = 'parse-server-push'; +const DEFAULT_BATCH_SIZE = 100; + +class PushQueue { + // config object of the publisher, right now it only contains the redisURL, + // but we may extend it later. + constructor(config = {}) { + this.channel = config.channel || PushQueue.defaultPushChannel(); + this.batchSize = config.batchSize || DEFAULT_BATCH_SIZE; + this.parsePublisher = _ParseMessageQueue.ParseMessageQueue.createPublisher(config); + } + + static defaultPushChannel() { + return `${_node.default.applicationId}-${PUSH_CHANNEL}`; + } + + enqueue(body, where, config, auth, pushStatus) { + const limit = this.batchSize; + where = (0, _utils.applyDeviceTokenExists)(where); // Order by objectId so no impact on the DB + + const order = 'objectId'; + return Promise.resolve().then(() => { + return _rest.default.find(config, auth, '_Installation', where, { + limit: 0, + count: true + }); + }).then(({ + results, + count + }) => { + if (!results || count == 0) { + return pushStatus.complete(); + } + + pushStatus.setRunning(Math.ceil(count / limit)); + let skip = 0; + + while (skip < count) { + const query = { + where, + limit, + skip, + order + }; + const pushWorkItem = { + body, + query, + pushStatus: { + objectId: pushStatus.objectId + }, + applicationId: config.applicationId + }; + this.parsePublisher.publish(this.channel, JSON.stringify(pushWorkItem)); + skip += limit; + } + }); + } + +} + +exports.PushQueue = PushQueue; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQVVNIX0NIQU5ORUwiLCJERUZBVUxUX0JBVENIX1NJWkUiLCJQdXNoUXVldWUiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNoYW5uZWwiLCJkZWZhdWx0UHVzaENoYW5uZWwiLCJiYXRjaFNpemUiLCJwYXJzZVB1Ymxpc2hlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlUHVibGlzaGVyIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwiZW5xdWV1ZSIsImJvZHkiLCJ3aGVyZSIsImF1dGgiLCJwdXNoU3RhdHVzIiwibGltaXQiLCJvcmRlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsInJlc3QiLCJmaW5kIiwiY291bnQiLCJyZXN1bHRzIiwiY29tcGxldGUiLCJzZXRSdW5uaW5nIiwiTWF0aCIsImNlaWwiLCJza2lwIiwicXVlcnkiLCJwdXNoV29ya0l0ZW0iLCJvYmplY3RJZCIsInB1Ymxpc2giLCJKU09OIiwic3RyaW5naWZ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxZQUFZLEdBQUcsbUJBQXJCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRU8sTUFBTUMsU0FBTixDQUFnQjtBQUtyQjtBQUNBO0FBQ0FDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBVyxHQUFHLEVBQWYsRUFBbUI7QUFDNUIsU0FBS0MsT0FBTCxHQUFlRCxNQUFNLENBQUNDLE9BQVAsSUFBa0JILFNBQVMsQ0FBQ0ksa0JBQVYsRUFBakM7QUFDQSxTQUFLQyxTQUFMLEdBQWlCSCxNQUFNLENBQUNHLFNBQVAsSUFBb0JOLGtCQUFyQztBQUNBLFNBQUtPLGNBQUwsR0FBc0JDLHFDQUFrQkMsZUFBbEIsQ0FBa0NOLE1BQWxDLENBQXRCO0FBQ0Q7O0FBRUQsU0FBT0Usa0JBQVAsR0FBNEI7QUFDMUIsV0FBUSxHQUFFSyxjQUFNQyxhQUFjLElBQUdaLFlBQWEsRUFBOUM7QUFDRDs7QUFFRGEsRUFBQUEsT0FBTyxDQUFDQyxJQUFELEVBQU9DLEtBQVAsRUFBY1gsTUFBZCxFQUFzQlksSUFBdEIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDLFVBQU1DLEtBQUssR0FBRyxLQUFLWCxTQUFuQjtBQUVBUSxJQUFBQSxLQUFLLEdBQUcsbUNBQXVCQSxLQUF2QixDQUFSLENBSDZDLENBSzdDOztBQUNBLFVBQU1JLEtBQUssR0FBRyxVQUFkO0FBQ0EsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBT0MsY0FBS0MsSUFBTCxDQUFVcEIsTUFBVixFQUFrQlksSUFBbEIsRUFBd0IsZUFBeEIsRUFBeUNELEtBQXpDLEVBQWdEO0FBQ3JERyxRQUFBQSxLQUFLLEVBQUUsQ0FEOEM7QUFFckRPLFFBQUFBLEtBQUssRUFBRTtBQUY4QyxPQUFoRCxDQUFQO0FBSUQsS0FOSSxFQU9KSCxJQVBJLENBT0MsQ0FBQztBQUFFSSxNQUFBQSxPQUFGO0FBQVdELE1BQUFBO0FBQVgsS0FBRCxLQUF3QjtBQUM1QixVQUFJLENBQUNDLE9BQUQsSUFBWUQsS0FBSyxJQUFJLENBQXpCLEVBQTRCO0FBQzFCLGVBQU9SLFVBQVUsQ0FBQ1UsUUFBWCxFQUFQO0FBQ0Q7O0FBQ0RWLE1BQUFBLFVBQVUsQ0FBQ1csVUFBWCxDQUFzQkMsSUFBSSxDQUFDQyxJQUFMLENBQVVMLEtBQUssR0FBR1AsS0FBbEIsQ0FBdEI7QUFDQSxVQUFJYSxJQUFJLEdBQUcsQ0FBWDs7QUFDQSxhQUFPQSxJQUFJLEdBQUdOLEtBQWQsRUFBcUI7QUFDbkIsY0FBTU8sS0FBSyxHQUFHO0FBQ1pqQixVQUFBQSxLQURZO0FBRVpHLFVBQUFBLEtBRlk7QUFHWmEsVUFBQUEsSUFIWTtBQUlaWixVQUFBQTtBQUpZLFNBQWQ7QUFPQSxjQUFNYyxZQUFZLEdBQUc7QUFDbkJuQixVQUFBQSxJQURtQjtBQUVuQmtCLFVBQUFBLEtBRm1CO0FBR25CZixVQUFBQSxVQUFVLEVBQUU7QUFBRWlCLFlBQUFBLFFBQVEsRUFBRWpCLFVBQVUsQ0FBQ2lCO0FBQXZCLFdBSE87QUFJbkJ0QixVQUFBQSxhQUFhLEVBQUVSLE1BQU0sQ0FBQ1E7QUFKSCxTQUFyQjtBQU1BLGFBQUtKLGNBQUwsQ0FBb0IyQixPQUFwQixDQUE0QixLQUFLOUIsT0FBakMsRUFBMEMrQixJQUFJLENBQUNDLFNBQUwsQ0FBZUosWUFBZixDQUExQztBQUNBRixRQUFBQSxJQUFJLElBQUliLEtBQVI7QUFDRDtBQUNGLEtBOUJJLENBQVA7QUErQkQ7O0FBdkRvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlTWVzc2FnZVF1ZXVlIH0gZnJvbSAnLi4vUGFyc2VNZXNzYWdlUXVldWUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgeyBhcHBseURldmljZVRva2VuRXhpc3RzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmNvbnN0IFBVU0hfQ0hBTk5FTCA9ICdwYXJzZS1zZXJ2ZXItcHVzaCc7XG5jb25zdCBERUZBVUxUX0JBVENIX1NJWkUgPSAxMDA7XG5cbmV4cG9ydCBjbGFzcyBQdXNoUXVldWUge1xuICBwYXJzZVB1Ymxpc2hlcjogT2JqZWN0O1xuICBjaGFubmVsOiBTdHJpbmc7XG4gIGJhdGNoU2l6ZTogTnVtYmVyO1xuXG4gIC8vIGNvbmZpZyBvYmplY3Qgb2YgdGhlIHB1Ymxpc2hlciwgcmlnaHQgbm93IGl0IG9ubHkgY29udGFpbnMgdGhlIHJlZGlzVVJMLFxuICAvLyBidXQgd2UgbWF5IGV4dGVuZCBpdCBsYXRlci5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBhbnkgPSB7fSkge1xuICAgIHRoaXMuY2hhbm5lbCA9IGNvbmZpZy5jaGFubmVsIHx8IFB1c2hRdWV1ZS5kZWZhdWx0UHVzaENoYW5uZWwoKTtcbiAgICB0aGlzLmJhdGNoU2l6ZSA9IGNvbmZpZy5iYXRjaFNpemUgfHwgREVGQVVMVF9CQVRDSF9TSVpFO1xuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIgPSBQYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVQdWJsaXNoZXIoY29uZmlnKTtcbiAgfVxuXG4gIHN0YXRpYyBkZWZhdWx0UHVzaENoYW5uZWwoKSB7XG4gICAgcmV0dXJuIGAke1BhcnNlLmFwcGxpY2F0aW9uSWR9LSR7UFVTSF9DSEFOTkVMfWA7XG4gIH1cblxuICBlbnF1ZXVlKGJvZHksIHdoZXJlLCBjb25maWcsIGF1dGgsIHB1c2hTdGF0dXMpIHtcbiAgICBjb25zdCBsaW1pdCA9IHRoaXMuYmF0Y2hTaXplO1xuXG4gICAgd2hlcmUgPSBhcHBseURldmljZVRva2VuRXhpc3RzKHdoZXJlKTtcblxuICAgIC8vIE9yZGVyIGJ5IG9iamVjdElkIHNvIG5vIGltcGFjdCBvbiB0aGUgREJcbiAgICBjb25zdCBvcmRlciA9ICdvYmplY3RJZCc7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiByZXN0LmZpbmQoY29uZmlnLCBhdXRoLCAnX0luc3RhbGxhdGlvbicsIHdoZXJlLCB7XG4gICAgICAgICAgbGltaXQ6IDAsXG4gICAgICAgICAgY291bnQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCh7IHJlc3VsdHMsIGNvdW50IH0pID0+IHtcbiAgICAgICAgaWYgKCFyZXN1bHRzIHx8IGNvdW50ID09IDApIHtcbiAgICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hTdGF0dXMuc2V0UnVubmluZyhNYXRoLmNlaWwoY291bnQgLyBsaW1pdCkpO1xuICAgICAgICBsZXQgc2tpcCA9IDA7XG4gICAgICAgIHdoaWxlIChza2lwIDwgY291bnQpIHtcbiAgICAgICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgICAgIHdoZXJlLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgb3JkZXIsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHB1c2hXb3JrSXRlbSA9IHtcbiAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgIHB1c2hTdGF0dXM6IHsgb2JqZWN0SWQ6IHB1c2hTdGF0dXMub2JqZWN0SWQgfSxcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uSWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5wYXJzZVB1Ymxpc2hlci5wdWJsaXNoKHRoaXMuY2hhbm5lbCwgSlNPTi5zdHJpbmdpZnkocHVzaFdvcmtJdGVtKSk7XG4gICAgICAgICAgc2tpcCArPSBsaW1pdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Push/PushWorker.js b/lib/Push/PushWorker.js new file mode 100644 index 0000000000..d845117b7b --- /dev/null +++ b/lib/Push/PushWorker.js @@ -0,0 +1,130 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushWorker = void 0; + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +var _AdaptableController = _interopRequireDefault(require("../Controllers/AdaptableController")); + +var _Auth = require("../Auth"); + +var _Config = _interopRequireDefault(require("../Config")); + +var _PushAdapter = require("../Adapters/Push/PushAdapter"); + +var _rest = _interopRequireDefault(require("../rest")); + +var _StatusHandler = require("../StatusHandler"); + +var utils = _interopRequireWildcard(require("./utils")); + +var _ParseMessageQueue = require("../ParseMessageQueue"); + +var _PushQueue = require("./PushQueue"); + +var _logger = _interopRequireDefault(require("../logger")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// -disable-next +function groupByBadge(installations) { + return installations.reduce((map, installation) => { + const badge = installation.badge + ''; + map[badge] = map[badge] || []; + map[badge].push(installation); + return map; + }, {}); +} + +class PushWorker { + constructor(pushAdapter, subscriberConfig = {}) { + _AdaptableController.default.validateAdapter(pushAdapter, this, _PushAdapter.PushAdapter); + + this.adapter = pushAdapter; + this.channel = subscriberConfig.channel || _PushQueue.PushQueue.defaultPushChannel(); + this.subscriber = _ParseMessageQueue.ParseMessageQueue.createSubscriber(subscriberConfig); + + if (this.subscriber) { + const subscriber = this.subscriber; + subscriber.subscribe(this.channel); + subscriber.on('message', (channel, messageStr) => { + const workItem = JSON.parse(messageStr); + this.run(workItem); + }); + } + } + + run({ + body, + query, + pushStatus, + applicationId, + UTCOffset + }) { + const config = _Config.default.get(applicationId); + + const auth = (0, _Auth.master)(config); + const where = utils.applyDeviceTokenExists(query.where); + delete query.where; + pushStatus = (0, _StatusHandler.pushStatusHandler)(config, pushStatus.objectId); + return _rest.default.find(config, auth, '_Installation', where, query).then(({ + results + }) => { + if (results.length == 0) { + return; + } + + return this.sendToAdapter(body, results, pushStatus, config, UTCOffset); + }); + } + + sendToAdapter(body, installations, pushStatus, config, UTCOffset) { + // Check if we have locales in the push body + const locales = utils.getLocalesFromPush(body); + + if (locales.length > 0) { + // Get all tranformed bodies for each locale + const bodiesPerLocales = utils.bodiesPerLocales(body, locales); // Group installations on the specified locales (en, fr, default etc...) + + const grouppedInstallations = utils.groupByLocaleIdentifier(installations, locales); + const promises = Object.keys(grouppedInstallations).map(locale => { + const installations = grouppedInstallations[locale]; + const body = bodiesPerLocales[locale]; + return this.sendToAdapter(body, installations, pushStatus, config, UTCOffset); + }); + return Promise.all(promises); + } + + if (!utils.isPushIncrementing(body)) { + _logger.default.verbose(`Sending push to ${installations.length}`); + + return this.adapter.send(body, installations, pushStatus.objectId).then(results => { + return pushStatus.trackSent(results, UTCOffset).then(() => results); + }); + } // Collect the badges to reduce the # of calls + + + const badgeInstallationsMap = groupByBadge(installations); // Map the on the badges count and return the send result + + const promises = Object.keys(badgeInstallationsMap).map(badge => { + const payload = (0, _deepcopy.default)(body); + payload.data.badge = parseInt(badge); + const installations = badgeInstallationsMap[badge]; + return this.sendToAdapter(payload, installations, pushStatus, config, UTCOffset); + }); + return Promise.all(promises); + } + +} + +exports.PushWorker = PushWorker; +var _default = PushWorker; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hXb3JrZXIuanMiXSwibmFtZXMiOlsiZ3JvdXBCeUJhZGdlIiwiaW5zdGFsbGF0aW9ucyIsInJlZHVjZSIsIm1hcCIsImluc3RhbGxhdGlvbiIsImJhZGdlIiwicHVzaCIsIlB1c2hXb3JrZXIiLCJjb25zdHJ1Y3RvciIsInB1c2hBZGFwdGVyIiwic3Vic2NyaWJlckNvbmZpZyIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJ2YWxpZGF0ZUFkYXB0ZXIiLCJQdXNoQWRhcHRlciIsImFkYXB0ZXIiLCJjaGFubmVsIiwiUHVzaFF1ZXVlIiwiZGVmYXVsdFB1c2hDaGFubmVsIiwic3Vic2NyaWJlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlU3Vic2NyaWJlciIsInN1YnNjcmliZSIsIm9uIiwibWVzc2FnZVN0ciIsIndvcmtJdGVtIiwiSlNPTiIsInBhcnNlIiwicnVuIiwiYm9keSIsInF1ZXJ5IiwicHVzaFN0YXR1cyIsImFwcGxpY2F0aW9uSWQiLCJVVENPZmZzZXQiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJhdXRoIiwid2hlcmUiLCJ1dGlscyIsImFwcGx5RGV2aWNlVG9rZW5FeGlzdHMiLCJvYmplY3RJZCIsInJlc3QiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJzZW5kVG9BZGFwdGVyIiwibG9jYWxlcyIsImdldExvY2FsZXNGcm9tUHVzaCIsImJvZGllc1BlckxvY2FsZXMiLCJncm91cHBlZEluc3RhbGxhdGlvbnMiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsInByb21pc2VzIiwiT2JqZWN0Iiwia2V5cyIsImxvY2FsZSIsIlByb21pc2UiLCJhbGwiLCJpc1B1c2hJbmNyZW1lbnRpbmciLCJsb2dnZXIiLCJ2ZXJib3NlIiwic2VuZCIsInRyYWNrU2VudCIsImJhZGdlSW5zdGFsbGF0aW9uc01hcCIsInBheWxvYWQiLCJkYXRhIiwicGFyc2VJbnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7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O0FBR0QsS0F0QlcsQ0F3Qlo7OztBQUNBLFVBQU1tQixxQkFBcUIsR0FBRy9ELFlBQVksQ0FBQ0MsYUFBRCxDQUExQyxDQXpCWSxDQTJCWjs7QUFDQSxVQUFNbUQsUUFBUSxHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWVMscUJBQVosRUFBbUM1RCxHQUFuQyxDQUF1Q0UsS0FBSyxJQUFJO0FBQy9ELFlBQU0yRCxPQUFPLEdBQUcsdUJBQVNwQyxJQUFULENBQWhCO0FBQ0FvQyxNQUFBQSxPQUFPLENBQUNDLElBQVIsQ0FBYTVELEtBQWIsR0FBcUI2RCxRQUFRLENBQUM3RCxLQUFELENBQTdCO0FBQ0EsWUFBTUosYUFBYSxHQUFHOEQscUJBQXFCLENBQUMxRCxLQUFELENBQTNDO0FBQ0EsYUFBTyxLQUFLeUMsYUFBTCxDQUFtQmtCLE9BQW5CLEVBQTRCL0QsYUFBNUIsRUFBMkM2QixVQUEzQyxFQUF1REcsTUFBdkQsRUFBK0RELFNBQS9ELENBQVA7QUFDRCxLQUxnQixDQUFqQjtBQU1BLFdBQU93QixPQUFPLENBQUNDLEdBQVIsQ0FBWUwsUUFBWixDQUFQO0FBQ0Q7O0FBNUVxQjs7O2VBK0VUN0MsVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBkZWVwY29weSBmcm9tICdkZWVwY29weSc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuLi9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IG1hc3RlciB9IGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IHsgUHVzaEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHVzaFN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUGFyc2VNZXNzYWdlUXVldWUgfSBmcm9tICcuLi9QYXJzZU1lc3NhZ2VRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuL1B1c2hRdWV1ZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKSB7XG4gIHJldHVybiBpbnN0YWxsYXRpb25zLnJlZHVjZSgobWFwLCBpbnN0YWxsYXRpb24pID0+IHtcbiAgICBjb25zdCBiYWRnZSA9IGluc3RhbGxhdGlvbi5iYWRnZSArICcnO1xuICAgIG1hcFtiYWRnZV0gPSBtYXBbYmFkZ2VdIHx8IFtdO1xuICAgIG1hcFtiYWRnZV0ucHVzaChpbnN0YWxsYXRpb24pO1xuICAgIHJldHVybiBtYXA7XG4gIH0sIHt9KTtcbn1cblxuZXhwb3J0IGNsYXNzIFB1c2hXb3JrZXIge1xuICBzdWJzY3JpYmVyOiA/YW55O1xuICBhZGFwdGVyOiBhbnk7XG4gIGNoYW5uZWw6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdXNoQWRhcHRlcjogUHVzaEFkYXB0ZXIsIHN1YnNjcmliZXJDb25maWc6IGFueSA9IHt9KSB7XG4gICAgQWRhcHRhYmxlQ29udHJvbGxlci52YWxpZGF0ZUFkYXB0ZXIocHVzaEFkYXB0ZXIsIHRoaXMsIFB1c2hBZGFwdGVyKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBwdXNoQWRhcHRlcjtcblxuICAgIHRoaXMuY2hhbm5lbCA9IHN1YnNjcmliZXJDb25maWcuY2hhbm5lbCB8fCBQdXNoUXVldWUuZGVmYXVsdFB1c2hDaGFubmVsKCk7XG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VNZXNzYWdlUXVldWUuY3JlYXRlU3Vic2NyaWJlcihzdWJzY3JpYmVyQ29uZmlnKTtcbiAgICBpZiAodGhpcy5zdWJzY3JpYmVyKSB7XG4gICAgICBjb25zdCBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmVyO1xuICAgICAgc3Vic2NyaWJlci5zdWJzY3JpYmUodGhpcy5jaGFubmVsKTtcbiAgICAgIHN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgICBjb25zdCB3b3JrSXRlbSA9IEpTT04ucGFyc2UobWVzc2FnZVN0cik7XG4gICAgICAgIHRoaXMucnVuKHdvcmtJdGVtKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJ1bih7IGJvZHksIHF1ZXJ5LCBwdXNoU3RhdHVzLCBhcHBsaWNhdGlvbklkLCBVVENPZmZzZXQgfTogYW55KTogUHJvbWlzZTwqPiB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBsaWNhdGlvbklkKTtcbiAgICBjb25zdCBhdXRoID0gbWFzdGVyKGNvbmZpZyk7XG4gICAgY29uc3Qgd2hlcmUgPSB1dGlscy5hcHBseURldmljZVRva2VuRXhpc3RzKHF1ZXJ5LndoZXJlKTtcbiAgICBkZWxldGUgcXVlcnkud2hlcmU7XG4gICAgcHVzaFN0YXR1cyA9IHB1c2hTdGF0dXNIYW5kbGVyKGNvbmZpZywgcHVzaFN0YXR1cy5vYmplY3RJZCk7XG4gICAgcmV0dXJuIHJlc3QuZmluZChjb25maWcsIGF1dGgsICdfSW5zdGFsbGF0aW9uJywgd2hlcmUsIHF1ZXJ5KS50aGVuKCh7IHJlc3VsdHMgfSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCByZXN1bHRzLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgfSk7XG4gIH1cblxuICBzZW5kVG9BZGFwdGVyKFxuICAgIGJvZHk6IGFueSxcbiAgICBpbnN0YWxsYXRpb25zOiBhbnlbXSxcbiAgICBwdXNoU3RhdHVzOiBhbnksXG4gICAgY29uZmlnOiBDb25maWcsXG4gICAgVVRDT2Zmc2V0OiA/YW55XG4gICk6IFByb21pc2U8Kj4ge1xuICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgbG9jYWxlcyBpbiB0aGUgcHVzaCBib2R5XG4gICAgY29uc3QgbG9jYWxlcyA9IHV0aWxzLmdldExvY2FsZXNGcm9tUHVzaChib2R5KTtcbiAgICBpZiAobG9jYWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBHZXQgYWxsIHRyYW5mb3JtZWQgYm9kaWVzIGZvciBlYWNoIGxvY2FsZVxuICAgICAgY29uc3QgYm9kaWVzUGVyTG9jYWxlcyA9IHV0aWxzLmJvZGllc1BlckxvY2FsZXMoYm9keSwgbG9jYWxlcyk7XG5cbiAgICAgIC8vIEdyb3VwIGluc3RhbGxhdGlvbnMgb24gdGhlIHNwZWNpZmllZCBsb2NhbGVzIChlbiwgZnIsIGRlZmF1bHQgZXRjLi4uKVxuICAgICAgY29uc3QgZ3JvdXBwZWRJbnN0YWxsYXRpb25zID0gdXRpbHMuZ3JvdXBCeUxvY2FsZUlkZW50aWZpZXIoaW5zdGFsbGF0aW9ucywgbG9jYWxlcyk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKGdyb3VwcGVkSW5zdGFsbGF0aW9ucykubWFwKGxvY2FsZSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbnMgPSBncm91cHBlZEluc3RhbGxhdGlvbnNbbG9jYWxlXTtcbiAgICAgICAgY29uc3QgYm9keSA9IGJvZGllc1BlckxvY2FsZXNbbG9jYWxlXTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlscy5pc1B1c2hJbmNyZW1lbnRpbmcoYm9keSkpIHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBTZW5kaW5nIHB1c2ggdG8gJHtpbnN0YWxsYXRpb25zLmxlbmd0aH1gKTtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuc2VuZChib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLm9iamVjdElkKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy50cmFja1NlbnQocmVzdWx0cywgVVRDT2Zmc2V0KS50aGVuKCgpID0+IHJlc3VsdHMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29sbGVjdCB0aGUgYmFkZ2VzIHRvIHJlZHVjZSB0aGUgIyBvZiBjYWxsc1xuICAgIGNvbnN0IGJhZGdlSW5zdGFsbGF0aW9uc01hcCA9IGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKTtcblxuICAgIC8vIE1hcCB0aGUgb24gdGhlIGJhZGdlcyBjb3VudCBhbmQgcmV0dXJuIHRoZSBzZW5kIHJlc3VsdFxuICAgIGNvbnN0IHByb21pc2VzID0gT2JqZWN0LmtleXMoYmFkZ2VJbnN0YWxsYXRpb25zTWFwKS5tYXAoYmFkZ2UgPT4ge1xuICAgICAgY29uc3QgcGF5bG9hZCA9IGRlZXBjb3B5KGJvZHkpO1xuICAgICAgcGF5bG9hZC5kYXRhLmJhZGdlID0gcGFyc2VJbnQoYmFkZ2UpO1xuICAgICAgY29uc3QgaW5zdGFsbGF0aW9ucyA9IGJhZGdlSW5zdGFsbGF0aW9uc01hcFtiYWRnZV07XG4gICAgICByZXR1cm4gdGhpcy5zZW5kVG9BZGFwdGVyKHBheWxvYWQsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMsIGNvbmZpZywgVVRDT2Zmc2V0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1c2hXb3JrZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Push/utils.js b/lib/Push/utils.js new file mode 100644 index 0000000000..a35a716a15 --- /dev/null +++ b/lib/Push/utils.js @@ -0,0 +1,159 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isPushIncrementing = isPushIncrementing; +exports.getLocalesFromPush = getLocalesFromPush; +exports.transformPushBodyForLocale = transformPushBodyForLocale; +exports.stripLocalesFromBody = stripLocalesFromBody; +exports.bodiesPerLocales = bodiesPerLocales; +exports.groupByLocaleIdentifier = groupByLocaleIdentifier; +exports.validatePushType = validatePushType; +exports.applyDeviceTokenExists = applyDeviceTokenExists; + +var _node = _interopRequireDefault(require("parse/node")); + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function isPushIncrementing(body) { + if (!body.data || !body.data.badge) { + return false; + } + + const badge = body.data.badge; + + if (typeof badge == 'string' && badge.toLowerCase() == 'increment') { + return true; + } + + return typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount); +} + +const localizableKeys = ['alert', 'title']; + +function getLocalesFromPush(body) { + const data = body.data; + + if (!data) { + return []; + } + + return [...new Set(Object.keys(data).reduce((memo, key) => { + localizableKeys.forEach(localizableKey => { + if (key.indexOf(`${localizableKey}-`) == 0) { + memo.push(key.slice(localizableKey.length + 1)); + } + }); + return memo; + }, []))]; +} + +function transformPushBodyForLocale(body, locale) { + const data = body.data; + + if (!data) { + return body; + } + + body = (0, _deepcopy.default)(body); + localizableKeys.forEach(key => { + const localeValue = body.data[`${key}-${locale}`]; + + if (localeValue) { + body.data[key] = localeValue; + } + }); + return stripLocalesFromBody(body); +} + +function stripLocalesFromBody(body) { + if (!body.data) { + return body; + } + + Object.keys(body.data).forEach(key => { + localizableKeys.forEach(localizableKey => { + if (key.indexOf(`${localizableKey}-`) == 0) { + delete body.data[key]; + } + }); + }); + return body; +} + +function bodiesPerLocales(body, locales = []) { + // Get all tranformed bodies for each locale + const result = locales.reduce((memo, locale) => { + memo[locale] = transformPushBodyForLocale(body, locale); + return memo; + }, {}); // Set the default locale, with the stripped body + + result.default = stripLocalesFromBody(body); + return result; +} + +function groupByLocaleIdentifier(installations, locales = []) { + return installations.reduce((map, installation) => { + let added = false; + locales.forEach(locale => { + if (added) { + return; + } + + if (installation.localeIdentifier && installation.localeIdentifier.indexOf(locale) === 0) { + added = true; + map[locale] = map[locale] || []; + map[locale].push(installation); + } + }); + + if (!added) { + map.default.push(installation); + } + + return map; + }, { + default: [] + }); +} +/** + * Check whether the deviceType parameter in qury condition is valid or not. + * @param {Object} where A query condition + * @param {Array} validPushTypes An array of valid push types(string) + */ + + +function validatePushType(where = {}, validPushTypes = []) { + var deviceTypeField = where.deviceType || {}; + var deviceTypes = []; + + if (typeof deviceTypeField === 'string') { + deviceTypes.push(deviceTypeField); + } else if (Array.isArray(deviceTypeField['$in'])) { + deviceTypes.concat(deviceTypeField['$in']); + } + + for (var i = 0; i < deviceTypes.length; i++) { + var deviceType = deviceTypes[i]; + + if (validPushTypes.indexOf(deviceType) < 0) { + throw new _node.default.Error(_node.default.Error.PUSH_MISCONFIGURED, deviceType + ' is not supported push type.'); + } + } +} + +function applyDeviceTokenExists(where) { + where = (0, _deepcopy.default)(where); + + if (!Object.prototype.hasOwnProperty.call(where, 'deviceToken')) { + where['deviceToken'] = { + $exists: true + }; + } + + return where; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL3V0aWxzLmpzIl0sIm5hbWVzIjpbImlzUHVzaEluY3JlbWVudGluZyIsImJvZHkiLCJkYXRhIiwiYmFkZ2UiLCJ0b0xvd2VyQ2FzZSIsIl9fb3AiLCJOdW1iZXIiLCJhbW91bnQiLCJsb2NhbGl6YWJsZUtleXMiLCJnZXRMb2NhbGVzRnJvbVB1c2giLCJTZXQiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwibWVtbyIsImtleSIsImZvckVhY2giLCJsb2NhbGl6YWJsZUtleSIsImluZGV4T2YiLCJwdXNoIiwic2xpY2UiLCJsZW5ndGgiLCJ0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZSIsImxvY2FsZSIsImxvY2FsZVZhbHVlIiwic3RyaXBMb2NhbGVzRnJvbUJvZHkiLCJib2RpZXNQZXJMb2NhbGVzIiwibG9jYWxlcyIsInJlc3VsdCIsImRlZmF1bHQiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsImluc3RhbGxhdGlvbnMiLCJtYXAiLCJpbnN0YWxsYXRpb24iLCJhZGRlZCIsImxvY2FsZUlkZW50aWZpZXIiLCJ2YWxpZGF0ZVB1c2hUeXBlIiwid2hlcmUiLCJ2YWxpZFB1c2hUeXBlcyIsImRldmljZVR5cGVGaWVsZCIsImRldmljZVR5cGUiLCJkZXZpY2VUeXBlcyIsIkFycmF5IiwiaXNBcnJheSIsImNvbmNhdCIsImkiLCJQYXJzZSIsIkVycm9yIiwiUFVTSF9NSVNDT05GSUdVUkVEIiwiYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIiRleGlzdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxTQUFTQSxrQkFBVCxDQUE0QkMsSUFBNUIsRUFBa0M7QUFDdkMsTUFBSSxDQUFDQSxJQUFJLENBQUNDLElBQU4sSUFBYyxDQUFDRCxJQUFJLENBQUNDLElBQUwsQ0FBVUMsS0FBN0IsRUFBb0M7QUFDbEMsV0FBTyxLQUFQO0FB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Z0IsTUFBQUEsT0FBTyxFQUFFO0FBQVgsS0FBdkI7QUFDRDs7QUFDRCxTQUFPaEIsS0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGRlZXBjb3B5IGZyb20gJ2RlZXBjb3B5JztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHVzaEluY3JlbWVudGluZyhib2R5KSB7XG4gIGlmICghYm9keS5kYXRhIHx8ICFib2R5LmRhdGEuYmFkZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBiYWRnZSA9IGJvZHkuZGF0YS5iYWRnZTtcbiAgaWYgKHR5cGVvZiBiYWRnZSA9PSAnc3RyaW5nJyAmJiBiYWRnZS50b0xvd2VyQ2FzZSgpID09ICdpbmNyZW1lbnQnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIHR5cGVvZiBiYWRnZSA9PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBiYWRnZS5fX29wID09ICdzdHJpbmcnICYmXG4gICAgYmFkZ2UuX19vcC50b0xvd2VyQ2FzZSgpID09ICdpbmNyZW1lbnQnICYmXG4gICAgTnVtYmVyKGJhZGdlLmFtb3VudClcbiAgKTtcbn1cblxuY29uc3QgbG9jYWxpemFibGVLZXlzID0gWydhbGVydCcsICd0aXRsZSddO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9jYWxlc0Zyb21QdXNoKGJvZHkpIHtcbiAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YTtcbiAgaWYgKCFkYXRhKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBbXG4gICAgLi4ubmV3IFNldChcbiAgICAgIE9iamVjdC5rZXlzKGRhdGEpLnJlZHVjZSgobWVtbywga2V5KSA9PiB7XG4gICAgICAgIGxvY2FsaXphYmxlS2V5cy5mb3JFYWNoKGxvY2FsaXphYmxlS2V5ID0+IHtcbiAgICAgICAgICBpZiAoa2V5LmluZGV4T2YoYCR7bG9jYWxpemFibGVLZXl9LWApID09IDApIHtcbiAgICAgICAgICAgIG1lbW8ucHVzaChrZXkuc2xpY2UobG9jYWxpemFibGVLZXkubGVuZ3RoICsgMSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgfSwgW10pXG4gICAgKSxcbiAgXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVB1c2hCb2R5Rm9yTG9jYWxlKGJvZHksIGxvY2FsZSkge1xuICBjb25zdCBkYXRhID0gYm9keS5kYXRhO1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm4gYm9keTtcbiAgfVxuICBib2R5ID0gZGVlcGNvcHkoYm9keSk7XG4gIGxvY2FsaXphYmxlS2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgY29uc3QgbG9jYWxlVmFsdWUgPSBib2R5LmRhdGFbYCR7a2V5fS0ke2xvY2FsZX1gXTtcbiAgICBpZiAobG9jYWxlVmFsdWUpIHtcbiAgICAgIGJvZHkuZGF0YVtrZXldID0gbG9jYWxlVmFsdWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHN0cmlwTG9jYWxlc0Zyb21Cb2R5KGJvZHkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RyaXBMb2NhbGVzRnJvbUJvZHkoYm9keSkge1xuICBpZiAoIWJvZHkuZGF0YSkge1xuICAgIHJldHVybiBib2R5O1xuICB9XG4gIE9iamVjdC5rZXlzKGJvZHkuZGF0YSkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGxvY2FsaXphYmxlS2V5cy5mb3JFYWNoKGxvY2FsaXphYmxlS2V5ID0+IHtcbiAgICAgIGlmIChrZXkuaW5kZXhPZihgJHtsb2NhbGl6YWJsZUtleX0tYCkgPT0gMCkge1xuICAgICAgICBkZWxldGUgYm9keS5kYXRhW2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gYm9keTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJvZGllc1BlckxvY2FsZXMoYm9keSwgbG9jYWxlcyA9IFtdKSB7XG4gIC8vIEdldCBhbGwgdHJhbmZvcm1lZCBib2RpZXMgZm9yIGVhY2ggbG9jYWxlXG4gIGNvbnN0IHJlc3VsdCA9IGxvY2FsZXMucmVkdWNlKChtZW1vLCBsb2NhbGUpID0+IHtcbiAgICBtZW1vW2xvY2FsZV0gPSB0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZShib2R5LCBsb2NhbGUpO1xuICAgIHJldHVybiBtZW1vO1xuICB9LCB7fSk7XG4gIC8vIFNldCB0aGUgZGVmYXVsdCBsb2NhbGUsIHdpdGggdGhlIHN0cmlwcGVkIGJvZHlcbiAgcmVzdWx0LmRlZmF1bHQgPSBzdHJpcExvY2FsZXNGcm9tQm9keShib2R5KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwQnlMb2NhbGVJZGVudGlmaWVyKGluc3RhbGxhdGlvbnMsIGxvY2FsZXMgPSBbXSkge1xuICByZXR1cm4gaW5zdGFsbGF0aW9ucy5yZWR1Y2UoXG4gICAgKG1hcCwgaW5zdGFsbGF0aW9uKSA9PiB7XG4gICAgICBsZXQgYWRkZWQgPSBmYWxzZTtcbiAgICAgIGxvY2FsZXMuZm9yRWFjaChsb2NhbGUgPT4ge1xuICAgICAgICBpZiAoYWRkZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5sb2NhbGVJZGVudGlmaWVyICYmIGluc3RhbGxhdGlvbi5sb2NhbGVJZGVudGlmaWVyLmluZGV4T2YobG9jYWxlKSA9PT0gMCkge1xuICAgICAgICAgIGFkZGVkID0gdHJ1ZTtcbiAgICAgICAgICBtYXBbbG9jYWxlXSA9IG1hcFtsb2NhbGVdIHx8IFtdO1xuICAgICAgICAgIG1hcFtsb2NhbGVdLnB1c2goaW5zdGFsbGF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoIWFkZGVkKSB7XG4gICAgICAgIG1hcC5kZWZhdWx0LnB1c2goaW5zdGFsbGF0aW9uKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYXA7XG4gICAgfSxcbiAgICB7IGRlZmF1bHQ6IFtdIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIHRoZSBkZXZpY2VUeXBlIHBhcmFtZXRlciBpbiBxdXJ5IGNvbmRpdGlvbiBpcyB2YWxpZCBvciBub3QuXG4gKiBAcGFyYW0ge09iamVjdH0gd2hlcmUgQSBxdWVyeSBjb25kaXRpb25cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbGlkUHVzaFR5cGVzIEFuIGFycmF5IG9mIHZhbGlkIHB1c2ggdHlwZXMoc3RyaW5nKVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQdXNoVHlwZSh3aGVyZSA9IHt9LCB2YWxpZFB1c2hUeXBlcyA9IFtdKSB7XG4gIHZhciBkZXZpY2VUeXBlRmllbGQgPSB3aGVyZS5kZXZpY2VUeXBlIHx8IHt9O1xuICB2YXIgZGV2aWNlVHlwZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBkZXZpY2VUeXBlRmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgZGV2aWNlVHlwZXMucHVzaChkZXZpY2VUeXBlRmllbGQpO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZGV2aWNlVHlwZUZpZWxkWyckaW4nXSkpIHtcbiAgICBkZXZpY2VUeXBlcy5jb25jYXQoZGV2aWNlVHlwZUZpZWxkWyckaW4nXSk7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXZpY2VUeXBlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXZpY2VUeXBlID0gZGV2aWNlVHlwZXNbaV07XG4gICAgaWYgKHZhbGlkUHVzaFR5cGVzLmluZGV4T2YoZGV2aWNlVHlwZSkgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgZGV2aWNlVHlwZSArICcgaXMgbm90IHN1cHBvcnRlZCBwdXNoIHR5cGUuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5RGV2aWNlVG9rZW5FeGlzdHMod2hlcmUpIHtcbiAgd2hlcmUgPSBkZWVwY29weSh3aGVyZSk7XG4gIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHdoZXJlLCAnZGV2aWNlVG9rZW4nKSkge1xuICAgIHdoZXJlWydkZXZpY2VUb2tlbiddID0geyAkZXhpc3RzOiB0cnVlIH07XG4gIH1cbiAgcmV0dXJuIHdoZXJlO1xufVxuIl19 \ No newline at end of file diff --git a/lib/RestQuery.js b/lib/RestQuery.js new file mode 100644 index 0000000000..02d7d0f9d3 --- /dev/null +++ b/lib/RestQuery.js @@ -0,0 +1,978 @@ +"use strict"; + +// An object that encapsulates everything we need to run a 'find' +// operation, encoded in the REST API format. +var SchemaController = require('./Controllers/SchemaController'); + +var Parse = require('parse/node').Parse; + +const triggers = require('./triggers'); + +const { + continueWhile +} = require('parse/lib/node/promiseUtils'); + +const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL']; // restOptions can include: +// skip +// limit +// order +// count +// include +// keys +// excludeKeys +// redirectClassNameForKey +// readPreference +// includeReadPreference +// subqueryReadPreference + +function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, clientSDK, runAfterFind = true) { + this.config = config; + this.auth = auth; + this.className = className; + this.restWhere = restWhere; + this.restOptions = restOptions; + this.clientSDK = clientSDK; + this.runAfterFind = runAfterFind; + this.response = null; + this.findOptions = {}; + + if (!this.auth.isMaster) { + if (this.className == '_Session') { + if (!this.auth.user) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + this.restWhere = { + $and: [this.restWhere, { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.auth.user.id + } + }] + }; + } + } + + this.doCount = false; + this.includeAll = false; // The format for this.include is not the same as the format for the + // include option - it's the paths we should include, in order, + // stored as arrays, taking into account that we need to include foo + // before including foo.bar. Also it should dedupe. + // For example, passing an arg of include=foo.bar,foo.baz could lead to + // this.include = [['foo'], ['foo', 'baz'], ['foo', 'bar']] + + this.include = []; // If we have keys, we probably want to force some includes (n-1 level) + // See issue: https://github.com/parse-community/parse-server/issues/3185 + + if (Object.prototype.hasOwnProperty.call(restOptions, 'keys')) { + const keysForInclude = restOptions.keys.split(',').filter(key => { + // At least 2 components + return key.split('.').length > 1; + }).map(key => { + // Slice the last component (a.b.c -> a.b) + // Otherwise we'll include one level too much. + return key.slice(0, key.lastIndexOf('.')); + }).join(','); // Concat the possibly present include string with the one from the keys + // Dedup / sorting is handle in 'include' case. + + if (keysForInclude.length > 0) { + if (!restOptions.include || restOptions.include.length == 0) { + restOptions.include = keysForInclude; + } else { + restOptions.include += ',' + keysForInclude; + } + } + } + + for (var option in restOptions) { + switch (option) { + case 'keys': + { + const keys = restOptions.keys.split(',').concat(AlwaysSelectedKeys); + this.keys = Array.from(new Set(keys)); + break; + } + + case 'excludeKeys': + { + const exclude = restOptions.excludeKeys.split(',').filter(k => AlwaysSelectedKeys.indexOf(k) < 0); + this.excludeKeys = Array.from(new Set(exclude)); + break; + } + + case 'count': + this.doCount = true; + break; + + case 'includeAll': + this.includeAll = true; + break; + + case 'explain': + case 'hint': + case 'distinct': + case 'pipeline': + case 'skip': + case 'limit': + case 'readPreference': + this.findOptions[option] = restOptions[option]; + break; + + case 'order': + var fields = restOptions.order.split(','); + this.findOptions.sort = fields.reduce((sortMap, field) => { + field = field.trim(); + + if (field === '$score') { + sortMap.score = { + $meta: 'textScore' + }; + } else if (field[0] == '-') { + sortMap[field.slice(1)] = -1; + } else { + sortMap[field] = 1; + } + + return sortMap; + }, {}); + break; + + case 'include': + { + const paths = restOptions.include.split(','); + + if (paths.includes('*')) { + this.includeAll = true; + break; + } // Load the existing includes (from keys) + + + const pathSet = paths.reduce((memo, path) => { + // Split each paths on . (a.b.c -> [a,b,c]) + // reduce to create all paths + // ([a,b,c] -> {a: true, 'a.b': true, 'a.b.c': true}) + return path.split('.').reduce((memo, path, index, parts) => { + memo[parts.slice(0, index + 1).join('.')] = true; + return memo; + }, memo); + }, {}); + this.include = Object.keys(pathSet).map(s => { + return s.split('.'); + }).sort((a, b) => { + return a.length - b.length; // Sort by number of components + }); + break; + } + + case 'redirectClassNameForKey': + this.redirectKey = restOptions.redirectClassNameForKey; + this.redirectClassName = null; + break; + + case 'includeReadPreference': + case 'subqueryReadPreference': + break; + + default: + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad option: ' + option); + } + } +} // A convenient method to perform all the steps of processing a query +// in order. +// Returns a promise for the response - an object with optional keys +// 'results' and 'count'. +// TODO: consolidate the replaceX functions + + +RestQuery.prototype.execute = function (executeOptions) { + return Promise.resolve().then(() => { + return this.buildRestWhere(); + }).then(() => { + return this.handleIncludeAll(); + }).then(() => { + return this.handleExcludeKeys(); + }).then(() => { + return this.runFind(executeOptions); + }).then(() => { + return this.runCount(); + }).then(() => { + return this.handleInclude(); + }).then(() => { + return this.runAfterFindTrigger(); + }).then(() => { + return this.response; + }); +}; + +RestQuery.prototype.each = function (callback) { + const { + config, + auth, + className, + restWhere, + restOptions, + clientSDK + } = this; // if the limit is set, use it + + restOptions.limit = restOptions.limit || 100; + restOptions.order = 'objectId'; + let finished = false; + return continueWhile(() => { + return !finished; + }, async () => { + const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); + const { + results + } = await query.execute(); + results.forEach(callback); + finished = results.length < restOptions.limit; + + if (!finished) { + restWhere.objectId = Object.assign({}, restWhere.objectId, { + $gt: results[results.length - 1].objectId + }); + } + }); +}; + +RestQuery.prototype.buildRestWhere = function () { + return Promise.resolve().then(() => { + return this.getUserAndRoleACL(); + }).then(() => { + return this.redirectClassNameForKey(); + }).then(() => { + return this.validateClientClassCreation(); + }).then(() => { + return this.replaceSelect(); + }).then(() => { + return this.replaceDontSelect(); + }).then(() => { + return this.replaceInQuery(); + }).then(() => { + return this.replaceNotInQuery(); + }).then(() => { + return this.replaceEquality(); + }); +}; // Uses the Auth object to get the list of roles, adds the user id + + +RestQuery.prototype.getUserAndRoleACL = function () { + if (this.auth.isMaster) { + return Promise.resolve(); + } + + this.findOptions.acl = ['*']; + + if (this.auth.user) { + return this.auth.getUserRoles().then(roles => { + this.findOptions.acl = this.findOptions.acl.concat(roles, [this.auth.user.id]); + return; + }); + } else { + return Promise.resolve(); + } +}; // Changes the className if redirectClassNameForKey is set. +// Returns a promise. + + +RestQuery.prototype.redirectClassNameForKey = function () { + if (!this.redirectKey) { + return Promise.resolve(); + } // We need to change the class name based on the schema + + + return this.config.database.redirectClassNameForKey(this.className, this.redirectKey).then(newClassName => { + this.className = newClassName; + this.redirectClassName = newClassName; + }); +}; // Validates this operation against the allowClientClassCreation config. + + +RestQuery.prototype.validateClientClassCreation = function () { + if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { + return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { + if (hasClass !== true) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); + } + }); + } else { + return Promise.resolve(); + } +}; + +function transformInQuery(inQueryObject, className, results) { + var values = []; + + for (var result of results) { + values.push({ + __type: 'Pointer', + className: className, + objectId: result.objectId + }); + } + + delete inQueryObject['$inQuery']; + + if (Array.isArray(inQueryObject['$in'])) { + inQueryObject['$in'] = inQueryObject['$in'].concat(values); + } else { + inQueryObject['$in'] = values; + } +} // Replaces a $inQuery clause by running the subquery, if there is an +// $inQuery clause. +// The $inQuery clause turns into an $in with values that are just +// pointers to the objects returned in the subquery. + + +RestQuery.prototype.replaceInQuery = function () { + var inQueryObject = findObjectWithKey(this.restWhere, '$inQuery'); + + if (!inQueryObject) { + return; + } // The inQuery value must have precisely two keys - where and className + + + var inQueryValue = inQueryObject['$inQuery']; + + if (!inQueryValue.where || !inQueryValue.className) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $inQuery'); + } + + const additionalOptions = { + redirectClassNameForKey: inQueryValue.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, inQueryValue.className, inQueryValue.where, additionalOptions); + return subquery.execute().then(response => { + transformInQuery(inQueryObject, subquery.className, response.results); // Recurse to repeat + + return this.replaceInQuery(); + }); +}; + +function transformNotInQuery(notInQueryObject, className, results) { + var values = []; + + for (var result of results) { + values.push({ + __type: 'Pointer', + className: className, + objectId: result.objectId + }); + } + + delete notInQueryObject['$notInQuery']; + + if (Array.isArray(notInQueryObject['$nin'])) { + notInQueryObject['$nin'] = notInQueryObject['$nin'].concat(values); + } else { + notInQueryObject['$nin'] = values; + } +} // Replaces a $notInQuery clause by running the subquery, if there is an +// $notInQuery clause. +// The $notInQuery clause turns into a $nin with values that are just +// pointers to the objects returned in the subquery. + + +RestQuery.prototype.replaceNotInQuery = function () { + var notInQueryObject = findObjectWithKey(this.restWhere, '$notInQuery'); + + if (!notInQueryObject) { + return; + } // The notInQuery value must have precisely two keys - where and className + + + var notInQueryValue = notInQueryObject['$notInQuery']; + + if (!notInQueryValue.where || !notInQueryValue.className) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $notInQuery'); + } + + const additionalOptions = { + redirectClassNameForKey: notInQueryValue.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, notInQueryValue.className, notInQueryValue.where, additionalOptions); + return subquery.execute().then(response => { + transformNotInQuery(notInQueryObject, subquery.className, response.results); // Recurse to repeat + + return this.replaceNotInQuery(); + }); +}; // Used to get the deepest object from json using dot notation. + + +const getDeepestObjectFromKey = (json, key, idx, src) => { + if (key in json) { + return json[key]; + } + + src.splice(1); // Exit Early +}; + +const transformSelect = (selectObject, key, objects) => { + var values = []; + + for (var result of objects) { + values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); + } + + delete selectObject['$select']; + + if (Array.isArray(selectObject['$in'])) { + selectObject['$in'] = selectObject['$in'].concat(values); + } else { + selectObject['$in'] = values; + } +}; // Replaces a $select clause by running the subquery, if there is a +// $select clause. +// The $select clause turns into an $in with values selected out of +// the subquery. +// Returns a possible-promise. + + +RestQuery.prototype.replaceSelect = function () { + var selectObject = findObjectWithKey(this.restWhere, '$select'); + + if (!selectObject) { + return; + } // The select value must have precisely two keys - query and key + + + var selectValue = selectObject['$select']; // iOS SDK don't send where if not set, let it pass + + if (!selectValue.query || !selectValue.key || typeof selectValue.query !== 'object' || !selectValue.query.className || Object.keys(selectValue).length !== 2) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $select'); + } + + const additionalOptions = { + redirectClassNameForKey: selectValue.query.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, selectValue.query.className, selectValue.query.where, additionalOptions); + return subquery.execute().then(response => { + transformSelect(selectObject, selectValue.key, response.results); // Keep replacing $select clauses + + return this.replaceSelect(); + }); +}; + +const transformDontSelect = (dontSelectObject, key, objects) => { + var values = []; + + for (var result of objects) { + values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); + } + + delete dontSelectObject['$dontSelect']; + + if (Array.isArray(dontSelectObject['$nin'])) { + dontSelectObject['$nin'] = dontSelectObject['$nin'].concat(values); + } else { + dontSelectObject['$nin'] = values; + } +}; // Replaces a $dontSelect clause by running the subquery, if there is a +// $dontSelect clause. +// The $dontSelect clause turns into an $nin with values selected out of +// the subquery. +// Returns a possible-promise. + + +RestQuery.prototype.replaceDontSelect = function () { + var dontSelectObject = findObjectWithKey(this.restWhere, '$dontSelect'); + + if (!dontSelectObject) { + return; + } // The dontSelect value must have precisely two keys - query and key + + + var dontSelectValue = dontSelectObject['$dontSelect']; + + if (!dontSelectValue.query || !dontSelectValue.key || typeof dontSelectValue.query !== 'object' || !dontSelectValue.query.className || Object.keys(dontSelectValue).length !== 2) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $dontSelect'); + } + + const additionalOptions = { + redirectClassNameForKey: dontSelectValue.query.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, dontSelectValue.query.className, dontSelectValue.query.where, additionalOptions); + return subquery.execute().then(response => { + transformDontSelect(dontSelectObject, dontSelectValue.key, response.results); // Keep replacing $dontSelect clauses + + return this.replaceDontSelect(); + }); +}; + +const cleanResultAuthData = function (result) { + delete result.password; + + if (result.authData) { + Object.keys(result.authData).forEach(provider => { + if (result.authData[provider] === null) { + delete result.authData[provider]; + } + }); + + if (Object.keys(result.authData).length == 0) { + delete result.authData; + } + } +}; + +const replaceEqualityConstraint = constraint => { + if (typeof constraint !== 'object') { + return constraint; + } + + const equalToObject = {}; + let hasDirectConstraint = false; + let hasOperatorConstraint = false; + + for (const key in constraint) { + if (key.indexOf('$') !== 0) { + hasDirectConstraint = true; + equalToObject[key] = constraint[key]; + } else { + hasOperatorConstraint = true; + } + } + + if (hasDirectConstraint && hasOperatorConstraint) { + constraint['$eq'] = equalToObject; + Object.keys(equalToObject).forEach(key => { + delete constraint[key]; + }); + } + + return constraint; +}; + +RestQuery.prototype.replaceEquality = function () { + if (typeof this.restWhere !== 'object') { + return; + } + + for (const key in this.restWhere) { + this.restWhere[key] = replaceEqualityConstraint(this.restWhere[key]); + } +}; // Returns a promise for whether it was successful. +// Populates this.response with an object that only has 'results'. + + +RestQuery.prototype.runFind = function (options = {}) { + if (this.findOptions.limit === 0) { + this.response = { + results: [] + }; + return Promise.resolve(); + } + + const findOptions = Object.assign({}, this.findOptions); + + if (this.keys) { + findOptions.keys = this.keys.map(key => { + return key.split('.')[0]; + }); + } + + if (options.op) { + findOptions.op = options.op; + } + + return this.config.database.find(this.className, this.restWhere, findOptions, this.auth).then(results => { + if (this.className === '_User' && findOptions.explain !== true) { + for (var result of results) { + cleanResultAuthData(result); + } + } + + this.config.filesController.expandFilesInObject(this.config, results); + + if (this.redirectClassName) { + for (var r of results) { + r.className = this.redirectClassName; + } + } + + this.response = { + results: results + }; + }); +}; // Returns a promise for whether it was successful. +// Populates this.response.count with the count + + +RestQuery.prototype.runCount = function () { + if (!this.doCount) { + return; + } + + this.findOptions.count = true; + delete this.findOptions.skip; + delete this.findOptions.limit; + return this.config.database.find(this.className, this.restWhere, this.findOptions).then(c => { + this.response.count = c; + }); +}; // Augments this.response with all pointers on an object + + +RestQuery.prototype.handleIncludeAll = function () { + if (!this.includeAll) { + return; + } + + return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { + const includeFields = []; + const keyFields = []; + + for (const field in schema.fields) { + if (schema.fields[field].type && schema.fields[field].type === 'Pointer') { + includeFields.push([field]); + keyFields.push(field); + } + } // Add fields to include, keys, remove dups + + + this.include = [...new Set([...this.include, ...includeFields])]; // if this.keys not set, then all keys are already included + + if (this.keys) { + this.keys = [...new Set([...this.keys, ...keyFields])]; + } + }); +}; // Updates property `this.keys` to contain all keys but the ones unselected. + + +RestQuery.prototype.handleExcludeKeys = function () { + if (!this.excludeKeys) { + return; + } + + if (this.keys) { + this.keys = this.keys.filter(k => !this.excludeKeys.includes(k)); + return; + } + + return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { + const fields = Object.keys(schema.fields); + this.keys = fields.filter(k => !this.excludeKeys.includes(k)); + }); +}; // Augments this.response with data at the paths provided in this.include. + + +RestQuery.prototype.handleInclude = function () { + if (this.include.length == 0) { + return; + } + + var pathResponse = includePath(this.config, this.auth, this.response, this.include[0], this.restOptions); + + if (pathResponse.then) { + return pathResponse.then(newResponse => { + this.response = newResponse; + this.include = this.include.slice(1); + return this.handleInclude(); + }); + } else if (this.include.length > 0) { + this.include = this.include.slice(1); + return this.handleInclude(); + } + + return pathResponse; +}; //Returns a promise of a processed set of results + + +RestQuery.prototype.runAfterFindTrigger = function () { + if (!this.response) { + return; + } + + if (!this.runAfterFind) { + return; + } // Avoid doing any setup for triggers if there is no 'afterFind' trigger for this class. + + + const hasAfterFindHook = triggers.triggerExists(this.className, triggers.Types.afterFind, this.config.applicationId); + + if (!hasAfterFindHook) { + return Promise.resolve(); + } // Skip Aggregate and Distinct Queries + + + if (this.findOptions.pipeline || this.findOptions.distinct) { + return Promise.resolve(); + } + + const json = Object.assign({}, this.restOptions); + json.where = this.restWhere; + const parseQuery = new Parse.Query(this.className); + parseQuery.withJSON(json); // Run afterFind trigger and set the new results + + return triggers.maybeRunAfterFindTrigger(triggers.Types.afterFind, this.auth, this.className, this.response.results, this.config, parseQuery).then(results => { + // Ensure we properly set the className back + if (this.redirectClassName) { + this.response.results = results.map(object => { + if (object instanceof Parse.Object) { + object = object.toJSON(); + } + + object.className = this.redirectClassName; + return object; + }); + } else { + this.response.results = results; + } + }); +}; // Adds included values to the response. +// Path is a list of field names. +// Returns a promise for an augmented response. + + +function includePath(config, auth, response, path, restOptions = {}) { + var pointers = findPointers(response.results, path); + + if (pointers.length == 0) { + return response; + } + + const pointersHash = {}; + + for (var pointer of pointers) { + if (!pointer) { + continue; + } + + const className = pointer.className; // only include the good pointers + + if (className) { + pointersHash[className] = pointersHash[className] || new Set(); + pointersHash[className].add(pointer.objectId); + } + } + + const includeRestOptions = {}; + + if (restOptions.keys) { + const keys = new Set(restOptions.keys.split(',')); + const keySet = Array.from(keys).reduce((set, key) => { + const keyPath = key.split('.'); + let i = 0; + + for (i; i < path.length; i++) { + if (path[i] != keyPath[i]) { + return set; + } + } + + if (i < keyPath.length) { + set.add(keyPath[i]); + } + + return set; + }, new Set()); + + if (keySet.size > 0) { + includeRestOptions.keys = Array.from(keySet).join(','); + } + } + + if (restOptions.includeReadPreference) { + includeRestOptions.readPreference = restOptions.includeReadPreference; + includeRestOptions.includeReadPreference = restOptions.includeReadPreference; + } else if (restOptions.readPreference) { + includeRestOptions.readPreference = restOptions.readPreference; + } + + const queryPromises = Object.keys(pointersHash).map(className => { + const objectIds = Array.from(pointersHash[className]); + let where; + + if (objectIds.length === 1) { + where = { + objectId: objectIds[0] + }; + } else { + where = { + objectId: { + $in: objectIds + } + }; + } + + var query = new RestQuery(config, auth, className, where, includeRestOptions); + return query.execute({ + op: 'get' + }).then(results => { + results.className = className; + return Promise.resolve(results); + }); + }); // Get the objects for all these object ids + + return Promise.all(queryPromises).then(responses => { + var replace = responses.reduce((replace, includeResponse) => { + for (var obj of includeResponse.results) { + obj.__type = 'Object'; + obj.className = includeResponse.className; + + if (obj.className == '_User' && !auth.isMaster) { + delete obj.sessionToken; + delete obj.authData; + } + + replace[obj.objectId] = obj; + } + + return replace; + }, {}); + var resp = { + results: replacePointers(response.results, path, replace) + }; + + if (response.count) { + resp.count = response.count; + } + + return resp; + }); +} // Object may be a list of REST-format object to find pointers in, or +// it may be a single object. +// If the path yields things that aren't pointers, this throws an error. +// Path is a list of fields to search into. +// Returns a list of pointers in REST format. + + +function findPointers(object, path) { + if (object instanceof Array) { + var answer = []; + + for (var x of object) { + answer = answer.concat(findPointers(x, path)); + } + + return answer; + } + + if (typeof object !== 'object' || !object) { + return []; + } + + if (path.length == 0) { + if (object === null || object.__type == 'Pointer') { + return [object]; + } + + return []; + } + + var subobject = object[path[0]]; + + if (!subobject) { + return []; + } + + return findPointers(subobject, path.slice(1)); +} // Object may be a list of REST-format objects to replace pointers +// in, or it may be a single object. +// Path is a list of fields to search into. +// replace is a map from object id -> object. +// Returns something analogous to object, but with the appropriate +// pointers inflated. + + +function replacePointers(object, path, replace) { + if (object instanceof Array) { + return object.map(obj => replacePointers(obj, path, replace)).filter(obj => typeof obj !== 'undefined'); + } + + if (typeof object !== 'object' || !object) { + return object; + } + + if (path.length === 0) { + if (object && object.__type === 'Pointer') { + return replace[object.objectId]; + } + + return object; + } + + var subobject = object[path[0]]; + + if (!subobject) { + return object; + } + + var newsub = replacePointers(subobject, path.slice(1), replace); + var answer = {}; + + for (var key in object) { + if (key == path[0]) { + answer[key] = newsub; + } else { + answer[key] = object[key]; + } + } + + return answer; +} // Finds a subobject that has the given key, if there is one. +// Returns undefined otherwise. + + +function findObjectWithKey(root, key) { + if (typeof root !== 'object') { + return; + } + + if (root instanceof Array) { + for (var item of root) { + const answer = findObjectWithKey(item, key); + + if (answer) { + return answer; + } + } + } + + if (root && root[key]) { + return root; + } + + for (var subkey in root) { + const answer = findObjectWithKey(root[subkey], key); + + if (answer) { + return answer; + } + } +} + +module.exports = RestQuery; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0UXVlcnkuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJQYXJzZSIsInRyaWdnZXJzIiwiY29udGludWVXaGlsZSIsIkFsd2F5c1NlbGVjdGVkS2V5cyIsIlJlc3RRdWVyeSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsImNsaWVudFNESyIsInJ1bkFmdGVyRmluZCIsInJlc3BvbnNlIiwiZmluZE9wdGlvbnMiLCJpc01hc3RlciIsInVzZXIiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIiRhbmQiLCJfX3R5cGUiLCJvYmplY3RJZCIsImlkIiwiZG9Db3VudCIsImluY2x1ZGVBbGwiLCJpbmNsdWRlIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwia2V5c0ZvckluY2x1ZGUiLCJrZXlzIiwic3BsaXQiLCJmaWx0ZXIiLCJrZXkiLCJsZW5ndGgiLCJtYXAiLCJzbGljZSIsImxhc3RJbmRleE9mIiwiam9pbiIsIm9wdGlvbiIsImNvbmNhdCIsIkFycmF5IiwiZnJvbSIsIlNldCIsImV4Y2x1ZGUiLCJleGNsdWRlS2V5cyIsImsiLCJpbmRleE9mIiwiZmllbGRzIiwib3JkZXIiLCJzb3J0IiwicmVkdWNlIiwic29ydE1hcCIsImZpZWxkIiwidHJpbSIsInNjb3JlIiwiJG1ldGEiLCJwYXRocyIsImluY2x1ZGVzIiwicGF0aFNldCIsIm1lbW8iLCJwYXRoIiwiaW5kZXgiLCJwYXJ0cyIsInMiLCJhIiwiYiIsInJlZGlyZWN0S2V5IiwicmVkaXJlY3RDbGFzc05hbWVGb3JLZXkiLCJyZWRpcmVjdENsYXNzTmFtZSIsIklOVkFMSURfSlNPTiIsImV4ZWN1dGUiLCJleGVjdXRlT3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImJ1aWxkUmVzdFdoZXJlIiwiaGFuZGxlSW5jbHVkZUFsbCIsImhhbmRsZUV4Y2x1ZGVLZXlzIiwicnVuRmluZCIsInJ1bkNvdW50IiwiaGFuZGxlSW5jbHVkZSIsInJ1bkFmdGVyRmluZFRyaWdnZXIiLCJlYWNoIiwiY2FsbGJhY2siLCJsaW1pdCIsImZpbmlzaGVkIiwicXVlcnkiLCJyZXN1bHRzIiwiZm9yRWFjaCIsImFzc2lnbiIsIiRndCIsImdldFVzZXJBbmRSb2xlQUNMIiwidmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uIiwicmVwbGFjZVNlbGVjdCIsInJlcGxhY2VEb250U2VsZWN0IiwicmVwbGFjZUluUXVlcnkiLCJyZXBsYWNlTm90SW5RdWVyeSIsInJlcGxhY2VFcXVhbGl0eSIsImFjbCIsImdldFVzZXJSb2xlcyIsInJvbGVzIiwiZGF0YWJhc2UiLCJuZXdDbGFzc05hbWUiLCJhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24iLCJzeXN0ZW1DbGFzc2VzIiwibG9hZFNjaGVtYSIsInNjaGVtYUNvbnRyb2xsZXIiLCJoYXNDbGFzcyIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJ0cmFuc2Zvcm1JblF1ZXJ5IiwiaW5RdWVyeU9iamVjdCIsInZhbHVlcyIsInJlc3VsdCIsInB1c2giLCJpc0FycmF5IiwiZmluZE9iamVjdFdpdGhLZXkiLCJpblF1ZXJ5VmFsdWUiLCJ3aGVyZSIsIklOVkFMSURfUVVFUlkiLCJhZGRpdGlvbmFsT3B0aW9ucyIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJyZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5IiwidHJhbnNmb3JtTm90SW5RdWVyeSIsIm5vdEluUXVlcnlPYmplY3QiLCJub3RJblF1ZXJ5VmFsdWUiLCJnZXREZWVwZXN0T2JqZWN0RnJvbUtleSIsImpzb24iLCJpZHgiLCJzcmMiLCJzcGxpY2UiLCJ0cmFuc2Zvcm1TZWxlY3QiLCJzZWxlY3RPYmplY3QiLCJvYmplY3RzIiwic2VsZWN0VmFsdWUiLCJ0cmFuc2Zvcm1Eb250U2VsZWN0IiwiZG9udFNlbGVjdE9iamVjdCIsImRvbnRTZWxlY3RWYWx1ZSIsImNsZWFuUmVzdWx0QXV0aERhdGEiLCJwYXNzd29yZCIsImF1dGhEYXRhIiwicHJvdmlkZXIiLCJyZXBsYWNlRXF1YWxpdHlDb25zdHJhaW50IiwiY29uc3RyYWludCIsImVxdWFsVG9PYmplY3QiLCJoYXNEaXJlY3RDb25zdHJhaW50IiwiaGFzT3BlcmF0b3JDb25zdHJhaW50Iiwib3B0aW9ucyIsIm9wIiwiZmluZCIsImV4cGxhaW4iLCJmaWxlc0NvbnRyb2xsZXIiLCJleHBhbmRGaWxlc0luT2JqZWN0IiwiciIsImNvdW50Iiwic2tpcCIsImMiLCJnZXRPbmVTY2hlbWEiLCJzY2hlbWEiLCJpbmNsdWRlRmllbGRzIiwia2V5RmllbGRzIiwidHlwZSIsInBhdGhSZXNwb25zZSIsImluY2x1ZGVQYXRoIiwibmV3UmVzcG9uc2UiLCJoYXNBZnRlckZpbmRIb29rIiwidHJpZ2dlckV4aXN0cyIsIlR5cGVzIiwiYWZ0ZXJGaW5kIiwiYXBwbGljYXRpb25JZCIsInBpcGVsaW5lIiwiZGlzdGluY3QiLCJwYXJzZVF1ZXJ5IiwiUXVlcnkiLCJ3aXRoSlNPTiIsIm1heWJlUnVuQWZ0ZXJGaW5kVHJpZ2dlciIsIm9iamVjdCIsInRvSlNPTiIsInBvaW50ZXJzIiwiZmluZFBvaW50ZXJzIiwicG9pbnRlcnNIYXNoIiwicG9pbnRlciIsImFkZCIsImluY2x1ZGVSZXN0T3B0aW9ucyIsImtleVNldCIsInNldCIsImtleVBhdGgiLCJpIiwic2l6ZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInF1ZXJ5UHJvbWlzZXMiLCJvYmplY3RJZHMiLCIkaW4iLCJhbGwiLCJyZXNwb25zZXMiLCJyZXBsYWNlIiwiaW5jbHVkZVJlc3BvbnNlIiwib2JqIiwic2Vzc2lvblRva2VuIiwicmVzcCIsInJlcGxhY2VQb2ludGVycyIsImFuc3dlciIsIngiLCJzdWJvYmplY3QiLCJuZXdzdWIiLCJyb290IiwiaXRlbSIsInN1YmtleSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUVBLElBQUlBLGdCQUFnQixH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QUFJQSxJQUFJLFlBQVlySyxLQUFwQixFQUEyQjtBQUN6QixTQUFLLElBQUlzSyxJQUFULElBQWlCRCxJQUFqQixFQUF1QjtBQUNyQixZQUFNSixNQUFNLEdBQUd0RixpQkFBaUIsQ0FBQzJGLElBQUQsRUFBTzlLLEdBQVAsQ0FBaEM7O0FBQ0EsVUFBSXlLLE1BQUosRUFBWTtBQUNWLGVBQU9BLE1BQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsTUFBSUksSUFBSSxJQUFJQSxJQUFJLENBQUM3SyxHQUFELENBQWhCLEVBQXVCO0FBQ3JCLFdBQU82SyxJQUFQO0FBQ0Q7O0FBQ0QsT0FBSyxJQUFJRSxNQUFULElBQW1CRixJQUFuQixFQUF5QjtBQUN2QixVQUFNSixNQUFNLEdBQUd0RixpQkFBaUIsQ0FBQzBGLElBQUksQ0FBQ0UsTUFBRCxDQUFMLEVBQWUvSyxHQUFmLENBQWhDOztBQUNBLFFBQUl5SyxNQUFKLEVBQVk7QUFDVixhQUFPQSxNQUFQO0FBQ0Q7QUFDRjtBQUNGOztBQUVETyxNQUFNLENBQUNDLE9BQVAsR0FBaUI5TSxTQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyBldmVyeXRoaW5nIHdlIG5lZWQgdG8gcnVuIGEgJ2ZpbmQnXG4vLyBvcGVyYXRpb24sIGVuY29kZWQgaW4gdGhlIFJFU1QgQVBJIGZvcm1hdC5cblxudmFyIFNjaGVtYUNvbnRyb2xsZXIgPSByZXF1aXJlKCcuL0NvbnRyb2xsZXJzL1NjaGVtYUNvbnRyb2xsZXInKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHRyaWdnZXJzID0gcmVxdWlyZSgnLi90cmlnZ2VycycpO1xuY29uc3QgeyBjb250aW51ZVdoaWxlIH0gPSByZXF1aXJlKCdwYXJzZS9saWIvbm9kZS9wcm9taXNlVXRpbHMnKTtcbmNvbnN0IEFsd2F5c1NlbGVjdGVkS2V5cyA9IFsnb2JqZWN0SWQnLCAnY3JlYXRlZEF0JywgJ3VwZGF0ZWRBdCcsICdBQ0wnXTtcbi8vIHJlc3RPcHRpb25zIGNhbiBpbmNsdWRlOlxuLy8gICBza2lwXG4vLyAgIGxpbWl0XG4vLyAgIG9yZGVyXG4vLyAgIGNvdW50XG4vLyAgIGluY2x1ZGVcbi8vICAga2V5c1xuLy8gICBleGNsdWRlS2V5c1xuLy8gICByZWRpcmVjdENsYXNzTmFtZUZvcktleVxuLy8gICByZWFkUHJlZmVyZW5jZVxuLy8gICBpbmNsdWRlUmVhZFByZWZlcmVuY2Vcbi8vICAgc3VicXVlcnlSZWFkUHJlZmVyZW5jZVxuZnVuY3Rpb24gUmVzdFF1ZXJ5KFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGNsYXNzTmFtZSxcbiAgcmVzdFdoZXJlID0ge30sXG4gIHJlc3RPcHRpb25zID0ge30sXG4gIGNsaWVudFNESyxcbiAgcnVuQWZ0ZXJGaW5kID0gdHJ1ZVxuKSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmF1dGggPSBhdXRoO1xuICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgdGhpcy5yZXN0V2hlcmUgPSByZXN0V2hlcmU7XG4gIHRoaXMucmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucztcbiAgdGhpcy5jbGllbnRTREsgPSBjbGllbnRTREs7XG4gIHRoaXMucnVuQWZ0ZXJGaW5kID0gcnVuQWZ0ZXJGaW5kO1xuICB0aGlzLnJlc3BvbnNlID0gbnVsbDtcbiAgdGhpcy5maW5kT3B0aW9ucyA9IHt9O1xuXG4gIGlmICghdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgIGlmICghdGhpcy5hdXRoLnVzZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXN0V2hlcmUgPSB7XG4gICAgICAgICRhbmQ6IFtcbiAgICAgICAgICB0aGlzLnJlc3RXaGVyZSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1c2VyOiB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgICAgICAgIG9iamVjdElkOiB0aGlzLmF1dGgudXNlci5pZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgdGhpcy5kb0NvdW50ID0gZmFsc2U7XG4gIHRoaXMuaW5jbHVkZUFsbCA9IGZhbHNlO1xuXG4gIC8vIFRoZSBmb3JtYXQgZm9yIHRoaXMuaW5jbHVkZSBpcyBub3QgdGhlIHNhbWUgYXMgdGhlIGZvcm1hdCBmb3IgdGhlXG4gIC8vIGluY2x1ZGUgb3B0aW9uIC0gaXQncyB0aGUgcGF0aHMgd2Ugc2hvdWxkIGluY2x1ZGUsIGluIG9yZGVyLFxuICAvLyBzdG9yZWQgYXMgYXJyYXlzLCB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgd2UgbmVlZCB0byBpbmNsdWRlIGZvb1xuICAvLyBiZWZvcmUgaW5jbHVkaW5nIGZvby5iYXIuIEFsc28gaXQgc2hvdWxkIGRlZHVwZS5cbiAgLy8gRm9yIGV4YW1wbGUsIHBhc3NpbmcgYW4gYXJnIG9mIGluY2x1ZGU9Zm9vLmJhcixmb28uYmF6IGNvdWxkIGxlYWQgdG9cbiAgLy8gdGhpcy5pbmNsdWRlID0gW1snZm9vJ10sIFsnZm9vJywgJ2JheiddLCBbJ2ZvbycsICdiYXInXV1cbiAgdGhpcy5pbmNsdWRlID0gW107XG5cbiAgLy8gSWYgd2UgaGF2ZSBrZXlzLCB3ZSBwcm9iYWJseSB3YW50IHRvIGZvcmNlIHNvbWUgaW5jbHVkZXMgKG4tMSBsZXZlbClcbiAgLy8gU2VlIGlzc3VlOiBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvMzE4NVxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3RPcHRpb25zLCAna2V5cycpKSB7XG4gICAgY29uc3Qga2V5c0ZvckluY2x1ZGUgPSByZXN0T3B0aW9ucy5rZXlzXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLmZpbHRlcihrZXkgPT4ge1xuICAgICAgICAvLyBBdCBsZWFzdCAyIGNvbXBvbmVudHNcbiAgICAgICAgcmV0dXJuIGtleS5zcGxpdCgnLicpLmxlbmd0aCA+IDE7XG4gICAgICB9KVxuICAgICAgLm1hcChrZXkgPT4ge1xuICAgICAgICAvLyBTbGljZSB0aGUgbGFzdCBjb21wb25lbnQgKGEuYi5jIC0+IGEuYilcbiAgICAgICAgLy8gT3RoZXJ3aXNlIHdlJ2xsIGluY2x1ZGUgb25lIGxldmVsIHRvbyBtdWNoLlxuICAgICAgICByZXR1cm4ga2V5LnNsaWNlKDAsIGtleS5sYXN0SW5kZXhPZignLicpKTtcbiAgICAgIH0pXG4gICAgICAuam9pbignLCcpO1xuXG4gICAgLy8gQ29uY2F0IHRoZSBwb3NzaWJseSBwcmVzZW50IGluY2x1ZGUgc3RyaW5nIHdpdGggdGhlIG9uZSBmcm9tIHRoZSBrZXlzXG4gICAgLy8gRGVkdXAgLyBzb3J0aW5nIGlzIGhhbmRsZSBpbiAnaW5jbHVkZScgY2FzZS5cbiAgICBpZiAoa2V5c0ZvckluY2x1ZGUubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFyZXN0T3B0aW9ucy5pbmNsdWRlIHx8IHJlc3RPcHRpb25zLmluY2x1ZGUubGVuZ3RoID09IDApIHtcbiAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZSA9IGtleXNGb3JJbmNsdWRlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZSArPSAnLCcgKyBrZXlzRm9ySW5jbHVkZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBvcHRpb24gaW4gcmVzdE9wdGlvbnMpIHtcbiAgICBzd2l0Y2ggKG9wdGlvbikge1xuICAgICAgY2FzZSAna2V5cyc6IHtcbiAgICAgICAgY29uc3Qga2V5cyA9IHJlc3RPcHRpb25zLmtleXMuc3BsaXQoJywnKS5jb25jYXQoQWx3YXlzU2VsZWN0ZWRLZXlzKTtcbiAgICAgICAgdGhpcy5rZXlzID0gQXJyYXkuZnJvbShuZXcgU2V0KGtleXMpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdleGNsdWRlS2V5cyc6IHtcbiAgICAgICAgY29uc3QgZXhjbHVkZSA9IHJlc3RPcHRpb25zLmV4Y2x1ZGVLZXlzXG4gICAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgICAuZmlsdGVyKGsgPT4gQWx3YXlzU2VsZWN0ZWRLZXlzLmluZGV4T2YoaykgPCAwKTtcbiAgICAgICAgdGhpcy5leGNsdWRlS2V5cyA9IEFycmF5LmZyb20obmV3IFNldChleGNsdWRlKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnY291bnQnOlxuICAgICAgICB0aGlzLmRvQ291bnQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2luY2x1ZGVBbGwnOlxuICAgICAgICB0aGlzLmluY2x1ZGVBbGwgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2V4cGxhaW4nOlxuICAgICAgY2FzZSAnaGludCc6XG4gICAgICBjYXNlICdkaXN0aW5jdCc6XG4gICAgICBjYXNlICdwaXBlbGluZSc6XG4gICAgICBjYXNlICdza2lwJzpcbiAgICAgIGNhc2UgJ2xpbWl0JzpcbiAgICAgIGNhc2UgJ3JlYWRQcmVmZXJlbmNlJzpcbiAgICAgICAgdGhpcy5maW5kT3B0aW9uc1tvcHRpb25dID0gcmVzdE9wdGlvbnNbb3B0aW9uXTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdvcmRlcic6XG4gICAgICAgIHZhciBmaWVsZHMgPSByZXN0T3B0aW9ucy5vcmRlci5zcGxpdCgnLCcpO1xuICAgICAgICB0aGlzLmZpbmRPcHRpb25zLnNvcnQgPSBmaWVsZHMucmVkdWNlKChzb3J0TWFwLCBmaWVsZCkgPT4ge1xuICAgICAgICAgIGZpZWxkID0gZmllbGQudHJpbSgpO1xuICAgICAgICAgIGlmIChmaWVsZCA9PT0gJyRzY29yZScpIHtcbiAgICAgICAgICAgIHNvcnRNYXAuc2NvcmUgPSB7ICRtZXRhOiAndGV4dFNjb3JlJyB9O1xuICAgICAgICAgIH0gZWxzZSBpZiAoZmllbGRbMF0gPT0gJy0nKSB7XG4gICAgICAgICAgICBzb3J0TWFwW2ZpZWxkLnNsaWNlKDEpXSA9IC0xO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzb3J0TWFwW2ZpZWxkXSA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBzb3J0TWFwO1xuICAgICAgICB9LCB7fSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5jbHVkZSc6IHtcbiAgICAgICAgY29uc3QgcGF0aHMgPSByZXN0T3B0aW9ucy5pbmNsdWRlLnNwbGl0KCcsJyk7XG4gICAgICAgIGlmIChwYXRocy5pbmNsdWRlcygnKicpKSB7XG4gICAgICAgICAgdGhpcy5pbmNsdWRlQWxsID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBMb2FkIHRoZSBleGlzdGluZyBpbmNsdWRlcyAoZnJvbSBrZXlzKVxuICAgICAgICBjb25zdCBwYXRoU2V0ID0gcGF0aHMucmVkdWNlKChtZW1vLCBwYXRoKSA9PiB7XG4gICAgICAgICAgLy8gU3BsaXQgZWFjaCBwYXRocyBvbiAuIChhLmIuYyAtPiBbYSxiLGNdKVxuICAgICAgICAgIC8vIHJlZHVjZSB0byBjcmVhdGUgYWxsIHBhdGhzXG4gICAgICAgICAgLy8gKFthLGIsY10gLT4ge2E6IHRydWUsICdhLmInOiB0cnVlLCAnYS5iLmMnOiB0cnVlfSlcbiAgICAgICAgICByZXR1cm4gcGF0aC5zcGxpdCgnLicpLnJlZHVjZSgobWVtbywgcGF0aCwgaW5kZXgsIHBhcnRzKSA9PiB7XG4gICAgICAgICAgICBtZW1vW3BhcnRzLnNsaWNlKDAsIGluZGV4ICsgMSkuam9pbignLicpXSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgICB9LCBtZW1vKTtcbiAgICAgICAgfSwge30pO1xuXG4gICAgICAgIHRoaXMuaW5jbHVkZSA9IE9iamVjdC5rZXlzKHBhdGhTZXQpXG4gICAgICAgICAgLm1hcChzID0+IHtcbiAgICAgICAgICAgIHJldHVybiBzLnNwbGl0KCcuJyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGEubGVuZ3RoIC0gYi5sZW5ndGg7IC8vIFNvcnQgYnkgbnVtYmVyIG9mIGNvbXBvbmVudHNcbiAgICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdyZWRpcmVjdENsYXNzTmFtZUZvcktleSc6XG4gICAgICAgIHRoaXMucmVkaXJlY3RLZXkgPSByZXN0T3B0aW9ucy5yZWRpcmVjdENsYXNzTmFtZUZvcktleTtcbiAgICAgICAgdGhpcy5yZWRpcmVjdENsYXNzTmFtZSA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5jbHVkZVJlYWRQcmVmZXJlbmNlJzpcbiAgICAgIGNhc2UgJ3N1YnF1ZXJ5UmVhZFByZWZlcmVuY2UnOlxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgb3B0aW9uOiAnICsgb3B0aW9uKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gQSBjb252ZW5pZW50IG1ldGhvZCB0byBwZXJmb3JtIGFsbCB0aGUgc3RlcHMgb2YgcHJvY2Vzc2luZyBhIHF1ZXJ5XG4vLyBpbiBvcmRlci5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzcG9uc2UgLSBhbiBvYmplY3Qgd2l0aCBvcHRpb25hbCBrZXlzXG4vLyAncmVzdWx0cycgYW5kICdjb3VudCcuXG4vLyBUT0RPOiBjb25zb2xpZGF0ZSB0aGUgcmVwbGFjZVggZnVuY3Rpb25zXG5SZXN0UXVlcnkucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoZXhlY3V0ZU9wdGlvbnMpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnVpbGRSZXN0V2hlcmUoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUluY2x1ZGVBbGwoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUV4Y2x1ZGVLZXlzKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5GaW5kKGV4ZWN1dGVPcHRpb25zKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJ1bkNvdW50KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVJbmNsdWRlKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5BZnRlckZpbmRUcmlnZ2VyKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZXNwb25zZTtcbiAgICB9KTtcbn07XG5cblJlc3RRdWVyeS5wcm90b3R5cGUuZWFjaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICBjb25zdCB7IGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREsgfSA9IHRoaXM7XG4gIC8vIGlmIHRoZSBsaW1pdCBpcyBzZXQsIHVzZSBpdFxuICByZXN0T3B0aW9ucy5saW1pdCA9IHJlc3RPcHRpb25zLmxpbWl0IHx8IDEwMDtcbiAgcmVzdE9wdGlvbnMub3JkZXIgPSAnb2JqZWN0SWQnO1xuICBsZXQgZmluaXNoZWQgPSBmYWxzZTtcblxuICByZXR1cm4gY29udGludWVXaGlsZShcbiAgICAoKSA9PiB7XG4gICAgICByZXR1cm4gIWZpbmlzaGVkO1xuICAgIH0sXG4gICAgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREspO1xuICAgICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCBxdWVyeS5leGVjdXRlKCk7XG4gICAgICByZXN1bHRzLmZvckVhY2goY2FsbGJhY2spO1xuICAgICAgZmluaXNoZWQgPSByZXN1bHRzLmxlbmd0aCA8IHJlc3RPcHRpb25zLmxpbWl0O1xuICAgICAgaWYgKCFmaW5pc2hlZCkge1xuICAgICAgICByZXN0V2hlcmUub2JqZWN0SWQgPSBPYmplY3QuYXNzaWduKHt9LCByZXN0V2hlcmUub2JqZWN0SWQsIHtcbiAgICAgICAgICAkZ3Q6IHJlc3VsdHNbcmVzdWx0cy5sZW5ndGggLSAxXS5vYmplY3RJZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICApO1xufTtcblxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5idWlsZFJlc3RXaGVyZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlckFuZFJvbGVBQ0woKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUNsaWVudENsYXNzQ3JlYXRpb24oKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VTZWxlY3QoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VEb250U2VsZWN0KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBsYWNlSW5RdWVyeSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZU5vdEluUXVlcnkoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VFcXVhbGl0eSgpO1xuICAgIH0pO1xufTtcblxuLy8gVXNlcyB0aGUgQXV0aCBvYmplY3QgdG8gZ2V0IHRoZSBsaXN0IG9mIHJvbGVzLCBhZGRzIHRoZSB1c2VyIGlkXG5SZXN0UXVlcnkucHJvdG90eXBlLmdldFVzZXJBbmRSb2xlQUNMID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgdGhpcy5maW5kT3B0aW9ucy5hY2wgPSBbJyonXTtcblxuICBpZiAodGhpcy5hdXRoLnVzZXIpIHtcbiAgICByZXR1cm4gdGhpcy5hdXRoLmdldFVzZXJSb2xlcygpLnRoZW4ocm9sZXMgPT4ge1xuICAgICAgdGhpcy5maW5kT3B0aW9ucy5hY2wgPSB0aGlzLmZpbmRPcHRpb25zLmFjbC5jb25jYXQocm9sZXMsIFt0aGlzLmF1dGgudXNlci5pZF0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxufTtcblxuLy8gQ2hhbmdlcyB0aGUgY2xhc3NOYW1lIGlmIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IGlzIHNldC5cbi8vIFJldHVybnMgYSBwcm9taXNlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnJlZGlyZWN0S2V5KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIGNsYXNzIG5hbWUgYmFzZWQgb24gdGhlIHNjaGVtYVxuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAucmVkaXJlY3RDbGFzc05hbWVGb3JLZXkodGhpcy5jbGFzc05hbWUsIHRoaXMucmVkaXJlY3RLZXkpXG4gICAgLnRoZW4obmV3Q2xhc3NOYW1lID0+IHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lID0gbmV3Q2xhc3NOYW1lO1xuICAgICAgdGhpcy5yZWRpcmVjdENsYXNzTmFtZSA9IG5ld0NsYXNzTmFtZTtcbiAgICB9KTtcbn07XG5cbi8vIFZhbGlkYXRlcyB0aGlzIG9wZXJhdGlvbiBhZ2FpbnN0IHRoZSBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gY29uZmlnLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS52YWxpZGF0ZUNsaWVudENsYXNzQ3JlYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmIChcbiAgICB0aGlzLmNvbmZpZy5hbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gPT09IGZhbHNlICYmXG4gICAgIXRoaXMuYXV0aC5pc01hc3RlciAmJlxuICAgIFNjaGVtYUNvbnRyb2xsZXIuc3lzdGVtQ2xhc3Nlcy5pbmRleE9mKHRoaXMuY2xhc3NOYW1lKSA9PT0gLTFcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAubG9hZFNjaGVtYSgpXG4gICAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHNjaGVtYUNvbnRyb2xsZXIuaGFzQ2xhc3ModGhpcy5jbGFzc05hbWUpKVxuICAgICAgLnRoZW4oaGFzQ2xhc3MgPT4ge1xuICAgICAgICBpZiAoaGFzQ2xhc3MgIT09IHRydWUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgJ1RoaXMgdXNlciBpcyBub3QgYWxsb3dlZCB0byBhY2Nlc3MgJyArICdub24tZXhpc3RlbnQgY2xhc3M6ICcgKyB0aGlzLmNsYXNzTmFtZVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtSW5RdWVyeShpblF1ZXJ5T2JqZWN0LCBjbGFzc05hbWUsIHJlc3VsdHMpIHtcbiAgdmFyIHZhbHVlcyA9IFtdO1xuICBmb3IgKHZhciByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIHZhbHVlcy5wdXNoKHtcbiAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICBvYmplY3RJZDogcmVzdWx0Lm9iamVjdElkLFxuICAgIH0pO1xuICB9XG4gIGRlbGV0ZSBpblF1ZXJ5T2JqZWN0WyckaW5RdWVyeSddO1xuICBpZiAoQXJyYXkuaXNBcnJheShpblF1ZXJ5T2JqZWN0WyckaW4nXSkpIHtcbiAgICBpblF1ZXJ5T2JqZWN0WyckaW4nXSA9IGluUXVlcnlPYmplY3RbJyRpbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIGluUXVlcnlPYmplY3RbJyRpbiddID0gdmFsdWVzO1xuICB9XG59XG5cbi8vIFJlcGxhY2VzIGEgJGluUXVlcnkgY2xhdXNlIGJ5IHJ1bm5pbmcgdGhlIHN1YnF1ZXJ5LCBpZiB0aGVyZSBpcyBhblxuLy8gJGluUXVlcnkgY2xhdXNlLlxuLy8gVGhlICRpblF1ZXJ5IGNsYXVzZSB0dXJucyBpbnRvIGFuICRpbiB3aXRoIHZhbHVlcyB0aGF0IGFyZSBqdXN0XG4vLyBwb2ludGVycyB0byB0aGUgb2JqZWN0cyByZXR1cm5lZCBpbiB0aGUgc3VicXVlcnkuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VJblF1ZXJ5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaW5RdWVyeU9iamVjdCA9IGZpbmRPYmplY3RXaXRoS2V5KHRoaXMucmVzdFdoZXJlLCAnJGluUXVlcnknKTtcbiAgaWYgKCFpblF1ZXJ5T2JqZWN0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVGhlIGluUXVlcnkgdmFsdWUgbXVzdCBoYXZlIHByZWNpc2VseSB0d28ga2V5cyAtIHdoZXJlIGFuZCBjbGFzc05hbWVcbiAgdmFyIGluUXVlcnlWYWx1ZSA9IGluUXVlcnlPYmplY3RbJyRpblF1ZXJ5J107XG4gIGlmICghaW5RdWVyeVZhbHVlLndoZXJlIHx8ICFpblF1ZXJ5VmFsdWUuY2xhc3NOYW1lKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdpbXByb3BlciB1c2FnZSBvZiAkaW5RdWVyeScpO1xuICB9XG5cbiAgY29uc3QgYWRkaXRpb25hbE9wdGlvbnMgPSB7XG4gICAgcmVkaXJlY3RDbGFzc05hbWVGb3JLZXk6IGluUXVlcnlWYWx1ZS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSxcbiAgfTtcblxuICBpZiAodGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgYWRkaXRpb25hbE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgYWRkaXRpb25hbE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgfSBlbHNlIGlmICh0aGlzLnJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlKSB7XG4gICAgYWRkaXRpb25hbE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgdmFyIHN1YnF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShcbiAgICB0aGlzLmNvbmZpZyxcbiAgICB0aGlzLmF1dGgsXG4gICAgaW5RdWVyeVZhbHVlLmNsYXNzTmFtZSxcbiAgICBpblF1ZXJ5VmFsdWUud2hlcmUsXG4gICAgYWRkaXRpb25hbE9wdGlvbnNcbiAgKTtcbiAgcmV0dXJuIHN1YnF1ZXJ5LmV4ZWN1dGUoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICB0cmFuc2Zvcm1JblF1ZXJ5KGluUXVlcnlPYmplY3QsIHN1YnF1ZXJ5LmNsYXNzTmFtZSwgcmVzcG9uc2UucmVzdWx0cyk7XG4gICAgLy8gUmVjdXJzZSB0byByZXBlYXRcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlSW5RdWVyeSgpO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybU5vdEluUXVlcnkobm90SW5RdWVyeU9iamVjdCwgY2xhc3NOYW1lLCByZXN1bHRzKSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICB2YWx1ZXMucHVzaCh7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgb2JqZWN0SWQ6IHJlc3VsdC5vYmplY3RJZCxcbiAgICB9KTtcbiAgfVxuICBkZWxldGUgbm90SW5RdWVyeU9iamVjdFsnJG5vdEluUXVlcnknXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkobm90SW5RdWVyeU9iamVjdFsnJG5pbiddKSkge1xuICAgIG5vdEluUXVlcnlPYmplY3RbJyRuaW4nXSA9IG5vdEluUXVlcnlPYmplY3RbJyRuaW4nXS5jb25jYXQodmFsdWVzKTtcbiAgfSBlbHNlIHtcbiAgICBub3RJblF1ZXJ5T2JqZWN0WyckbmluJ10gPSB2YWx1ZXM7XG4gIH1cbn1cblxuLy8gUmVwbGFjZXMgYSAkbm90SW5RdWVyeSBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFuXG4vLyAkbm90SW5RdWVyeSBjbGF1c2UuXG4vLyBUaGUgJG5vdEluUXVlcnkgY2xhdXNlIHR1cm5zIGludG8gYSAkbmluIHdpdGggdmFsdWVzIHRoYXQgYXJlIGp1c3Rcbi8vIHBvaW50ZXJzIHRvIHRoZSBvYmplY3RzIHJldHVybmVkIGluIHRoZSBzdWJxdWVyeS5cblJlc3RRdWVyeS5wcm90b3R5cGUucmVwbGFjZU5vdEluUXVlcnkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub3RJblF1ZXJ5T2JqZWN0ID0gZmluZE9iamVjdFdpdGhLZXkodGhpcy5yZXN0V2hlcmUsICckbm90SW5RdWVyeScpO1xuICBpZiAoIW5vdEluUXVlcnlPYmplY3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgbm90SW5RdWVyeSB2YWx1ZSBtdXN0IGhhdmUgcHJlY2lzZWx5IHR3byBrZXlzIC0gd2hlcmUgYW5kIGNsYXNzTmFtZVxuICB2YXIgbm90SW5RdWVyeVZhbHVlID0gbm90SW5RdWVyeU9iamVjdFsnJG5vdEluUXVlcnknXTtcbiAgaWYgKCFub3RJblF1ZXJ5VmFsdWUud2hlcmUgfHwgIW5vdEluUXVlcnlWYWx1ZS5jbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ2ltcHJvcGVyIHVzYWdlIG9mICRub3RJblF1ZXJ5Jyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogbm90SW5RdWVyeVZhbHVlLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBub3RJblF1ZXJ5VmFsdWUuY2xhc3NOYW1lLFxuICAgIG5vdEluUXVlcnlWYWx1ZS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybU5vdEluUXVlcnkobm90SW5RdWVyeU9iamVjdCwgc3VicXVlcnkuY2xhc3NOYW1lLCByZXNwb25zZS5yZXN1bHRzKTtcbiAgICAvLyBSZWN1cnNlIHRvIHJlcGVhdFxuICAgIHJldHVybiB0aGlzLnJlcGxhY2VOb3RJblF1ZXJ5KCk7XG4gIH0pO1xufTtcblxuLy8gVXNlZCB0byBnZXQgdGhlIGRlZXBlc3Qgb2JqZWN0IGZyb20ganNvbiB1c2luZyBkb3Qgbm90YXRpb24uXG5jb25zdCBnZXREZWVwZXN0T2JqZWN0RnJvbUtleSA9IChqc29uLCBrZXksIGlkeCwgc3JjKSA9PiB7XG4gIGlmIChrZXkgaW4ganNvbikge1xuICAgIHJldHVybiBqc29uW2tleV07XG4gIH1cbiAgc3JjLnNwbGljZSgxKTsgLy8gRXhpdCBFYXJseVxufTtcblxuY29uc3QgdHJhbnNmb3JtU2VsZWN0ID0gKHNlbGVjdE9iamVjdCwga2V5LCBvYmplY3RzKSA9PiB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIgcmVzdWx0IG9mIG9iamVjdHMpIHtcbiAgICB2YWx1ZXMucHVzaChrZXkuc3BsaXQoJy4nKS5yZWR1Y2UoZ2V0RGVlcGVzdE9iamVjdEZyb21LZXksIHJlc3VsdCkpO1xuICB9XG4gIGRlbGV0ZSBzZWxlY3RPYmplY3RbJyRzZWxlY3QnXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZWN0T2JqZWN0WyckaW4nXSkpIHtcbiAgICBzZWxlY3RPYmplY3RbJyRpbiddID0gc2VsZWN0T2JqZWN0WyckaW4nXS5jb25jYXQodmFsdWVzKTtcbiAgfSBlbHNlIHtcbiAgICBzZWxlY3RPYmplY3RbJyRpbiddID0gdmFsdWVzO1xuICB9XG59O1xuXG4vLyBSZXBsYWNlcyBhICRzZWxlY3QgY2xhdXNlIGJ5IHJ1bm5pbmcgdGhlIHN1YnF1ZXJ5LCBpZiB0aGVyZSBpcyBhXG4vLyAkc2VsZWN0IGNsYXVzZS5cbi8vIFRoZSAkc2VsZWN0IGNsYXVzZSB0dXJucyBpbnRvIGFuICRpbiB3aXRoIHZhbHVlcyBzZWxlY3RlZCBvdXQgb2Zcbi8vIHRoZSBzdWJxdWVyeS5cbi8vIFJldHVybnMgYSBwb3NzaWJsZS1wcm9taXNlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlU2VsZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZWN0T2JqZWN0ID0gZmluZE9iamVjdFdpdGhLZXkodGhpcy5yZXN0V2hlcmUsICckc2VsZWN0Jyk7XG4gIGlmICghc2VsZWN0T2JqZWN0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVGhlIHNlbGVjdCB2YWx1ZSBtdXN0IGhhdmUgcHJlY2lzZWx5IHR3byBrZXlzIC0gcXVlcnkgYW5kIGtleVxuICB2YXIgc2VsZWN0VmFsdWUgPSBzZWxlY3RPYmplY3RbJyRzZWxlY3QnXTtcbiAgLy8gaU9TIFNESyBkb24ndCBzZW5kIHdoZXJlIGlmIG5vdCBzZXQsIGxldCBpdCBwYXNzXG4gIGlmIChcbiAgICAhc2VsZWN0VmFsdWUucXVlcnkgfHxcbiAgICAhc2VsZWN0VmFsdWUua2V5IHx8XG4gICAgdHlwZW9mIHNlbGVjdFZhbHVlLnF1ZXJ5ICE9PSAnb2JqZWN0JyB8fFxuICAgICFzZWxlY3RWYWx1ZS5xdWVyeS5jbGFzc05hbWUgfHxcbiAgICBPYmplY3Qua2V5cyhzZWxlY3RWYWx1ZSkubGVuZ3RoICE9PSAyXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnaW1wcm9wZXIgdXNhZ2Ugb2YgJHNlbGVjdCcpO1xuICB9XG5cbiAgY29uc3QgYWRkaXRpb25hbE9wdGlvbnMgPSB7XG4gICAgcmVkaXJlY3RDbGFzc05hbWVGb3JLZXk6IHNlbGVjdFZhbHVlLnF1ZXJ5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBzZWxlY3RWYWx1ZS5xdWVyeS5jbGFzc05hbWUsXG4gICAgc2VsZWN0VmFsdWUucXVlcnkud2hlcmUsXG4gICAgYWRkaXRpb25hbE9wdGlvbnNcbiAgKTtcbiAgcmV0dXJuIHN1YnF1ZXJ5LmV4ZWN1dGUoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICB0cmFuc2Zvcm1TZWxlY3Qoc2VsZWN0T2JqZWN0LCBzZWxlY3RWYWx1ZS5rZXksIHJlc3BvbnNlLnJlc3VsdHMpO1xuICAgIC8vIEtlZXAgcmVwbGFjaW5nICRzZWxlY3QgY2xhdXNlc1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2VTZWxlY3QoKTtcbiAgfSk7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1Eb250U2VsZWN0ID0gKGRvbnRTZWxlY3RPYmplY3QsIGtleSwgb2JqZWN0cykgPT4ge1xuICB2YXIgdmFsdWVzID0gW107XG4gIGZvciAodmFyIHJlc3VsdCBvZiBvYmplY3RzKSB7XG4gICAgdmFsdWVzLnB1c2goa2V5LnNwbGl0KCcuJykucmVkdWNlKGdldERlZXBlc3RPYmplY3RGcm9tS2V5LCByZXN1bHQpKTtcbiAgfVxuICBkZWxldGUgZG9udFNlbGVjdE9iamVjdFsnJGRvbnRTZWxlY3QnXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZG9udFNlbGVjdE9iamVjdFsnJG5pbiddKSkge1xuICAgIGRvbnRTZWxlY3RPYmplY3RbJyRuaW4nXSA9IGRvbnRTZWxlY3RPYmplY3RbJyRuaW4nXS5jb25jYXQodmFsdWVzKTtcbiAgfSBlbHNlIHtcbiAgICBkb250U2VsZWN0T2JqZWN0WyckbmluJ10gPSB2YWx1ZXM7XG4gIH1cbn07XG5cbi8vIFJlcGxhY2VzIGEgJGRvbnRTZWxlY3QgY2xhdXNlIGJ5IHJ1bm5pbmcgdGhlIHN1YnF1ZXJ5LCBpZiB0aGVyZSBpcyBhXG4vLyAkZG9udFNlbGVjdCBjbGF1c2UuXG4vLyBUaGUgJGRvbnRTZWxlY3QgY2xhdXNlIHR1cm5zIGludG8gYW4gJG5pbiB3aXRoIHZhbHVlcyBzZWxlY3RlZCBvdXQgb2Zcbi8vIHRoZSBzdWJxdWVyeS5cbi8vIFJldHVybnMgYSBwb3NzaWJsZS1wcm9taXNlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlRG9udFNlbGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRvbnRTZWxlY3RPYmplY3QgPSBmaW5kT2JqZWN0V2l0aEtleSh0aGlzLnJlc3RXaGVyZSwgJyRkb250U2VsZWN0Jyk7XG4gIGlmICghZG9udFNlbGVjdE9iamVjdCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFRoZSBkb250U2VsZWN0IHZhbHVlIG11c3QgaGF2ZSBwcmVjaXNlbHkgdHdvIGtleXMgLSBxdWVyeSBhbmQga2V5XG4gIHZhciBkb250U2VsZWN0VmFsdWUgPSBkb250U2VsZWN0T2JqZWN0WyckZG9udFNlbGVjdCddO1xuICBpZiAoXG4gICAgIWRvbnRTZWxlY3RWYWx1ZS5xdWVyeSB8fFxuICAgICFkb250U2VsZWN0VmFsdWUua2V5IHx8XG4gICAgdHlwZW9mIGRvbnRTZWxlY3RWYWx1ZS5xdWVyeSAhPT0gJ29iamVjdCcgfHxcbiAgICAhZG9udFNlbGVjdFZhbHVlLnF1ZXJ5LmNsYXNzTmFtZSB8fFxuICAgIE9iamVjdC5rZXlzKGRvbnRTZWxlY3RWYWx1ZSkubGVuZ3RoICE9PSAyXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnaW1wcm9wZXIgdXNhZ2Ugb2YgJGRvbnRTZWxlY3QnKTtcbiAgfVxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogZG9udFNlbGVjdFZhbHVlLnF1ZXJ5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBkb250U2VsZWN0VmFsdWUucXVlcnkuY2xhc3NOYW1lLFxuICAgIGRvbnRTZWxlY3RWYWx1ZS5xdWVyeS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybURvbnRTZWxlY3QoZG9udFNlbGVjdE9iamVjdCwgZG9udFNlbGVjdFZhbHVlLmtleSwgcmVzcG9uc2UucmVzdWx0cyk7XG4gICAgLy8gS2VlcCByZXBsYWNpbmcgJGRvbnRTZWxlY3QgY2xhdXNlc1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2VEb250U2VsZWN0KCk7XG4gIH0pO1xufTtcblxuY29uc3QgY2xlYW5SZXN1bHRBdXRoRGF0YSA9IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgZGVsZXRlIHJlc3VsdC5wYXNzd29yZDtcbiAgaWYgKHJlc3VsdC5hdXRoRGF0YSkge1xuICAgIE9iamVjdC5rZXlzKHJlc3VsdC5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICBpZiAocmVzdWx0LmF1dGhEYXRhW3Byb3ZpZGVyXSA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgcmVzdWx0LmF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChPYmplY3Qua2V5cyhyZXN1bHQuYXV0aERhdGEpLmxlbmd0aCA9PSAwKSB7XG4gICAgICBkZWxldGUgcmVzdWx0LmF1dGhEYXRhO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgcmVwbGFjZUVxdWFsaXR5Q29uc3RyYWludCA9IGNvbnN0cmFpbnQgPT4ge1xuICBpZiAodHlwZW9mIGNvbnN0cmFpbnQgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGNvbnN0cmFpbnQ7XG4gIH1cbiAgY29uc3QgZXF1YWxUb09iamVjdCA9IHt9O1xuICBsZXQgaGFzRGlyZWN0Q29uc3RyYWludCA9IGZhbHNlO1xuICBsZXQgaGFzT3BlcmF0b3JDb25zdHJhaW50ID0gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IGluIGNvbnN0cmFpbnQpIHtcbiAgICBpZiAoa2V5LmluZGV4T2YoJyQnKSAhPT0gMCkge1xuICAgICAgaGFzRGlyZWN0Q29uc3RyYWludCA9IHRydWU7XG4gICAgICBlcXVhbFRvT2JqZWN0W2tleV0gPSBjb25zdHJhaW50W2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGhhc09wZXJhdG9yQ29uc3RyYWludCA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmIChoYXNEaXJlY3RDb25zdHJhaW50ICYmIGhhc09wZXJhdG9yQ29uc3RyYWludCkge1xuICAgIGNvbnN0cmFpbnRbJyRlcSddID0gZXF1YWxUb09iamVjdDtcbiAgICBPYmplY3Qua2V5cyhlcXVhbFRvT2JqZWN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBkZWxldGUgY29uc3RyYWludFtrZXldO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBjb25zdHJhaW50O1xufTtcblxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlRXF1YWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgdGhpcy5yZXN0V2hlcmUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAoY29uc3Qga2V5IGluIHRoaXMucmVzdFdoZXJlKSB7XG4gICAgdGhpcy5yZXN0V2hlcmVba2V5XSA9IHJlcGxhY2VFcXVhbGl0eUNvbnN0cmFpbnQodGhpcy5yZXN0V2hlcmVba2V5XSk7XG4gIH1cbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB3aGV0aGVyIGl0IHdhcyBzdWNjZXNzZnVsLlxuLy8gUG9wdWxhdGVzIHRoaXMucmVzcG9uc2Ugd2l0aCBhbiBvYmplY3QgdGhhdCBvbmx5IGhhcyAncmVzdWx0cycuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJ1bkZpbmQgPSBmdW5jdGlvbiAob3B0aW9ucyA9IHt9KSB7XG4gIGlmICh0aGlzLmZpbmRPcHRpb25zLmxpbWl0ID09PSAwKSB7XG4gICAgdGhpcy5yZXNwb25zZSA9IHsgcmVzdWx0czogW10gfTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgY29uc3QgZmluZE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmZpbmRPcHRpb25zKTtcbiAgaWYgKHRoaXMua2V5cykge1xuICAgIGZpbmRPcHRpb25zLmtleXMgPSB0aGlzLmtleXMubWFwKGtleSA9PiB7XG4gICAgICByZXR1cm4ga2V5LnNwbGl0KCcuJylbMF07XG4gICAgfSk7XG4gIH1cbiAgaWYgKG9wdGlvbnMub3ApIHtcbiAgICBmaW5kT3B0aW9ucy5vcCA9IG9wdGlvbnMub3A7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgLmZpbmQodGhpcy5jbGFzc05hbWUsIHRoaXMucmVzdFdoZXJlLCBmaW5kT3B0aW9ucywgdGhpcy5hdXRoKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmIGZpbmRPcHRpb25zLmV4cGxhaW4gIT09IHRydWUpIHtcbiAgICAgICAgZm9yICh2YXIgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICBjbGVhblJlc3VsdEF1dGhEYXRhKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5jb25maWcuZmlsZXNDb250cm9sbGVyLmV4cGFuZEZpbGVzSW5PYmplY3QodGhpcy5jb25maWcsIHJlc3VsdHMpO1xuXG4gICAgICBpZiAodGhpcy5yZWRpcmVjdENsYXNzTmFtZSkge1xuICAgICAgICBmb3IgKHZhciByIG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICByLmNsYXNzTmFtZSA9IHRoaXMucmVkaXJlY3RDbGFzc05hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMucmVzcG9uc2UgPSB7IHJlc3VsdHM6IHJlc3VsdHMgfTtcbiAgICB9KTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB3aGV0aGVyIGl0IHdhcyBzdWNjZXNzZnVsLlxuLy8gUG9wdWxhdGVzIHRoaXMucmVzcG9uc2UuY291bnQgd2l0aCB0aGUgY291bnRcblJlc3RRdWVyeS5wcm90b3R5cGUucnVuQ291bnQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5kb0NvdW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuZmluZE9wdGlvbnMuY291bnQgPSB0cnVlO1xuICBkZWxldGUgdGhpcy5maW5kT3B0aW9ucy5za2lwO1xuICBkZWxldGUgdGhpcy5maW5kT3B0aW9ucy5saW1pdDtcbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQodGhpcy5jbGFzc05hbWUsIHRoaXMucmVzdFdoZXJlLCB0aGlzLmZpbmRPcHRpb25zKS50aGVuKGMgPT4ge1xuICAgIHRoaXMucmVzcG9uc2UuY291bnQgPSBjO1xuICB9KTtcbn07XG5cbi8vIEF1Z21lbnRzIHRoaXMucmVzcG9uc2Ugd2l0aCBhbGwgcG9pbnRlcnMgb24gYW4gb2JqZWN0XG5SZXN0UXVlcnkucHJvdG90eXBlLmhhbmRsZUluY2x1ZGVBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5pbmNsdWRlQWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKClcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHNjaGVtYUNvbnRyb2xsZXIuZ2V0T25lU2NoZW1hKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgY29uc3QgaW5jbHVkZUZpZWxkcyA9IFtdO1xuICAgICAgY29uc3Qga2V5RmllbGRzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHNjaGVtYS5maWVsZHMpIHtcbiAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgICAgaW5jbHVkZUZpZWxkcy5wdXNoKFtmaWVsZF0pO1xuICAgICAgICAgIGtleUZpZWxkcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQWRkIGZpZWxkcyB0byBpbmNsdWRlLCBrZXlzLCByZW1vdmUgZHVwc1xuICAgICAgdGhpcy5pbmNsdWRlID0gWy4uLm5ldyBTZXQoWy4uLnRoaXMuaW5jbHVkZSwgLi4uaW5jbHVkZUZpZWxkc10pXTtcbiAgICAgIC8vIGlmIHRoaXMua2V5cyBub3Qgc2V0LCB0aGVuIGFsbCBrZXlzIGFyZSBhbHJlYWR5IGluY2x1ZGVkXG4gICAgICBpZiAodGhpcy5rZXlzKSB7XG4gICAgICAgIHRoaXMua2V5cyA9IFsuLi5uZXcgU2V0KFsuLi50aGlzLmtleXMsIC4uLmtleUZpZWxkc10pXTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8vIFVwZGF0ZXMgcHJvcGVydHkgYHRoaXMua2V5c2AgdG8gY29udGFpbiBhbGwga2V5cyBidXQgdGhlIG9uZXMgdW5zZWxlY3RlZC5cblJlc3RRdWVyeS5wcm90b3R5cGUuaGFuZGxlRXhjbHVkZUtleXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5leGNsdWRlS2V5cykge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAodGhpcy5rZXlzKSB7XG4gICAgdGhpcy5rZXlzID0gdGhpcy5rZXlzLmZpbHRlcihrID0+ICF0aGlzLmV4Y2x1ZGVLZXlzLmluY2x1ZGVzKGspKTtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoKVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEodGhpcy5jbGFzc05hbWUpKVxuICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhzY2hlbWEuZmllbGRzKTtcbiAgICAgIHRoaXMua2V5cyA9IGZpZWxkcy5maWx0ZXIoayA9PiAhdGhpcy5leGNsdWRlS2V5cy5pbmNsdWRlcyhrKSk7XG4gICAgfSk7XG59O1xuXG4vLyBBdWdtZW50cyB0aGlzLnJlc3BvbnNlIHdpdGggZGF0YSBhdCB0aGUgcGF0aHMgcHJvdmlkZWQgaW4gdGhpcy5pbmNsdWRlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5oYW5kbGVJbmNsdWRlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5pbmNsdWRlLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBhdGhSZXNwb25zZSA9IGluY2x1ZGVQYXRoKFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICB0aGlzLnJlc3BvbnNlLFxuICAgIHRoaXMuaW5jbHVkZVswXSxcbiAgICB0aGlzLnJlc3RPcHRpb25zXG4gICk7XG4gIGlmIChwYXRoUmVzcG9uc2UudGhlbikge1xuICAgIHJldHVybiBwYXRoUmVzcG9uc2UudGhlbihuZXdSZXNwb25zZSA9PiB7XG4gICAgICB0aGlzLnJlc3BvbnNlID0gbmV3UmVzcG9uc2U7XG4gICAgICB0aGlzLmluY2x1ZGUgPSB0aGlzLmluY2x1ZGUuc2xpY2UoMSk7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVJbmNsdWRlKCk7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodGhpcy5pbmNsdWRlLmxlbmd0aCA+IDApIHtcbiAgICB0aGlzLmluY2x1ZGUgPSB0aGlzLmluY2x1ZGUuc2xpY2UoMSk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5jbHVkZSgpO1xuICB9XG5cbiAgcmV0dXJuIHBhdGhSZXNwb25zZTtcbn07XG5cbi8vUmV0dXJucyBhIHByb21pc2Ugb2YgYSBwcm9jZXNzZWQgc2V0IG9mIHJlc3VsdHNcblJlc3RRdWVyeS5wcm90b3R5cGUucnVuQWZ0ZXJGaW5kVHJpZ2dlciA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnJlc3BvbnNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICghdGhpcy5ydW5BZnRlckZpbmQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gQXZvaWQgZG9pbmcgYW55IHNldHVwIGZvciB0cmlnZ2VycyBpZiB0aGVyZSBpcyBubyAnYWZ0ZXJGaW5kJyB0cmlnZ2VyIGZvciB0aGlzIGNsYXNzLlxuICBjb25zdCBoYXNBZnRlckZpbmRIb29rID0gdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyhcbiAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckZpbmQsXG4gICAgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZFxuICApO1xuICBpZiAoIWhhc0FmdGVyRmluZEhvb2spIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gU2tpcCBBZ2dyZWdhdGUgYW5kIERpc3RpbmN0IFF1ZXJpZXNcbiAgaWYgKHRoaXMuZmluZE9wdGlvbnMucGlwZWxpbmUgfHwgdGhpcy5maW5kT3B0aW9ucy5kaXN0aW5jdCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNvbnN0IGpzb24gPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnJlc3RPcHRpb25zKTtcbiAganNvbi53aGVyZSA9IHRoaXMucmVzdFdoZXJlO1xuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KHRoaXMuY2xhc3NOYW1lKTtcbiAgcGFyc2VRdWVyeS53aXRoSlNPTihqc29uKTtcbiAgLy8gUnVuIGFmdGVyRmluZCB0cmlnZ2VyIGFuZCBzZXQgdGhlIG5ldyByZXN1bHRzXG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1bkFmdGVyRmluZFRyaWdnZXIoXG4gICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckZpbmQsXG4gICAgICB0aGlzLmF1dGgsXG4gICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgIHRoaXMucmVzcG9uc2UucmVzdWx0cyxcbiAgICAgIHRoaXMuY29uZmlnLFxuICAgICAgcGFyc2VRdWVyeVxuICAgIClcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIC8vIEVuc3VyZSB3ZSBwcm9wZXJseSBzZXQgdGhlIGNsYXNzTmFtZSBiYWNrXG4gICAgICBpZiAodGhpcy5yZWRpcmVjdENsYXNzTmFtZSkge1xuICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3VsdHMgPSByZXN1bHRzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpIHtcbiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC50b0pTT04oKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0LmNsYXNzTmFtZSA9IHRoaXMucmVkaXJlY3RDbGFzc05hbWU7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3VsdHMgPSByZXN1bHRzO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuLy8gQWRkcyBpbmNsdWRlZCB2YWx1ZXMgdG8gdGhlIHJlc3BvbnNlLlxuLy8gUGF0aCBpcyBhIGxpc3Qgb2YgZmllbGQgbmFtZXMuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYW4gYXVnbWVudGVkIHJlc3BvbnNlLlxuZnVuY3Rpb24gaW5jbHVkZVBhdGgoY29uZmlnLCBhdXRoLCByZXNwb25zZSwgcGF0aCwgcmVzdE9wdGlvbnMgPSB7fSkge1xuICB2YXIgcG9pbnRlcnMgPSBmaW5kUG9pbnRlcnMocmVzcG9uc2UucmVzdWx0cywgcGF0aCk7XG4gIGlmIChwb2ludGVycy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuICBjb25zdCBwb2ludGVyc0hhc2ggPSB7fTtcbiAgZm9yICh2YXIgcG9pbnRlciBvZiBwb2ludGVycykge1xuICAgIGlmICghcG9pbnRlcikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHBvaW50ZXIuY2xhc3NOYW1lO1xuICAgIC8vIG9ubHkgaW5jbHVkZSB0aGUgZ29vZCBwb2ludGVyc1xuICAgIGlmIChjbGFzc05hbWUpIHtcbiAgICAgIHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdID0gcG9pbnRlcnNIYXNoW2NsYXNzTmFtZV0gfHwgbmV3IFNldCgpO1xuICAgICAgcG9pbnRlcnNIYXNoW2NsYXNzTmFtZV0uYWRkKHBvaW50ZXIub2JqZWN0SWQpO1xuICAgIH1cbiAgfVxuICBjb25zdCBpbmNsdWRlUmVzdE9wdGlvbnMgPSB7fTtcbiAgaWYgKHJlc3RPcHRpb25zLmtleXMpIHtcbiAgICBjb25zdCBrZXlzID0gbmV3IFNldChyZXN0T3B0aW9ucy5rZXlzLnNwbGl0KCcsJykpO1xuICAgIGNvbnN0IGtleVNldCA9IEFycmF5LmZyb20oa2V5cykucmVkdWNlKChzZXQsIGtleSkgPT4ge1xuICAgICAgY29uc3Qga2V5UGF0aCA9IGtleS5zcGxpdCgnLicpO1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgZm9yIChpOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aFtpXSAhPSBrZXlQYXRoW2ldKSB7XG4gICAgICAgICAgcmV0dXJuIHNldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGkgPCBrZXlQYXRoLmxlbmd0aCkge1xuICAgICAgICBzZXQuYWRkKGtleVBhdGhbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNldDtcbiAgICB9LCBuZXcgU2V0KCkpO1xuICAgIGlmIChrZXlTZXQuc2l6ZSA+IDApIHtcbiAgICAgIGluY2x1ZGVSZXN0T3B0aW9ucy5rZXlzID0gQXJyYXkuZnJvbShrZXlTZXQpLmpvaW4oJywnKTtcbiAgICB9XG4gIH1cblxuICBpZiAocmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgaW5jbHVkZVJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIGluY2x1ZGVSZXN0T3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSByZXN0T3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAocmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBpbmNsdWRlUmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIGNvbnN0IHF1ZXJ5UHJvbWlzZXMgPSBPYmplY3Qua2V5cyhwb2ludGVyc0hhc2gpLm1hcChjbGFzc05hbWUgPT4ge1xuICAgIGNvbnN0IG9iamVjdElkcyA9IEFycmF5LmZyb20ocG9pbnRlcnNIYXNoW2NsYXNzTmFtZV0pO1xuICAgIGxldCB3aGVyZTtcbiAgICBpZiAob2JqZWN0SWRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgd2hlcmUgPSB7IG9iamVjdElkOiBvYmplY3RJZHNbMF0gfTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hlcmUgPSB7IG9iamVjdElkOiB7ICRpbjogb2JqZWN0SWRzIH0gfTtcbiAgICB9XG4gICAgdmFyIHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgd2hlcmUsIGluY2x1ZGVSZXN0T3B0aW9ucyk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoeyBvcDogJ2dldCcgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHJlc3VsdHMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHRzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gR2V0IHRoZSBvYmplY3RzIGZvciBhbGwgdGhlc2Ugb2JqZWN0IGlkc1xuICByZXR1cm4gUHJvbWlzZS5hbGwocXVlcnlQcm9taXNlcykudGhlbihyZXNwb25zZXMgPT4ge1xuICAgIHZhciByZXBsYWNlID0gcmVzcG9uc2VzLnJlZHVjZSgocmVwbGFjZSwgaW5jbHVkZVJlc3BvbnNlKSA9PiB7XG4gICAgICBmb3IgKHZhciBvYmogb2YgaW5jbHVkZVJlc3BvbnNlLnJlc3VsdHMpIHtcbiAgICAgICAgb2JqLl9fdHlwZSA9ICdPYmplY3QnO1xuICAgICAgICBvYmouY2xhc3NOYW1lID0gaW5jbHVkZVJlc3BvbnNlLmNsYXNzTmFtZTtcblxuICAgICAgICBpZiAob2JqLmNsYXNzTmFtZSA9PSAnX1VzZXInICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgICAgICAgZGVsZXRlIG9iai5zZXNzaW9uVG9rZW47XG4gICAgICAgICAgZGVsZXRlIG9iai5hdXRoRGF0YTtcbiAgICAgICAgfVxuICAgICAgICByZXBsYWNlW29iai5vYmplY3RJZF0gPSBvYmo7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVwbGFjZTtcbiAgICB9LCB7fSk7XG5cbiAgICB2YXIgcmVzcCA9IHtcbiAgICAgIHJlc3VsdHM6IHJlcGxhY2VQb2ludGVycyhyZXNwb25zZS5yZXN1bHRzLCBwYXRoLCByZXBsYWNlKSxcbiAgICB9O1xuICAgIGlmIChyZXNwb25zZS5jb3VudCkge1xuICAgICAgcmVzcC5jb3VudCA9IHJlc3BvbnNlLmNvdW50O1xuICAgIH1cbiAgICByZXR1cm4gcmVzcDtcbiAgfSk7XG59XG5cbi8vIE9iamVjdCBtYXkgYmUgYSBsaXN0IG9mIFJFU1QtZm9ybWF0IG9iamVjdCB0byBmaW5kIHBvaW50ZXJzIGluLCBvclxuLy8gaXQgbWF5IGJlIGEgc2luZ2xlIG9iamVjdC5cbi8vIElmIHRoZSBwYXRoIHlpZWxkcyB0aGluZ3MgdGhhdCBhcmVuJ3QgcG9pbnRlcnMsIHRoaXMgdGhyb3dzIGFuIGVycm9yLlxuLy8gUGF0aCBpcyBhIGxpc3Qgb2YgZmllbGRzIHRvIHNlYXJjaCBpbnRvLlxuLy8gUmV0dXJucyBhIGxpc3Qgb2YgcG9pbnRlcnMgaW4gUkVTVCBmb3JtYXQuXG5mdW5jdGlvbiBmaW5kUG9pbnRlcnMob2JqZWN0LCBwYXRoKSB7XG4gIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHZhciBhbnN3ZXIgPSBbXTtcbiAgICBmb3IgKHZhciB4IG9mIG9iamVjdCkge1xuICAgICAgYW5zd2VyID0gYW5zd2VyLmNvbmNhdChmaW5kUG9pbnRlcnMoeCwgcGF0aCkpO1xuICAgIH1cbiAgICByZXR1cm4gYW5zd2VyO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdvYmplY3QnIHx8ICFvYmplY3QpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBpZiAocGF0aC5sZW5ndGggPT0gMCkge1xuICAgIGlmIChvYmplY3QgPT09IG51bGwgfHwgb2JqZWN0Ll9fdHlwZSA9PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiBbb2JqZWN0XTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgdmFyIHN1Ym9iamVjdCA9IG9iamVjdFtwYXRoWzBdXTtcbiAgaWYgKCFzdWJvYmplY3QpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGZpbmRQb2ludGVycyhzdWJvYmplY3QsIHBhdGguc2xpY2UoMSkpO1xufVxuXG4vLyBPYmplY3QgbWF5IGJlIGEgbGlzdCBvZiBSRVNULWZvcm1hdCBvYmplY3RzIHRvIHJlcGxhY2UgcG9pbnRlcnNcbi8vIGluLCBvciBpdCBtYXkgYmUgYSBzaW5nbGUgb2JqZWN0LlxuLy8gUGF0aCBpcyBhIGxpc3Qgb2YgZmllbGRzIHRvIHNlYXJjaCBpbnRvLlxuLy8gcmVwbGFjZSBpcyBhIG1hcCBmcm9tIG9iamVjdCBpZCAtPiBvYmplY3QuXG4vLyBSZXR1cm5zIHNvbWV0aGluZyBhbmFsb2dvdXMgdG8gb2JqZWN0LCBidXQgd2l0aCB0aGUgYXBwcm9wcmlhdGVcbi8vIHBvaW50ZXJzIGluZmxhdGVkLlxuZnVuY3Rpb24gcmVwbGFjZVBvaW50ZXJzKG9iamVjdCwgcGF0aCwgcmVwbGFjZSkge1xuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICByZXR1cm4gb2JqZWN0XG4gICAgICAubWFwKG9iaiA9PiByZXBsYWNlUG9pbnRlcnMob2JqLCBwYXRoLCByZXBsYWNlKSlcbiAgICAgIC5maWx0ZXIob2JqID0+IHR5cGVvZiBvYmogIT09ICd1bmRlZmluZWQnKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0JyB8fCAhb2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChvYmplY3QgJiYgb2JqZWN0Ll9fdHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICByZXR1cm4gcmVwbGFjZVtvYmplY3Qub2JqZWN0SWRdO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG5cbiAgdmFyIHN1Ym9iamVjdCA9IG9iamVjdFtwYXRoWzBdXTtcbiAgaWYgKCFzdWJvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG4gIHZhciBuZXdzdWIgPSByZXBsYWNlUG9pbnRlcnMoc3Vib2JqZWN0LCBwYXRoLnNsaWNlKDEpLCByZXBsYWNlKTtcbiAgdmFyIGFuc3dlciA9IHt9O1xuICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKGtleSA9PSBwYXRoWzBdKSB7XG4gICAgICBhbnN3ZXJba2V5XSA9IG5ld3N1YjtcbiAgICB9IGVsc2Uge1xuICAgICAgYW5zd2VyW2tleV0gPSBvYmplY3Rba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFuc3dlcjtcbn1cblxuLy8gRmluZHMgYSBzdWJvYmplY3QgdGhhdCBoYXMgdGhlIGdpdmVuIGtleSwgaWYgdGhlcmUgaXMgb25lLlxuLy8gUmV0dXJucyB1bmRlZmluZWQgb3RoZXJ3aXNlLlxuZnVuY3Rpb24gZmluZE9iamVjdFdpdGhLZXkocm9vdCwga2V5KSB7XG4gIGlmICh0eXBlb2Ygcm9vdCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHJvb3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIGZvciAodmFyIGl0ZW0gb2Ygcm9vdCkge1xuICAgICAgY29uc3QgYW5zd2VyID0gZmluZE9iamVjdFdpdGhLZXkoaXRlbSwga2V5KTtcbiAgICAgIGlmIChhbnN3ZXIpIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKHJvb3QgJiYgcm9vdFtrZXldKSB7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cbiAgZm9yICh2YXIgc3Via2V5IGluIHJvb3QpIHtcbiAgICBjb25zdCBhbnN3ZXIgPSBmaW5kT2JqZWN0V2l0aEtleShyb290W3N1YmtleV0sIGtleSk7XG4gICAgaWYgKGFuc3dlcikge1xuICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZXN0UXVlcnk7XG4iXX0= \ No newline at end of file diff --git a/lib/RestWrite.js b/lib/RestWrite.js new file mode 100644 index 0000000000..4ba32bcb48 --- /dev/null +++ b/lib/RestWrite.js @@ -0,0 +1,1480 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _RestQuery = _interopRequireDefault(require("./RestQuery")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _logger = _interopRequireDefault(require("./logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// A RestWrite encapsulates everything we need to run an operation +// that writes to the database. +// This could be either a "create" or an "update". +var SchemaController = require('./Controllers/SchemaController'); + +var deepcopy = require('deepcopy'); + +const Auth = require('./Auth'); + +var cryptoUtils = require('./cryptoUtils'); + +var passwordCrypto = require('./password'); + +var Parse = require('parse/node'); + +var triggers = require('./triggers'); + +var ClientSDK = require('./ClientSDK'); + +// query and data are both provided in REST API format. So data +// types are encoded by plain old objects. +// If query is null, this is a "create" and the data in data should be +// created. +// Otherwise this is an "update" - the object matching the query +// should get updated with data. +// RestWrite will handle objectId, createdAt, and updatedAt for +// everything. It also knows to use triggers and special modifications +// for the _User class. +function RestWrite(config, auth, className, query, data, originalData, clientSDK, context, action) { + if (auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Cannot perform a write operation when using readOnlyMasterKey'); + } + + this.config = config; + this.auth = auth; + this.className = className; + this.clientSDK = clientSDK; + this.storage = {}; + this.runOptions = {}; + this.context = context || {}; + + if (action) { + this.runOptions.action = action; + } + + if (!query) { + if (this.config.allowCustomObjectId) { + if (Object.prototype.hasOwnProperty.call(data, 'objectId') && !data.objectId) { + throw new Parse.Error(Parse.Error.MISSING_OBJECT_ID, 'objectId must not be empty, null or undefined'); + } + } else { + if (data.objectId) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.'); + } + + if (data.id) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'id is an invalid field name.'); + } + } + } // When the operation is complete, this.response may have several + // fields. + // response: the actual data to be returned + // status: the http status code. if not present, treated like a 200 + // location: the location header. if not present, no location header + + + this.response = null; // Processing this operation may mutate our data, so we operate on a + // copy + + this.query = deepcopy(query); + this.data = deepcopy(data); // We never change originalData, so we do not need a deep copy + + this.originalData = originalData; // The timestamp we'll use for this whole operation + + this.updatedAt = Parse._encode(new Date()).iso; // Shared SchemaController to be reused to reduce the number of loadSchema() calls per request + // Once set the schemaData should be immutable + + this.validSchemaController = null; +} // A convenient method to perform all the steps of processing the +// write, in order. +// Returns a promise for a {response, status, location} object. +// status and location are optional. + + +RestWrite.prototype.execute = function () { + return Promise.resolve().then(() => { + return this.getUserAndRoleACL(); + }).then(() => { + return this.validateClientClassCreation(); + }).then(() => { + return this.handleInstallation(); + }).then(() => { + return this.handleSession(); + }).then(() => { + return this.validateAuthData(); + }).then(() => { + return this.runBeforeSaveTrigger(); + }).then(() => { + return this.deleteEmailResetTokenIfNeeded(); + }).then(() => { + return this.validateSchema(); + }).then(schemaController => { + this.validSchemaController = schemaController; + return this.setRequiredFieldsIfNeeded(); + }).then(() => { + return this.transformUser(); + }).then(() => { + return this.expandFilesForExistingObjects(); + }).then(() => { + return this.destroyDuplicatedSessions(); + }).then(() => { + return this.runDatabaseOperation(); + }).then(() => { + return this.createSessionTokenIfNeeded(); + }).then(() => { + return this.handleFollowup(); + }).then(() => { + return this.runAfterSaveTrigger(); + }).then(() => { + return this.cleanUserAuthData(); + }).then(() => { + return this.response; + }); +}; // Uses the Auth object to get the list of roles, adds the user id + + +RestWrite.prototype.getUserAndRoleACL = function () { + if (this.auth.isMaster) { + return Promise.resolve(); + } + + this.runOptions.acl = ['*']; + + if (this.auth.user) { + return this.auth.getUserRoles().then(roles => { + this.runOptions.acl = this.runOptions.acl.concat(roles, [this.auth.user.id]); + return; + }); + } else { + return Promise.resolve(); + } +}; // Validates this operation against the allowClientClassCreation config. + + +RestWrite.prototype.validateClientClassCreation = function () { + if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { + return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { + if (hasClass !== true) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); + } + }); + } else { + return Promise.resolve(); + } +}; // Validates this operation against the schema. + + +RestWrite.prototype.validateSchema = function () { + return this.config.database.validateObject(this.className, this.data, this.query, this.runOptions); +}; // Runs any beforeSave triggers against this operation. +// Any change leads to our data being mutated. + + +RestWrite.prototype.runBeforeSaveTrigger = function () { + if (this.response) { + return; + } // Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class. + + + if (!triggers.triggerExists(this.className, triggers.Types.beforeSave, this.config.applicationId)) { + return Promise.resolve(); + } // Cloud code gets a bit of extra data for its objects + + + var extraData = { + className: this.className + }; + + if (this.query && this.query.objectId) { + extraData.objectId = this.query.objectId; + } + + let originalObject = null; + const updatedObject = this.buildUpdatedObject(extraData); + + if (this.query && this.query.objectId) { + // This is an update for existing object. + originalObject = triggers.inflate(extraData, this.originalData); + } + + return Promise.resolve().then(() => { + // Before calling the trigger, validate the permissions for the save operation + let databasePromise = null; + + if (this.query) { + // Validate for updating + databasePromise = this.config.database.update(this.className, this.query, this.data, this.runOptions, false, true); + } else { + // Validate for creating + databasePromise = this.config.database.create(this.className, this.data, this.runOptions, true); + } // In the case that there is no permission for the operation, it throws an error + + + return databasePromise.then(result => { + if (!result || result.length <= 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + }); + }).then(() => { + return triggers.maybeRunTrigger(triggers.Types.beforeSave, this.auth, updatedObject, originalObject, this.config, this.context); + }).then(response => { + if (response && response.object) { + this.storage.fieldsChangedByTrigger = _lodash.default.reduce(response.object, (result, value, key) => { + if (!_lodash.default.isEqual(this.data[key], value)) { + result.push(key); + } + + return result; + }, []); + this.data = response.object; // We should delete the objectId for an update write + + if (this.query && this.query.objectId) { + delete this.data.objectId; + } + } + }); +}; + +RestWrite.prototype.runBeforeLoginTrigger = async function (userData) { + // Avoid doing any setup for triggers if there is no 'beforeLogin' trigger + if (!triggers.triggerExists(this.className, triggers.Types.beforeLogin, this.config.applicationId)) { + return; + } // Cloud code gets a bit of extra data for its objects + + + const extraData = { + className: this.className + }; // Expand file objects + + this.config.filesController.expandFilesInObject(this.config, userData); + const user = triggers.inflate(extraData, userData); // no need to return a response + + await triggers.maybeRunTrigger(triggers.Types.beforeLogin, this.auth, user, null, this.config, this.context); +}; + +RestWrite.prototype.setRequiredFieldsIfNeeded = function () { + if (this.data) { + return this.validSchemaController.getAllClasses().then(allClasses => { + const schema = allClasses.find(oneClass => oneClass.className === this.className); + + const setRequiredFieldIfNeeded = (fieldName, setDefault) => { + if (this.data[fieldName] === undefined || this.data[fieldName] === null || this.data[fieldName] === '' || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete') { + if (setDefault && schema.fields[fieldName] && schema.fields[fieldName].defaultValue !== null && schema.fields[fieldName].defaultValue !== undefined && (this.data[fieldName] === undefined || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete')) { + this.data[fieldName] = schema.fields[fieldName].defaultValue; + this.storage.fieldsChangedByTrigger = this.storage.fieldsChangedByTrigger || []; + + if (this.storage.fieldsChangedByTrigger.indexOf(fieldName) < 0) { + this.storage.fieldsChangedByTrigger.push(fieldName); + } + } else if (schema.fields[fieldName] && schema.fields[fieldName].required === true) { + throw new Parse.Error(Parse.Error.VALIDATION_ERROR, `${fieldName} is required`); + } + } + }; // Add default fields + + + this.data.updatedAt = this.updatedAt; + + if (!this.query) { + this.data.createdAt = this.updatedAt; // Only assign new objectId if we are creating new object + + if (!this.data.objectId) { + this.data.objectId = cryptoUtils.newObjectId(this.config.objectIdSize); + } + + if (schema) { + Object.keys(schema.fields).forEach(fieldName => { + setRequiredFieldIfNeeded(fieldName, true); + }); + } + } else if (schema) { + Object.keys(this.data).forEach(fieldName => { + setRequiredFieldIfNeeded(fieldName, false); + }); + } + }); + } + + return Promise.resolve(); +}; // Transforms auth data for a user object. +// Does nothing if this isn't a user object. +// Returns a promise for when we're done if it can't finish this tick. + + +RestWrite.prototype.validateAuthData = function () { + if (this.className !== '_User') { + return; + } + + if (!this.query && !this.data.authData) { + if (typeof this.data.username !== 'string' || _lodash.default.isEmpty(this.data.username)) { + throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'bad or missing username'); + } + + if (typeof this.data.password !== 'string' || _lodash.default.isEmpty(this.data.password)) { + throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'password is required'); + } + } + + if (this.data.authData && !Object.keys(this.data.authData).length || !Object.prototype.hasOwnProperty.call(this.data, 'authData')) { + // Handle saving authData to {} or if authData doesn't exist + return; + } else if (Object.prototype.hasOwnProperty.call(this.data, 'authData') && !this.data.authData) { + // Handle saving authData to null + throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); + } + + var authData = this.data.authData; + var providers = Object.keys(authData); + + if (providers.length > 0) { + const canHandleAuthData = providers.reduce((canHandle, provider) => { + var providerAuthData = authData[provider]; + var hasToken = providerAuthData && providerAuthData.id; + return canHandle && (hasToken || providerAuthData == null); + }, true); + + if (canHandleAuthData) { + return this.handleAuthData(authData); + } + } + + throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); +}; + +RestWrite.prototype.handleAuthDataValidation = function (authData) { + const validations = Object.keys(authData).map(provider => { + if (authData[provider] === null) { + return Promise.resolve(); + } + + const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider); + + if (!validateAuthData) { + throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); + } + + return validateAuthData(authData[provider]); + }); + return Promise.all(validations); +}; + +RestWrite.prototype.findUsersWithAuthData = function (authData) { + const providers = Object.keys(authData); + const query = providers.reduce((memo, provider) => { + if (!authData[provider]) { + return memo; + } + + const queryKey = `authData.${provider}.id`; + const query = {}; + query[queryKey] = authData[provider].id; + memo.push(query); + return memo; + }, []).filter(q => { + return typeof q !== 'undefined'; + }); + let findPromise = Promise.resolve([]); + + if (query.length > 0) { + findPromise = this.config.database.find(this.className, { + $or: query + }, {}); + } + + return findPromise; +}; + +RestWrite.prototype.filteredObjectsByACL = function (objects) { + if (this.auth.isMaster) { + return objects; + } + + return objects.filter(object => { + if (!object.ACL) { + return true; // legacy users that have no ACL field on them + } // Regular users that have been locked out. + + + return object.ACL && Object.keys(object.ACL).length > 0; + }); +}; + +RestWrite.prototype.handleAuthData = function (authData) { + let results; + return this.findUsersWithAuthData(authData).then(async r => { + results = this.filteredObjectsByACL(r); + + if (results.length == 1) { + this.storage['authProvider'] = Object.keys(authData).join(','); + const userResult = results[0]; + const mutatedAuthData = {}; + Object.keys(authData).forEach(provider => { + const providerData = authData[provider]; + const userAuthData = userResult.authData[provider]; + + if (!_lodash.default.isEqual(providerData, userAuthData)) { + mutatedAuthData[provider] = providerData; + } + }); + const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; + let userId; + + if (this.query && this.query.objectId) { + userId = this.query.objectId; + } else if (this.auth && this.auth.user && this.auth.user.id) { + userId = this.auth.user.id; + } + + if (!userId || userId === userResult.objectId) { + // no user making the call + // OR the user making the call is the right one + // Login with auth data + delete results[0].password; // need to set the objectId first otherwise location has trailing undefined + + this.data.objectId = userResult.objectId; + + if (!this.query || !this.query.objectId) { + // this a login call, no userId passed + this.response = { + response: userResult, + location: this.location() + }; // Run beforeLogin hook before storing any updates + // to authData on the db; changes to userResult + // will be ignored. + + await this.runBeforeLoginTrigger(deepcopy(userResult)); + } // If we didn't change the auth data, just keep going + + + if (!hasMutatedAuthData) { + return; + } // We have authData that is updated on login + // that can happen when token are refreshed, + // We should update the token and let the user in + // We should only check the mutated keys + + + return this.handleAuthDataValidation(mutatedAuthData).then(async () => { + // IF we have a response, we'll skip the database operation / beforeSave / afterSave etc... + // we need to set it up there. + // We are supposed to have a response only on LOGIN with authData, so we skip those + // If we're not logging in, but just updating the current user, we can safely skip that part + if (this.response) { + // Assign the new authData in the response + Object.keys(mutatedAuthData).forEach(provider => { + this.response.response.authData[provider] = mutatedAuthData[provider]; + }); // Run the DB update directly, as 'master' + // Just update the authData part + // Then we're good for the user, early exit of sorts + + return this.config.database.update(this.className, { + objectId: this.data.objectId + }, { + authData: mutatedAuthData + }, {}); + } + }); + } else if (userId) { + // Trying to update auth data but users + // are different + if (userResult.objectId !== userId) { + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } // No auth data was mutated, just keep going + + + if (!hasMutatedAuthData) { + return; + } + } + } + + return this.handleAuthDataValidation(authData).then(() => { + if (results.length > 1) { + // More than 1 user with the passed id's + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } + }); + }); +}; // The non-third-party parts of User transformation + + +RestWrite.prototype.transformUser = function () { + var promise = Promise.resolve(); + + if (this.className !== '_User') { + return promise; + } + + if (!this.auth.isMaster && 'emailVerified' in this.data) { + const error = `Clients aren't allowed to manually update email verification.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } // Do not cleanup session if objectId is not set + + + if (this.query && this.objectId()) { + // If we're updating a _User object, we need to clear out the cache for that user. Find all their + // session tokens, and remove them from the cache. + promise = new _RestQuery.default(this.config, Auth.master(this.config), '_Session', { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.objectId() + } + }).execute().then(results => { + results.results.forEach(session => this.config.cacheController.user.del(session.sessionToken)); + }); + } + + return promise.then(() => { + // Transform the password + if (this.data.password === undefined) { + // ignore only if undefined. should proceed if empty ('') + return Promise.resolve(); + } + + if (this.query) { + this.storage['clearSessions'] = true; // Generate a new session only if the user requested + + if (!this.auth.isMaster) { + this.storage['generateNewSession'] = true; + } + } + + return this._validatePasswordPolicy().then(() => { + return passwordCrypto.hash(this.data.password).then(hashedPassword => { + this.data._hashed_password = hashedPassword; + delete this.data.password; + }); + }); + }).then(() => { + return this._validateUserName(); + }).then(() => { + return this._validateEmail(); + }); +}; + +RestWrite.prototype._validateUserName = function () { + // Check for username uniqueness + if (!this.data.username) { + if (!this.query) { + this.data.username = cryptoUtils.randomString(25); + this.responseShouldHaveUsername = true; + } + + return Promise.resolve(); + } + /* + Usernames should be unique when compared case insensitively + Users should be able to make case sensitive usernames and + login using the case they entered. I.e. 'Snoopy' should preclude + 'snoopy' as a valid username. + */ + + + return this.config.database.find(this.className, { + username: this.data.username, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1, + caseInsensitive: true + }, {}, this.validSchemaController).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); + } + + return; + }); +}; +/* + As with usernames, Parse should not allow case insensitive collisions of email. + unlike with usernames (which can have case insensitive collisions in the case of + auth adapters), emails should never have a case insensitive collision. + + This behavior can be enforced through a properly configured index see: + https://docs.mongodb.com/manual/core/index-case-insensitive/#create-a-case-insensitive-index + which could be implemented instead of this code based validation. + + Given that this lookup should be a relatively low use case and that the case sensitive + unique index will be used by the db for the query, this is an adequate solution. +*/ + + +RestWrite.prototype._validateEmail = function () { + if (!this.data.email || this.data.email.__op === 'Delete') { + return Promise.resolve(); + } // Validate basic email address format + + + if (!this.data.email.match(/^.+@.+$/)) { + return Promise.reject(new Parse.Error(Parse.Error.INVALID_EMAIL_ADDRESS, 'Email address format is invalid.')); + } // Case insensitive match, see note above function. + + + return this.config.database.find(this.className, { + email: this.data.email, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1, + caseInsensitive: true + }, {}, this.validSchemaController).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); + } + + if (!this.data.authData || !Object.keys(this.data.authData).length || Object.keys(this.data.authData).length === 1 && Object.keys(this.data.authData)[0] === 'anonymous') { + // We updated the email, send a new validation + this.storage['sendVerificationEmail'] = true; + this.config.userController.setEmailVerifyToken(this.data); + } + }); +}; + +RestWrite.prototype._validatePasswordPolicy = function () { + if (!this.config.passwordPolicy) return Promise.resolve(); + return this._validatePasswordRequirements().then(() => { + return this._validatePasswordHistory(); + }); +}; + +RestWrite.prototype._validatePasswordRequirements = function () { + // check if the password conforms to the defined password policy if configured + // If we specified a custom error in our configuration use it. + // Example: "Passwords must include a Capital Letter, Lowercase Letter, and a number." + // + // This is especially useful on the generic "password reset" page, + // as it allows the programmer to communicate specific requirements instead of: + // a. making the user guess whats wrong + // b. making a custom password reset page that shows the requirements + const policyError = this.config.passwordPolicy.validationError ? this.config.passwordPolicy.validationError : 'Password does not meet the Password Policy requirements.'; + const containsUsernameError = 'Password cannot contain your username.'; // check whether the password meets the password strength requirements + + if (this.config.passwordPolicy.patternValidator && !this.config.passwordPolicy.patternValidator(this.data.password) || this.config.passwordPolicy.validatorCallback && !this.config.passwordPolicy.validatorCallback(this.data.password)) { + return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError)); + } // check whether password contain username + + + if (this.config.passwordPolicy.doNotAllowUsername === true) { + if (this.data.username) { + // username is not passed during password reset + if (this.data.password.indexOf(this.data.username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); + } else { + // retrieve the User object using objectId during password reset + return this.config.database.find('_User', { + objectId: this.objectId() + }).then(results => { + if (results.length != 1) { + throw undefined; + } + + if (this.data.password.indexOf(results[0].username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); + return Promise.resolve(); + }); + } + } + + return Promise.resolve(); +}; + +RestWrite.prototype._validatePasswordHistory = function () { + // check whether password is repeating from specified history + if (this.query && this.config.passwordPolicy.maxPasswordHistory) { + return this.config.database.find('_User', { + objectId: this.objectId() + }, { + keys: ['_password_history', '_hashed_password'] + }).then(results => { + if (results.length != 1) { + throw undefined; + } + + const user = results[0]; + let oldPasswords = []; + if (user._password_history) oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory - 1); + oldPasswords.push(user.password); + const newPassword = this.data.password; // compare the new password hash with all old password hashes + + const promises = oldPasswords.map(function (hash) { + return passwordCrypto.compare(newPassword, hash).then(result => { + if (result) // reject if there is a match + return Promise.reject('REPEAT_PASSWORD'); + return Promise.resolve(); + }); + }); // wait for all comparisons to complete + + return Promise.all(promises).then(() => { + return Promise.resolve(); + }).catch(err => { + if (err === 'REPEAT_PASSWORD') // a match was found + return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, `New password should not be the same as last ${this.config.passwordPolicy.maxPasswordHistory} passwords.`)); + throw err; + }); + }); + } + + return Promise.resolve(); +}; + +RestWrite.prototype.createSessionTokenIfNeeded = function () { + if (this.className !== '_User') { + return; + } // Don't generate session for updating user (this.query is set) unless authData exists + + + if (this.query && !this.data.authData) { + return; + } // Don't generate new sessionToken if linking via sessionToken + + + if (this.auth.user && this.data.authData) { + return; + } + + if (!this.storage['authProvider'] && // signup call, with + this.config.preventLoginWithUnverifiedEmail && // no login without verification + this.config.verifyUserEmails) { + // verification is on + return; // do not create the session token in that case! + } + + return this.createSessionToken(); +}; + +RestWrite.prototype.createSessionToken = async function () { + // cloud installationId from Cloud Code, + // never create session tokens from there. + if (this.auth.installationId && this.auth.installationId === 'cloud') { + return; + } + + const { + sessionData, + createSession + } = Auth.createSession(this.config, { + userId: this.objectId(), + createdWith: { + action: this.storage['authProvider'] ? 'login' : 'signup', + authProvider: this.storage['authProvider'] || 'password' + }, + installationId: this.auth.installationId + }); + + if (this.response && this.response.response) { + this.response.response.sessionToken = sessionData.sessionToken; + } + + return createSession(); +}; // Delete email reset tokens if user is changing password or email. + + +RestWrite.prototype.deleteEmailResetTokenIfNeeded = function () { + if (this.className !== '_User' || this.query === null) { + // null query means create + return; + } + + if ('password' in this.data || 'email' in this.data) { + const addOps = { + _perishable_token: { + __op: 'Delete' + }, + _perishable_token_expires_at: { + __op: 'Delete' + } + }; + this.data = Object.assign(this.data, addOps); + } +}; + +RestWrite.prototype.destroyDuplicatedSessions = function () { + // Only for _Session, and at creation time + if (this.className != '_Session' || this.query) { + return; + } // Destroy the sessions in 'Background' + + + const { + user, + installationId, + sessionToken + } = this.data; + + if (!user || !installationId) { + return; + } + + if (!user.objectId) { + return; + } + + this.config.database.destroy('_Session', { + user, + installationId, + sessionToken: { + $ne: sessionToken + } + }, {}, this.validSchemaController); +}; // Handles any followup logic + + +RestWrite.prototype.handleFollowup = function () { + if (this.storage && this.storage['clearSessions'] && this.config.revokeSessionOnPasswordReset) { + var sessionQuery = { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.objectId() + } + }; + delete this.storage['clearSessions']; + return this.config.database.destroy('_Session', sessionQuery).then(this.handleFollowup.bind(this)); + } + + if (this.storage && this.storage['generateNewSession']) { + delete this.storage['generateNewSession']; + return this.createSessionToken().then(this.handleFollowup.bind(this)); + } + + if (this.storage && this.storage['sendVerificationEmail']) { + delete this.storage['sendVerificationEmail']; // Fire and forget! + + this.config.userController.sendVerificationEmail(this.data); + return this.handleFollowup.bind(this); + } +}; // Handles the _Session class specialness. +// Does nothing if this isn't an _Session object. + + +RestWrite.prototype.handleSession = function () { + if (this.response || this.className !== '_Session') { + return; + } + + if (!this.auth.user && !this.auth.isMaster) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token required.'); + } // TODO: Verify proper error to throw + + + if (this.data.ACL) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'Cannot set ' + 'ACL on a Session.'); + } + + if (this.query) { + if (this.data.user && !this.auth.isMaster && this.data.user.objectId != this.auth.user.id) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); + } else if (this.data.installationId) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); + } else if (this.data.sessionToken) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); + } + } + + if (!this.query && !this.auth.isMaster) { + const additionalSessionData = {}; + + for (var key in this.data) { + if (key === 'objectId' || key === 'user') { + continue; + } + + additionalSessionData[key] = this.data[key]; + } + + const { + sessionData, + createSession + } = Auth.createSession(this.config, { + userId: this.auth.user.id, + createdWith: { + action: 'create' + }, + additionalSessionData + }); + return createSession().then(results => { + if (!results.response) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Error creating session.'); + } + + sessionData['objectId'] = results.response['objectId']; + this.response = { + status: 201, + location: results.location, + response: sessionData + }; + }); + } +}; // Handles the _Installation class specialness. +// Does nothing if this isn't an installation object. +// If an installation is found, this can mutate this.query and turn a create +// into an update. +// Returns a promise for when we're done if it can't finish this tick. + + +RestWrite.prototype.handleInstallation = function () { + if (this.response || this.className !== '_Installation') { + return; + } + + if (!this.query && !this.data.deviceToken && !this.data.installationId && !this.auth.installationId) { + throw new Parse.Error(135, 'at least one ID field (deviceToken, installationId) ' + 'must be specified in this operation'); + } // If the device token is 64 characters long, we assume it is for iOS + // and lowercase it. + + + if (this.data.deviceToken && this.data.deviceToken.length == 64) { + this.data.deviceToken = this.data.deviceToken.toLowerCase(); + } // We lowercase the installationId if present + + + if (this.data.installationId) { + this.data.installationId = this.data.installationId.toLowerCase(); + } + + let installationId = this.data.installationId; // If data.installationId is not set and we're not master, we can lookup in auth + + if (!installationId && !this.auth.isMaster) { + installationId = this.auth.installationId; + } + + if (installationId) { + installationId = installationId.toLowerCase(); + } // Updating _Installation but not updating anything critical + + + if (this.query && !this.data.deviceToken && !installationId && !this.data.deviceType) { + return; + } + + var promise = Promise.resolve(); + var idMatch; // Will be a match on either objectId or installationId + + var objectIdMatch; + var installationIdMatch; + var deviceTokenMatches = []; // Instead of issuing 3 reads, let's do it with one OR. + + const orQueries = []; + + if (this.query && this.query.objectId) { + orQueries.push({ + objectId: this.query.objectId + }); + } + + if (installationId) { + orQueries.push({ + installationId: installationId + }); + } + + if (this.data.deviceToken) { + orQueries.push({ + deviceToken: this.data.deviceToken + }); + } + + if (orQueries.length == 0) { + return; + } + + promise = promise.then(() => { + return this.config.database.find('_Installation', { + $or: orQueries + }, {}); + }).then(results => { + results.forEach(result => { + if (this.query && this.query.objectId && result.objectId == this.query.objectId) { + objectIdMatch = result; + } + + if (result.installationId == installationId) { + installationIdMatch = result; + } + + if (result.deviceToken == this.data.deviceToken) { + deviceTokenMatches.push(result); + } + }); // Sanity checks when running a query + + if (this.query && this.query.objectId) { + if (!objectIdMatch) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for update.'); + } + + if (this.data.installationId && objectIdMatch.installationId && this.data.installationId !== objectIdMatch.installationId) { + throw new Parse.Error(136, 'installationId may not be changed in this ' + 'operation'); + } + + if (this.data.deviceToken && objectIdMatch.deviceToken && this.data.deviceToken !== objectIdMatch.deviceToken && !this.data.installationId && !objectIdMatch.installationId) { + throw new Parse.Error(136, 'deviceToken may not be changed in this ' + 'operation'); + } + + if (this.data.deviceType && this.data.deviceType && this.data.deviceType !== objectIdMatch.deviceType) { + throw new Parse.Error(136, 'deviceType may not be changed in this ' + 'operation'); + } + } + + if (this.query && this.query.objectId && objectIdMatch) { + idMatch = objectIdMatch; + } + + if (installationId && installationIdMatch) { + idMatch = installationIdMatch; + } // need to specify deviceType only if it's new + + + if (!this.query && !this.data.deviceType && !idMatch) { + throw new Parse.Error(135, 'deviceType must be specified in this operation'); + } + }).then(() => { + if (!idMatch) { + if (!deviceTokenMatches.length) { + return; + } else if (deviceTokenMatches.length == 1 && (!deviceTokenMatches[0]['installationId'] || !installationId)) { + // Single match on device token but none on installationId, and either + // the passed object or the match is missing an installationId, so we + // can just return the match. + return deviceTokenMatches[0]['objectId']; + } else if (!this.data.installationId) { + throw new Parse.Error(132, 'Must specify installationId when deviceToken ' + 'matches multiple Installation objects'); + } else { + // Multiple device token matches and we specified an installation ID, + // or a single match where both the passed and matching objects have + // an installation ID. Try cleaning out old installations that match + // the deviceToken, and return nil to signal that a new object should + // be created. + var delQuery = { + deviceToken: this.data.deviceToken, + installationId: { + $ne: installationId + } + }; + + if (this.data.appIdentifier) { + delQuery['appIdentifier'] = this.data.appIdentifier; + } + + this.config.database.destroy('_Installation', delQuery).catch(err => { + if (err.code == Parse.Error.OBJECT_NOT_FOUND) { + // no deletions were made. Can be ignored. + return; + } // rethrow the error + + + throw err; + }); + return; + } + } else { + if (deviceTokenMatches.length == 1 && !deviceTokenMatches[0]['installationId']) { + // Exactly one device token match and it doesn't have an installation + // ID. This is the one case where we want to merge with the existing + // object. + const delQuery = { + objectId: idMatch.objectId + }; + return this.config.database.destroy('_Installation', delQuery).then(() => { + return deviceTokenMatches[0]['objectId']; + }).catch(err => { + if (err.code == Parse.Error.OBJECT_NOT_FOUND) { + // no deletions were made. Can be ignored + return; + } // rethrow the error + + + throw err; + }); + } else { + if (this.data.deviceToken && idMatch.deviceToken != this.data.deviceToken) { + // We're setting the device token on an existing installation, so + // we should try cleaning out old installations that match this + // device token. + const delQuery = { + deviceToken: this.data.deviceToken + }; // We have a unique install Id, use that to preserve + // the interesting installation + + if (this.data.installationId) { + delQuery['installationId'] = { + $ne: this.data.installationId + }; + } else if (idMatch.objectId && this.data.objectId && idMatch.objectId == this.data.objectId) { + // we passed an objectId, preserve that instalation + delQuery['objectId'] = { + $ne: idMatch.objectId + }; + } else { + // What to do here? can't really clean up everything... + return idMatch.objectId; + } + + if (this.data.appIdentifier) { + delQuery['appIdentifier'] = this.data.appIdentifier; + } + + this.config.database.destroy('_Installation', delQuery).catch(err => { + if (err.code == Parse.Error.OBJECT_NOT_FOUND) { + // no deletions were made. Can be ignored. + return; + } // rethrow the error + + + throw err; + }); + } // In non-merge scenarios, just return the installation match id + + + return idMatch.objectId; + } + } + }).then(objId => { + if (objId) { + this.query = { + objectId: objId + }; + delete this.data.objectId; + delete this.data.createdAt; + } // TODO: Validate ops (add/remove on channels, $inc on badge, etc.) + + }); + return promise; +}; // If we short-circuted the object response - then we need to make sure we expand all the files, +// since this might not have a query, meaning it won't return the full result back. +// TODO: (nlutsenko) This should die when we move to per-class based controllers on _Session/_User + + +RestWrite.prototype.expandFilesForExistingObjects = function () { + // Check whether we have a short-circuited response - only then run expansion. + if (this.response && this.response.response) { + this.config.filesController.expandFilesInObject(this.config, this.response.response); + } +}; + +RestWrite.prototype.runDatabaseOperation = function () { + if (this.response) { + return; + } + + if (this.className === '_Role') { + this.config.cacheController.role.clear(); + } + + if (this.className === '_User' && this.query && this.auth.isUnauthenticated()) { + throw new Parse.Error(Parse.Error.SESSION_MISSING, `Cannot modify user ${this.query.objectId}.`); + } + + if (this.className === '_Product' && this.data.download) { + this.data.downloadName = this.data.download.name; + } // TODO: Add better detection for ACL, ensuring a user can't be locked from + // their own user record. + + + if (this.data.ACL && this.data.ACL['*unresolved']) { + throw new Parse.Error(Parse.Error.INVALID_ACL, 'Invalid ACL.'); + } + + if (this.query) { + // Force the user to not lockout + // Matched with parse.com + if (this.className === '_User' && this.data.ACL && this.auth.isMaster !== true) { + this.data.ACL[this.query.objectId] = { + read: true, + write: true + }; + } // update password timestamp if user password is being changed + + + if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { + this.data._password_changed_at = Parse._encode(new Date()); + } // Ignore createdAt when update + + + delete this.data.createdAt; + let defer = Promise.resolve(); // if password history is enabled then save the current password to history + + if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordHistory) { + defer = this.config.database.find('_User', { + objectId: this.objectId() + }, { + keys: ['_password_history', '_hashed_password'] + }).then(results => { + if (results.length != 1) { + throw undefined; + } + + const user = results[0]; + let oldPasswords = []; + + if (user._password_history) { + oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory); + } //n-1 passwords go into history including last password + + + while (oldPasswords.length > Math.max(0, this.config.passwordPolicy.maxPasswordHistory - 2)) { + oldPasswords.shift(); + } + + oldPasswords.push(user.password); + this.data._password_history = oldPasswords; + }); + } + + return defer.then(() => { + // Run an update + return this.config.database.update(this.className, this.query, this.data, this.runOptions, false, false, this.validSchemaController).then(response => { + response.updatedAt = this.updatedAt; + + this._updateResponseWithData(response, this.data); + + this.response = { + response + }; + }); + }); + } else { + // Set the default ACL and password timestamp for the new _User + if (this.className === '_User') { + var ACL = this.data.ACL; // default public r/w ACL + + if (!ACL) { + ACL = {}; + ACL['*'] = { + read: true, + write: false + }; + } // make sure the user is not locked down + + + ACL[this.data.objectId] = { + read: true, + write: true + }; + this.data.ACL = ACL; // password timestamp to be used when password expiry policy is enforced + + if (this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { + this.data._password_changed_at = Parse._encode(new Date()); + } + } // Run a create + + + return this.config.database.create(this.className, this.data, this.runOptions, false, this.validSchemaController).catch(error => { + if (this.className !== '_User' || error.code !== Parse.Error.DUPLICATE_VALUE) { + throw error; + } // Quick check, if we were able to infer the duplicated field name + + + if (error && error.userInfo && error.userInfo.duplicated_field === 'username') { + throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); + } + + if (error && error.userInfo && error.userInfo.duplicated_field === 'email') { + throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); + } // If this was a failed user creation due to username or email already taken, we need to + // check whether it was username or email and return the appropriate error. + // Fallback to the original method + // TODO: See if we can later do this without additional queries by using named indexes. + + + return this.config.database.find(this.className, { + username: this.data.username, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1 + }).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); + } + + return this.config.database.find(this.className, { + email: this.data.email, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1 + }); + }).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); + } + + throw new Parse.Error(Parse.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + }); + }).then(response => { + response.objectId = this.data.objectId; + response.createdAt = this.data.createdAt; + + if (this.responseShouldHaveUsername) { + response.username = this.data.username; + } + + this._updateResponseWithData(response, this.data); + + this.response = { + status: 201, + response, + location: this.location() + }; + }); + } +}; // Returns nothing - doesn't wait for the trigger. + + +RestWrite.prototype.runAfterSaveTrigger = function () { + if (!this.response || !this.response.response) { + return; + } // Avoid doing any setup for triggers if there is no 'afterSave' trigger for this class. + + + const hasAfterSaveHook = triggers.triggerExists(this.className, triggers.Types.afterSave, this.config.applicationId); + const hasLiveQuery = this.config.liveQueryController.hasLiveQuery(this.className); + + if (!hasAfterSaveHook && !hasLiveQuery) { + return Promise.resolve(); + } + + var extraData = { + className: this.className + }; + + if (this.query && this.query.objectId) { + extraData.objectId = this.query.objectId; + } // Build the original object, we only do this for a update write. + + + let originalObject; + + if (this.query && this.query.objectId) { + originalObject = triggers.inflate(extraData, this.originalData); + } // Build the inflated object, different from beforeSave, originalData is not empty + // since developers can change data in the beforeSave. + + + const updatedObject = this.buildUpdatedObject(extraData); + + updatedObject._handleSaveResponse(this.response.response, this.response.status || 200); + + this.config.database.loadSchema().then(schemaController => { + // Notifiy LiveQueryServer if possible + const perms = schemaController.getClassLevelPermissions(updatedObject.className); + this.config.liveQueryController.onAfterSave(updatedObject.className, updatedObject, originalObject, perms); + }); // Run afterSave trigger + + return triggers.maybeRunTrigger(triggers.Types.afterSave, this.auth, updatedObject, originalObject, this.config, this.context).then(result => { + if (result && typeof result === 'object') { + this.response.response = result; + } + }).catch(function (err) { + _logger.default.warn('afterSave caught an error', err); + }); +}; // A helper to figure out what location this operation happens at. + + +RestWrite.prototype.location = function () { + var middle = this.className === '_User' ? '/users/' : '/classes/' + this.className + '/'; + const mount = this.config.mount || this.config.serverURL; + return mount + middle + this.data.objectId; +}; // A helper to get the object id for this operation. +// Because it could be either on the query or on the data + + +RestWrite.prototype.objectId = function () { + return this.data.objectId || this.query.objectId; +}; // Returns a copy of the data and delete bad keys (_auth_data, _hashed_password...) + + +RestWrite.prototype.sanitizedData = function () { + const data = Object.keys(this.data).reduce((data, key) => { + // Regexp comes from Parse.Object.prototype.validate + if (!/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { + delete data[key]; + } + + return data; + }, deepcopy(this.data)); + return Parse._decode(undefined, data); +}; // Returns an updated copy of the object + + +RestWrite.prototype.buildUpdatedObject = function (extraData) { + const updatedObject = triggers.inflate(extraData, this.originalData); + Object.keys(this.data).reduce(function (data, key) { + if (key.indexOf('.') > 0) { + // subdocument key with dot notation ('x.y':v => 'x':{'y':v}) + const splittedKey = key.split('.'); + const parentProp = splittedKey[0]; + let parentVal = updatedObject.get(parentProp); + + if (typeof parentVal !== 'object') { + parentVal = {}; + } + + parentVal[splittedKey[1]] = data[key]; + updatedObject.set(parentProp, parentVal); + delete data[key]; + } + + return data; + }, deepcopy(this.data)); + updatedObject.set(this.sanitizedData()); + return updatedObject; +}; + +RestWrite.prototype.cleanUserAuthData = function () { + if (this.response && this.response.response && this.className === '_User') { + const user = this.response.response; + + if (user.authData) { + Object.keys(user.authData).forEach(provider => { + if (user.authData[provider] === null) { + delete user.authData[provider]; + } + }); + + if (Object.keys(user.authData).length == 0) { + delete user.authData; + } + } + } +}; + +RestWrite.prototype._updateResponseWithData = function (response, data) { + if (_lodash.default.isEmpty(this.storage.fieldsChangedByTrigger)) { + return response; + } + + const clientSupportsDelete = ClientSDK.supportsForwardDelete(this.clientSDK); + this.storage.fieldsChangedByTrigger.forEach(fieldName => { + const dataValue = data[fieldName]; + + if (!Object.prototype.hasOwnProperty.call(response, fieldName)) { + response[fieldName] = dataValue; + } // Strips operations from responses + + + if (response[fieldName] && response[fieldName].__op) { + delete response[fieldName]; + + if (clientSupportsDelete && dataValue.__op == 'Delete') { + response[fieldName] = dataValue; + } + } + }); + return response; +}; + +var _default = RestWrite; +exports.default = _default; +module.exports = RestWrite; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0V3JpdGUuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJkZWVwY29weSIsIkF1dGgiLCJjcnlwdG9VdGlscyIsInBhc3N3b3JkQ3J5cHRvIiwiUGFyc2UiLCJ0cmlnZ2VycyIsIkNsaWVudFNESyIsIlJlc3RXcml0ZSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJxdWVyeSIsImRhdGEiLCJvcmlnaW5hbERhdGEiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiYWN0aW9uIiwiaXNSZWFkT25seSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInN0b3JhZ2UiLCJydW5PcHRpb25zIiwiYWxsb3dDdXN0b21PYmplY3RJZCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm9iamVjdElkIiwiTUlTU0lOR19PQkpFQ1RfSUQiLCJJTlZBTElEX0tFWV9OQU1FIiwiaWQiLCJyZXNwb25zZSIsInVwZGF0ZWRBdCIsIl9lbmNvZGUiLCJEYXRlIiwiaXNvIiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwiZXhlY3V0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldFVzZXJBbmRSb2xlQUNMIiwidmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uIiwiaGFuZGxlSW5zdGFsbGF0aW9uIiwiaGFuZGxlU2Vzc2lvbiIsInZhbGlkYXRlQXV0aERhdGEiLCJydW5CZWZvcmVTYXZlVHJpZ2dlciIsImRlbGV0ZUVtYWlsUmVzZXRUb2tlbklmTmVlZGVkIiwidmFsaWRhdGVTY2hlbWEiLCJzY2hlbWFDb250cm9sbGVyIiwic2V0UmVxdWlyZWRGaWVsZHNJZk5lZWRlZCIsInRyYW5zZm9ybVVzZXIiLCJleHBhbmRGaWxlc0ZvckV4aXN0aW5nT2JqZWN0cyIsImRlc3Ryb3lEdXBsaWNhdGVkU2Vzc2lvbnMiLCJydW5EYXRhYmFzZU9wZXJhdGlvbiIsImNyZWF0ZVNlc3Npb25Ub2tlbklmTmVlZGVkIiwiaGFuZGxlRm9sbG93dXAiLCJydW5BZnRlclNhdmVUcmlnZ2VyIiwiY2xlYW5Vc2VyQXV0aERhdGEiLCJpc01hc3RlciIsImFjbCIsInVzZXIiLCJnZXRVc2VyUm9sZXMiLCJyb2xlcyIsImNvbmNhdCIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsInN5c3RlbUNsYXNzZXMiLCJpbmRleE9mIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiaGFzQ2xhc3MiLCJ2YWxpZGF0ZU9iamVjdCIsInRyaWdnZXJFeGlzdHMiLCJUeXBlcyIsImJlZm9yZVNhdmUiLCJhcHBsaWNhdGlvbklkIiwiZXh0cmFEYXRhIiwib3JpZ2luYWxPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwiYnVpbGRVcGRhdGVkT2JqZWN0IiwiaW5mbGF0ZSIsImRhdGFiYXNlUHJvbWlzZSIsInVwZGF0ZSIsImNyZWF0ZSIsInJlc3VsdCIsImxlbmd0aCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJtYXliZVJ1blRyaWdnZXIiLCJvYmplY3QiLCJmaWVsZHNDaGFuZ2VkQnlUcmlnZ2VyIiwiXyIsInJlZHVjZSIsInZhbHVlIiwia2V5IiwiaXNFcXVhbCIsInB1c2giLCJydW5CZWZvcmVMb2dpblRyaWdnZXIiLCJ1c2VyRGF0YSIsImJlZm9yZUxvZ2luIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsImdldEFsbENsYXNzZXMiLCJhbGxDbGFzc2VzIiwic2NoZW1hIiwiZmluZCIsIm9uZUNsYXNzIiwic2V0UmVxdWlyZWRGaWVsZElmTmVlZGVkIiwiZmllbGROYW1lIiwic2V0RGVmYXVsdCIsInVuZGVmaW5lZCIsIl9fb3AiLCJmaWVsZHMiLCJkZWZhdWx0VmFsdWUiLCJyZXF1aXJlZCIsIlZBTElEQVRJT05fRVJST1IiLCJjcmVhdGVkQXQiLCJuZXdPYmplY3RJZCIsIm9iamVjdElkU2l6ZSIsImtleXMiLCJmb3JFYWNoIiwiYXV0aERhdGEiLCJ1c2VybmFtZSIsImlzRW1wdHkiLCJVU0VSTkFNRV9NSVNTSU5HIiwicGFzc3dvcmQiLCJQQVNTV09SRF9NSVNTSU5HIiwiVU5TVVBQT1JURURfU0VSVklDRSIsInByb3ZpZGVycyIsImNhbkhhbmRsZUF1dGhEYXRhIiwiY2FuSGFuZGxlIiwicHJvdmlkZXIiLCJwcm92aWRlckF1dGhEYXRhIiwiaGFzVG9rZW4iLCJoYW5kbGVBdXRoRGF0YSIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsInZhbGlkYXRpb25zIiwibWFwIiwiYXV0aERhdGFNYW5hZ2VyIiwiZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIiLCJhbGwiLCJmaW5kVXNlcnNXaXRoQXV0aERhdGEiLCJtZW1vIiwicXVlcnlLZXkiLCJmaWx0ZXIiLCJxIiwiZmluZFByb21pc2UiLCIkb3IiLCJmaWx0ZXJlZE9iamVjdHNCeUFDTCIsIm9iamVjdHMiLCJBQ0wiLCJyZXN1bHRzIiwiciIsImpvaW4iLCJ1c2VyUmVzdWx0IiwibXV0YXRlZEF1dGhEYXRhIiwicHJvdmlkZXJEYXRhIiwidXNlckF1dGhEYXRhIiwiaGFzTXV0YXRlZEF1dGhEYXRhIiwidXNlcklkIiwibG9jYXRpb24iLCJBQ0NPVU5UX0FMUkVBRFlfTElOS0VEIiwicHJvbWlzZSIsImVycm9yIiwiUmVzdFF1ZXJ5IiwibWFzdGVyIiwiX190eXBlIiwic2Vzc2lvbiIsImNhY2hlQ29udHJvbGxlciIsImRlbCIsInNlc3Npb25Ub2tlbiIsIl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5IiwiaGFzaCIsImhhc2hlZFBhc3N3b3JkIiwiX2hhc2hlZF9wYXNzd29yZCIsIl92YWxpZGF0ZVVzZXJOYW1lIiwiX3ZhbGlkYXRlRW1haWwiLCJyYW5kb21TdHJpbmciLCJyZXNwb25zZVNob3VsZEhhdmVVc2VybmFtZSIsIiRuZSIsImxpbWl0IiwiY2FzZUluc2Vuc2l0aXZlIiwiVVNFUk5BTUVfVEFLRU4iLCJlbWFpbCIsIm1hdGNoIiwicmVqZWN0IiwiSU5WQUxJRF9FTUFJTF9BRERSRVNTIiwiRU1BSUxfVEFLRU4iLCJ1c2VyQ29udHJvbGxlciIsInNldEVtYWlsVmVyaWZ5VG9rZW4iLCJwYXNzd29yZFBvbGljeSIsIl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzIiwiX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5IiwicG9saWN5RXJyb3IiLCJ2YWxpZGF0aW9uRXJyb3IiLCJjb250YWluc1VzZXJuYW1lRXJyb3IiLCJwYXR0ZXJuVmFsaWRhdG9yIiwidmFsaWRhdG9yQ2FsbGJhY2siLCJkb05vdEFsbG93VXNlcm5hbWUiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJvbGRQYXNzd29yZHMiLCJfcGFzc3dvcmRfaGlzdG9yeSIsInRha2UiLCJuZXdQYXNzd29yZCIsInByb21pc2VzIiwiY29tcGFyZSIsImNhdGNoIiwiZXJyIiwicHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCIsInZlcmlmeVVzZXJFbWFpbHMiLCJjcmVhdGVTZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsImNyZWF0ZWRXaXRoIiwiYXV0aFByb3ZpZGVyIiwiYWRkT3BzIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiYXNzaWduIiwiZGVzdHJveSIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJzZXNzaW9uUXVlcnkiLCJiaW5kIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiYWRkaXRpb25hbFNlc3Npb25EYXRhIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwic3RhdHVzIiwiZGV2aWNlVG9rZW4iLCJ0b0xvd2VyQ2FzZSIsImRldmljZVR5cGUiLCJpZE1hdGNoIiwib2JqZWN0SWRNYXRjaCIsImluc3RhbGxhdGlvbklkTWF0Y2giLCJkZXZpY2VUb2tlbk1hdGNoZXMiLCJvclF1ZXJpZXMiLCJkZWxRdWVyeSIsImFwcElkZW50aWZpZXIiLCJjb2RlIiwib2JqSWQiLCJyb2xlIiwiY2xlYXIiLCJpc1VuYXV0aGVudGljYXRlZCIsIlNFU1NJT05fTUlTU0lORyIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwibmFtZSIsIklOVkFMSURfQUNMIiwicmVhZCIsIndyaXRlIiwibWF4UGFzc3dvcmRBZ2UiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsImRlZmVyIiwiTWF0aCIsIm1heCIsInNoaWZ0IiwiX3VwZGF0ZVJlc3BvbnNlV2l0aERhdGEiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1c2VySW5mbyIsImR1cGxpY2F0ZWRfZmllbGQiLCJoYXNBZnRlclNhdmVIb29rIiwiYWZ0ZXJTYXZlIiwiaGFzTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsIl9oYW5kbGVTYXZlUmVzcG9uc2UiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIm9uQWZ0ZXJTYXZlIiwibG9nZ2VyIiwid2FybiIsIm1pZGRsZSIsIm1vdW50Iiwic2VydmVyVVJMIiwic2FuaXRpemVkRGF0YSIsInRlc3QiLCJfZGVjb2RlIiwic3BsaXR0ZWRLZXkiLCJzcGxpdCIsInBhcmVudFByb3AiLCJwYXJlbnRWYWwiLCJnZXQiLCJzZXQiLCJjbGllbnRTdXBwb3J0c0RlbGV0ZSIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImRhdGFWYWx1ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFhQTs7QUFDQTs7QUFDQTs7OztBQWZBO0FBQ0E7QUFDQTtBQUVBLElBQUlBLGdCQUFnQixHQUFHQyxPQUFPLENBQUMsZ0NBQUQsQ0FBOUI7O0FBQ0EsSUFBSUMsUUFBUSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUF0Qjs7QUFFQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxRQUFELENBQXBCOztBQUNBLElBQUlHLFdBQVcsR0FBR0gsT0FBTyxDQUFDLGVBQUQsQ0FBekI7O0FBQ0EsSUFBSUksY0FBYyxHQUFHSixPQUFPLENBQUMsWUFBRCxDQUE1Qjs7QUFDQSxJQUFJSyxLQUFLLEdBQUdMLE9BQU8sQ0FBQyxZQUFELENBQW5COztBQUNBLElBQUlNLFFBQVEsR0FBR04sT0FBTyxDQUFDLFlBQUQsQ0FBdEI7O0FBQ0EsSUFBSU8sU0FBUyxHQUFHUCxPQUFPLENBQUMsYUFBRCxDQUF2Qjs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTUSxTQUFULENBQW1CQyxNQUFuQixFQUEyQkMsSUFBM0IsRUFBaUNDLFNBQWpDLEVBQTRDQyxLQUE1QyxFQUFtREMsSUFBbkQsRUFBeURDLFlBQXpELEVBQXVFQyxTQUF2RSxFQUFrRkMsT0FBbEYsRUFBMkZDLE1BQTNGLEVBQW1HO0FBQ2pHLE1BQUlQLElBQUksQ0FBQ1EsVUFBVCxFQUFxQjtBQUNuQixVQUFNLElBQUliLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSiwrREFGSSxDQUFOO0FBSUQ7O0FBQ0QsT0FBS1gsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsT0FBS0MsSUFBTCxHQUFZQSxJQUFaO0FBQ0EsT0FBS0MsU0FBTCxHQUFpQkEsU0FBakI7QUFDQSxPQUFLSSxTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLE9BQUtNLE9BQUwsR0FBZSxFQUFmO0FBQ0EsT0FBS0MsVUFBTCxHQUFrQixFQUFsQjtBQUNBLE9BQUtOLE9BQUwsR0FBZUEsT0FBTyxJQUFJLEVBQTFCOztBQUVBLE1BQUlDLE1BQUosRUFBWTtBQUNWLFNBQUtLLFVBQUwsQ0FBZ0JMLE1BQWhCLEdBQXlCQSxNQUF6QjtBQUNEOztBQUVELE1BQUksQ0FBQ0wsS0FBTCxFQUFZO0FBQ1YsUUFBSSxLQUFLSCxNQUFMLENBQVljLG1CQUFoQixFQUFxQztBQUNuQyxVQUFJQyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ2QsSUFBckMsRUFBMkMsVUFBM0MsS0FBMEQsQ0FBQ0EsSUFBSSxDQUFDZSxRQUFwRSxFQUE4RTtBQUM1RSxjQUFNLElBQUl2QixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlVLGlCQURSLEVBRUosK0NBRkksQ0FBTjtBQUlEO0FBQ0YsS0FQRCxNQU9PO0FBQ0wsVUFBSWhCLElBQUksQ0FBQ2UsUUFBVCxFQUFtQjtBQUNqQixjQUFNLElBQUl2QixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZVyxnQkFBNUIsRUFBOEMsb0NBQTlDLENBQU47QUFDRDs7QUFDRCxVQUFJakIsSUFBSSxDQUFDa0IsRUFBVCxFQUFhO0FBQ1gsY0FBTSxJQUFJMUIsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWVcsZ0JBQTVCLEVBQThDLDhCQUE5QyxDQUFOO0FBQ0Q7QUFDRjtBQUNGLEdBbkNnRyxDQXFDakc7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsT0FBS0UsUUFBTCxHQUFnQixJQUFoQixDQTFDaUcsQ0E0Q2pHO0FBQ0E7O0FBQ0EsT0FBS3BCLEtBQUwsR0FBYVgsUUFBUSxDQUFDVyxLQUFELENBQXJCO0FBQ0EsT0FBS0MsSUFBTCxHQUFZWixRQUFRLENBQUNZLElBQUQsQ0FBcEIsQ0EvQ2lHLENBZ0RqRzs7QUFDQSxPQUFLQyxZQUFMLEdBQW9CQSxZQUFwQixDQWpEaUcsQ0FtRGpHOztBQUNBLE9BQUttQixTQUFMLEdBQWlCNUIsS0FBSyxDQUFDNkIsT0FBTixDQUFjLElBQUlDLElBQUosRUFBZCxFQUEwQkMsR0FBM0MsQ0FwRGlHLENBc0RqRztBQUNBOztBQUNBLE9BQUtDLHFCQUFMLEdBQTZCLElBQTdCO0FBQ0QsQyxDQUVEO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTdCLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JhLE9BQXBCLEdBQThCLFlBQVk7QUFDeEMsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsV0FBTyxLQUFLQyxpQkFBTCxFQUFQO0FBQ0QsR0FISSxFQUlKRCxJQUpJLENBSUMsTUFBTTtBQUNWLFdBQU8sS0FBS0UsMkJBQUwsRUFBUDtBQUNELEdBTkksRUFPSkYsSUFQSSxDQU9DLE1BQU07QUFDVixXQUFPLEtBQUtHLGtCQUFMLEVBQVA7QUFDRCxHQVRJLEVBVUpILElBVkksQ0FVQyxNQUFNO0FBQ1YsV0FBTyxLQUFLSSxhQUFMLEVBQVA7QUFDRCxHQVpJLEVBYUpKLElBYkksQ0FhQyxNQUFNO0FBQ1YsV0FBTyxLQUFLSyxnQkFBTCxFQUFQO0FBQ0QsR0FmSSxFQWdCSkwsSUFoQkksQ0FnQkMsTUFBTTtBQUNWLFdBQU8sS0FBS00sb0JBQUwsRUFBUDtBQUNELEdBbEJJLEVBbUJKTixJQW5CSSxDQW1CQyxNQUFNO0FBQ1YsV0FBTyxLQUFLTyw2QkFBTCxFQUFQO0FBQ0QsR0FyQkksRUFzQkpQLElBdEJJLENBc0JDLE1BQU07QUFDVixXQUFPLEtBQUtRLGNBQUwsRUFBUDtBQUNELEdBeEJJLEVBeUJKUixJQXpCSSxDQXlCQ1MsZ0JBQWdCLElBQUk7QUFDeEIsU0FBS2IscUJBQUwsR0FBNkJhLGdCQUE3QjtBQUNBLFdBQU8sS0FBS0MseUJBQUwsRUFBUDtBQUNELEdBNUJJLEVBNkJKVixJQTdCSSxDQTZCQyxNQUFNO0FBQ1YsV0FBTyxLQUFLVyxhQUFMLEVBQVA7QUFDRCxHQS9CSSxFQWdDSlgsSUFoQ0ksQ0FnQ0MsTUFBTTtBQUNWLFdBQU8sS0FBS1ksNkJBQUwsRUFBUDtBQUNELEdBbENJLEVBbUNKWixJQW5DSSxDQW1DQyxNQUFNO0FBQ1YsV0FBTyxLQUFLYSx5QkFBTCxFQUFQO0FBQ0QsR0FyQ0ksRUFzQ0piLElBdENJLENBc0NDLE1BQU07QUFDVixXQUFPLEtBQUtjLG9CQUFMLEVBQVA7QUFDRCxHQXhDSSxFQXlDSmQsSUF6Q0ksQ0F5Q0MsTUFBTTtBQUNWLFdBQU8sS0FBS2UsMEJBQUwsRUFBUDtBQUNELEdBM0NJLEVBNENKZixJQTVDSSxDQTRDQyxNQUFNO0FBQ1YsV0FBTyxLQUFLZ0IsY0FBTCxFQUFQO0FBQ0QsR0E5Q0ksRUErQ0poQixJQS9DSSxDQStDQyxNQUFNO0FBQ1YsV0FBTyxLQUFLaUIsbUJBQUwsRUFBUDtBQUNELEdBakRJLEVBa0RKakIsSUFsREksQ0FrREMsTUFBTTtBQUNWLFdBQU8sS0FBS2tCLGlCQUFMLEVBQVA7QUFDRCxHQXBESSxFQXFESmxCLElBckRJLENBcURDLE1BQU07QUFDVixXQUFPLEtBQUtULFFBQVo7QUFDRCxHQXZESSxDQUFQO0FBd0RELENBekRELEMsQ0EyREE7OztBQUNBeEIsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmlCLGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUksS0FBS2hDLElBQUwsQ0FBVWtELFFBQWQsRUFBd0I7QUFDdEIsV0FBT3JCLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsT0FBS2xCLFVBQUwsQ0FBZ0J1QyxHQUFoQixHQUFzQixDQUFDLEdBQUQsQ0FBdEI7O0FBRUEsTUFBSSxLQUFLbkQsSUFBTCxDQUFVb0QsSUFBZCxFQUFvQjtBQUNsQixXQUFPLEtBQUtwRCxJQUFMLENBQVVxRCxZQUFWLEdBQXlCdEIsSUFBekIsQ0FBOEJ1QixLQUFLLElBQUk7QUFDNUMsV0FBSzFDLFVBQUwsQ0FBZ0J1QyxHQUFoQixHQUFzQixLQUFLdkMsVUFBTCxDQUFnQnVDLEdBQWhCLENBQW9CSSxNQUFwQixDQUEyQkQsS0FBM0IsRUFBa0MsQ0FBQyxLQUFLdEQsSUFBTCxDQUFVb0QsSUFBVixDQUFlL0IsRUFBaEIsQ0FBbEMsQ0FBdEI7QUFDQTtBQUNELEtBSE0sQ0FBUDtBQUlELEdBTEQsTUFLTztBQUNMLFdBQU9RLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7QUFDRixDQWZELEMsQ0FpQkE7OztBQUNBaEMsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmtCLDJCQUFwQixHQUFrRCxZQUFZO0FBQzVELE1BQ0UsS0FBS2xDLE1BQUwsQ0FBWXlELHdCQUFaLEtBQXlDLEtBQXpDLElBQ0EsQ0FBQyxLQUFLeEQsSUFBTCxDQUFVa0QsUUFEWCxJQUVBN0QsZ0JBQWdCLENBQUNvRSxhQUFqQixDQUErQkMsT0FBL0IsQ0FBdUMsS0FBS3pELFNBQTVDLE1BQTJELENBQUMsQ0FIOUQsRUFJRTtBQUNBLFdBQU8sS0FBS0YsTUFBTCxDQUFZNEQsUUFBWixDQUNKQyxVQURJLEdBRUo3QixJQUZJLENBRUNTLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ3FCLFFBQWpCLENBQTBCLEtBQUs1RCxTQUEvQixDQUZyQixFQUdKOEIsSUFISSxDQUdDOEIsUUFBUSxJQUFJO0FBQ2hCLFVBQUlBLFFBQVEsS0FBSyxJQUFqQixFQUF1QjtBQUNyQixjQUFNLElBQUlsRSxLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLG1CQURSLEVBRUosd0NBQXdDLHNCQUF4QyxHQUFpRSxLQUFLVCxTQUZsRSxDQUFOO0FBSUQ7QUFDRixLQVZJLENBQVA7QUFXRCxHQWhCRCxNQWdCTztBQUNMLFdBQU80QixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEO0FBQ0YsQ0FwQkQsQyxDQXNCQTs7O0FBQ0FoQyxTQUFTLENBQUNpQixTQUFWLENBQW9Cd0IsY0FBcEIsR0FBcUMsWUFBWTtBQUMvQyxTQUFPLEtBQUt4QyxNQUFMLENBQVk0RCxRQUFaLENBQXFCRyxjQUFyQixDQUNMLEtBQUs3RCxTQURBLEVBRUwsS0FBS0UsSUFGQSxFQUdMLEtBQUtELEtBSEEsRUFJTCxLQUFLVSxVQUpBLENBQVA7QUFNRCxDQVBELEMsQ0FTQTtBQUNBOzs7QUFDQWQsU0FBUyxDQUFDaUIsU0FBVixDQUFvQnNCLG9CQUFwQixHQUEyQyxZQUFZO0FBQ3JELE1BQUksS0FBS2YsUUFBVCxFQUFtQjtBQUNqQjtBQUNELEdBSG9ELENBS3JEOzs7QUFDQSxNQUNFLENBQUMxQixRQUFRLENBQUNtRSxhQUFULENBQXVCLEtBQUs5RCxTQUE1QixFQUF1Q0wsUUFBUSxDQUFDb0UsS0FBVCxDQUFlQyxVQUF0RCxFQUFrRSxLQUFLbEUsTUFBTCxDQUFZbUUsYUFBOUUsQ0FESCxFQUVFO0FBQ0EsV0FBT3JDLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsR0FWb0QsQ0FZckQ7OztBQUNBLE1BQUlxQyxTQUFTLEdBQUc7QUFBRWxFLElBQUFBLFNBQVMsRUFBRSxLQUFLQTtBQUFsQixHQUFoQjs7QUFDQSxNQUFJLEtBQUtDLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQ2lELElBQUFBLFNBQVMsQ0FBQ2pELFFBQVYsR0FBcUIsS0FBS2hCLEtBQUwsQ0FBV2dCLFFBQWhDO0FBQ0Q7O0FBRUQsTUFBSWtELGNBQWMsR0FBRyxJQUFyQjtBQUNBLFFBQU1DLGFBQWEsR0FBRyxLQUFLQyxrQkFBTCxDQUF3QkgsU0FBeEIsQ0FBdEI7O0FBQ0EsTUFBSSxLQUFLakUsS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQTdCLEVBQXVDO0FBQ3JDO0FBQ0FrRCxJQUFBQSxjQUFjLEdBQUd4RSxRQUFRLENBQUMyRSxPQUFULENBQWlCSixTQUFqQixFQUE0QixLQUFLL0QsWUFBakMsQ0FBakI7QUFDRDs7QUFFRCxTQUFPeUIsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1Y7QUFDQSxRQUFJeUMsZUFBZSxHQUFHLElBQXRCOztBQUNBLFFBQUksS0FBS3RFLEtBQVQsRUFBZ0I7QUFDZDtBQUNBc0UsTUFBQUEsZUFBZSxHQUFHLEtBQUt6RSxNQUFMLENBQVk0RCxRQUFaLENBQXFCYyxNQUFyQixDQUNoQixLQUFLeEUsU0FEVyxFQUVoQixLQUFLQyxLQUZXLEVBR2hCLEtBQUtDLElBSFcsRUFJaEIsS0FBS1MsVUFKVyxFQUtoQixLQUxnQixFQU1oQixJQU5nQixDQUFsQjtBQVFELEtBVkQsTUFVTztBQUNMO0FBQ0E0RCxNQUFBQSxlQUFlLEdBQUcsS0FBS3pFLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJlLE1BQXJCLENBQ2hCLEtBQUt6RSxTQURXLEVBRWhCLEtBQUtFLElBRlcsRUFHaEIsS0FBS1MsVUFIVyxFQUloQixJQUpnQixDQUFsQjtBQU1ELEtBckJTLENBc0JWOzs7QUFDQSxXQUFPNEQsZUFBZSxDQUFDekMsSUFBaEIsQ0FBcUI0QyxNQUFNLElBQUk7QUFDcEMsVUFBSSxDQUFDQSxNQUFELElBQVdBLE1BQU0sQ0FBQ0MsTUFBUCxJQUFpQixDQUFoQyxFQUFtQztBQUNqQyxjQUFNLElBQUlqRixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZb0UsZ0JBQTVCLEVBQThDLG1CQUE5QyxDQUFOO0FBQ0Q7QUFDRixLQUpNLENBQVA7QUFLRCxHQTdCSSxFQThCSjlDLElBOUJJLENBOEJDLE1BQU07QUFDVixXQUFPbkMsUUFBUSxDQUFDa0YsZUFBVCxDQUNMbEYsUUFBUSxDQUFDb0UsS0FBVCxDQUFlQyxVQURWLEVBRUwsS0FBS2pFLElBRkEsRUFHTHFFLGFBSEssRUFJTEQsY0FKSyxFQUtMLEtBQUtyRSxNQUxBLEVBTUwsS0FBS08sT0FOQSxDQUFQO0FBUUQsR0F2Q0ksRUF3Q0p5QixJQXhDSSxDQXdDQ1QsUUFBUSxJQUFJO0FBQ2hCLFFBQUlBLFFBQVEsSUFBSUEsUUFBUSxDQUFDeUQsTUFBekIsRUFBaUM7QUFDL0IsV0FBS3BFLE9BQUwsQ0FBYXFFLHNCQUFiLEdBQXNDQyxnQkFBRUMsTUFBRixDQUNwQzVELFFBQVEsQ0FBQ3lELE1BRDJCLEVBRXBDLENBQUNKLE1BQUQsRUFBU1EsS0FBVCxFQUFnQkMsR0FBaEIsS0FBd0I7QUFDdEIsWUFBSSxDQUFDSCxnQkFBRUksT0FBRixDQUFVLEtBQUtsRixJQUFMLENBQVVpRixHQUFWLENBQVYsRUFBMEJELEtBQTFCLENBQUwsRUFBdUM7QUFDckNSLFVBQUFBLE1BQU0sQ0FBQ1csSUFBUCxDQUFZRixHQUFaO0FBQ0Q7O0FBQ0QsZUFBT1QsTUFBUDtBQUNELE9BUG1DLEVBUXBDLEVBUm9DLENBQXRDO0FBVUEsV0FBS3hFLElBQUwsR0FBWW1CLFFBQVEsQ0FBQ3lELE1BQXJCLENBWCtCLENBWS9COztBQUNBLFVBQUksS0FBSzdFLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQyxlQUFPLEtBQUtmLElBQUwsQ0FBVWUsUUFBakI7QUFDRDtBQUNGO0FBQ0YsR0ExREksQ0FBUDtBQTJERCxDQXBGRDs7QUFzRkFwQixTQUFTLENBQUNpQixTQUFWLENBQW9Cd0UscUJBQXBCLEdBQTRDLGdCQUFnQkMsUUFBaEIsRUFBMEI7QUFDcEU7QUFDQSxNQUNFLENBQUM1RixRQUFRLENBQUNtRSxhQUFULENBQXVCLEtBQUs5RCxTQUE1QixFQUF1Q0wsUUFBUSxDQUFDb0UsS0FBVCxDQUFleUIsV0FBdEQsRUFBbUUsS0FBSzFGLE1BQUwsQ0FBWW1FLGFBQS9FLENBREgsRUFFRTtBQUNBO0FBQ0QsR0FObUUsQ0FRcEU7OztBQUNBLFFBQU1DLFNBQVMsR0FBRztBQUFFbEUsSUFBQUEsU0FBUyxFQUFFLEtBQUtBO0FBQWxCLEdBQWxCLENBVG9FLENBV3BFOztBQUNBLE9BQUtGLE1BQUwsQ0FBWTJGLGVBQVosQ0FBNEJDLG1CQUE1QixDQUFnRCxLQUFLNUYsTUFBckQsRUFBNkR5RixRQUE3RDtBQUVBLFFBQU1wQyxJQUFJLEdBQUd4RCxRQUFRLENBQUMyRSxPQUFULENBQWlCSixTQUFqQixFQUE0QnFCLFFBQTVCLENBQWIsQ0Fkb0UsQ0FnQnBFOztBQUNBLFFBQU01RixRQUFRLENBQUNrRixlQUFULENBQ0psRixRQUFRLENBQUNvRSxLQUFULENBQWV5QixXQURYLEVBRUosS0FBS3pGLElBRkQsRUFHSm9ELElBSEksRUFJSixJQUpJLEVBS0osS0FBS3JELE1BTEQsRUFNSixLQUFLTyxPQU5ELENBQU47QUFRRCxDQXpCRDs7QUEyQkFSLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0IwQix5QkFBcEIsR0FBZ0QsWUFBWTtBQUMxRCxNQUFJLEtBQUt0QyxJQUFULEVBQWU7QUFDYixXQUFPLEtBQUt3QixxQkFBTCxDQUEyQmlFLGFBQTNCLEdBQTJDN0QsSUFBM0MsQ0FBZ0Q4RCxVQUFVLElBQUk7QUFDbkUsWUFBTUMsTUFBTSxHQUFHRCxVQUFVLENBQUNFLElBQVgsQ0FBZ0JDLFFBQVEsSUFBSUEsUUFBUSxDQUFDL0YsU0FBVCxLQUF1QixLQUFLQSxTQUF4RCxDQUFmOztBQUNBLFlBQU1nRyx3QkFBd0IsR0FBRyxDQUFDQyxTQUFELEVBQVlDLFVBQVosS0FBMkI7QUFDMUQsWUFDRSxLQUFLaEcsSUFBTCxDQUFVK0YsU0FBVixNQUF5QkUsU0FBekIsSUFDQSxLQUFLakcsSUFBTCxDQUFVK0YsU0FBVixNQUF5QixJQUR6QixJQUVBLEtBQUsvRixJQUFMLENBQVUrRixTQUFWLE1BQXlCLEVBRnpCLElBR0MsT0FBTyxLQUFLL0YsSUFBTCxDQUFVK0YsU0FBVixDQUFQLEtBQWdDLFFBQWhDLElBQTRDLEtBQUsvRixJQUFMLENBQVUrRixTQUFWLEVBQXFCRyxJQUFyQixLQUE4QixRQUo3RSxFQUtFO0FBQ0EsY0FDRUYsVUFBVSxJQUNWTCxNQUFNLENBQUNRLE1BQVAsQ0FBY0osU0FBZCxDQURBLElBRUFKLE1BQU0sQ0FBQ1EsTUFBUCxDQUFjSixTQUFkLEVBQXlCSyxZQUF6QixLQUEwQyxJQUYxQyxJQUdBVCxNQUFNLENBQUNRLE1BQVAsQ0FBY0osU0FBZCxFQUF5QkssWUFBekIsS0FBMENILFNBSDFDLEtBSUMsS0FBS2pHLElBQUwsQ0FBVStGLFNBQVYsTUFBeUJFLFNBQXpCLElBQ0UsT0FBTyxLQUFLakcsSUFBTCxDQUFVK0YsU0FBVixDQUFQLEtBQWdDLFFBQWhDLElBQTRDLEtBQUsvRixJQUFMLENBQVUrRixTQUFWLEVBQXFCRyxJQUFyQixLQUE4QixRQUw3RSxDQURGLEVBT0U7QUFDQSxpQkFBS2xHLElBQUwsQ0FBVStGLFNBQVYsSUFBdUJKLE1BQU0sQ0FBQ1EsTUFBUCxDQUFjSixTQUFkLEVBQXlCSyxZQUFoRDtBQUNBLGlCQUFLNUYsT0FBTCxDQUFhcUUsc0JBQWIsR0FBc0MsS0FBS3JFLE9BQUwsQ0FBYXFFLHNCQUFiLElBQXVDLEVBQTdFOztBQUNBLGdCQUFJLEtBQUtyRSxPQUFMLENBQWFxRSxzQkFBYixDQUFvQ3RCLE9BQXBDLENBQTRDd0MsU0FBNUMsSUFBeUQsQ0FBN0QsRUFBZ0U7QUFDOUQsbUJBQUt2RixPQUFMLENBQWFxRSxzQkFBYixDQUFvQ00sSUFBcEMsQ0FBeUNZLFNBQXpDO0FBQ0Q7QUFDRixXQWJELE1BYU8sSUFBSUosTUFBTSxDQUFDUSxNQUFQLENBQWNKLFNBQWQsS0FBNEJKLE1BQU0sQ0FBQ1EsTUFBUCxDQUFjSixTQUFkLEVBQXlCTSxRQUF6QixLQUFzQyxJQUF0RSxFQUE0RTtBQUNqRixrQkFBTSxJQUFJN0csS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWWdHLGdCQUE1QixFQUErQyxHQUFFUCxTQUFVLGNBQTNELENBQU47QUFDRDtBQUNGO0FBQ0YsT0F4QkQsQ0FGbUUsQ0E0Qm5FOzs7QUFDQSxXQUFLL0YsSUFBTCxDQUFVb0IsU0FBVixHQUFzQixLQUFLQSxTQUEzQjs7QUFDQSxVQUFJLENBQUMsS0FBS3JCLEtBQVYsRUFBaUI7QUFDZixhQUFLQyxJQUFMLENBQVV1RyxTQUFWLEdBQXNCLEtBQUtuRixTQUEzQixDQURlLENBR2Y7O0FBQ0EsWUFBSSxDQUFDLEtBQUtwQixJQUFMLENBQVVlLFFBQWYsRUFBeUI7QUFDdkIsZUFBS2YsSUFBTCxDQUFVZSxRQUFWLEdBQXFCekIsV0FBVyxDQUFDa0gsV0FBWixDQUF3QixLQUFLNUcsTUFBTCxDQUFZNkcsWUFBcEMsQ0FBckI7QUFDRDs7QUFDRCxZQUFJZCxNQUFKLEVBQVk7QUFDVmhGLFVBQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWWYsTUFBTSxDQUFDUSxNQUFuQixFQUEyQlEsT0FBM0IsQ0FBbUNaLFNBQVMsSUFBSTtBQUM5Q0QsWUFBQUEsd0JBQXdCLENBQUNDLFNBQUQsRUFBWSxJQUFaLENBQXhCO0FBQ0QsV0FGRDtBQUdEO0FBQ0YsT0FaRCxNQVlPLElBQUlKLE1BQUosRUFBWTtBQUNqQmhGLFFBQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWSxLQUFLMUcsSUFBakIsRUFBdUIyRyxPQUF2QixDQUErQlosU0FBUyxJQUFJO0FBQzFDRCxVQUFBQSx3QkFBd0IsQ0FBQ0MsU0FBRCxFQUFZLEtBQVosQ0FBeEI7QUFDRCxTQUZEO0FBR0Q7QUFDRixLQS9DTSxDQUFQO0FBZ0REOztBQUNELFNBQU9yRSxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELENBcERELEMsQ0FzREE7QUFDQTtBQUNBOzs7QUFDQWhDLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JxQixnQkFBcEIsR0FBdUMsWUFBWTtBQUNqRCxNQUFJLEtBQUtuQyxTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDLEtBQUtDLEtBQU4sSUFBZSxDQUFDLEtBQUtDLElBQUwsQ0FBVTRHLFFBQTlCLEVBQXdDO0FBQ3RDLFFBQUksT0FBTyxLQUFLNUcsSUFBTCxDQUFVNkcsUUFBakIsS0FBOEIsUUFBOUIsSUFBMEMvQixnQkFBRWdDLE9BQUYsQ0FBVSxLQUFLOUcsSUFBTCxDQUFVNkcsUUFBcEIsQ0FBOUMsRUFBNkU7QUFDM0UsWUFBTSxJQUFJckgsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWXlHLGdCQUE1QixFQUE4Qyx5QkFBOUMsQ0FBTjtBQUNEOztBQUNELFFBQUksT0FBTyxLQUFLL0csSUFBTCxDQUFVZ0gsUUFBakIsS0FBOEIsUUFBOUIsSUFBMENsQyxnQkFBRWdDLE9BQUYsQ0FBVSxLQUFLOUcsSUFBTCxDQUFVZ0gsUUFBcEIsQ0FBOUMsRUFBNkU7QUFDM0UsWUFBTSxJQUFJeEgsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTJHLGdCQUE1QixFQUE4QyxzQkFBOUMsQ0FBTjtBQUNEO0FBQ0Y7O0FBRUQsTUFDRyxLQUFLakgsSUFBTCxDQUFVNEcsUUFBVixJQUFzQixDQUFDakcsTUFBTSxDQUFDK0YsSUFBUCxDQUFZLEtBQUsxRyxJQUFMLENBQVU0RyxRQUF0QixFQUFnQ25DLE1BQXhELElBQ0EsQ0FBQzlELE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDLEtBQUtkLElBQTFDLEVBQWdELFVBQWhELENBRkgsRUFHRTtBQUNBO0FBQ0E7QUFDRCxHQU5ELE1BTU8sSUFBSVcsTUFBTSxDQUFDQyxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUMsS0FBS2QsSUFBMUMsRUFBZ0QsVUFBaEQsS0FBK0QsQ0FBQyxLQUFLQSxJQUFMLENBQVU0RyxRQUE5RSxFQUF3RjtBQUM3RjtBQUNBLFVBQU0sSUFBSXBILEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTRHLG1CQURSLEVBRUosNENBRkksQ0FBTjtBQUlEOztBQUVELE1BQUlOLFFBQVEsR0FBRyxLQUFLNUcsSUFBTCxDQUFVNEcsUUFBekI7QUFDQSxNQUFJTyxTQUFTLEdBQUd4RyxNQUFNLENBQUMrRixJQUFQLENBQVlFLFFBQVosQ0FBaEI7O0FBQ0EsTUFBSU8sU0FBUyxDQUFDMUMsTUFBVixHQUFtQixDQUF2QixFQUEwQjtBQUN4QixVQUFNMkMsaUJBQWlCLEdBQUdELFNBQVMsQ0FBQ3BDLE1BQVYsQ0FBaUIsQ0FBQ3NDLFNBQUQsRUFBWUMsUUFBWixLQUF5QjtBQUNsRSxVQUFJQyxnQkFBZ0IsR0FBR1gsUUFBUSxDQUFDVSxRQUFELENBQS9CO0FBQ0EsVUFBSUUsUUFBUSxHQUFHRCxnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNyRyxFQUFwRDtBQUNBLGFBQU9tRyxTQUFTLEtBQUtHLFFBQVEsSUFBSUQsZ0JBQWdCLElBQUksSUFBckMsQ0FBaEI7QUFDRCxLQUp5QixFQUl2QixJQUp1QixDQUExQjs7QUFLQSxRQUFJSCxpQkFBSixFQUF1QjtBQUNyQixhQUFPLEtBQUtLLGNBQUwsQ0FBb0JiLFFBQXBCLENBQVA7QUFDRDtBQUNGOztBQUNELFFBQU0sSUFBSXBILEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTRHLG1CQURSLEVBRUosNENBRkksQ0FBTjtBQUlELENBNUNEOztBQThDQXZILFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0I4Ryx3QkFBcEIsR0FBK0MsVUFBVWQsUUFBVixFQUFvQjtBQUNqRSxRQUFNZSxXQUFXLEdBQUdoSCxNQUFNLENBQUMrRixJQUFQLENBQVlFLFFBQVosRUFBc0JnQixHQUF0QixDQUEwQk4sUUFBUSxJQUFJO0FBQ3hELFFBQUlWLFFBQVEsQ0FBQ1UsUUFBRCxDQUFSLEtBQXVCLElBQTNCLEVBQWlDO0FBQy9CLGFBQU81RixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFVBQU1NLGdCQUFnQixHQUFHLEtBQUtyQyxNQUFMLENBQVlpSSxlQUFaLENBQTRCQyx1QkFBNUIsQ0FBb0RSLFFBQXBELENBQXpCOztBQUNBLFFBQUksQ0FBQ3JGLGdCQUFMLEVBQXVCO0FBQ3JCLFlBQU0sSUFBSXpDLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTRHLG1CQURSLEVBRUosNENBRkksQ0FBTjtBQUlEOztBQUNELFdBQU9qRixnQkFBZ0IsQ0FBQzJFLFFBQVEsQ0FBQ1UsUUFBRCxDQUFULENBQXZCO0FBQ0QsR0FabUIsQ0FBcEI7QUFhQSxTQUFPNUYsT0FBTyxDQUFDcUcsR0FBUixDQUFZSixXQUFaLENBQVA7QUFDRCxDQWZEOztBQWlCQWhJLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JvSCxxQkFBcEIsR0FBNEMsVUFBVXBCLFFBQVYsRUFBb0I7QUFDOUQsUUFBTU8sU0FBUyxHQUFHeEcsTUFBTSxDQUFDK0YsSUFBUCxDQUFZRSxRQUFaLENBQWxCO0FBQ0EsUUFBTTdHLEtBQUssR0FBR29ILFNBQVMsQ0FDcEJwQyxNQURXLENBQ0osQ0FBQ2tELElBQUQsRUFBT1gsUUFBUCxLQUFvQjtBQUMxQixRQUFJLENBQUNWLFFBQVEsQ0FBQ1UsUUFBRCxDQUFiLEVBQXlCO0FBQ3ZCLGFBQU9XLElBQVA7QUFDRDs7QUFDRCxVQUFNQyxRQUFRLEdBQUksWUFBV1osUUFBUyxLQUF0QztBQUNBLFVBQU12SCxLQUFLLEdBQUcsRUFBZDtBQUNBQSxJQUFBQSxLQUFLLENBQUNtSSxRQUFELENBQUwsR0FBa0J0QixRQUFRLENBQUNVLFFBQUQsQ0FBUixDQUFtQnBHLEVBQXJDO0FBQ0ErRyxJQUFBQSxJQUFJLENBQUM5QyxJQUFMLENBQVVwRixLQUFWO0FBQ0EsV0FBT2tJLElBQVA7QUFDRCxHQVZXLEVBVVQsRUFWUyxFQVdYRSxNQVhXLENBV0pDLENBQUMsSUFBSTtBQUNYLFdBQU8sT0FBT0EsQ0FBUCxLQUFhLFdBQXBCO0FBQ0QsR0FiVyxDQUFkO0FBZUEsTUFBSUMsV0FBVyxHQUFHM0csT0FBTyxDQUFDQyxPQUFSLENBQWdCLEVBQWhCLENBQWxCOztBQUNBLE1BQUk1QixLQUFLLENBQUMwRSxNQUFOLEdBQWUsQ0FBbkIsRUFBc0I7QUFDcEI0RCxJQUFBQSxXQUFXLEdBQUcsS0FBS3pJLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJvQyxJQUFyQixDQUEwQixLQUFLOUYsU0FBL0IsRUFBMEM7QUFBRXdJLE1BQUFBLEdBQUcsRUFBRXZJO0FBQVAsS0FBMUMsRUFBMEQsRUFBMUQsQ0FBZDtBQUNEOztBQUVELFNBQU9zSSxXQUFQO0FBQ0QsQ0F2QkQ7O0FBeUJBMUksU0FBUyxDQUFDaUIsU0FBVixDQUFvQjJILG9CQUFwQixHQUEyQyxVQUFVQyxPQUFWLEVBQW1CO0FBQzVELE1BQUksS0FBSzNJLElBQUwsQ0FBVWtELFFBQWQsRUFBd0I7QUFDdEIsV0FBT3lGLE9BQVA7QUFDRDs7QUFDRCxTQUFPQSxPQUFPLENBQUNMLE1BQVIsQ0FBZXZELE1BQU0sSUFBSTtBQUM5QixRQUFJLENBQUNBLE1BQU0sQ0FBQzZELEdBQVosRUFBaUI7QUFDZixhQUFPLElBQVAsQ0FEZSxDQUNGO0FBQ2QsS0FINkIsQ0FJOUI7OztBQUNBLFdBQU83RCxNQUFNLENBQUM2RCxHQUFQLElBQWM5SCxNQUFNLENBQUMrRixJQUFQLENBQVk5QixNQUFNLENBQUM2RCxHQUFuQixFQUF3QmhFLE1BQXhCLEdBQWlDLENBQXREO0FBQ0QsR0FOTSxDQUFQO0FBT0QsQ0FYRDs7QUFhQTlFLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0I2RyxjQUFwQixHQUFxQyxVQUFVYixRQUFWLEVBQW9CO0FBQ3ZELE1BQUk4QixPQUFKO0FBQ0EsU0FBTyxLQUFLVixxQkFBTCxDQUEyQnBCLFFBQTNCLEVBQXFDaEYsSUFBckMsQ0FBMEMsTUFBTStHLENBQU4sSUFBVztBQUMxREQsSUFBQUEsT0FBTyxHQUFHLEtBQUtILG9CQUFMLENBQTBCSSxDQUExQixDQUFWOztBQUVBLFFBQUlELE9BQU8sQ0FBQ2pFLE1BQVIsSUFBa0IsQ0FBdEIsRUFBeUI7QUFDdkIsV0FBS2pFLE9BQUwsQ0FBYSxjQUFiLElBQStCRyxNQUFNLENBQUMrRixJQUFQLENBQVlFLFFBQVosRUFBc0JnQyxJQUF0QixDQUEyQixHQUEzQixDQUEvQjtBQUVBLFlBQU1DLFVBQVUsR0FBR0gsT0FBTyxDQUFDLENBQUQsQ0FBMUI7QUFDQSxZQUFNSSxlQUFlLEdBQUcsRUFBeEI7QUFDQW5JLE1BQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWUUsUUFBWixFQUFzQkQsT0FBdEIsQ0FBOEJXLFFBQVEsSUFBSTtBQUN4QyxjQUFNeUIsWUFBWSxHQUFHbkMsUUFBUSxDQUFDVSxRQUFELENBQTdCO0FBQ0EsY0FBTTBCLFlBQVksR0FBR0gsVUFBVSxDQUFDakMsUUFBWCxDQUFvQlUsUUFBcEIsQ0FBckI7O0FBQ0EsWUFBSSxDQUFDeEMsZ0JBQUVJLE9BQUYsQ0FBVTZELFlBQVYsRUFBd0JDLFlBQXhCLENBQUwsRUFBNEM7QUFDMUNGLFVBQUFBLGVBQWUsQ0FBQ3hCLFFBQUQsQ0FBZixHQUE0QnlCLFlBQTVCO0FBQ0Q7QUFDRixPQU5EO0FBT0EsWUFBTUUsa0JBQWtCLEdBQUd0SSxNQUFNLENBQUMrRixJQUFQLENBQVlvQyxlQUFaLEVBQTZCckUsTUFBN0IsS0FBd0MsQ0FBbkU7QUFDQSxVQUFJeUUsTUFBSjs7QUFDQSxVQUFJLEtBQUtuSixLQUFMLElBQWMsS0FBS0EsS0FBTCxDQUFXZ0IsUUFBN0IsRUFBdUM7QUFDckNtSSxRQUFBQSxNQUFNLEdBQUcsS0FBS25KLEtBQUwsQ0FBV2dCLFFBQXBCO0FBQ0QsT0FGRCxNQUVPLElBQUksS0FBS2xCLElBQUwsSUFBYSxLQUFLQSxJQUFMLENBQVVvRCxJQUF2QixJQUErQixLQUFLcEQsSUFBTCxDQUFVb0QsSUFBVixDQUFlL0IsRUFBbEQsRUFBc0Q7QUFDM0RnSSxRQUFBQSxNQUFNLEdBQUcsS0FBS3JKLElBQUwsQ0FBVW9ELElBQVYsQ0FBZS9CLEVBQXhCO0FBQ0Q7O0FBQ0QsVUFBSSxDQUFDZ0ksTUFBRCxJQUFXQSxNQUFNLEtBQUtMLFVBQVUsQ0FBQzlILFFBQXJDLEVBQStDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBLGVBQU8ySCxPQUFPLENBQUMsQ0FBRCxDQUFQLENBQVcxQixRQUFsQixDQUo2QyxDQU03Qzs7QUFDQSxhQUFLaEgsSUFBTCxDQUFVZSxRQUFWLEdBQXFCOEgsVUFBVSxDQUFDOUgsUUFBaEM7O0FBRUEsWUFBSSxDQUFDLEtBQUtoQixLQUFOLElBQWUsQ0FBQyxLQUFLQSxLQUFMLENBQVdnQixRQUEvQixFQUF5QztBQUN2QztBQUNBLGVBQUtJLFFBQUwsR0FBZ0I7QUFDZEEsWUFBQUEsUUFBUSxFQUFFMEgsVUFESTtBQUVkTSxZQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUZJLFdBQWhCLENBRnVDLENBTXZDO0FBQ0E7QUFDQTs7QUFDQSxnQkFBTSxLQUFLL0QscUJBQUwsQ0FBMkJoRyxRQUFRLENBQUN5SixVQUFELENBQW5DLENBQU47QUFDRCxTQW5CNEMsQ0FxQjdDOzs7QUFDQSxZQUFJLENBQUNJLGtCQUFMLEVBQXlCO0FBQ3ZCO0FBQ0QsU0F4QjRDLENBeUI3QztBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsZUFBTyxLQUFLdkIsd0JBQUwsQ0FBOEJvQixlQUE5QixFQUErQ2xILElBQS9DLENBQW9ELFlBQVk7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFJLEtBQUtULFFBQVQsRUFBbUI7QUFDakI7QUFDQVIsWUFBQUEsTUFBTSxDQUFDK0YsSUFBUCxDQUFZb0MsZUFBWixFQUE2Qm5DLE9BQTdCLENBQXFDVyxRQUFRLElBQUk7QUFDL0MsbUJBQUtuRyxRQUFMLENBQWNBLFFBQWQsQ0FBdUJ5RixRQUF2QixDQUFnQ1UsUUFBaEMsSUFBNEN3QixlQUFlLENBQUN4QixRQUFELENBQTNEO0FBQ0QsYUFGRCxFQUZpQixDQU1qQjtBQUNBO0FBQ0E7O0FBQ0EsbUJBQU8sS0FBSzFILE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJjLE1BQXJCLENBQ0wsS0FBS3hFLFNBREEsRUFFTDtBQUFFaUIsY0FBQUEsUUFBUSxFQUFFLEtBQUtmLElBQUwsQ0FBVWU7QUFBdEIsYUFGSyxFQUdMO0FBQUU2RixjQUFBQSxRQUFRLEVBQUVrQztBQUFaLGFBSEssRUFJTCxFQUpLLENBQVA7QUFNRDtBQUNGLFNBckJNLENBQVA7QUFzQkQsT0FuREQsTUFtRE8sSUFBSUksTUFBSixFQUFZO0FBQ2pCO0FBQ0E7QUFDQSxZQUFJTCxVQUFVLENBQUM5SCxRQUFYLEtBQXdCbUksTUFBNUIsRUFBb0M7QUFDbEMsZ0JBQU0sSUFBSTFKLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVk4SSxzQkFBNUIsRUFBb0QsMkJBQXBELENBQU47QUFDRCxTQUxnQixDQU1qQjs7O0FBQ0EsWUFBSSxDQUFDSCxrQkFBTCxFQUF5QjtBQUN2QjtBQUNEO0FBQ0Y7QUFDRjs7QUFDRCxXQUFPLEtBQUt2Qix3QkFBTCxDQUE4QmQsUUFBOUIsRUFBd0NoRixJQUF4QyxDQUE2QyxNQUFNO0FBQ3hELFVBQUk4RyxPQUFPLENBQUNqRSxNQUFSLEdBQWlCLENBQXJCLEVBQXdCO0FBQ3RCO0FBQ0EsY0FBTSxJQUFJakYsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWThJLHNCQUE1QixFQUFvRCwyQkFBcEQsQ0FBTjtBQUNEO0FBQ0YsS0FMTSxDQUFQO0FBTUQsR0EzRk0sQ0FBUDtBQTRGRCxDQTlGRCxDLENBZ0dBOzs7QUFDQXpKLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0IyQixhQUFwQixHQUFvQyxZQUFZO0FBQzlDLE1BQUk4RyxPQUFPLEdBQUczSCxPQUFPLENBQUNDLE9BQVIsRUFBZDs7QUFFQSxNQUFJLEtBQUs3QixTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCLFdBQU91SixPQUFQO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDLEtBQUt4SixJQUFMLENBQVVrRCxRQUFYLElBQXVCLG1CQUFtQixLQUFLL0MsSUFBbkQsRUFBeUQ7QUFDdkQsVUFBTXNKLEtBQUssR0FBSSwrREFBZjtBQUNBLFVBQU0sSUFBSTlKLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLG1CQUE1QixFQUFpRCtJLEtBQWpELENBQU47QUFDRCxHQVY2QyxDQVk5Qzs7O0FBQ0EsTUFBSSxLQUFLdkosS0FBTCxJQUFjLEtBQUtnQixRQUFMLEVBQWxCLEVBQW1DO0FBQ2pDO0FBQ0E7QUFDQXNJLElBQUFBLE9BQU8sR0FBRyxJQUFJRSxrQkFBSixDQUFjLEtBQUszSixNQUFuQixFQUEyQlAsSUFBSSxDQUFDbUssTUFBTCxDQUFZLEtBQUs1SixNQUFqQixDQUEzQixFQUFxRCxVQUFyRCxFQUFpRTtBQUN6RXFELE1BQUFBLElBQUksRUFBRTtBQUNKd0csUUFBQUEsTUFBTSxFQUFFLFNBREo7QUFFSjNKLFFBQUFBLFNBQVMsRUFBRSxPQUZQO0FBR0ppQixRQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUhOO0FBRG1FLEtBQWpFLEVBT1BVLE9BUE8sR0FRUEcsSUFSTyxDQVFGOEcsT0FBTyxJQUFJO0FBQ2ZBLE1BQUFBLE9BQU8sQ0FBQ0EsT0FBUixDQUFnQi9CLE9BQWhCLENBQXdCK0MsT0FBTyxJQUM3QixLQUFLOUosTUFBTCxDQUFZK0osZUFBWixDQUE0QjFHLElBQTVCLENBQWlDMkcsR0FBakMsQ0FBcUNGLE9BQU8sQ0FBQ0csWUFBN0MsQ0FERjtBQUdELEtBWk8sQ0FBVjtBQWFEOztBQUVELFNBQU9SLE9BQU8sQ0FDWHpILElBREksQ0FDQyxNQUFNO0FBQ1Y7QUFDQSxRQUFJLEtBQUs1QixJQUFMLENBQVVnSCxRQUFWLEtBQXVCZixTQUEzQixFQUFzQztBQUNwQztBQUNBLGFBQU92RSxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVELFFBQUksS0FBSzVCLEtBQVQsRUFBZ0I7QUFDZCxXQUFLUyxPQUFMLENBQWEsZUFBYixJQUFnQyxJQUFoQyxDQURjLENBRWQ7O0FBQ0EsVUFBSSxDQUFDLEtBQUtYLElBQUwsQ0FBVWtELFFBQWYsRUFBeUI7QUFDdkIsYUFBS3ZDLE9BQUwsQ0FBYSxvQkFBYixJQUFxQyxJQUFyQztBQUNEO0FBQ0Y7O0FBRUQsV0FBTyxLQUFLc0osdUJBQUwsR0FBK0JsSSxJQUEvQixDQUFvQyxNQUFNO0FBQy9DLGFBQU9yQyxjQUFjLENBQUN3SyxJQUFmLENBQW9CLEtBQUsvSixJQUFMLENBQVVnSCxRQUE5QixFQUF3Q3BGLElBQXhDLENBQTZDb0ksY0FBYyxJQUFJO0FBQ3BFLGFBQUtoSyxJQUFMLENBQVVpSyxnQkFBVixHQUE2QkQsY0FBN0I7QUFDQSxlQUFPLEtBQUtoSyxJQUFMLENBQVVnSCxRQUFqQjtBQUNELE9BSE0sQ0FBUDtBQUlELEtBTE0sQ0FBUDtBQU1ELEdBdEJJLEVBdUJKcEYsSUF2QkksQ0F1QkMsTUFBTTtBQUNWLFdBQU8sS0FBS3NJLGlCQUFMLEVBQVA7QUFDRCxHQXpCSSxFQTBCSnRJLElBMUJJLENBMEJDLE1BQU07QUFDVixXQUFPLEtBQUt1SSxjQUFMLEVBQVA7QUFDRCxHQTVCSSxDQUFQO0FBNkJELENBNUREOztBQThEQXhLLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JzSixpQkFBcEIsR0FBd0MsWUFBWTtBQUNsRDtBQUNBLE1BQUksQ0FBQyxLQUFLbEssSUFBTCxDQUFVNkcsUUFBZixFQUF5QjtBQUN2QixRQUFJLENBQUMsS0FBSzlHLEtBQVYsRUFBaUI7QUFDZixXQUFLQyxJQUFMLENBQVU2RyxRQUFWLEdBQXFCdkgsV0FBVyxDQUFDOEssWUFBWixDQUF5QixFQUF6QixDQUFyQjtBQUNBLFdBQUtDLDBCQUFMLEdBQWtDLElBQWxDO0FBQ0Q7O0FBQ0QsV0FBTzNJLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7QUFDRDs7Ozs7Ozs7QUFPQSxTQUFPLEtBQUsvQixNQUFMLENBQVk0RCxRQUFaLENBQ0pvQyxJQURJLENBRUgsS0FBSzlGLFNBRkYsRUFHSDtBQUNFK0csSUFBQUEsUUFBUSxFQUFFLEtBQUs3RyxJQUFMLENBQVU2RyxRQUR0QjtBQUVFOUYsSUFBQUEsUUFBUSxFQUFFO0FBQUV1SixNQUFBQSxHQUFHLEVBQUUsS0FBS3ZKLFFBQUw7QUFBUDtBQUZaLEdBSEcsRUFPSDtBQUFFd0osSUFBQUEsS0FBSyxFQUFFLENBQVQ7QUFBWUMsSUFBQUEsZUFBZSxFQUFFO0FBQTdCLEdBUEcsRUFRSCxFQVJHLEVBU0gsS0FBS2hKLHFCQVRGLEVBV0pJLElBWEksQ0FXQzhHLE9BQU8sSUFBSTtBQUNmLFFBQUlBLE9BQU8sQ0FBQ2pFLE1BQVIsR0FBaUIsQ0FBckIsRUFBd0I7QUFDdEIsWUFBTSxJQUFJakYsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZbUssY0FEUixFQUVKLDJDQUZJLENBQU47QUFJRDs7QUFDRDtBQUNELEdBbkJJLENBQVA7QUFvQkQsQ0FwQ0Q7QUFzQ0E7Ozs7Ozs7Ozs7Ozs7O0FBWUE5SyxTQUFTLENBQUNpQixTQUFWLENBQW9CdUosY0FBcEIsR0FBcUMsWUFBWTtBQUMvQyxNQUFJLENBQUMsS0FBS25LLElBQUwsQ0FBVTBLLEtBQVgsSUFBb0IsS0FBSzFLLElBQUwsQ0FBVTBLLEtBQVYsQ0FBZ0J4RSxJQUFoQixLQUF5QixRQUFqRCxFQUEyRDtBQUN6RCxXQUFPeEUsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxHQUg4QyxDQUkvQzs7O0FBQ0EsTUFBSSxDQUFDLEtBQUszQixJQUFMLENBQVUwSyxLQUFWLENBQWdCQyxLQUFoQixDQUFzQixTQUF0QixDQUFMLEVBQXVDO0FBQ3JDLFdBQU9qSixPQUFPLENBQUNrSixNQUFSLENBQ0wsSUFBSXBMLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVl1SyxxQkFBNUIsRUFBbUQsa0NBQW5ELENBREssQ0FBUDtBQUdELEdBVDhDLENBVS9DOzs7QUFDQSxTQUFPLEtBQUtqTCxNQUFMLENBQVk0RCxRQUFaLENBQ0pvQyxJQURJLENBRUgsS0FBSzlGLFNBRkYsRUFHSDtBQUNFNEssSUFBQUEsS0FBSyxFQUFFLEtBQUsxSyxJQUFMLENBQVUwSyxLQURuQjtBQUVFM0osSUFBQUEsUUFBUSxFQUFFO0FBQUV1SixNQUFBQSxHQUFHLEVBQUUsS0FBS3ZKLFFBQUw7QUFBUDtBQUZaLEdBSEcsRUFPSDtBQUFFd0osSUFBQUEsS0FBSyxFQUFFLENBQVQ7QUFBWUMsSUFBQUEsZUFBZSxFQUFFO0FBQTdCLEdBUEcsRUFRSCxFQVJHLEVBU0gsS0FBS2hKLHFCQVRGLEVBV0pJLElBWEksQ0FXQzhHLE9BQU8sSUFBSTtBQUNmLFFBQUlBLE9BQU8sQ0FBQ2pFLE1BQVIsR0FBaUIsQ0FBckIsRUFBd0I7QUFDdEIsWUFBTSxJQUFJakYsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZd0ssV0FEUixFQUVKLGdEQUZJLENBQU47QUFJRDs7QUFDRCxRQUNFLENBQUMsS0FBSzlLLElBQUwsQ0FBVTRHLFFBQVgsSUFDQSxDQUFDakcsTUFBTSxDQUFDK0YsSUFBUCxDQUFZLEtBQUsxRyxJQUFMLENBQVU0RyxRQUF0QixFQUFnQ25DLE1BRGpDLElBRUM5RCxNQUFNLENBQUMrRixJQUFQLENBQVksS0FBSzFHLElBQUwsQ0FBVTRHLFFBQXRCLEVBQWdDbkMsTUFBaEMsS0FBMkMsQ0FBM0MsSUFDQzlELE1BQU0sQ0FBQytGLElBQVAsQ0FBWSxLQUFLMUcsSUFBTCxDQUFVNEcsUUFBdEIsRUFBZ0MsQ0FBaEMsTUFBdUMsV0FKM0MsRUFLRTtBQUNBO0FBQ0EsV0FBS3BHLE9BQUwsQ0FBYSx1QkFBYixJQUF3QyxJQUF4QztBQUNBLFdBQUtaLE1BQUwsQ0FBWW1MLGNBQVosQ0FBMkJDLG1CQUEzQixDQUErQyxLQUFLaEwsSUFBcEQ7QUFDRDtBQUNGLEdBNUJJLENBQVA7QUE2QkQsQ0F4Q0Q7O0FBMENBTCxTQUFTLENBQUNpQixTQUFWLENBQW9Ca0osdUJBQXBCLEdBQThDLFlBQVk7QUFDeEQsTUFBSSxDQUFDLEtBQUtsSyxNQUFMLENBQVlxTCxjQUFqQixFQUFpQyxPQUFPdkosT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDakMsU0FBTyxLQUFLdUosNkJBQUwsR0FBcUN0SixJQUFyQyxDQUEwQyxNQUFNO0FBQ3JELFdBQU8sS0FBS3VKLHdCQUFMLEVBQVA7QUFDRCxHQUZNLENBQVA7QUFHRCxDQUxEOztBQU9BeEwsU0FBUyxDQUFDaUIsU0FBVixDQUFvQnNLLDZCQUFwQixHQUFvRCxZQUFZO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFNRSxXQUFXLEdBQUcsS0FBS3hMLE1BQUwsQ0FBWXFMLGNBQVosQ0FBMkJJLGVBQTNCLEdBQ2hCLEtBQUt6TCxNQUFMLENBQVlxTCxjQUFaLENBQTJCSSxlQURYLEdBRWhCLDBEQUZKO0FBR0EsUUFBTUMscUJBQXFCLEdBQUcsd0NBQTlCLENBWjhELENBYzlEOztBQUNBLE1BQ0csS0FBSzFMLE1BQUwsQ0FBWXFMLGNBQVosQ0FBMkJNLGdCQUEzQixJQUNDLENBQUMsS0FBSzNMLE1BQUwsQ0FBWXFMLGNBQVosQ0FBMkJNLGdCQUEzQixDQUE0QyxLQUFLdkwsSUFBTCxDQUFVZ0gsUUFBdEQsQ0FESCxJQUVDLEtBQUtwSCxNQUFMLENBQVlxTCxjQUFaLENBQTJCTyxpQkFBM0IsSUFDQyxDQUFDLEtBQUs1TCxNQUFMLENBQVlxTCxjQUFaLENBQTJCTyxpQkFBM0IsQ0FBNkMsS0FBS3hMLElBQUwsQ0FBVWdILFFBQXZELENBSkwsRUFLRTtBQUNBLFdBQU90RixPQUFPLENBQUNrSixNQUFSLENBQWUsSUFBSXBMLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlnRyxnQkFBNUIsRUFBOEM4RSxXQUE5QyxDQUFmLENBQVA7QUFDRCxHQXRCNkQsQ0F3QjlEOzs7QUFDQSxNQUFJLEtBQUt4TCxNQUFMLENBQVlxTCxjQUFaLENBQTJCUSxrQkFBM0IsS0FBa0QsSUFBdEQsRUFBNEQ7QUFDMUQsUUFBSSxLQUFLekwsSUFBTCxDQUFVNkcsUUFBZCxFQUF3QjtBQUN0QjtBQUNBLFVBQUksS0FBSzdHLElBQUwsQ0FBVWdILFFBQVYsQ0FBbUJ6RCxPQUFuQixDQUEyQixLQUFLdkQsSUFBTCxDQUFVNkcsUUFBckMsS0FBa0QsQ0FBdEQsRUFDRSxPQUFPbkYsT0FBTyxDQUFDa0osTUFBUixDQUFlLElBQUlwTCxLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZZ0csZ0JBQTVCLEVBQThDZ0YscUJBQTlDLENBQWYsQ0FBUDtBQUNILEtBSkQsTUFJTztBQUNMO0FBQ0EsYUFBTyxLQUFLMUwsTUFBTCxDQUFZNEQsUUFBWixDQUFxQm9DLElBQXJCLENBQTBCLE9BQTFCLEVBQW1DO0FBQUU3RSxRQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUFaLE9BQW5DLEVBQWtFYSxJQUFsRSxDQUF1RThHLE9BQU8sSUFBSTtBQUN2RixZQUFJQSxPQUFPLENBQUNqRSxNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCLGdCQUFNd0IsU0FBTjtBQUNEOztBQUNELFlBQUksS0FBS2pHLElBQUwsQ0FBVWdILFFBQVYsQ0FBbUJ6RCxPQUFuQixDQUEyQm1GLE9BQU8sQ0FBQyxDQUFELENBQVAsQ0FBVzdCLFFBQXRDLEtBQW1ELENBQXZELEVBQ0UsT0FBT25GLE9BQU8sQ0FBQ2tKLE1BQVIsQ0FDTCxJQUFJcEwsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWWdHLGdCQUE1QixFQUE4Q2dGLHFCQUE5QyxDQURLLENBQVA7QUFHRixlQUFPNUosT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxPQVRNLENBQVA7QUFVRDtBQUNGOztBQUNELFNBQU9ELE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQ0E3Q0Q7O0FBK0NBaEMsU0FBUyxDQUFDaUIsU0FBVixDQUFvQnVLLHdCQUFwQixHQUErQyxZQUFZO0FBQ3pEO0FBQ0EsTUFBSSxLQUFLcEwsS0FBTCxJQUFjLEtBQUtILE1BQUwsQ0FBWXFMLGNBQVosQ0FBMkJTLGtCQUE3QyxFQUFpRTtBQUMvRCxXQUFPLEtBQUs5TCxNQUFMLENBQVk0RCxRQUFaLENBQ0pvQyxJQURJLENBRUgsT0FGRyxFQUdIO0FBQUU3RSxNQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUFaLEtBSEcsRUFJSDtBQUFFMkYsTUFBQUEsSUFBSSxFQUFFLENBQUMsbUJBQUQsRUFBc0Isa0JBQXRCO0FBQVIsS0FKRyxFQU1KOUUsSUFOSSxDQU1DOEcsT0FBTyxJQUFJO0FBQ2YsVUFBSUEsT0FBTyxDQUFDakUsTUFBUixJQUFrQixDQUF0QixFQUF5QjtBQUN2QixjQUFNd0IsU0FBTjtBQUNEOztBQUNELFlBQU1oRCxJQUFJLEdBQUd5RixPQUFPLENBQUMsQ0FBRCxDQUFwQjtBQUNBLFVBQUlpRCxZQUFZLEdBQUcsRUFBbkI7QUFDQSxVQUFJMUksSUFBSSxDQUFDMkksaUJBQVQsRUFDRUQsWUFBWSxHQUFHN0csZ0JBQUUrRyxJQUFGLENBQ2I1SSxJQUFJLENBQUMySSxpQkFEUSxFQUViLEtBQUtoTSxNQUFMLENBQVlxTCxjQUFaLENBQTJCUyxrQkFBM0IsR0FBZ0QsQ0FGbkMsQ0FBZjtBQUlGQyxNQUFBQSxZQUFZLENBQUN4RyxJQUFiLENBQWtCbEMsSUFBSSxDQUFDK0QsUUFBdkI7QUFDQSxZQUFNOEUsV0FBVyxHQUFHLEtBQUs5TCxJQUFMLENBQVVnSCxRQUE5QixDQVplLENBYWY7O0FBQ0EsWUFBTStFLFFBQVEsR0FBR0osWUFBWSxDQUFDL0QsR0FBYixDQUFpQixVQUFVbUMsSUFBVixFQUFnQjtBQUNoRCxlQUFPeEssY0FBYyxDQUFDeU0sT0FBZixDQUF1QkYsV0FBdkIsRUFBb0MvQixJQUFwQyxFQUEwQ25JLElBQTFDLENBQStDNEMsTUFBTSxJQUFJO0FBQzlELGNBQUlBLE1BQUosRUFDRTtBQUNBLG1CQUFPOUMsT0FBTyxDQUFDa0osTUFBUixDQUFlLGlCQUFmLENBQVA7QUFDRixpQkFBT2xKLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsU0FMTSxDQUFQO0FBTUQsT0FQZ0IsQ0FBakIsQ0FkZSxDQXNCZjs7QUFDQSxhQUFPRCxPQUFPLENBQUNxRyxHQUFSLENBQVlnRSxRQUFaLEVBQ0puSyxJQURJLENBQ0MsTUFBTTtBQUNWLGVBQU9GLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsT0FISSxFQUlKc0ssS0FKSSxDQUlFQyxHQUFHLElBQUk7QUFDWixZQUFJQSxHQUFHLEtBQUssaUJBQVosRUFDRTtBQUNBLGlCQUFPeEssT0FBTyxDQUFDa0osTUFBUixDQUNMLElBQUlwTCxLQUFLLENBQUNjLEtBQVYsQ0FDRWQsS0FBSyxDQUFDYyxLQUFOLENBQVlnRyxnQkFEZCxFQUVHLCtDQUE4QyxLQUFLMUcsTUFBTCxDQUFZcUwsY0FBWixDQUEyQlMsa0JBQW1CLGFBRi9GLENBREssQ0FBUDtBQU1GLGNBQU1RLEdBQU47QUFDRCxPQWRJLENBQVA7QUFlRCxLQTVDSSxDQUFQO0FBNkNEOztBQUNELFNBQU94SyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELENBbEREOztBQW9EQWhDLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0IrQiwwQkFBcEIsR0FBaUQsWUFBWTtBQUMzRCxNQUFJLEtBQUs3QyxTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCO0FBQ0QsR0FIMEQsQ0FJM0Q7OztBQUNBLE1BQUksS0FBS0MsS0FBTCxJQUFjLENBQUMsS0FBS0MsSUFBTCxDQUFVNEcsUUFBN0IsRUFBdUM7QUFDckM7QUFDRCxHQVAwRCxDQVEzRDs7O0FBQ0EsTUFBSSxLQUFLL0csSUFBTCxDQUFVb0QsSUFBVixJQUFrQixLQUFLakQsSUFBTCxDQUFVNEcsUUFBaEMsRUFBMEM7QUFDeEM7QUFDRDs7QUFDRCxNQUNFLENBQUMsS0FBS3BHLE9BQUwsQ0FBYSxjQUFiLENBQUQsSUFBaUM7QUFDakMsT0FBS1osTUFBTCxDQUFZdU0sK0JBRFosSUFDK0M7QUFDL0MsT0FBS3ZNLE1BQUwsQ0FBWXdNLGdCQUhkLEVBSUU7QUFDQTtBQUNBLFdBRkEsQ0FFUTtBQUNUOztBQUNELFNBQU8sS0FBS0Msa0JBQUwsRUFBUDtBQUNELENBckJEOztBQXVCQTFNLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0J5TCxrQkFBcEIsR0FBeUMsa0JBQWtCO0FBQ3pEO0FBQ0E7QUFDQSxNQUFJLEtBQUt4TSxJQUFMLENBQVV5TSxjQUFWLElBQTRCLEtBQUt6TSxJQUFMLENBQVV5TSxjQUFWLEtBQTZCLE9BQTdELEVBQXNFO0FBQ3BFO0FBQ0Q7O0FBRUQsUUFBTTtBQUFFQyxJQUFBQSxXQUFGO0FBQWVDLElBQUFBO0FBQWYsTUFBaUNuTixJQUFJLENBQUNtTixhQUFMLENBQW1CLEtBQUs1TSxNQUF4QixFQUFnQztBQUNyRXNKLElBQUFBLE1BQU0sRUFBRSxLQUFLbkksUUFBTCxFQUQ2RDtBQUVyRTBMLElBQUFBLFdBQVcsRUFBRTtBQUNYck0sTUFBQUEsTUFBTSxFQUFFLEtBQUtJLE9BQUwsQ0FBYSxjQUFiLElBQStCLE9BQS9CLEdBQXlDLFFBRHRDO0FBRVhrTSxNQUFBQSxZQUFZLEVBQUUsS0FBS2xNLE9BQUwsQ0FBYSxjQUFiLEtBQWdDO0FBRm5DLEtBRndEO0FBTXJFOEwsSUFBQUEsY0FBYyxFQUFFLEtBQUt6TSxJQUFMLENBQVV5TTtBQU4yQyxHQUFoQyxDQUF2Qzs7QUFTQSxNQUFJLEtBQUtuTCxRQUFMLElBQWlCLEtBQUtBLFFBQUwsQ0FBY0EsUUFBbkMsRUFBNkM7QUFDM0MsU0FBS0EsUUFBTCxDQUFjQSxRQUFkLENBQXVCMEksWUFBdkIsR0FBc0MwQyxXQUFXLENBQUMxQyxZQUFsRDtBQUNEOztBQUVELFNBQU8yQyxhQUFhLEVBQXBCO0FBQ0QsQ0FyQkQsQyxDQXVCQTs7O0FBQ0E3TSxTQUFTLENBQUNpQixTQUFWLENBQW9CdUIsNkJBQXBCLEdBQW9ELFlBQVk7QUFDOUQsTUFBSSxLQUFLckMsU0FBTCxLQUFtQixPQUFuQixJQUE4QixLQUFLQyxLQUFMLEtBQWUsSUFBakQsRUFBdUQ7QUFDckQ7QUFDQTtBQUNEOztBQUVELE1BQUksY0FBYyxLQUFLQyxJQUFuQixJQUEyQixXQUFXLEtBQUtBLElBQS9DLEVBQXFEO0FBQ25ELFVBQU0yTSxNQUFNLEdBQUc7QUFDYkMsTUFBQUEsaUJBQWlCLEVBQUU7QUFBRTFHLFFBQUFBLElBQUksRUFBRTtBQUFSLE9BRE47QUFFYjJHLE1BQUFBLDRCQUE0QixFQUFFO0FBQUUzRyxRQUFBQSxJQUFJLEVBQUU7QUFBUjtBQUZqQixLQUFmO0FBSUEsU0FBS2xHLElBQUwsR0FBWVcsTUFBTSxDQUFDbU0sTUFBUCxDQUFjLEtBQUs5TSxJQUFuQixFQUF5QjJNLE1BQXpCLENBQVo7QUFDRDtBQUNGLENBYkQ7O0FBZUFoTixTQUFTLENBQUNpQixTQUFWLENBQW9CNkIseUJBQXBCLEdBQWdELFlBQVk7QUFDMUQ7QUFDQSxNQUFJLEtBQUszQyxTQUFMLElBQWtCLFVBQWxCLElBQWdDLEtBQUtDLEtBQXpDLEVBQWdEO0FBQzlDO0FBQ0QsR0FKeUQsQ0FLMUQ7OztBQUNBLFFBQU07QUFBRWtELElBQUFBLElBQUY7QUFBUXFKLElBQUFBLGNBQVI7QUFBd0J6QyxJQUFBQTtBQUF4QixNQUF5QyxLQUFLN0osSUFBcEQ7O0FBQ0EsTUFBSSxDQUFDaUQsSUFBRCxJQUFTLENBQUNxSixjQUFkLEVBQThCO0FBQzVCO0FBQ0Q7O0FBQ0QsTUFBSSxDQUFDckosSUFBSSxDQUFDbEMsUUFBVixFQUFvQjtBQUNsQjtBQUNEOztBQUNELE9BQUtuQixNQUFMLENBQVk0RCxRQUFaLENBQXFCdUosT0FBckIsQ0FDRSxVQURGLEVBRUU7QUFDRTlKLElBQUFBLElBREY7QUFFRXFKLElBQUFBLGNBRkY7QUFHRXpDLElBQUFBLFlBQVksRUFBRTtBQUFFUyxNQUFBQSxHQUFHLEVBQUVUO0FBQVA7QUFIaEIsR0FGRixFQU9FLEVBUEYsRUFRRSxLQUFLckkscUJBUlA7QUFVRCxDQXZCRCxDLENBeUJBOzs7QUFDQTdCLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JnQyxjQUFwQixHQUFxQyxZQUFZO0FBQy9DLE1BQUksS0FBS3BDLE9BQUwsSUFBZ0IsS0FBS0EsT0FBTCxDQUFhLGVBQWIsQ0FBaEIsSUFBaUQsS0FBS1osTUFBTCxDQUFZb04sNEJBQWpFLEVBQStGO0FBQzdGLFFBQUlDLFlBQVksR0FBRztBQUNqQmhLLE1BQUFBLElBQUksRUFBRTtBQUNKd0csUUFBQUEsTUFBTSxFQUFFLFNBREo7QUFFSjNKLFFBQUFBLFNBQVMsRUFBRSxPQUZQO0FBR0ppQixRQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUhOO0FBRFcsS0FBbkI7QUFPQSxXQUFPLEtBQUtQLE9BQUwsQ0FBYSxlQUFiLENBQVA7QUFDQSxXQUFPLEtBQUtaLE1BQUwsQ0FBWTRELFFBQVosQ0FDSnVKLE9BREksQ0FDSSxVQURKLEVBQ2dCRSxZQURoQixFQUVKckwsSUFGSSxDQUVDLEtBQUtnQixjQUFMLENBQW9Cc0ssSUFBcEIsQ0FBeUIsSUFBekIsQ0FGRCxDQUFQO0FBR0Q7O0FBRUQsTUFBSSxLQUFLMU0sT0FBTCxJQUFnQixLQUFLQSxPQUFMLENBQWEsb0JBQWIsQ0FBcEIsRUFBd0Q7QUFDdEQsV0FBTyxLQUFLQSxPQUFMLENBQWEsb0JBQWIsQ0FBUDtBQUNBLFdBQU8sS0FBSzZMLGtCQUFMLEdBQTBCekssSUFBMUIsQ0FBK0IsS0FBS2dCLGNBQUwsQ0FBb0JzSyxJQUFwQixDQUF5QixJQUF6QixDQUEvQixDQUFQO0FBQ0Q7O0FBRUQsTUFBSSxLQUFLMU0sT0FBTCxJQUFnQixLQUFLQSxPQUFMLENBQWEsdUJBQWIsQ0FBcEIsRUFBMkQ7QUFDekQsV0FBTyxLQUFLQSxPQUFMLENBQWEsdUJBQWIsQ0FBUCxDQUR5RCxDQUV6RDs7QUFDQSxTQUFLWixNQUFMLENBQVltTCxjQUFaLENBQTJCb0MscUJBQTNCLENBQWlELEtBQUtuTixJQUF0RDtBQUNBLFdBQU8sS0FBSzRDLGNBQUwsQ0FBb0JzSyxJQUFwQixDQUF5QixJQUF6QixDQUFQO0FBQ0Q7QUFDRixDQTFCRCxDLENBNEJBO0FBQ0E7OztBQUNBdk4sU0FBUyxDQUFDaUIsU0FBVixDQUFvQm9CLGFBQXBCLEdBQW9DLFlBQVk7QUFDOUMsTUFBSSxLQUFLYixRQUFMLElBQWlCLEtBQUtyQixTQUFMLEtBQW1CLFVBQXhDLEVBQW9EO0FBQ2xEO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDLEtBQUtELElBQUwsQ0FBVW9ELElBQVgsSUFBbUIsQ0FBQyxLQUFLcEQsSUFBTCxDQUFVa0QsUUFBbEMsRUFBNEM7QUFDMUMsVUFBTSxJQUFJdkQsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWThNLHFCQUE1QixFQUFtRCx5QkFBbkQsQ0FBTjtBQUNELEdBUDZDLENBUzlDOzs7QUFDQSxNQUFJLEtBQUtwTixJQUFMLENBQVV5SSxHQUFkLEVBQW1CO0FBQ2pCLFVBQU0sSUFBSWpKLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlXLGdCQUE1QixFQUE4QyxnQkFBZ0IsbUJBQTlELENBQU47QUFDRDs7QUFFRCxNQUFJLEtBQUtsQixLQUFULEVBQWdCO0FBQ2QsUUFBSSxLQUFLQyxJQUFMLENBQVVpRCxJQUFWLElBQWtCLENBQUMsS0FBS3BELElBQUwsQ0FBVWtELFFBQTdCLElBQXlDLEtBQUsvQyxJQUFMLENBQVVpRCxJQUFWLENBQWVsQyxRQUFmLElBQTJCLEtBQUtsQixJQUFMLENBQVVvRCxJQUFWLENBQWUvQixFQUF2RixFQUEyRjtBQUN6RixZQUFNLElBQUkxQixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZVyxnQkFBNUIsQ0FBTjtBQUNELEtBRkQsTUFFTyxJQUFJLEtBQUtqQixJQUFMLENBQVVzTSxjQUFkLEVBQThCO0FBQ25DLFlBQU0sSUFBSTlNLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlXLGdCQUE1QixDQUFOO0FBQ0QsS0FGTSxNQUVBLElBQUksS0FBS2pCLElBQUwsQ0FBVTZKLFlBQWQsRUFBNEI7QUFDakMsWUFBTSxJQUFJckssS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWVcsZ0JBQTVCLENBQU47QUFDRDtBQUNGOztBQUVELE1BQUksQ0FBQyxLQUFLbEIsS0FBTixJQUFlLENBQUMsS0FBS0YsSUFBTCxDQUFVa0QsUUFBOUIsRUFBd0M7QUFDdEMsVUFBTXNLLHFCQUFxQixHQUFHLEVBQTlCOztBQUNBLFNBQUssSUFBSXBJLEdBQVQsSUFBZ0IsS0FBS2pGLElBQXJCLEVBQTJCO0FBQ3pCLFVBQUlpRixHQUFHLEtBQUssVUFBUixJQUFzQkEsR0FBRyxLQUFLLE1BQWxDLEVBQTBDO0FBQ3hDO0FBQ0Q7O0FBQ0RvSSxNQUFBQSxxQkFBcUIsQ0FBQ3BJLEdBQUQsQ0FBckIsR0FBNkIsS0FBS2pGLElBQUwsQ0FBVWlGLEdBQVYsQ0FBN0I7QUFDRDs7QUFFRCxVQUFNO0FBQUVzSCxNQUFBQSxXQUFGO0FBQWVDLE1BQUFBO0FBQWYsUUFBaUNuTixJQUFJLENBQUNtTixhQUFMLENBQW1CLEtBQUs1TSxNQUF4QixFQUFnQztBQUNyRXNKLE1BQUFBLE1BQU0sRUFBRSxLQUFLckosSUFBTCxDQUFVb0QsSUFBVixDQUFlL0IsRUFEOEM7QUFFckV1TCxNQUFBQSxXQUFXLEVBQUU7QUFDWHJNLFFBQUFBLE1BQU0sRUFBRTtBQURHLE9BRndEO0FBS3JFaU4sTUFBQUE7QUFMcUUsS0FBaEMsQ0FBdkM7QUFRQSxXQUFPYixhQUFhLEdBQUc1SyxJQUFoQixDQUFxQjhHLE9BQU8sSUFBSTtBQUNyQyxVQUFJLENBQUNBLE9BQU8sQ0FBQ3ZILFFBQWIsRUFBdUI7QUFDckIsY0FBTSxJQUFJM0IsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWWdOLHFCQUE1QixFQUFtRCx5QkFBbkQsQ0FBTjtBQUNEOztBQUNEZixNQUFBQSxXQUFXLENBQUMsVUFBRCxDQUFYLEdBQTBCN0QsT0FBTyxDQUFDdkgsUUFBUixDQUFpQixVQUFqQixDQUExQjtBQUNBLFdBQUtBLFFBQUwsR0FBZ0I7QUFDZG9NLFFBQUFBLE1BQU0sRUFBRSxHQURNO0FBRWRwRSxRQUFBQSxRQUFRLEVBQUVULE9BQU8sQ0FBQ1MsUUFGSjtBQUdkaEksUUFBQUEsUUFBUSxFQUFFb0w7QUFISSxPQUFoQjtBQUtELEtBVk0sQ0FBUDtBQVdEO0FBQ0YsQ0FyREQsQyxDQXVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTVNLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JtQixrQkFBcEIsR0FBeUMsWUFBWTtBQUNuRCxNQUFJLEtBQUtaLFFBQUwsSUFBaUIsS0FBS3JCLFNBQUwsS0FBbUIsZUFBeEMsRUFBeUQ7QUFDdkQ7QUFDRDs7QUFFRCxNQUNFLENBQUMsS0FBS0MsS0FBTixJQUNBLENBQUMsS0FBS0MsSUFBTCxDQUFVd04sV0FEWCxJQUVBLENBQUMsS0FBS3hOLElBQUwsQ0FBVXNNLGNBRlgsSUFHQSxDQUFDLEtBQUt6TSxJQUFMLENBQVV5TSxjQUpiLEVBS0U7QUFDQSxVQUFNLElBQUk5TSxLQUFLLENBQUNjLEtBQVYsQ0FDSixHQURJLEVBRUoseURBQXlELHFDQUZyRCxDQUFOO0FBSUQsR0Fma0QsQ0FpQm5EO0FBQ0E7OztBQUNBLE1BQUksS0FBS04sSUFBTCxDQUFVd04sV0FBVixJQUF5QixLQUFLeE4sSUFBTCxDQUFVd04sV0FBVixDQUFzQi9JLE1BQXRCLElBQWdDLEVBQTdELEVBQWlFO0FBQy9ELFNBQUt6RSxJQUFMLENBQVV3TixXQUFWLEdBQXdCLEtBQUt4TixJQUFMLENBQVV3TixXQUFWLENBQXNCQyxXQUF0QixFQUF4QjtBQUNELEdBckJrRCxDQXVCbkQ7OztBQUNBLE1BQUksS0FBS3pOLElBQUwsQ0FBVXNNLGNBQWQsRUFBOEI7QUFDNUIsU0FBS3RNLElBQUwsQ0FBVXNNLGNBQVYsR0FBMkIsS0FBS3RNLElBQUwsQ0FBVXNNLGNBQVYsQ0FBeUJtQixXQUF6QixFQUEzQjtBQUNEOztBQUVELE1BQUluQixjQUFjLEdBQUcsS0FBS3RNLElBQUwsQ0FBVXNNLGNBQS9CLENBNUJtRCxDQThCbkQ7O0FBQ0EsTUFBSSxDQUFDQSxjQUFELElBQW1CLENBQUMsS0FBS3pNLElBQUwsQ0FBVWtELFFBQWxDLEVBQTRDO0FBQzFDdUosSUFBQUEsY0FBYyxHQUFHLEtBQUt6TSxJQUFMLENBQVV5TSxjQUEzQjtBQUNEOztBQUVELE1BQUlBLGNBQUosRUFBb0I7QUFDbEJBLElBQUFBLGNBQWMsR0FBR0EsY0FBYyxDQUFDbUIsV0FBZixFQUFqQjtBQUNELEdBckNrRCxDQXVDbkQ7OztBQUNBLE1BQUksS0FBSzFOLEtBQUwsSUFBYyxDQUFDLEtBQUtDLElBQUwsQ0FBVXdOLFdBQXpCLElBQXdDLENBQUNsQixjQUF6QyxJQUEyRCxDQUFDLEtBQUt0TSxJQUFMLENBQVUwTixVQUExRSxFQUFzRjtBQUNwRjtBQUNEOztBQUVELE1BQUlyRSxPQUFPLEdBQUczSCxPQUFPLENBQUNDLE9BQVIsRUFBZDtBQUVBLE1BQUlnTSxPQUFKLENBOUNtRCxDQThDdEM7O0FBQ2IsTUFBSUMsYUFBSjtBQUNBLE1BQUlDLG1CQUFKO0FBQ0EsTUFBSUMsa0JBQWtCLEdBQUcsRUFBekIsQ0FqRG1ELENBbURuRDs7QUFDQSxRQUFNQyxTQUFTLEdBQUcsRUFBbEI7O0FBQ0EsTUFBSSxLQUFLaE8sS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQTdCLEVBQXVDO0FBQ3JDZ04sSUFBQUEsU0FBUyxDQUFDNUksSUFBVixDQUFlO0FBQ2JwRSxNQUFBQSxRQUFRLEVBQUUsS0FBS2hCLEtBQUwsQ0FBV2dCO0FBRFIsS0FBZjtBQUdEOztBQUNELE1BQUl1TCxjQUFKLEVBQW9CO0FBQ2xCeUIsSUFBQUEsU0FBUyxDQUFDNUksSUFBVixDQUFlO0FBQ2JtSCxNQUFBQSxjQUFjLEVBQUVBO0FBREgsS0FBZjtBQUdEOztBQUNELE1BQUksS0FBS3RNLElBQUwsQ0FBVXdOLFdBQWQsRUFBMkI7QUFDekJPLElBQUFBLFNBQVMsQ0FBQzVJLElBQVYsQ0FBZTtBQUFFcUksTUFBQUEsV0FBVyxFQUFFLEtBQUt4TixJQUFMLENBQVV3TjtBQUF6QixLQUFmO0FBQ0Q7O0FBRUQsTUFBSU8sU0FBUyxDQUFDdEosTUFBVixJQUFvQixDQUF4QixFQUEyQjtBQUN6QjtBQUNEOztBQUVENEUsRUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQ2R6SCxJQURPLENBQ0YsTUFBTTtBQUNWLFdBQU8sS0FBS2hDLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJvQyxJQUFyQixDQUNMLGVBREssRUFFTDtBQUNFMEMsTUFBQUEsR0FBRyxFQUFFeUY7QUFEUCxLQUZLLEVBS0wsRUFMSyxDQUFQO0FBT0QsR0FUTyxFQVVQbk0sSUFWTyxDQVVGOEcsT0FBTyxJQUFJO0FBQ2ZBLElBQUFBLE9BQU8sQ0FBQy9CLE9BQVIsQ0FBZ0JuQyxNQUFNLElBQUk7QUFDeEIsVUFBSSxLQUFLekUsS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQXpCLElBQXFDeUQsTUFBTSxDQUFDekQsUUFBUCxJQUFtQixLQUFLaEIsS0FBTCxDQUFXZ0IsUUFBdkUsRUFBaUY7QUFDL0U2TSxRQUFBQSxhQUFhLEdBQUdwSixNQUFoQjtBQUNEOztBQUNELFVBQUlBLE1BQU0sQ0FBQzhILGNBQVAsSUFBeUJBLGNBQTdCLEVBQTZDO0FBQzNDdUIsUUFBQUEsbUJBQW1CLEdBQUdySixNQUF0QjtBQUNEOztBQUNELFVBQUlBLE1BQU0sQ0FBQ2dKLFdBQVAsSUFBc0IsS0FBS3hOLElBQUwsQ0FBVXdOLFdBQXBDLEVBQWlEO0FBQy9DTSxRQUFBQSxrQkFBa0IsQ0FBQzNJLElBQW5CLENBQXdCWCxNQUF4QjtBQUNEO0FBQ0YsS0FWRCxFQURlLENBYWY7O0FBQ0EsUUFBSSxLQUFLekUsS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQTdCLEVBQXVDO0FBQ3JDLFVBQUksQ0FBQzZNLGFBQUwsRUFBb0I7QUFDbEIsY0FBTSxJQUFJcE8sS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWW9FLGdCQUE1QixFQUE4Qyw4QkFBOUMsQ0FBTjtBQUNEOztBQUNELFVBQ0UsS0FBSzFFLElBQUwsQ0FBVXNNLGNBQVYsSUFDQXNCLGFBQWEsQ0FBQ3RCLGNBRGQsSUFFQSxLQUFLdE0sSUFBTCxDQUFVc00sY0FBVixLQUE2QnNCLGFBQWEsQ0FBQ3RCLGNBSDdDLEVBSUU7QUFDQSxjQUFNLElBQUk5TSxLQUFLLENBQUNjLEtBQVYsQ0FBZ0IsR0FBaEIsRUFBcUIsK0NBQStDLFdBQXBFLENBQU47QUFDRDs7QUFDRCxVQUNFLEtBQUtOLElBQUwsQ0FBVXdOLFdBQVYsSUFDQUksYUFBYSxDQUFDSixXQURkLElBRUEsS0FBS3hOLElBQUwsQ0FBVXdOLFdBQVYsS0FBMEJJLGFBQWEsQ0FBQ0osV0FGeEMsSUFHQSxDQUFDLEtBQUt4TixJQUFMLENBQVVzTSxjQUhYLElBSUEsQ0FBQ3NCLGFBQWEsQ0FBQ3RCLGNBTGpCLEVBTUU7QUFDQSxjQUFNLElBQUk5TSxLQUFLLENBQUNjLEtBQVYsQ0FBZ0IsR0FBaEIsRUFBcUIsNENBQTRDLFdBQWpFLENBQU47QUFDRDs7QUFDRCxVQUNFLEtBQUtOLElBQUwsQ0FBVTBOLFVBQVYsSUFDQSxLQUFLMU4sSUFBTCxDQUFVME4sVUFEVixJQUVBLEtBQUsxTixJQUFMLENBQVUwTixVQUFWLEtBQXlCRSxhQUFhLENBQUNGLFVBSHpDLEVBSUU7QUFDQSxjQUFNLElBQUlsTyxLQUFLLENBQUNjLEtBQVYsQ0FBZ0IsR0FBaEIsRUFBcUIsMkNBQTJDLFdBQWhFLENBQU47QUFDRDtBQUNGOztBQUVELFFBQUksS0FBS1AsS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQXpCLElBQXFDNk0sYUFBekMsRUFBd0Q7QUFDdERELE1BQUFBLE9BQU8sR0FBR0MsYUFBVjtBQUNEOztBQUVELFFBQUl0QixjQUFjLElBQUl1QixtQkFBdEIsRUFBMkM7QUFDekNGLE1BQUFBLE9BQU8sR0FBR0UsbUJBQVY7QUFDRCxLQWpEYyxDQWtEZjs7O0FBQ0EsUUFBSSxDQUFDLEtBQUs5TixLQUFOLElBQWUsQ0FBQyxLQUFLQyxJQUFMLENBQVUwTixVQUExQixJQUF3QyxDQUFDQyxPQUE3QyxFQUFzRDtBQUNwRCxZQUFNLElBQUluTyxLQUFLLENBQUNjLEtBQVYsQ0FBZ0IsR0FBaEIsRUFBcUIsZ0RBQXJCLENBQU47QUFDRDtBQUNGLEdBaEVPLEVBaUVQc0IsSUFqRU8sQ0FpRUYsTUFBTTtBQUNWLFFBQUksQ0FBQytMLE9BQUwsRUFBYztBQUNaLFVBQUksQ0FBQ0csa0JBQWtCLENBQUNySixNQUF4QixFQUFnQztBQUM5QjtBQUNELE9BRkQsTUFFTyxJQUNMcUosa0JBQWtCLENBQUNySixNQUFuQixJQUE2QixDQUE3QixLQUNDLENBQUNxSixrQkFBa0IsQ0FBQyxDQUFELENBQWxCLENBQXNCLGdCQUF0QixDQUFELElBQTRDLENBQUN4QixjQUQ5QyxDQURLLEVBR0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFPd0Isa0JBQWtCLENBQUMsQ0FBRCxDQUFsQixDQUFzQixVQUF0QixDQUFQO0FBQ0QsT0FSTSxNQVFBLElBQUksQ0FBQyxLQUFLOU4sSUFBTCxDQUFVc00sY0FBZixFQUErQjtBQUNwQyxjQUFNLElBQUk5TSxLQUFLLENBQUNjLEtBQVYsQ0FDSixHQURJLEVBRUosa0RBQ0UsdUNBSEUsQ0FBTjtBQUtELE9BTk0sTUFNQTtBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFJME4sUUFBUSxHQUFHO0FBQ2JSLFVBQUFBLFdBQVcsRUFBRSxLQUFLeE4sSUFBTCxDQUFVd04sV0FEVjtBQUVibEIsVUFBQUEsY0FBYyxFQUFFO0FBQ2RoQyxZQUFBQSxHQUFHLEVBQUVnQztBQURTO0FBRkgsU0FBZjs7QUFNQSxZQUFJLEtBQUt0TSxJQUFMLENBQVVpTyxhQUFkLEVBQTZCO0FBQzNCRCxVQUFBQSxRQUFRLENBQUMsZUFBRCxDQUFSLEdBQTRCLEtBQUtoTyxJQUFMLENBQVVpTyxhQUF0QztBQUNEOztBQUNELGFBQUtyTyxNQUFMLENBQVk0RCxRQUFaLENBQXFCdUosT0FBckIsQ0FBNkIsZUFBN0IsRUFBOENpQixRQUE5QyxFQUF3RC9CLEtBQXhELENBQThEQyxHQUFHLElBQUk7QUFDbkUsY0FBSUEsR0FBRyxDQUFDZ0MsSUFBSixJQUFZMU8sS0FBSyxDQUFDYyxLQUFOLENBQVlvRSxnQkFBNUIsRUFBOEM7QUFDNUM7QUFDQTtBQUNELFdBSmtFLENBS25FOzs7QUFDQSxnQkFBTXdILEdBQU47QUFDRCxTQVBEO0FBUUE7QUFDRDtBQUNGLEtBMUNELE1BMENPO0FBQ0wsVUFBSTRCLGtCQUFrQixDQUFDckosTUFBbkIsSUFBNkIsQ0FBN0IsSUFBa0MsQ0FBQ3FKLGtCQUFrQixDQUFDLENBQUQsQ0FBbEIsQ0FBc0IsZ0JBQXRCLENBQXZDLEVBQWdGO0FBQzlFO0FBQ0E7QUFDQTtBQUNBLGNBQU1FLFFBQVEsR0FBRztBQUFFak4sVUFBQUEsUUFBUSxFQUFFNE0sT0FBTyxDQUFDNU07QUFBcEIsU0FBakI7QUFDQSxlQUFPLEtBQUtuQixNQUFMLENBQVk0RCxRQUFaLENBQ0p1SixPQURJLENBQ0ksZUFESixFQUNxQmlCLFFBRHJCLEVBRUpwTSxJQUZJLENBRUMsTUFBTTtBQUNWLGlCQUFPa00sa0JBQWtCLENBQUMsQ0FBRCxDQUFsQixDQUFzQixVQUF0QixDQUFQO0FBQ0QsU0FKSSxFQUtKN0IsS0FMSSxDQUtFQyxHQUFHLElBQUk7QUFDWixjQUFJQSxHQUFHLENBQUNnQyxJQUFKLElBQVkxTyxLQUFLLENBQUNjLEtBQU4sQ0FBWW9FLGdCQUE1QixFQUE4QztBQUM1QztBQUNBO0FBQ0QsV0FKVyxDQUtaOzs7QUFDQSxnQkFBTXdILEdBQU47QUFDRCxTQVpJLENBQVA7QUFhRCxPQWxCRCxNQWtCTztBQUNMLFlBQUksS0FBS2xNLElBQUwsQ0FBVXdOLFdBQVYsSUFBeUJHLE9BQU8sQ0FBQ0gsV0FBUixJQUF1QixLQUFLeE4sSUFBTCxDQUFVd04sV0FBOUQsRUFBMkU7QUFDekU7QUFDQTtBQUNBO0FBQ0EsZ0JBQU1RLFFBQVEsR0FBRztBQUNmUixZQUFBQSxXQUFXLEVBQUUsS0FBS3hOLElBQUwsQ0FBVXdOO0FBRFIsV0FBakIsQ0FKeUUsQ0FPekU7QUFDQTs7QUFDQSxjQUFJLEtBQUt4TixJQUFMLENBQVVzTSxjQUFkLEVBQThCO0FBQzVCMEIsWUFBQUEsUUFBUSxDQUFDLGdCQUFELENBQVIsR0FBNkI7QUFDM0IxRCxjQUFBQSxHQUFHLEVBQUUsS0FBS3RLLElBQUwsQ0FBVXNNO0FBRFksYUFBN0I7QUFHRCxXQUpELE1BSU8sSUFDTHFCLE9BQU8sQ0FBQzVNLFFBQVIsSUFDQSxLQUFLZixJQUFMLENBQVVlLFFBRFYsSUFFQTRNLE9BQU8sQ0FBQzVNLFFBQVIsSUFBb0IsS0FBS2YsSUFBTCxDQUFVZSxRQUh6QixFQUlMO0FBQ0E7QUFDQWlOLFlBQUFBLFFBQVEsQ0FBQyxVQUFELENBQVIsR0FBdUI7QUFDckIxRCxjQUFBQSxHQUFHLEVBQUVxRCxPQUFPLENBQUM1TTtBQURRLGFBQXZCO0FBR0QsV0FUTSxNQVNBO0FBQ0w7QUFDQSxtQkFBTzRNLE9BQU8sQ0FBQzVNLFFBQWY7QUFDRDs7QUFDRCxjQUFJLEtBQUtmLElBQUwsQ0FBVWlPLGFBQWQsRUFBNkI7QUFDM0JELFlBQUFBLFFBQVEsQ0FBQyxlQUFELENBQVIsR0FBNEIsS0FBS2hPLElBQUwsQ0FBVWlPLGFBQXRDO0FBQ0Q7O0FBQ0QsZUFBS3JPLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJ1SixPQUFyQixDQUE2QixlQUE3QixFQUE4Q2lCLFFBQTlDLEVBQXdEL0IsS0FBeEQsQ0FBOERDLEdBQUcsSUFBSTtBQUNuRSxnQkFBSUEsR0FBRyxDQUFDZ0MsSUFBSixJQUFZMU8sS0FBSyxDQUFDYyxLQUFOLENBQVlvRSxnQkFBNUIsRUFBOEM7QUFDNUM7QUFDQTtBQUNELGFBSmtFLENBS25FOzs7QUFDQSxrQkFBTXdILEdBQU47QUFDRCxXQVBEO0FBUUQsU0F0Q0ksQ0F1Q0w7OztBQUNBLGVBQU95QixPQUFPLENBQUM1TSxRQUFmO0FBQ0Q7QUFDRjtBQUNGLEdBMUtPLEVBMktQYSxJQTNLTyxDQTJLRnVNLEtBQUssSUFBSTtBQUNiLFFBQUlBLEtBQUosRUFBVztBQUNULFdBQUtwTyxLQUFMLEdBQWE7QUFBRWdCLFFBQUFBLFFBQVEsRUFBRW9OO0FBQVosT0FBYjtBQUNBLGFBQU8sS0FBS25PLElBQUwsQ0FBVWUsUUFBakI7QUFDQSxhQUFPLEtBQUtmLElBQUwsQ0FBVXVHLFNBQWpCO0FBQ0QsS0FMWSxDQU1iOztBQUNELEdBbExPLENBQVY7QUFtTEEsU0FBTzhDLE9BQVA7QUFDRCxDQTNQRCxDLENBNlBBO0FBQ0E7QUFDQTs7O0FBQ0ExSixTQUFTLENBQUNpQixTQUFWLENBQW9CNEIsNkJBQXBCLEdBQW9ELFlBQVk7QUFDOUQ7QUFDQSxNQUFJLEtBQUtyQixRQUFMLElBQWlCLEtBQUtBLFFBQUwsQ0FBY0EsUUFBbkMsRUFBNkM7QUFDM0MsU0FBS3ZCLE1BQUwsQ0FBWTJGLGVBQVosQ0FBNEJDLG1CQUE1QixDQUFnRCxLQUFLNUYsTUFBckQsRUFBNkQsS0FBS3VCLFFBQUwsQ0FBY0EsUUFBM0U7QUFDRDtBQUNGLENBTEQ7O0FBT0F4QixTQUFTLENBQUNpQixTQUFWLENBQW9COEIsb0JBQXBCLEdBQTJDLFlBQVk7QUFDckQsTUFBSSxLQUFLdkIsUUFBVCxFQUFtQjtBQUNqQjtBQUNEOztBQUVELE1BQUksS0FBS3JCLFNBQUwsS0FBbUIsT0FBdkIsRUFBZ0M7QUFDOUIsU0FBS0YsTUFBTCxDQUFZK0osZUFBWixDQUE0QnlFLElBQTVCLENBQWlDQyxLQUFqQztBQUNEOztBQUVELE1BQUksS0FBS3ZPLFNBQUwsS0FBbUIsT0FBbkIsSUFBOEIsS0FBS0MsS0FBbkMsSUFBNEMsS0FBS0YsSUFBTCxDQUFVeU8saUJBQVYsRUFBaEQsRUFBK0U7QUFDN0UsVUFBTSxJQUFJOU8sS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZaU8sZUFEUixFQUVILHNCQUFxQixLQUFLeE8sS0FBTCxDQUFXZ0IsUUFBUyxHQUZ0QyxDQUFOO0FBSUQ7O0FBRUQsTUFBSSxLQUFLakIsU0FBTCxLQUFtQixVQUFuQixJQUFpQyxLQUFLRSxJQUFMLENBQVV3TyxRQUEvQyxFQUF5RDtBQUN2RCxTQUFLeE8sSUFBTCxDQUFVeU8sWUFBVixHQUF5QixLQUFLek8sSUFBTCxDQUFVd08sUUFBVixDQUFtQkUsSUFBNUM7QUFDRCxHQWxCb0QsQ0FvQnJEO0FBQ0E7OztBQUNBLE1BQUksS0FBSzFPLElBQUwsQ0FBVXlJLEdBQVYsSUFBaUIsS0FBS3pJLElBQUwsQ0FBVXlJLEdBQVYsQ0FBYyxhQUFkLENBQXJCLEVBQW1EO0FBQ2pELFVBQU0sSUFBSWpKLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlxTyxXQUE1QixFQUF5QyxjQUF6QyxDQUFOO0FBQ0Q7O0FBRUQsTUFBSSxLQUFLNU8sS0FBVCxFQUFnQjtBQUNkO0FBQ0E7QUFDQSxRQUFJLEtBQUtELFNBQUwsS0FBbUIsT0FBbkIsSUFBOEIsS0FBS0UsSUFBTCxDQUFVeUksR0FBeEMsSUFBK0MsS0FBSzVJLElBQUwsQ0FBVWtELFFBQVYsS0FBdUIsSUFBMUUsRUFBZ0Y7QUFDOUUsV0FBSy9DLElBQUwsQ0FBVXlJLEdBQVYsQ0FBYyxLQUFLMUksS0FBTCxDQUFXZ0IsUUFBekIsSUFBcUM7QUFBRTZOLFFBQUFBLElBQUksRUFBRSxJQUFSO0FBQWNDLFFBQUFBLEtBQUssRUFBRTtBQUFyQixPQUFyQztBQUNELEtBTGEsQ0FNZDs7O0FBQ0EsUUFDRSxLQUFLL08sU0FBTCxLQUFtQixPQUFuQixJQUNBLEtBQUtFLElBQUwsQ0FBVWlLLGdCQURWLElBRUEsS0FBS3JLLE1BQUwsQ0FBWXFMLGNBRlosSUFHQSxLQUFLckwsTUFBTCxDQUFZcUwsY0FBWixDQUEyQjZELGNBSjdCLEVBS0U7QUFDQSxXQUFLOU8sSUFBTCxDQUFVK08sb0JBQVYsR0FBaUN2UCxLQUFLLENBQUM2QixPQUFOLENBQWMsSUFBSUMsSUFBSixFQUFkLENBQWpDO0FBQ0QsS0FkYSxDQWVkOzs7QUFDQSxXQUFPLEtBQUt0QixJQUFMLENBQVV1RyxTQUFqQjtBQUVBLFFBQUl5SSxLQUFLLEdBQUd0TixPQUFPLENBQUNDLE9BQVIsRUFBWixDQWxCYyxDQW1CZDs7QUFDQSxRQUNFLEtBQUs3QixTQUFMLEtBQW1CLE9BQW5CLElBQ0EsS0FBS0UsSUFBTCxDQUFVaUssZ0JBRFYsSUFFQSxLQUFLckssTUFBTCxDQUFZcUwsY0FGWixJQUdBLEtBQUtyTCxNQUFMLENBQVlxTCxjQUFaLENBQTJCUyxrQkFKN0IsRUFLRTtBQUNBc0QsTUFBQUEsS0FBSyxHQUFHLEtBQUtwUCxNQUFMLENBQVk0RCxRQUFaLENBQ0xvQyxJQURLLENBRUosT0FGSSxFQUdKO0FBQUU3RSxRQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUFaLE9BSEksRUFJSjtBQUFFMkYsUUFBQUEsSUFBSSxFQUFFLENBQUMsbUJBQUQsRUFBc0Isa0JBQXRCO0FBQVIsT0FKSSxFQU1MOUUsSUFOSyxDQU1BOEcsT0FBTyxJQUFJO0FBQ2YsWUFBSUEsT0FBTyxDQUFDakUsTUFBUixJQUFrQixDQUF0QixFQUF5QjtBQUN2QixnQkFBTXdCLFNBQU47QUFDRDs7QUFDRCxjQUFNaEQsSUFBSSxHQUFHeUYsT0FBTyxDQUFDLENBQUQsQ0FBcEI7QUFDQSxZQUFJaUQsWUFBWSxHQUFHLEVBQW5COztBQUNBLFlBQUkxSSxJQUFJLENBQUMySSxpQkFBVCxFQUE0QjtBQUMxQkQsVUFBQUEsWUFBWSxHQUFHN0csZ0JBQUUrRyxJQUFGLENBQ2I1SSxJQUFJLENBQUMySSxpQkFEUSxFQUViLEtBQUtoTSxNQUFMLENBQVlxTCxjQUFaLENBQTJCUyxrQkFGZCxDQUFmO0FBSUQsU0FYYyxDQVlmOzs7QUFDQSxlQUNFQyxZQUFZLENBQUNsSCxNQUFiLEdBQXNCd0ssSUFBSSxDQUFDQyxHQUFMLENBQVMsQ0FBVCxFQUFZLEtBQUt0UCxNQUFMLENBQVlxTCxjQUFaLENBQTJCUyxrQkFBM0IsR0FBZ0QsQ0FBNUQsQ0FEeEIsRUFFRTtBQUNBQyxVQUFBQSxZQUFZLENBQUN3RCxLQUFiO0FBQ0Q7O0FBQ0R4RCxRQUFBQSxZQUFZLENBQUN4RyxJQUFiLENBQWtCbEMsSUFBSSxDQUFDK0QsUUFBdkI7QUFDQSxhQUFLaEgsSUFBTCxDQUFVNEwsaUJBQVYsR0FBOEJELFlBQTlCO0FBQ0QsT0ExQkssQ0FBUjtBQTJCRDs7QUFFRCxXQUFPcUQsS0FBSyxDQUFDcE4sSUFBTixDQUFXLE1BQU07QUFDdEI7QUFDQSxhQUFPLEtBQUtoQyxNQUFMLENBQVk0RCxRQUFaLENBQ0pjLE1BREksQ0FFSCxLQUFLeEUsU0FGRixFQUdILEtBQUtDLEtBSEYsRUFJSCxLQUFLQyxJQUpGLEVBS0gsS0FBS1MsVUFMRixFQU1ILEtBTkcsRUFPSCxLQVBHLEVBUUgsS0FBS2UscUJBUkYsRUFVSkksSUFWSSxDQVVDVCxRQUFRLElBQUk7QUFDaEJBLFFBQUFBLFFBQVEsQ0FBQ0MsU0FBVCxHQUFxQixLQUFLQSxTQUExQjs7QUFDQSxhQUFLZ08sdUJBQUwsQ0FBNkJqTyxRQUE3QixFQUF1QyxLQUFLbkIsSUFBNUM7O0FBQ0EsYUFBS21CLFFBQUwsR0FBZ0I7QUFBRUEsVUFBQUE7QUFBRixTQUFoQjtBQUNELE9BZEksQ0FBUDtBQWVELEtBakJNLENBQVA7QUFrQkQsR0F6RUQsTUF5RU87QUFDTDtBQUNBLFFBQUksS0FBS3JCLFNBQUwsS0FBbUIsT0FBdkIsRUFBZ0M7QUFDOUIsVUFBSTJJLEdBQUcsR0FBRyxLQUFLekksSUFBTCxDQUFVeUksR0FBcEIsQ0FEOEIsQ0FFOUI7O0FBQ0EsVUFBSSxDQUFDQSxHQUFMLEVBQVU7QUFDUkEsUUFBQUEsR0FBRyxHQUFHLEVBQU47QUFDQUEsUUFBQUEsR0FBRyxDQUFDLEdBQUQsQ0FBSCxHQUFXO0FBQUVtRyxVQUFBQSxJQUFJLEVBQUUsSUFBUjtBQUFjQyxVQUFBQSxLQUFLLEVBQUU7QUFBckIsU0FBWDtBQUNELE9BTjZCLENBTzlCOzs7QUFDQXBHLE1BQUFBLEdBQUcsQ0FBQyxLQUFLekksSUFBTCxDQUFVZSxRQUFYLENBQUgsR0FBMEI7QUFBRTZOLFFBQUFBLElBQUksRUFBRSxJQUFSO0FBQWNDLFFBQUFBLEtBQUssRUFBRTtBQUFyQixPQUExQjtBQUNBLFdBQUs3TyxJQUFMLENBQVV5SSxHQUFWLEdBQWdCQSxHQUFoQixDQVQ4QixDQVU5Qjs7QUFDQSxVQUFJLEtBQUs3SSxNQUFMLENBQVlxTCxjQUFaLElBQThCLEtBQUtyTCxNQUFMLENBQVlxTCxjQUFaLENBQTJCNkQsY0FBN0QsRUFBNkU7QUFDM0UsYUFBSzlPLElBQUwsQ0FBVStPLG9CQUFWLEdBQWlDdlAsS0FBSyxDQUFDNkIsT0FBTixDQUFjLElBQUlDLElBQUosRUFBZCxDQUFqQztBQUNEO0FBQ0YsS0FoQkksQ0FrQkw7OztBQUNBLFdBQU8sS0FBSzFCLE1BQUwsQ0FBWTRELFFBQVosQ0FDSmUsTUFESSxDQUNHLEtBQUt6RSxTQURSLEVBQ21CLEtBQUtFLElBRHhCLEVBQzhCLEtBQUtTLFVBRG5DLEVBQytDLEtBRC9DLEVBQ3NELEtBQUtlLHFCQUQzRCxFQUVKeUssS0FGSSxDQUVFM0MsS0FBSyxJQUFJO0FBQ2QsVUFBSSxLQUFLeEosU0FBTCxLQUFtQixPQUFuQixJQUE4QndKLEtBQUssQ0FBQzRFLElBQU4sS0FBZTFPLEtBQUssQ0FBQ2MsS0FBTixDQUFZK08sZUFBN0QsRUFBOEU7QUFDNUUsY0FBTS9GLEtBQU47QUFDRCxPQUhhLENBS2Q7OztBQUNBLFVBQUlBLEtBQUssSUFBSUEsS0FBSyxDQUFDZ0csUUFBZixJQUEyQmhHLEtBQUssQ0FBQ2dHLFFBQU4sQ0FBZUMsZ0JBQWYsS0FBb0MsVUFBbkUsRUFBK0U7QUFDN0UsY0FBTSxJQUFJL1AsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZbUssY0FEUixFQUVKLDJDQUZJLENBQU47QUFJRDs7QUFFRCxVQUFJbkIsS0FBSyxJQUFJQSxLQUFLLENBQUNnRyxRQUFmLElBQTJCaEcsS0FBSyxDQUFDZ0csUUFBTixDQUFlQyxnQkFBZixLQUFvQyxPQUFuRSxFQUE0RTtBQUMxRSxjQUFNLElBQUkvUCxLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVl3SyxXQURSLEVBRUosZ0RBRkksQ0FBTjtBQUlELE9BbEJhLENBb0JkO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQSxhQUFPLEtBQUtsTCxNQUFMLENBQVk0RCxRQUFaLENBQ0pvQyxJQURJLENBRUgsS0FBSzlGLFNBRkYsRUFHSDtBQUNFK0csUUFBQUEsUUFBUSxFQUFFLEtBQUs3RyxJQUFMLENBQVU2RyxRQUR0QjtBQUVFOUYsUUFBQUEsUUFBUSxFQUFFO0FBQUV1SixVQUFBQSxHQUFHLEVBQUUsS0FBS3ZKLFFBQUw7QUFBUDtBQUZaLE9BSEcsRUFPSDtBQUFFd0osUUFBQUEsS0FBSyxFQUFFO0FBQVQsT0FQRyxFQVNKM0ksSUFUSSxDQVNDOEcsT0FBTyxJQUFJO0FBQ2YsWUFBSUEsT0FBTyxDQUFDakUsTUFBUixHQUFpQixDQUFyQixFQUF3QjtBQUN0QixnQkFBTSxJQUFJakYsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZbUssY0FEUixFQUVKLDJDQUZJLENBQU47QUFJRDs7QUFDRCxlQUFPLEtBQUs3SyxNQUFMLENBQVk0RCxRQUFaLENBQXFCb0MsSUFBckIsQ0FDTCxLQUFLOUYsU0FEQSxFQUVMO0FBQUU0SyxVQUFBQSxLQUFLLEVBQUUsS0FBSzFLLElBQUwsQ0FBVTBLLEtBQW5CO0FBQTBCM0osVUFBQUEsUUFBUSxFQUFFO0FBQUV1SixZQUFBQSxHQUFHLEVBQUUsS0FBS3ZKLFFBQUw7QUFBUDtBQUFwQyxTQUZLLEVBR0w7QUFBRXdKLFVBQUFBLEtBQUssRUFBRTtBQUFULFNBSEssQ0FBUDtBQUtELE9BckJJLEVBc0JKM0ksSUF0QkksQ0FzQkM4RyxPQUFPLElBQUk7QUFDZixZQUFJQSxPQUFPLENBQUNqRSxNQUFSLEdBQWlCLENBQXJCLEVBQXdCO0FBQ3RCLGdCQUFNLElBQUlqRixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVl3SyxXQURSLEVBRUosZ0RBRkksQ0FBTjtBQUlEOztBQUNELGNBQU0sSUFBSXRMLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWStPLGVBRFIsRUFFSiwrREFGSSxDQUFOO0FBSUQsT0FqQ0ksQ0FBUDtBQWtDRCxLQTVESSxFQTZESnpOLElBN0RJLENBNkRDVCxRQUFRLElBQUk7QUFDaEJBLE1BQUFBLFFBQVEsQ0FBQ0osUUFBVCxHQUFvQixLQUFLZixJQUFMLENBQVVlLFFBQTlCO0FBQ0FJLE1BQUFBLFFBQVEsQ0FBQ29GLFNBQVQsR0FBcUIsS0FBS3ZHLElBQUwsQ0FBVXVHLFNBQS9COztBQUVBLFVBQUksS0FBSzhELDBCQUFULEVBQXFDO0FBQ25DbEosUUFBQUEsUUFBUSxDQUFDMEYsUUFBVCxHQUFvQixLQUFLN0csSUFBTCxDQUFVNkcsUUFBOUI7QUFDRDs7QUFDRCxXQUFLdUksdUJBQUwsQ0FBNkJqTyxRQUE3QixFQUF1QyxLQUFLbkIsSUFBNUM7O0FBQ0EsV0FBS21CLFFBQUwsR0FBZ0I7QUFDZG9NLFFBQUFBLE1BQU0sRUFBRSxHQURNO0FBRWRwTSxRQUFBQSxRQUZjO0FBR2RnSSxRQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUhJLE9BQWhCO0FBS0QsS0ExRUksQ0FBUDtBQTJFRDtBQUNGLENBbE1ELEMsQ0FvTUE7OztBQUNBeEosU0FBUyxDQUFDaUIsU0FBVixDQUFvQmlDLG1CQUFwQixHQUEwQyxZQUFZO0FBQ3BELE1BQUksQ0FBQyxLQUFLMUIsUUFBTixJQUFrQixDQUFDLEtBQUtBLFFBQUwsQ0FBY0EsUUFBckMsRUFBK0M7QUFDN0M7QUFDRCxHQUhtRCxDQUtwRDs7O0FBQ0EsUUFBTXFPLGdCQUFnQixHQUFHL1AsUUFBUSxDQUFDbUUsYUFBVCxDQUN2QixLQUFLOUQsU0FEa0IsRUFFdkJMLFFBQVEsQ0FBQ29FLEtBQVQsQ0FBZTRMLFNBRlEsRUFHdkIsS0FBSzdQLE1BQUwsQ0FBWW1FLGFBSFcsQ0FBekI7QUFLQSxRQUFNMkwsWUFBWSxHQUFHLEtBQUs5UCxNQUFMLENBQVkrUCxtQkFBWixDQUFnQ0QsWUFBaEMsQ0FBNkMsS0FBSzVQLFNBQWxELENBQXJCOztBQUNBLE1BQUksQ0FBQzBQLGdCQUFELElBQXFCLENBQUNFLFlBQTFCLEVBQXdDO0FBQ3RDLFdBQU9oTyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVELE1BQUlxQyxTQUFTLEdBQUc7QUFBRWxFLElBQUFBLFNBQVMsRUFBRSxLQUFLQTtBQUFsQixHQUFoQjs7QUFDQSxNQUFJLEtBQUtDLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQ2lELElBQUFBLFNBQVMsQ0FBQ2pELFFBQVYsR0FBcUIsS0FBS2hCLEtBQUwsQ0FBV2dCLFFBQWhDO0FBQ0QsR0FuQm1ELENBcUJwRDs7O0FBQ0EsTUFBSWtELGNBQUo7O0FBQ0EsTUFBSSxLQUFLbEUsS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQTdCLEVBQXVDO0FBQ3JDa0QsSUFBQUEsY0FBYyxHQUFHeEUsUUFBUSxDQUFDMkUsT0FBVCxDQUFpQkosU0FBakIsRUFBNEIsS0FBSy9ELFlBQWpDLENBQWpCO0FBQ0QsR0F6Qm1ELENBMkJwRDtBQUNBOzs7QUFDQSxRQUFNaUUsYUFBYSxHQUFHLEtBQUtDLGtCQUFMLENBQXdCSCxTQUF4QixDQUF0Qjs7QUFDQUUsRUFBQUEsYUFBYSxDQUFDMEwsbUJBQWQsQ0FBa0MsS0FBS3pPLFFBQUwsQ0FBY0EsUUFBaEQsRUFBMEQsS0FBS0EsUUFBTCxDQUFjb00sTUFBZCxJQUF3QixHQUFsRjs7QUFFQSxPQUFLM04sTUFBTCxDQUFZNEQsUUFBWixDQUFxQkMsVUFBckIsR0FBa0M3QixJQUFsQyxDQUF1Q1MsZ0JBQWdCLElBQUk7QUFDekQ7QUFDQSxVQUFNd04sS0FBSyxHQUFHeE4sZ0JBQWdCLENBQUN5Tix3QkFBakIsQ0FBMEM1TCxhQUFhLENBQUNwRSxTQUF4RCxDQUFkO0FBQ0EsU0FBS0YsTUFBTCxDQUFZK1AsbUJBQVosQ0FBZ0NJLFdBQWhDLENBQ0U3TCxhQUFhLENBQUNwRSxTQURoQixFQUVFb0UsYUFGRixFQUdFRCxjQUhGLEVBSUU0TCxLQUpGO0FBTUQsR0FURCxFQWhDb0QsQ0EyQ3BEOztBQUNBLFNBQU9wUSxRQUFRLENBQ1prRixlQURJLENBRUhsRixRQUFRLENBQUNvRSxLQUFULENBQWU0TCxTQUZaLEVBR0gsS0FBSzVQLElBSEYsRUFJSHFFLGFBSkcsRUFLSEQsY0FMRyxFQU1ILEtBQUtyRSxNQU5GLEVBT0gsS0FBS08sT0FQRixFQVNKeUIsSUFUSSxDQVNDNEMsTUFBTSxJQUFJO0FBQ2QsUUFBSUEsTUFBTSxJQUFJLE9BQU9BLE1BQVAsS0FBa0IsUUFBaEMsRUFBMEM7QUFDeEMsV0FBS3JELFFBQUwsQ0FBY0EsUUFBZCxHQUF5QnFELE1BQXpCO0FBQ0Q7QUFDRixHQWJJLEVBY0p5SCxLQWRJLENBY0UsVUFBVUMsR0FBVixFQUFlO0FBQ3BCOEQsb0JBQU9DLElBQVAsQ0FBWSwyQkFBWixFQUF5Qy9ELEdBQXpDO0FBQ0QsR0FoQkksQ0FBUDtBQWlCRCxDQTdERCxDLENBK0RBOzs7QUFDQXZNLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0J1SSxRQUFwQixHQUErQixZQUFZO0FBQ3pDLE1BQUkrRyxNQUFNLEdBQUcsS0FBS3BRLFNBQUwsS0FBbUIsT0FBbkIsR0FBNkIsU0FBN0IsR0FBeUMsY0FBYyxLQUFLQSxTQUFuQixHQUErQixHQUFyRjtBQUNBLFFBQU1xUSxLQUFLLEdBQUcsS0FBS3ZRLE1BQUwsQ0FBWXVRLEtBQVosSUFBcUIsS0FBS3ZRLE1BQUwsQ0FBWXdRLFNBQS9DO0FBQ0EsU0FBT0QsS0FBSyxHQUFHRCxNQUFSLEdBQWlCLEtBQUtsUSxJQUFMLENBQVVlLFFBQWxDO0FBQ0QsQ0FKRCxDLENBTUE7QUFDQTs7O0FBQ0FwQixTQUFTLENBQUNpQixTQUFWLENBQW9CRyxRQUFwQixHQUErQixZQUFZO0FBQ3pDLFNBQU8sS0FBS2YsSUFBTCxDQUFVZSxRQUFWLElBQXNCLEtBQUtoQixLQUFMLENBQVdnQixRQUF4QztBQUNELENBRkQsQyxDQUlBOzs7QUFDQXBCLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0J5UCxhQUFwQixHQUFvQyxZQUFZO0FBQzlDLFFBQU1yUSxJQUFJLEdBQUdXLE1BQU0sQ0FBQytGLElBQVAsQ0FBWSxLQUFLMUcsSUFBakIsRUFBdUIrRSxNQUF2QixDQUE4QixDQUFDL0UsSUFBRCxFQUFPaUYsR0FBUCxLQUFlO0FBQ3hEO0FBQ0EsUUFBSSxDQUFDLDBCQUEwQnFMLElBQTFCLENBQStCckwsR0FBL0IsQ0FBTCxFQUEwQztBQUN4QyxhQUFPakYsSUFBSSxDQUFDaUYsR0FBRCxDQUFYO0FBQ0Q7O0FBQ0QsV0FBT2pGLElBQVA7QUFDRCxHQU5ZLEVBTVZaLFFBQVEsQ0FBQyxLQUFLWSxJQUFOLENBTkUsQ0FBYjtBQU9BLFNBQU9SLEtBQUssQ0FBQytRLE9BQU4sQ0FBY3RLLFNBQWQsRUFBeUJqRyxJQUF6QixDQUFQO0FBQ0QsQ0FURCxDLENBV0E7OztBQUNBTCxTQUFTLENBQUNpQixTQUFWLENBQW9CdUQsa0JBQXBCLEdBQXlDLFVBQVVILFNBQVYsRUFBcUI7QUFDNUQsUUFBTUUsYUFBYSxHQUFHekUsUUFBUSxDQUFDMkUsT0FBVCxDQUFpQkosU0FBakIsRUFBNEIsS0FBSy9ELFlBQWpDLENBQXRCO0FBQ0FVLEVBQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWSxLQUFLMUcsSUFBakIsRUFBdUIrRSxNQUF2QixDQUE4QixVQUFVL0UsSUFBVixFQUFnQmlGLEdBQWhCLEVBQXFCO0FBQ2pELFFBQUlBLEdBQUcsQ0FBQzFCLE9BQUosQ0FBWSxHQUFaLElBQW1CLENBQXZCLEVBQTBCO0FBQ3hCO0FBQ0EsWUFBTWlOLFdBQVcsR0FBR3ZMLEdBQUcsQ0FBQ3dMLEtBQUosQ0FBVSxHQUFWLENBQXBCO0FBQ0EsWUFBTUMsVUFBVSxHQUFHRixXQUFXLENBQUMsQ0FBRCxDQUE5QjtBQUNBLFVBQUlHLFNBQVMsR0FBR3pNLGFBQWEsQ0FBQzBNLEdBQWQsQ0FBa0JGLFVBQWxCLENBQWhCOztBQUNBLFVBQUksT0FBT0MsU0FBUCxLQUFxQixRQUF6QixFQUFtQztBQUNqQ0EsUUFBQUEsU0FBUyxHQUFHLEVBQVo7QUFDRDs7QUFDREEsTUFBQUEsU0FBUyxDQUFDSCxXQUFXLENBQUMsQ0FBRCxDQUFaLENBQVQsR0FBNEJ4USxJQUFJLENBQUNpRixHQUFELENBQWhDO0FBQ0FmLE1BQUFBLGFBQWEsQ0FBQzJNLEdBQWQsQ0FBa0JILFVBQWxCLEVBQThCQyxTQUE5QjtBQUNBLGFBQU8zUSxJQUFJLENBQUNpRixHQUFELENBQVg7QUFDRDs7QUFDRCxXQUFPakYsSUFBUDtBQUNELEdBZEQsRUFjR1osUUFBUSxDQUFDLEtBQUtZLElBQU4sQ0FkWDtBQWdCQWtFLEVBQUFBLGFBQWEsQ0FBQzJNLEdBQWQsQ0FBa0IsS0FBS1IsYUFBTCxFQUFsQjtBQUNBLFNBQU9uTSxhQUFQO0FBQ0QsQ0FwQkQ7O0FBc0JBdkUsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmtDLGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUksS0FBSzNCLFFBQUwsSUFBaUIsS0FBS0EsUUFBTCxDQUFjQSxRQUEvQixJQUEyQyxLQUFLckIsU0FBTCxLQUFtQixPQUFsRSxFQUEyRTtBQUN6RSxVQUFNbUQsSUFBSSxHQUFHLEtBQUs5QixRQUFMLENBQWNBLFFBQTNCOztBQUNBLFFBQUk4QixJQUFJLENBQUMyRCxRQUFULEVBQW1CO0FBQ2pCakcsTUFBQUEsTUFBTSxDQUFDK0YsSUFBUCxDQUFZekQsSUFBSSxDQUFDMkQsUUFBakIsRUFBMkJELE9BQTNCLENBQW1DVyxRQUFRLElBQUk7QUFDN0MsWUFBSXJFLElBQUksQ0FBQzJELFFBQUwsQ0FBY1UsUUFBZCxNQUE0QixJQUFoQyxFQUFzQztBQUNwQyxpQkFBT3JFLElBQUksQ0FBQzJELFFBQUwsQ0FBY1UsUUFBZCxDQUFQO0FBQ0Q7QUFDRixPQUpEOztBQUtBLFVBQUkzRyxNQUFNLENBQUMrRixJQUFQLENBQVl6RCxJQUFJLENBQUMyRCxRQUFqQixFQUEyQm5DLE1BQTNCLElBQXFDLENBQXpDLEVBQTRDO0FBQzFDLGVBQU94QixJQUFJLENBQUMyRCxRQUFaO0FBQ0Q7QUFDRjtBQUNGO0FBQ0YsQ0FkRDs7QUFnQkFqSCxTQUFTLENBQUNpQixTQUFWLENBQW9Cd08sdUJBQXBCLEdBQThDLFVBQVVqTyxRQUFWLEVBQW9CbkIsSUFBcEIsRUFBMEI7QUFDdEUsTUFBSThFLGdCQUFFZ0MsT0FBRixDQUFVLEtBQUt0RyxPQUFMLENBQWFxRSxzQkFBdkIsQ0FBSixFQUFvRDtBQUNsRCxXQUFPMUQsUUFBUDtBQUNEOztBQUNELFFBQU0yUCxvQkFBb0IsR0FBR3BSLFNBQVMsQ0FBQ3FSLHFCQUFWLENBQWdDLEtBQUs3USxTQUFyQyxDQUE3QjtBQUNBLE9BQUtNLE9BQUwsQ0FBYXFFLHNCQUFiLENBQW9DOEIsT0FBcEMsQ0FBNENaLFNBQVMsSUFBSTtBQUN2RCxVQUFNaUwsU0FBUyxHQUFHaFIsSUFBSSxDQUFDK0YsU0FBRCxDQUF0Qjs7QUFFQSxRQUFJLENBQUNwRixNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0ssUUFBckMsRUFBK0M0RSxTQUEvQyxDQUFMLEVBQWdFO0FBQzlENUUsTUFBQUEsUUFBUSxDQUFDNEUsU0FBRCxDQUFSLEdBQXNCaUwsU0FBdEI7QUFDRCxLQUxzRCxDQU92RDs7O0FBQ0EsUUFBSTdQLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixJQUF1QjVFLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixDQUFvQkcsSUFBL0MsRUFBcUQ7QUFDbkQsYUFBTy9FLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBZjs7QUFDQSxVQUFJK0ssb0JBQW9CLElBQUlFLFNBQVMsQ0FBQzlLLElBQVYsSUFBa0IsUUFBOUMsRUFBd0Q7QUFDdEQvRSxRQUFBQSxRQUFRLENBQUM0RSxTQUFELENBQVIsR0FBc0JpTCxTQUF0QjtBQUNEO0FBQ0Y7QUFDRixHQWREO0FBZUEsU0FBTzdQLFFBQVA7QUFDRCxDQXJCRDs7ZUF1QmV4QixTOztBQUNmc1IsTUFBTSxDQUFDQyxPQUFQLEdBQWlCdlIsU0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIFJlc3RXcml0ZSBlbmNhcHN1bGF0ZXMgZXZlcnl0aGluZyB3ZSBuZWVkIHRvIHJ1biBhbiBvcGVyYXRpb25cbi8vIHRoYXQgd3JpdGVzIHRvIHRoZSBkYXRhYmFzZS5cbi8vIFRoaXMgY291bGQgYmUgZWl0aGVyIGEgXCJjcmVhdGVcIiBvciBhbiBcInVwZGF0ZVwiLlxuXG52YXIgU2NoZW1hQ29udHJvbGxlciA9IHJlcXVpcmUoJy4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xudmFyIGRlZXBjb3B5ID0gcmVxdWlyZSgnZGVlcGNvcHknKTtcblxuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xudmFyIGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xudmFyIHBhc3N3b3JkQ3J5cHRvID0gcmVxdWlyZSgnLi9wYXNzd29yZCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xudmFyIHRyaWdnZXJzID0gcmVxdWlyZSgnLi90cmlnZ2VycycpO1xudmFyIENsaWVudFNESyA9IHJlcXVpcmUoJy4vQ2xpZW50U0RLJyk7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4vUmVzdFF1ZXJ5JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcblxuLy8gcXVlcnkgYW5kIGRhdGEgYXJlIGJvdGggcHJvdmlkZWQgaW4gUkVTVCBBUEkgZm9ybWF0LiBTbyBkYXRhXG4vLyB0eXBlcyBhcmUgZW5jb2RlZCBieSBwbGFpbiBvbGQgb2JqZWN0cy5cbi8vIElmIHF1ZXJ5IGlzIG51bGwsIHRoaXMgaXMgYSBcImNyZWF0ZVwiIGFuZCB0aGUgZGF0YSBpbiBkYXRhIHNob3VsZCBiZVxuLy8gY3JlYXRlZC5cbi8vIE90aGVyd2lzZSB0aGlzIGlzIGFuIFwidXBkYXRlXCIgLSB0aGUgb2JqZWN0IG1hdGNoaW5nIHRoZSBxdWVyeVxuLy8gc2hvdWxkIGdldCB1cGRhdGVkIHdpdGggZGF0YS5cbi8vIFJlc3RXcml0ZSB3aWxsIGhhbmRsZSBvYmplY3RJZCwgY3JlYXRlZEF0LCBhbmQgdXBkYXRlZEF0IGZvclxuLy8gZXZlcnl0aGluZy4gSXQgYWxzbyBrbm93cyB0byB1c2UgdHJpZ2dlcnMgYW5kIHNwZWNpYWwgbW9kaWZpY2F0aW9uc1xuLy8gZm9yIHRoZSBfVXNlciBjbGFzcy5cbmZ1bmN0aW9uIFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcXVlcnksIGRhdGEsIG9yaWdpbmFsRGF0YSwgY2xpZW50U0RLLCBjb250ZXh0LCBhY3Rpb24pIHtcbiAgaWYgKGF1dGguaXNSZWFkT25seSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAnQ2Fubm90IHBlcmZvcm0gYSB3cml0ZSBvcGVyYXRpb24gd2hlbiB1c2luZyByZWFkT25seU1hc3RlcktleSdcbiAgICApO1xuICB9XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmF1dGggPSBhdXRoO1xuICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgdGhpcy5jbGllbnRTREsgPSBjbGllbnRTREs7XG4gIHRoaXMuc3RvcmFnZSA9IHt9O1xuICB0aGlzLnJ1bk9wdGlvbnMgPSB7fTtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dCB8fCB7fTtcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgdGhpcy5ydW5PcHRpb25zLmFjdGlvbiA9IGFjdGlvbjtcbiAgfVxuXG4gIGlmICghcXVlcnkpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYWxsb3dDdXN0b21PYmplY3RJZCkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCAnb2JqZWN0SWQnKSAmJiAhZGF0YS5vYmplY3RJZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuTUlTU0lOR19PQkpFQ1RfSUQsXG4gICAgICAgICAgJ29iamVjdElkIG11c3Qgbm90IGJlIGVtcHR5LCBudWxsIG9yIHVuZGVmaW5lZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGEub2JqZWN0SWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsICdvYmplY3RJZCBpcyBhbiBpbnZhbGlkIGZpZWxkIG5hbWUuJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5pZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgJ2lkIGlzIGFuIGludmFsaWQgZmllbGQgbmFtZS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXaGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGUsIHRoaXMucmVzcG9uc2UgbWF5IGhhdmUgc2V2ZXJhbFxuICAvLyBmaWVsZHMuXG4gIC8vIHJlc3BvbnNlOiB0aGUgYWN0dWFsIGRhdGEgdG8gYmUgcmV0dXJuZWRcbiAgLy8gc3RhdHVzOiB0aGUgaHR0cCBzdGF0dXMgY29kZS4gaWYgbm90IHByZXNlbnQsIHRyZWF0ZWQgbGlrZSBhIDIwMFxuICAvLyBsb2NhdGlvbjogdGhlIGxvY2F0aW9uIGhlYWRlci4gaWYgbm90IHByZXNlbnQsIG5vIGxvY2F0aW9uIGhlYWRlclxuICB0aGlzLnJlc3BvbnNlID0gbnVsbDtcblxuICAvLyBQcm9jZXNzaW5nIHRoaXMgb3BlcmF0aW9uIG1heSBtdXRhdGUgb3VyIGRhdGEsIHNvIHdlIG9wZXJhdGUgb24gYVxuICAvLyBjb3B5XG4gIHRoaXMucXVlcnkgPSBkZWVwY29weShxdWVyeSk7XG4gIHRoaXMuZGF0YSA9IGRlZXBjb3B5KGRhdGEpO1xuICAvLyBXZSBuZXZlciBjaGFuZ2Ugb3JpZ2luYWxEYXRhLCBzbyB3ZSBkbyBub3QgbmVlZCBhIGRlZXAgY29weVxuICB0aGlzLm9yaWdpbmFsRGF0YSA9IG9yaWdpbmFsRGF0YTtcblxuICAvLyBUaGUgdGltZXN0YW1wIHdlJ2xsIHVzZSBmb3IgdGhpcyB3aG9sZSBvcGVyYXRpb25cbiAgdGhpcy51cGRhdGVkQXQgPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpLmlzbztcblxuICAvLyBTaGFyZWQgU2NoZW1hQ29udHJvbGxlciB0byBiZSByZXVzZWQgdG8gcmVkdWNlIHRoZSBudW1iZXIgb2YgbG9hZFNjaGVtYSgpIGNhbGxzIHBlciByZXF1ZXN0XG4gIC8vIE9uY2Ugc2V0IHRoZSBzY2hlbWFEYXRhIHNob3VsZCBiZSBpbW11dGFibGVcbiAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIgPSBudWxsO1xufVxuXG4vLyBBIGNvbnZlbmllbnQgbWV0aG9kIHRvIHBlcmZvcm0gYWxsIHRoZSBzdGVwcyBvZiBwcm9jZXNzaW5nIHRoZVxuLy8gd3JpdGUsIGluIG9yZGVyLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlLCBzdGF0dXMsIGxvY2F0aW9ufSBvYmplY3QuXG4vLyBzdGF0dXMgYW5kIGxvY2F0aW9uIGFyZSBvcHRpb25hbC5cblJlc3RXcml0ZS5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlckFuZFJvbGVBQ0woKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5zdGFsbGF0aW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVTZXNzaW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUF1dGhEYXRhKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5CZWZvcmVTYXZlVHJpZ2dlcigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlRW1haWxSZXNldFRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlU2NoZW1hKCk7XG4gICAgfSlcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcbiAgICAgIHJldHVybiB0aGlzLnNldFJlcXVpcmVkRmllbGRzSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybVVzZXIoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmV4cGFuZEZpbGVzRm9yRXhpc3RpbmdPYmplY3RzKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5kZXN0cm95RHVwbGljYXRlZFNlc3Npb25zKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5EYXRhYmFzZU9wZXJhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZvbGxvd3VwKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5BZnRlclNhdmVUcmlnZ2VyKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jbGVhblVzZXJBdXRoRGF0YSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVzcG9uc2U7XG4gICAgfSk7XG59O1xuXG4vLyBVc2VzIHRoZSBBdXRoIG9iamVjdCB0byBnZXQgdGhlIGxpc3Qgb2Ygcm9sZXMsIGFkZHMgdGhlIHVzZXIgaWRcblJlc3RXcml0ZS5wcm90b3R5cGUuZ2V0VXNlckFuZFJvbGVBQ0wgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICB0aGlzLnJ1bk9wdGlvbnMuYWNsID0gWycqJ107XG5cbiAgaWYgKHRoaXMuYXV0aC51c2VyKSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aC5nZXRVc2VyUm9sZXMoKS50aGVuKHJvbGVzID0+IHtcbiAgICAgIHRoaXMucnVuT3B0aW9ucy5hY2wgPSB0aGlzLnJ1bk9wdGlvbnMuYWNsLmNvbmNhdChyb2xlcywgW3RoaXMuYXV0aC51c2VyLmlkXSk7XG4gICAgICByZXR1cm47XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG4vLyBWYWxpZGF0ZXMgdGhpcyBvcGVyYXRpb24gYWdhaW5zdCB0aGUgYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIGNvbmZpZy5cblJlc3RXcml0ZS5wcm90b3R5cGUudmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAoXG4gICAgdGhpcy5jb25maWcuYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uID09PSBmYWxzZSAmJlxuICAgICF0aGlzLmF1dGguaXNNYXN0ZXIgJiZcbiAgICBTY2hlbWFDb250cm9sbGVyLnN5c3RlbUNsYXNzZXMuaW5kZXhPZih0aGlzLmNsYXNzTmFtZSkgPT09IC0xXG4gICkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmxvYWRTY2hlbWEoKVxuICAgICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmhhc0NsYXNzKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGhhc0NsYXNzID0+IHtcbiAgICAgICAgaWYgKGhhc0NsYXNzICE9PSB0cnVlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgICAgICdUaGlzIHVzZXIgaXMgbm90IGFsbG93ZWQgdG8gYWNjZXNzICcgKyAnbm9uLWV4aXN0ZW50IGNsYXNzOiAnICsgdGhpcy5jbGFzc05hbWVcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn07XG5cbi8vIFZhbGlkYXRlcyB0aGlzIG9wZXJhdGlvbiBhZ2FpbnN0IHRoZSBzY2hlbWEuXG5SZXN0V3JpdGUucHJvdG90eXBlLnZhbGlkYXRlU2NoZW1hID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudmFsaWRhdGVPYmplY3QoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdGhpcy5kYXRhLFxuICAgIHRoaXMucXVlcnksXG4gICAgdGhpcy5ydW5PcHRpb25zXG4gICk7XG59O1xuXG4vLyBSdW5zIGFueSBiZWZvcmVTYXZlIHRyaWdnZXJzIGFnYWluc3QgdGhpcyBvcGVyYXRpb24uXG4vLyBBbnkgY2hhbmdlIGxlYWRzIHRvIG91ciBkYXRhIGJlaW5nIG11dGF0ZWQuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkJlZm9yZVNhdmVUcmlnZ2VyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2JlZm9yZVNhdmUnIHRyaWdnZXIgZm9yIHRoaXMgY2xhc3MuXG4gIGlmIChcbiAgICAhdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyh0aGlzLmNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZSwgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZClcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gQ2xvdWQgY29kZSBnZXRzIGEgYml0IG9mIGV4dHJhIGRhdGEgZm9yIGl0cyBvYmplY3RzXG4gIHZhciBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIGV4dHJhRGF0YS5vYmplY3RJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gIH1cblxuICBsZXQgb3JpZ2luYWxPYmplY3QgPSBudWxsO1xuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdGhpcy5idWlsZFVwZGF0ZWRPYmplY3QoZXh0cmFEYXRhKTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIC8vIFRoaXMgaXMgYW4gdXBkYXRlIGZvciBleGlzdGluZyBvYmplY3QuXG4gICAgb3JpZ2luYWxPYmplY3QgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdGhpcy5vcmlnaW5hbERhdGEpO1xuICB9XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gQmVmb3JlIGNhbGxpbmcgdGhlIHRyaWdnZXIsIHZhbGlkYXRlIHRoZSBwZXJtaXNzaW9ucyBmb3IgdGhlIHNhdmUgb3BlcmF0aW9uXG4gICAgICBsZXQgZGF0YWJhc2VQcm9taXNlID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZvciB1cGRhdGluZ1xuICAgICAgICBkYXRhYmFzZVByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgdGhpcy5xdWVyeSxcbiAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgdGhpcy5ydW5PcHRpb25zLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZvciBjcmVhdGluZ1xuICAgICAgICBkYXRhYmFzZVByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5jcmVhdGUoXG4gICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgdGhpcy5kYXRhLFxuICAgICAgICAgIHRoaXMucnVuT3B0aW9ucyxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBJbiB0aGUgY2FzZSB0aGF0IHRoZXJlIGlzIG5vIHBlcm1pc3Npb24gZm9yIHRoZSBvcGVyYXRpb24sIGl0IHRocm93cyBhbiBlcnJvclxuICAgICAgcmV0dXJuIGRhdGFiYXNlUHJvbWlzZS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmICghcmVzdWx0IHx8IHJlc3VsdC5sZW5ndGggPD0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTYXZlLFxuICAgICAgICB0aGlzLmF1dGgsXG4gICAgICAgIHVwZGF0ZWRPYmplY3QsXG4gICAgICAgIG9yaWdpbmFsT2JqZWN0LFxuICAgICAgICB0aGlzLmNvbmZpZyxcbiAgICAgICAgdGhpcy5jb250ZXh0XG4gICAgICApO1xuICAgIH0pXG4gICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLm9iamVjdCkge1xuICAgICAgICB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlciA9IF8ucmVkdWNlKFxuICAgICAgICAgIHJlc3BvbnNlLm9iamVjdCxcbiAgICAgICAgICAocmVzdWx0LCB2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoIV8uaXNFcXVhbCh0aGlzLmRhdGFba2V5XSwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgW11cbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5kYXRhID0gcmVzcG9uc2Uub2JqZWN0O1xuICAgICAgICAvLyBXZSBzaG91bGQgZGVsZXRlIHRoZSBvYmplY3RJZCBmb3IgYW4gdXBkYXRlIHdyaXRlXG4gICAgICAgIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5kYXRhLm9iamVjdElkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkJlZm9yZUxvZ2luVHJpZ2dlciA9IGFzeW5jIGZ1bmN0aW9uICh1c2VyRGF0YSkge1xuICAvLyBBdm9pZCBkb2luZyBhbnkgc2V0dXAgZm9yIHRyaWdnZXJzIGlmIHRoZXJlIGlzIG5vICdiZWZvcmVMb2dpbicgdHJpZ2dlclxuICBpZiAoXG4gICAgIXRyaWdnZXJzLnRyaWdnZXJFeGlzdHModGhpcy5jbGFzc05hbWUsIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUxvZ2luLCB0aGlzLmNvbmZpZy5hcHBsaWNhdGlvbklkKVxuICApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBDbG91ZCBjb2RlIGdldHMgYSBiaXQgb2YgZXh0cmEgZGF0YSBmb3IgaXRzIG9iamVjdHNcbiAgY29uc3QgZXh0cmFEYXRhID0geyBjbGFzc05hbWU6IHRoaXMuY2xhc3NOYW1lIH07XG5cbiAgLy8gRXhwYW5kIGZpbGUgb2JqZWN0c1xuICB0aGlzLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdCh0aGlzLmNvbmZpZywgdXNlckRhdGEpO1xuXG4gIGNvbnN0IHVzZXIgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdXNlckRhdGEpO1xuXG4gIC8vIG5vIG5lZWQgdG8gcmV0dXJuIGEgcmVzcG9uc2VcbiAgYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUxvZ2luLFxuICAgIHRoaXMuYXV0aCxcbiAgICB1c2VyLFxuICAgIG51bGwsXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5jb250ZXh0XG4gICk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLnNldFJlcXVpcmVkRmllbGRzSWZOZWVkZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIuZ2V0QWxsQ2xhc3NlcygpLnRoZW4oYWxsQ2xhc3NlcyA9PiB7XG4gICAgICBjb25zdCBzY2hlbWEgPSBhbGxDbGFzc2VzLmZpbmQob25lQ2xhc3MgPT4gb25lQ2xhc3MuY2xhc3NOYW1lID09PSB0aGlzLmNsYXNzTmFtZSk7XG4gICAgICBjb25zdCBzZXRSZXF1aXJlZEZpZWxkSWZOZWVkZWQgPSAoZmllbGROYW1lLCBzZXREZWZhdWx0KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPT09IG51bGwgfHxcbiAgICAgICAgICB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gJycgfHxcbiAgICAgICAgICAodHlwZW9mIHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSAnb2JqZWN0JyAmJiB0aGlzLmRhdGFbZmllbGROYW1lXS5fX29wID09PSAnRGVsZXRlJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgc2V0RGVmYXVsdCAmJlxuICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdICYmXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uZGVmYXVsdFZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICh0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgICh0eXBlb2YgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPT09ICdvYmplY3QnICYmIHRoaXMuZGF0YVtmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YVtmaWVsZE5hbWVdID0gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLmRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyID0gdGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIgfHwgW107XG4gICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIuaW5kZXhPZihmaWVsZE5hbWUpIDwgMCkge1xuICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnJlcXVpcmVkID09PSB0cnVlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgYCR7ZmllbGROYW1lfSBpcyByZXF1aXJlZGApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gQWRkIGRlZmF1bHQgZmllbGRzXG4gICAgICB0aGlzLmRhdGEudXBkYXRlZEF0ID0gdGhpcy51cGRhdGVkQXQ7XG4gICAgICBpZiAoIXRoaXMucXVlcnkpIHtcbiAgICAgICAgdGhpcy5kYXRhLmNyZWF0ZWRBdCA9IHRoaXMudXBkYXRlZEF0O1xuXG4gICAgICAgIC8vIE9ubHkgYXNzaWduIG5ldyBvYmplY3RJZCBpZiB3ZSBhcmUgY3JlYXRpbmcgbmV3IG9iamVjdFxuICAgICAgICBpZiAoIXRoaXMuZGF0YS5vYmplY3RJZCkge1xuICAgICAgICAgIHRoaXMuZGF0YS5vYmplY3RJZCA9IGNyeXB0b1V0aWxzLm5ld09iamVjdElkKHRoaXMuY29uZmlnLm9iamVjdElkU2l6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjaGVtYSkge1xuICAgICAgICAgIE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgIHNldFJlcXVpcmVkRmllbGRJZk5lZWRlZChmaWVsZE5hbWUsIHRydWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNjaGVtYSkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICBzZXRSZXF1aXJlZEZpZWxkSWZOZWVkZWQoZmllbGROYW1lLCBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cbi8vIFRyYW5zZm9ybXMgYXV0aCBkYXRhIGZvciBhIHVzZXIgb2JqZWN0LlxuLy8gRG9lcyBub3RoaW5nIGlmIHRoaXMgaXNuJ3QgYSB1c2VyIG9iamVjdC5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB3aGVuIHdlJ3JlIGRvbmUgaWYgaXQgY2FuJ3QgZmluaXNoIHRoaXMgdGljay5cblJlc3RXcml0ZS5wcm90b3R5cGUudmFsaWRhdGVBdXRoRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCF0aGlzLnF1ZXJ5ICYmICF0aGlzLmRhdGEuYXV0aERhdGEpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuZGF0YS51c2VybmFtZSAhPT0gJ3N0cmluZycgfHwgXy5pc0VtcHR5KHRoaXMuZGF0YS51c2VybmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5VU0VSTkFNRV9NSVNTSU5HLCAnYmFkIG9yIG1pc3NpbmcgdXNlcm5hbWUnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0aGlzLmRhdGEucGFzc3dvcmQgIT09ICdzdHJpbmcnIHx8IF8uaXNFbXB0eSh0aGlzLmRhdGEucGFzc3dvcmQpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUEFTU1dPUkRfTUlTU0lORywgJ3Bhc3N3b3JkIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgICh0aGlzLmRhdGEuYXV0aERhdGEgJiYgIU9iamVjdC5rZXlzKHRoaXMuZGF0YS5hdXRoRGF0YSkubGVuZ3RoKSB8fFxuICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5kYXRhLCAnYXV0aERhdGEnKVxuICApIHtcbiAgICAvLyBIYW5kbGUgc2F2aW5nIGF1dGhEYXRhIHRvIHt9IG9yIGlmIGF1dGhEYXRhIGRvZXNuJ3QgZXhpc3RcbiAgICByZXR1cm47XG4gIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuZGF0YSwgJ2F1dGhEYXRhJykgJiYgIXRoaXMuZGF0YS5hdXRoRGF0YSkge1xuICAgIC8vIEhhbmRsZSBzYXZpbmcgYXV0aERhdGEgdG8gbnVsbFxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLlVOU1VQUE9SVEVEX1NFUlZJQ0UsXG4gICAgICAnVGhpcyBhdXRoZW50aWNhdGlvbiBtZXRob2QgaXMgdW5zdXBwb3J0ZWQuJ1xuICAgICk7XG4gIH1cblxuICB2YXIgYXV0aERhdGEgPSB0aGlzLmRhdGEuYXV0aERhdGE7XG4gIHZhciBwcm92aWRlcnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSk7XG4gIGlmIChwcm92aWRlcnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGNhbkhhbmRsZUF1dGhEYXRhID0gcHJvdmlkZXJzLnJlZHVjZSgoY2FuSGFuZGxlLCBwcm92aWRlcikgPT4ge1xuICAgICAgdmFyIHByb3ZpZGVyQXV0aERhdGEgPSBhdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICB2YXIgaGFzVG9rZW4gPSBwcm92aWRlckF1dGhEYXRhICYmIHByb3ZpZGVyQXV0aERhdGEuaWQ7XG4gICAgICByZXR1cm4gY2FuSGFuZGxlICYmIChoYXNUb2tlbiB8fCBwcm92aWRlckF1dGhEYXRhID09IG51bGwpO1xuICAgIH0sIHRydWUpO1xuICAgIGlmIChjYW5IYW5kbGVBdXRoRGF0YSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQXV0aERhdGEoYXV0aERhdGEpO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgUGFyc2UuRXJyb3IuVU5TVVBQT1JURURfU0VSVklDRSxcbiAgICAnVGhpcyBhdXRoZW50aWNhdGlvbiBtZXRob2QgaXMgdW5zdXBwb3J0ZWQuJ1xuICApO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24gPSBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgY29uc3QgdmFsaWRhdGlvbnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSkubWFwKHByb3ZpZGVyID0+IHtcbiAgICBpZiAoYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGNvbnN0IHZhbGlkYXRlQXV0aERhdGEgPSB0aGlzLmNvbmZpZy5hdXRoRGF0YU1hbmFnZXIuZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIocHJvdmlkZXIpO1xuICAgIGlmICghdmFsaWRhdGVBdXRoRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5VTlNVUFBPUlRFRF9TRVJWSUNFLFxuICAgICAgICAnVGhpcyBhdXRoZW50aWNhdGlvbiBtZXRob2QgaXMgdW5zdXBwb3J0ZWQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGFbcHJvdmlkZXJdKTtcbiAgfSk7XG4gIHJldHVybiBQcm9taXNlLmFsbCh2YWxpZGF0aW9ucyk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmZpbmRVc2Vyc1dpdGhBdXRoRGF0YSA9IGZ1bmN0aW9uIChhdXRoRGF0YSkge1xuICBjb25zdCBwcm92aWRlcnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSk7XG4gIGNvbnN0IHF1ZXJ5ID0gcHJvdmlkZXJzXG4gICAgLnJlZHVjZSgobWVtbywgcHJvdmlkZXIpID0+IHtcbiAgICAgIGlmICghYXV0aERhdGFbcHJvdmlkZXJdKSB7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgfVxuICAgICAgY29uc3QgcXVlcnlLZXkgPSBgYXV0aERhdGEuJHtwcm92aWRlcn0uaWRgO1xuICAgICAgY29uc3QgcXVlcnkgPSB7fTtcbiAgICAgIHF1ZXJ5W3F1ZXJ5S2V5XSA9IGF1dGhEYXRhW3Byb3ZpZGVyXS5pZDtcbiAgICAgIG1lbW8ucHVzaChxdWVyeSk7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9LCBbXSlcbiAgICAuZmlsdGVyKHEgPT4ge1xuICAgICAgcmV0dXJuIHR5cGVvZiBxICE9PSAndW5kZWZpbmVkJztcbiAgICB9KTtcblxuICBsZXQgZmluZFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoW10pO1xuICBpZiAocXVlcnkubGVuZ3RoID4gMCkge1xuICAgIGZpbmRQcm9taXNlID0gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCh0aGlzLmNsYXNzTmFtZSwgeyAkb3I6IHF1ZXJ5IH0sIHt9KTtcbiAgfVxuXG4gIHJldHVybiBmaW5kUHJvbWlzZTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuZmlsdGVyZWRPYmplY3RzQnlBQ0wgPSBmdW5jdGlvbiAob2JqZWN0cykge1xuICBpZiAodGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIG9iamVjdHM7XG4gIH1cbiAgcmV0dXJuIG9iamVjdHMuZmlsdGVyKG9iamVjdCA9PiB7XG4gICAgaWYgKCFvYmplY3QuQUNMKSB7XG4gICAgICByZXR1cm4gdHJ1ZTsgLy8gbGVnYWN5IHVzZXJzIHRoYXQgaGF2ZSBubyBBQ0wgZmllbGQgb24gdGhlbVxuICAgIH1cbiAgICAvLyBSZWd1bGFyIHVzZXJzIHRoYXQgaGF2ZSBiZWVuIGxvY2tlZCBvdXQuXG4gICAgcmV0dXJuIG9iamVjdC5BQ0wgJiYgT2JqZWN0LmtleXMob2JqZWN0LkFDTCkubGVuZ3RoID4gMDtcbiAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUF1dGhEYXRhID0gZnVuY3Rpb24gKGF1dGhEYXRhKSB7XG4gIGxldCByZXN1bHRzO1xuICByZXR1cm4gdGhpcy5maW5kVXNlcnNXaXRoQXV0aERhdGEoYXV0aERhdGEpLnRoZW4oYXN5bmMgciA9PiB7XG4gICAgcmVzdWx0cyA9IHRoaXMuZmlsdGVyZWRPYmplY3RzQnlBQ0wocik7XG5cbiAgICBpZiAocmVzdWx0cy5sZW5ndGggPT0gMSkge1xuICAgICAgdGhpcy5zdG9yYWdlWydhdXRoUHJvdmlkZXInXSA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKS5qb2luKCcsJyk7XG5cbiAgICAgIGNvbnN0IHVzZXJSZXN1bHQgPSByZXN1bHRzWzBdO1xuICAgICAgY29uc3QgbXV0YXRlZEF1dGhEYXRhID0ge307XG4gICAgICBPYmplY3Qua2V5cyhhdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyRGF0YSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgY29uc3QgdXNlckF1dGhEYXRhID0gdXNlclJlc3VsdC5hdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgIGlmICghXy5pc0VxdWFsKHByb3ZpZGVyRGF0YSwgdXNlckF1dGhEYXRhKSkge1xuICAgICAgICAgIG11dGF0ZWRBdXRoRGF0YVtwcm92aWRlcl0gPSBwcm92aWRlckRhdGE7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgaGFzTXV0YXRlZEF1dGhEYXRhID0gT2JqZWN0LmtleXMobXV0YXRlZEF1dGhEYXRhKS5sZW5ndGggIT09IDA7XG4gICAgICBsZXQgdXNlcklkO1xuICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICB1c2VySWQgPSB0aGlzLnF1ZXJ5Lm9iamVjdElkO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmF1dGggJiYgdGhpcy5hdXRoLnVzZXIgJiYgdGhpcy5hdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgdXNlcklkID0gdGhpcy5hdXRoLnVzZXIuaWQ7XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXJJZCB8fCB1c2VySWQgPT09IHVzZXJSZXN1bHQub2JqZWN0SWQpIHtcbiAgICAgICAgLy8gbm8gdXNlciBtYWtpbmcgdGhlIGNhbGxcbiAgICAgICAgLy8gT1IgdGhlIHVzZXIgbWFraW5nIHRoZSBjYWxsIGlzIHRoZSByaWdodCBvbmVcbiAgICAgICAgLy8gTG9naW4gd2l0aCBhdXRoIGRhdGFcbiAgICAgICAgZGVsZXRlIHJlc3VsdHNbMF0ucGFzc3dvcmQ7XG5cbiAgICAgICAgLy8gbmVlZCB0byBzZXQgdGhlIG9iamVjdElkIGZpcnN0IG90aGVyd2lzZSBsb2NhdGlvbiBoYXMgdHJhaWxpbmcgdW5kZWZpbmVkXG4gICAgICAgIHRoaXMuZGF0YS5vYmplY3RJZCA9IHVzZXJSZXN1bHQub2JqZWN0SWQ7XG5cbiAgICAgICAgaWYgKCF0aGlzLnF1ZXJ5IHx8ICF0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgICAgICAgLy8gdGhpcyBhIGxvZ2luIGNhbGwsIG5vIHVzZXJJZCBwYXNzZWRcbiAgICAgICAgICB0aGlzLnJlc3BvbnNlID0ge1xuICAgICAgICAgICAgcmVzcG9uc2U6IHVzZXJSZXN1bHQsXG4gICAgICAgICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbigpLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gUnVuIGJlZm9yZUxvZ2luIGhvb2sgYmVmb3JlIHN0b3JpbmcgYW55IHVwZGF0ZXNcbiAgICAgICAgICAvLyB0byBhdXRoRGF0YSBvbiB0aGUgZGI7IGNoYW5nZXMgdG8gdXNlclJlc3VsdFxuICAgICAgICAgIC8vIHdpbGwgYmUgaWdub3JlZC5cbiAgICAgICAgICBhd2FpdCB0aGlzLnJ1bkJlZm9yZUxvZ2luVHJpZ2dlcihkZWVwY29weSh1c2VyUmVzdWx0KSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB3ZSBkaWRuJ3QgY2hhbmdlIHRoZSBhdXRoIGRhdGEsIGp1c3Qga2VlcCBnb2luZ1xuICAgICAgICBpZiAoIWhhc011dGF0ZWRBdXRoRGF0YSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBXZSBoYXZlIGF1dGhEYXRhIHRoYXQgaXMgdXBkYXRlZCBvbiBsb2dpblxuICAgICAgICAvLyB0aGF0IGNhbiBoYXBwZW4gd2hlbiB0b2tlbiBhcmUgcmVmcmVzaGVkLFxuICAgICAgICAvLyBXZSBzaG91bGQgdXBkYXRlIHRoZSB0b2tlbiBhbmQgbGV0IHRoZSB1c2VyIGluXG4gICAgICAgIC8vIFdlIHNob3VsZCBvbmx5IGNoZWNrIHRoZSBtdXRhdGVkIGtleXNcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQXV0aERhdGFWYWxpZGF0aW9uKG11dGF0ZWRBdXRoRGF0YSkudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgLy8gSUYgd2UgaGF2ZSBhIHJlc3BvbnNlLCB3ZSdsbCBza2lwIHRoZSBkYXRhYmFzZSBvcGVyYXRpb24gLyBiZWZvcmVTYXZlIC8gYWZ0ZXJTYXZlIGV0Yy4uLlxuICAgICAgICAgIC8vIHdlIG5lZWQgdG8gc2V0IGl0IHVwIHRoZXJlLlxuICAgICAgICAgIC8vIFdlIGFyZSBzdXBwb3NlZCB0byBoYXZlIGEgcmVzcG9uc2Ugb25seSBvbiBMT0dJTiB3aXRoIGF1dGhEYXRhLCBzbyB3ZSBza2lwIHRob3NlXG4gICAgICAgICAgLy8gSWYgd2UncmUgbm90IGxvZ2dpbmcgaW4sIGJ1dCBqdXN0IHVwZGF0aW5nIHRoZSBjdXJyZW50IHVzZXIsIHdlIGNhbiBzYWZlbHkgc2tpcCB0aGF0IHBhcnRcbiAgICAgICAgICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgICAgICAgICAgLy8gQXNzaWduIHRoZSBuZXcgYXV0aERhdGEgaW4gdGhlIHJlc3BvbnNlXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhtdXRhdGVkQXV0aERhdGEpLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlLmF1dGhEYXRhW3Byb3ZpZGVyXSA9IG11dGF0ZWRBdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUnVuIHRoZSBEQiB1cGRhdGUgZGlyZWN0bHksIGFzICdtYXN0ZXInXG4gICAgICAgICAgICAvLyBKdXN0IHVwZGF0ZSB0aGUgYXV0aERhdGEgcGFydFxuICAgICAgICAgICAgLy8gVGhlbiB3ZSdyZSBnb29kIGZvciB0aGUgdXNlciwgZWFybHkgZXhpdCBvZiBzb3J0c1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgIHsgb2JqZWN0SWQ6IHRoaXMuZGF0YS5vYmplY3RJZCB9LFxuICAgICAgICAgICAgICB7IGF1dGhEYXRhOiBtdXRhdGVkQXV0aERhdGEgfSxcbiAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodXNlcklkKSB7XG4gICAgICAgIC8vIFRyeWluZyB0byB1cGRhdGUgYXV0aCBkYXRhIGJ1dCB1c2Vyc1xuICAgICAgICAvLyBhcmUgZGlmZmVyZW50XG4gICAgICAgIGlmICh1c2VyUmVzdWx0Lm9iamVjdElkICE9PSB1c2VySWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuQUNDT1VOVF9BTFJFQURZX0xJTktFRCwgJ3RoaXMgYXV0aCBpcyBhbHJlYWR5IHVzZWQnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBhdXRoIGRhdGEgd2FzIG11dGF0ZWQsIGp1c3Qga2VlcCBnb2luZ1xuICAgICAgICBpZiAoIWhhc011dGF0ZWRBdXRoRGF0YSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24oYXV0aERhdGEpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMSkge1xuICAgICAgICAvLyBNb3JlIHRoYW4gMSB1c2VyIHdpdGggdGhlIHBhc3NlZCBpZCdzXG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5BQ0NPVU5UX0FMUkVBRFlfTElOS0VELCAndGhpcyBhdXRoIGlzIGFscmVhZHkgdXNlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn07XG5cbi8vIFRoZSBub24tdGhpcmQtcGFydHkgcGFydHMgb2YgVXNlciB0cmFuc2Zvcm1hdGlvblxuUmVzdFdyaXRlLnByb3RvdHlwZS50cmFuc2Zvcm1Vc2VyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuXG4gIGlmICh0aGlzLmNsYXNzTmFtZSAhPT0gJ19Vc2VyJykge1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgaWYgKCF0aGlzLmF1dGguaXNNYXN0ZXIgJiYgJ2VtYWlsVmVyaWZpZWQnIGluIHRoaXMuZGF0YSkge1xuICAgIGNvbnN0IGVycm9yID0gYENsaWVudHMgYXJlbid0IGFsbG93ZWQgdG8gbWFudWFsbHkgdXBkYXRlIGVtYWlsIHZlcmlmaWNhdGlvbi5gO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gIH1cblxuICAvLyBEbyBub3QgY2xlYW51cCBzZXNzaW9uIGlmIG9iamVjdElkIGlzIG5vdCBzZXRcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5vYmplY3RJZCgpKSB7XG4gICAgLy8gSWYgd2UncmUgdXBkYXRpbmcgYSBfVXNlciBvYmplY3QsIHdlIG5lZWQgdG8gY2xlYXIgb3V0IHRoZSBjYWNoZSBmb3IgdGhhdCB1c2VyLiBGaW5kIGFsbCB0aGVpclxuICAgIC8vIHNlc3Npb24gdG9rZW5zLCBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgY2FjaGUuXG4gICAgcHJvbWlzZSA9IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSwgJ19TZXNzaW9uJywge1xuICAgICAgdXNlcjoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpLFxuICAgICAgfSxcbiAgICB9KVxuICAgICAgLmV4ZWN1dGUoKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIHJlc3VsdHMucmVzdWx0cy5mb3JFYWNoKHNlc3Npb24gPT5cbiAgICAgICAgICB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXIudXNlci5kZWwoc2Vzc2lvbi5zZXNzaW9uVG9rZW4pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBwcm9taXNlXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gVHJhbnNmb3JtIHRoZSBwYXNzd29yZFxuICAgICAgaWYgKHRoaXMuZGF0YS5wYXNzd29yZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGlnbm9yZSBvbmx5IGlmIHVuZGVmaW5lZC4gc2hvdWxkIHByb2NlZWQgaWYgZW1wdHkgKCcnKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgICAgIHRoaXMuc3RvcmFnZVsnY2xlYXJTZXNzaW9ucyddID0gdHJ1ZTtcbiAgICAgICAgLy8gR2VuZXJhdGUgYSBuZXcgc2Vzc2lvbiBvbmx5IGlmIHRoZSB1c2VyIHJlcXVlc3RlZFxuICAgICAgICBpZiAoIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgICAgICAgIHRoaXMuc3RvcmFnZVsnZ2VuZXJhdGVOZXdTZXNzaW9uJ10gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5KCkudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBwYXNzd29yZENyeXB0by5oYXNoKHRoaXMuZGF0YS5wYXNzd29yZCkudGhlbihoYXNoZWRQYXNzd29yZCA9PiB7XG4gICAgICAgICAgdGhpcy5kYXRhLl9oYXNoZWRfcGFzc3dvcmQgPSBoYXNoZWRQYXNzd29yZDtcbiAgICAgICAgICBkZWxldGUgdGhpcy5kYXRhLnBhc3N3b3JkO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlVXNlck5hbWUoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUVtYWlsKCk7XG4gICAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLl92YWxpZGF0ZVVzZXJOYW1lID0gZnVuY3Rpb24gKCkge1xuICAvLyBDaGVjayBmb3IgdXNlcm5hbWUgdW5pcXVlbmVzc1xuICBpZiAoIXRoaXMuZGF0YS51c2VybmFtZSkge1xuICAgIGlmICghdGhpcy5xdWVyeSkge1xuICAgICAgdGhpcy5kYXRhLnVzZXJuYW1lID0gY3J5cHRvVXRpbHMucmFuZG9tU3RyaW5nKDI1KTtcbiAgICAgIHRoaXMucmVzcG9uc2VTaG91bGRIYXZlVXNlcm5hbWUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLypcbiAgICBVc2VybmFtZXMgc2hvdWxkIGJlIHVuaXF1ZSB3aGVuIGNvbXBhcmVkIGNhc2UgaW5zZW5zaXRpdmVseVxuXG4gICAgVXNlcnMgc2hvdWxkIGJlIGFibGUgdG8gbWFrZSBjYXNlIHNlbnNpdGl2ZSB1c2VybmFtZXMgYW5kXG4gICAgbG9naW4gdXNpbmcgdGhlIGNhc2UgdGhleSBlbnRlcmVkLiAgSS5lLiAnU25vb3B5JyBzaG91bGQgcHJlY2x1ZGVcbiAgICAnc25vb3B5JyBhcyBhIHZhbGlkIHVzZXJuYW1lLlxuICAqL1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAuZmluZChcbiAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAge1xuICAgICAgICB1c2VybmFtZTogdGhpcy5kYXRhLnVzZXJuYW1lLFxuICAgICAgICBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgfSxcbiAgICAgIHsgbGltaXQ6IDEsIGNhc2VJbnNlbnNpdGl2ZTogdHJ1ZSB9LFxuICAgICAge30sXG4gICAgICB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlclxuICAgIClcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLlVTRVJOQU1FX1RBS0VOLFxuICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHVzZXJuYW1lLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9KTtcbn07XG5cbi8qXG4gIEFzIHdpdGggdXNlcm5hbWVzLCBQYXJzZSBzaG91bGQgbm90IGFsbG93IGNhc2UgaW5zZW5zaXRpdmUgY29sbGlzaW9ucyBvZiBlbWFpbC5cbiAgdW5saWtlIHdpdGggdXNlcm5hbWVzICh3aGljaCBjYW4gaGF2ZSBjYXNlIGluc2Vuc2l0aXZlIGNvbGxpc2lvbnMgaW4gdGhlIGNhc2Ugb2ZcbiAgYXV0aCBhZGFwdGVycyksIGVtYWlscyBzaG91bGQgbmV2ZXIgaGF2ZSBhIGNhc2UgaW5zZW5zaXRpdmUgY29sbGlzaW9uLlxuXG4gIFRoaXMgYmVoYXZpb3IgY2FuIGJlIGVuZm9yY2VkIHRocm91Z2ggYSBwcm9wZXJseSBjb25maWd1cmVkIGluZGV4IHNlZTpcbiAgaHR0cHM6Ly9kb2NzLm1vbmdvZGIuY29tL21hbnVhbC9jb3JlL2luZGV4LWNhc2UtaW5zZW5zaXRpdmUvI2NyZWF0ZS1hLWNhc2UtaW5zZW5zaXRpdmUtaW5kZXhcbiAgd2hpY2ggY291bGQgYmUgaW1wbGVtZW50ZWQgaW5zdGVhZCBvZiB0aGlzIGNvZGUgYmFzZWQgdmFsaWRhdGlvbi5cblxuICBHaXZlbiB0aGF0IHRoaXMgbG9va3VwIHNob3VsZCBiZSBhIHJlbGF0aXZlbHkgbG93IHVzZSBjYXNlIGFuZCB0aGF0IHRoZSBjYXNlIHNlbnNpdGl2ZVxuICB1bmlxdWUgaW5kZXggd2lsbCBiZSB1c2VkIGJ5IHRoZSBkYiBmb3IgdGhlIHF1ZXJ5LCB0aGlzIGlzIGFuIGFkZXF1YXRlIHNvbHV0aW9uLlxuKi9cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlRW1haWwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5kYXRhLmVtYWlsIHx8IHRoaXMuZGF0YS5lbWFpbC5fX29wID09PSAnRGVsZXRlJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBWYWxpZGF0ZSBiYXNpYyBlbWFpbCBhZGRyZXNzIGZvcm1hdFxuICBpZiAoIXRoaXMuZGF0YS5lbWFpbC5tYXRjaCgvXi4rQC4rJC8pKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUywgJ0VtYWlsIGFkZHJlc3MgZm9ybWF0IGlzIGludmFsaWQuJylcbiAgICApO1xuICB9XG4gIC8vIENhc2UgaW5zZW5zaXRpdmUgbWF0Y2gsIHNlZSBub3RlIGFib3ZlIGZ1bmN0aW9uLlxuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAuZmluZChcbiAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAge1xuICAgICAgICBlbWFpbDogdGhpcy5kYXRhLmVtYWlsLFxuICAgICAgICBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgfSxcbiAgICAgIHsgbGltaXQ6IDEsIGNhc2VJbnNlbnNpdGl2ZTogdHJ1ZSB9LFxuICAgICAge30sXG4gICAgICB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlclxuICAgIClcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLkVNQUlMX1RBS0VOLFxuICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVtYWlsIGFkZHJlc3MuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5kYXRhLmF1dGhEYXRhIHx8XG4gICAgICAgICFPYmplY3Qua2V5cyh0aGlzLmRhdGEuYXV0aERhdGEpLmxlbmd0aCB8fFxuICAgICAgICAoT2JqZWN0LmtleXModGhpcy5kYXRhLmF1dGhEYXRhKS5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmRhdGEuYXV0aERhdGEpWzBdID09PSAnYW5vbnltb3VzJylcbiAgICAgICkge1xuICAgICAgICAvLyBXZSB1cGRhdGVkIHRoZSBlbWFpbCwgc2VuZCBhIG5ldyB2YWxpZGF0aW9uXG4gICAgICAgIHRoaXMuc3RvcmFnZVsnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJ10gPSB0cnVlO1xuICAgICAgICB0aGlzLmNvbmZpZy51c2VyQ29udHJvbGxlci5zZXRFbWFpbFZlcmlmeVRva2VuKHRoaXMuZGF0YSk7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5ID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5KSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIHJldHVybiB0aGlzLl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzKCkudGhlbigoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5KCk7XG4gIH0pO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5fdmFsaWRhdGVQYXNzd29yZFJlcXVpcmVtZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gY2hlY2sgaWYgdGhlIHBhc3N3b3JkIGNvbmZvcm1zIHRvIHRoZSBkZWZpbmVkIHBhc3N3b3JkIHBvbGljeSBpZiBjb25maWd1cmVkXG4gIC8vIElmIHdlIHNwZWNpZmllZCBhIGN1c3RvbSBlcnJvciBpbiBvdXIgY29uZmlndXJhdGlvbiB1c2UgaXQuXG4gIC8vIEV4YW1wbGU6IFwiUGFzc3dvcmRzIG11c3QgaW5jbHVkZSBhIENhcGl0YWwgTGV0dGVyLCBMb3dlcmNhc2UgTGV0dGVyLCBhbmQgYSBudW1iZXIuXCJcbiAgLy9cbiAgLy8gVGhpcyBpcyBlc3BlY2lhbGx5IHVzZWZ1bCBvbiB0aGUgZ2VuZXJpYyBcInBhc3N3b3JkIHJlc2V0XCIgcGFnZSxcbiAgLy8gYXMgaXQgYWxsb3dzIHRoZSBwcm9ncmFtbWVyIHRvIGNvbW11bmljYXRlIHNwZWNpZmljIHJlcXVpcmVtZW50cyBpbnN0ZWFkIG9mOlxuICAvLyBhLiBtYWtpbmcgdGhlIHVzZXIgZ3Vlc3Mgd2hhdHMgd3JvbmdcbiAgLy8gYi4gbWFraW5nIGEgY3VzdG9tIHBhc3N3b3JkIHJlc2V0IHBhZ2UgdGhhdCBzaG93cyB0aGUgcmVxdWlyZW1lbnRzXG4gIGNvbnN0IHBvbGljeUVycm9yID0gdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kudmFsaWRhdGlvbkVycm9yXG4gICAgPyB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS52YWxpZGF0aW9uRXJyb3JcbiAgICA6ICdQYXNzd29yZCBkb2VzIG5vdCBtZWV0IHRoZSBQYXNzd29yZCBQb2xpY3kgcmVxdWlyZW1lbnRzLic7XG4gIGNvbnN0IGNvbnRhaW5zVXNlcm5hbWVFcnJvciA9ICdQYXNzd29yZCBjYW5ub3QgY29udGFpbiB5b3VyIHVzZXJuYW1lLic7XG5cbiAgLy8gY2hlY2sgd2hldGhlciB0aGUgcGFzc3dvcmQgbWVldHMgdGhlIHBhc3N3b3JkIHN0cmVuZ3RoIHJlcXVpcmVtZW50c1xuICBpZiAoXG4gICAgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgJiZcbiAgICAgICF0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5wYXR0ZXJuVmFsaWRhdG9yKHRoaXMuZGF0YS5wYXNzd29yZCkpIHx8XG4gICAgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnZhbGlkYXRvckNhbGxiYWNrICYmXG4gICAgICAhdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sodGhpcy5kYXRhLnBhc3N3b3JkKSlcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBwb2xpY3lFcnJvcikpO1xuICB9XG5cbiAgLy8gY2hlY2sgd2hldGhlciBwYXNzd29yZCBjb250YWluIHVzZXJuYW1lXG4gIGlmICh0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgPT09IHRydWUpIHtcbiAgICBpZiAodGhpcy5kYXRhLnVzZXJuYW1lKSB7XG4gICAgICAvLyB1c2VybmFtZSBpcyBub3QgcGFzc2VkIGR1cmluZyBwYXNzd29yZCByZXNldFxuICAgICAgaWYgKHRoaXMuZGF0YS5wYXNzd29yZC5pbmRleE9mKHRoaXMuZGF0YS51c2VybmFtZSkgPj0gMClcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBjb250YWluc1VzZXJuYW1lRXJyb3IpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcmV0cmlldmUgdGhlIFVzZXIgb2JqZWN0IHVzaW5nIG9iamVjdElkIGR1cmluZyBwYXNzd29yZCByZXNldFxuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpIH0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmRhdGEucGFzc3dvcmQuaW5kZXhPZihyZXN1bHRzWzBdLnVzZXJuYW1lKSA+PSAwKVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBjb250YWluc1VzZXJuYW1lRXJyb3IpXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjaGVjayB3aGV0aGVyIHBhc3N3b3JkIGlzIHJlcGVhdGluZyBmcm9tIHNwZWNpZmllZCBoaXN0b3J5XG4gIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmZpbmQoXG4gICAgICAgICdfVXNlcicsXG4gICAgICAgIHsgb2JqZWN0SWQ6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgICB7IGtleXM6IFsnX3Bhc3N3b3JkX2hpc3RvcnknLCAnX2hhc2hlZF9wYXNzd29yZCddIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgbGV0IG9sZFBhc3N3b3JkcyA9IFtdO1xuICAgICAgICBpZiAodXNlci5fcGFzc3dvcmRfaGlzdG9yeSlcbiAgICAgICAgICBvbGRQYXNzd29yZHMgPSBfLnRha2UoXG4gICAgICAgICAgICB1c2VyLl9wYXNzd29yZF9oaXN0b3J5LFxuICAgICAgICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5IC0gMVxuICAgICAgICAgICk7XG4gICAgICAgIG9sZFBhc3N3b3Jkcy5wdXNoKHVzZXIucGFzc3dvcmQpO1xuICAgICAgICBjb25zdCBuZXdQYXNzd29yZCA9IHRoaXMuZGF0YS5wYXNzd29yZDtcbiAgICAgICAgLy8gY29tcGFyZSB0aGUgbmV3IHBhc3N3b3JkIGhhc2ggd2l0aCBhbGwgb2xkIHBhc3N3b3JkIGhhc2hlc1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG9sZFBhc3N3b3Jkcy5tYXAoZnVuY3Rpb24gKGhhc2gpIHtcbiAgICAgICAgICByZXR1cm4gcGFzc3dvcmRDcnlwdG8uY29tcGFyZShuZXdQYXNzd29yZCwgaGFzaCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3VsdClcbiAgICAgICAgICAgICAgLy8gcmVqZWN0IGlmIHRoZXJlIGlzIGEgbWF0Y2hcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdSRVBFQVRfUEFTU1dPUkQnKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHdhaXQgZm9yIGFsbCBjb21wYXJpc29ucyB0byBjb21wbGV0ZVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyID09PSAnUkVQRUFUX1BBU1NXT1JEJylcbiAgICAgICAgICAgICAgLy8gYSBtYXRjaCB3YXMgZm91bmRcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsXG4gICAgICAgICAgICAgICAgICBgTmV3IHBhc3N3b3JkIHNob3VsZCBub3QgYmUgdGhlIHNhbWUgYXMgbGFzdCAke3RoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeX0gcGFzc3dvcmRzLmBcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmNyZWF0ZVNlc3Npb25Ub2tlbklmTmVlZGVkID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gRG9uJ3QgZ2VuZXJhdGUgc2Vzc2lvbiBmb3IgdXBkYXRpbmcgdXNlciAodGhpcy5xdWVyeSBpcyBzZXQpIHVubGVzcyBhdXRoRGF0YSBleGlzdHNcbiAgaWYgKHRoaXMucXVlcnkgJiYgIXRoaXMuZGF0YS5hdXRoRGF0YSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBEb24ndCBnZW5lcmF0ZSBuZXcgc2Vzc2lvblRva2VuIGlmIGxpbmtpbmcgdmlhIHNlc3Npb25Ub2tlblxuICBpZiAodGhpcy5hdXRoLnVzZXIgJiYgdGhpcy5kYXRhLmF1dGhEYXRhKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChcbiAgICAhdGhpcy5zdG9yYWdlWydhdXRoUHJvdmlkZXInXSAmJiAvLyBzaWdudXAgY2FsbCwgd2l0aFxuICAgIHRoaXMuY29uZmlnLnByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwgJiYgLy8gbm8gbG9naW4gd2l0aG91dCB2ZXJpZmljYXRpb25cbiAgICB0aGlzLmNvbmZpZy52ZXJpZnlVc2VyRW1haWxzXG4gICkge1xuICAgIC8vIHZlcmlmaWNhdGlvbiBpcyBvblxuICAgIHJldHVybjsgLy8gZG8gbm90IGNyZWF0ZSB0aGUgc2Vzc2lvbiB0b2tlbiBpbiB0aGF0IGNhc2UhXG4gIH1cbiAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuKCk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmNyZWF0ZVNlc3Npb25Ub2tlbiA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgLy8gY2xvdWQgaW5zdGFsbGF0aW9uSWQgZnJvbSBDbG91ZCBDb2RlLFxuICAvLyBuZXZlciBjcmVhdGUgc2Vzc2lvbiB0b2tlbnMgZnJvbSB0aGVyZS5cbiAgaWYgKHRoaXMuYXV0aC5pbnN0YWxsYXRpb25JZCAmJiB0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWQgPT09ICdjbG91ZCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24odGhpcy5jb25maWcsIHtcbiAgICB1c2VySWQ6IHRoaXMub2JqZWN0SWQoKSxcbiAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgYWN0aW9uOiB0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddID8gJ2xvZ2luJyA6ICdzaWdudXAnLFxuICAgICAgYXV0aFByb3ZpZGVyOiB0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddIHx8ICdwYXNzd29yZCcsXG4gICAgfSxcbiAgICBpbnN0YWxsYXRpb25JZDogdGhpcy5hdXRoLmluc3RhbGxhdGlvbklkLFxuICB9KTtcblxuICBpZiAodGhpcy5yZXNwb25zZSAmJiB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlKSB7XG4gICAgdGhpcy5yZXNwb25zZS5yZXNwb25zZS5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uRGF0YS5zZXNzaW9uVG9rZW47XG4gIH1cblxuICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpO1xufTtcblxuLy8gRGVsZXRlIGVtYWlsIHJlc2V0IHRva2VucyBpZiB1c2VyIGlzIGNoYW5naW5nIHBhc3N3b3JkIG9yIGVtYWlsLlxuUmVzdFdyaXRlLnByb3RvdHlwZS5kZWxldGVFbWFpbFJlc2V0VG9rZW5JZk5lZWRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInIHx8IHRoaXMucXVlcnkgPT09IG51bGwpIHtcbiAgICAvLyBudWxsIHF1ZXJ5IG1lYW5zIGNyZWF0ZVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICgncGFzc3dvcmQnIGluIHRoaXMuZGF0YSB8fCAnZW1haWwnIGluIHRoaXMuZGF0YSkge1xuICAgIGNvbnN0IGFkZE9wcyA9IHtcbiAgICAgIF9wZXJpc2hhYmxlX3Rva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgICBfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0OiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgfTtcbiAgICB0aGlzLmRhdGEgPSBPYmplY3QuYXNzaWduKHRoaXMuZGF0YSwgYWRkT3BzKTtcbiAgfVxufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5kZXN0cm95RHVwbGljYXRlZFNlc3Npb25zID0gZnVuY3Rpb24gKCkge1xuICAvLyBPbmx5IGZvciBfU2Vzc2lvbiwgYW5kIGF0IGNyZWF0aW9uIHRpbWVcbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9ICdfU2Vzc2lvbicgfHwgdGhpcy5xdWVyeSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBEZXN0cm95IHRoZSBzZXNzaW9ucyBpbiAnQmFja2dyb3VuZCdcbiAgY29uc3QgeyB1c2VyLCBpbnN0YWxsYXRpb25JZCwgc2Vzc2lvblRva2VuIH0gPSB0aGlzLmRhdGE7XG4gIGlmICghdXNlciB8fCAhaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKCF1c2VyLm9iamVjdElkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koXG4gICAgJ19TZXNzaW9uJyxcbiAgICB7XG4gICAgICB1c2VyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQsXG4gICAgICBzZXNzaW9uVG9rZW46IHsgJG5lOiBzZXNzaW9uVG9rZW4gfSxcbiAgICB9LFxuICAgIHt9LFxuICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyXG4gICk7XG59O1xuXG4vLyBIYW5kbGVzIGFueSBmb2xsb3d1cCBsb2dpY1xuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVGb2xsb3d1cCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc3RvcmFnZSAmJiB0aGlzLnN0b3JhZ2VbJ2NsZWFyU2Vzc2lvbnMnXSAmJiB0aGlzLmNvbmZpZy5yZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0KSB7XG4gICAgdmFyIHNlc3Npb25RdWVyeSA9IHtcbiAgICAgIHVzZXI6IHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgb2JqZWN0SWQ6IHRoaXMub2JqZWN0SWQoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBkZWxldGUgdGhpcy5zdG9yYWdlWydjbGVhclNlc3Npb25zJ107XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuZGVzdHJveSgnX1Nlc3Npb24nLCBzZXNzaW9uUXVlcnkpXG4gICAgICAudGhlbih0aGlzLmhhbmRsZUZvbGxvd3VwLmJpbmQodGhpcykpO1xuICB9XG5cbiAgaWYgKHRoaXMuc3RvcmFnZSAmJiB0aGlzLnN0b3JhZ2VbJ2dlbmVyYXRlTmV3U2Vzc2lvbiddKSB7XG4gICAgZGVsZXRlIHRoaXMuc3RvcmFnZVsnZ2VuZXJhdGVOZXdTZXNzaW9uJ107XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuKCkudGhlbih0aGlzLmhhbmRsZUZvbGxvd3VwLmJpbmQodGhpcykpO1xuICB9XG5cbiAgaWYgKHRoaXMuc3RvcmFnZSAmJiB0aGlzLnN0b3JhZ2VbJ3NlbmRWZXJpZmljYXRpb25FbWFpbCddKSB7XG4gICAgZGVsZXRlIHRoaXMuc3RvcmFnZVsnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJ107XG4gICAgLy8gRmlyZSBhbmQgZm9yZ2V0IVxuICAgIHRoaXMuY29uZmlnLnVzZXJDb250cm9sbGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbCh0aGlzLmRhdGEpO1xuICAgIHJldHVybiB0aGlzLmhhbmRsZUZvbGxvd3VwLmJpbmQodGhpcyk7XG4gIH1cbn07XG5cbi8vIEhhbmRsZXMgdGhlIF9TZXNzaW9uIGNsYXNzIHNwZWNpYWxuZXNzLlxuLy8gRG9lcyBub3RoaW5nIGlmIHRoaXMgaXNuJ3QgYW4gX1Nlc3Npb24gb2JqZWN0LlxuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVTZXNzaW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSB8fCB0aGlzLmNsYXNzTmFtZSAhPT0gJ19TZXNzaW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghdGhpcy5hdXRoLnVzZXIgJiYgIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdTZXNzaW9uIHRva2VuIHJlcXVpcmVkLicpO1xuICB9XG5cbiAgLy8gVE9ETzogVmVyaWZ5IHByb3BlciBlcnJvciB0byB0aHJvd1xuICBpZiAodGhpcy5kYXRhLkFDTCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCAnQ2Fubm90IHNldCAnICsgJ0FDTCBvbiBhIFNlc3Npb24uJyk7XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSkge1xuICAgIGlmICh0aGlzLmRhdGEudXNlciAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyICYmIHRoaXMuZGF0YS51c2VyLm9iamVjdElkICE9IHRoaXMuYXV0aC51c2VyLmlkKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YS5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRoaXMucXVlcnkgJiYgIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgIGNvbnN0IGFkZGl0aW9uYWxTZXNzaW9uRGF0YSA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmRhdGEpIHtcbiAgICAgIGlmIChrZXkgPT09ICdvYmplY3RJZCcgfHwga2V5ID09PSAndXNlcicpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBhZGRpdGlvbmFsU2Vzc2lvbkRhdGFba2V5XSA9IHRoaXMuZGF0YVtrZXldO1xuICAgIH1cblxuICAgIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IEF1dGguY3JlYXRlU2Vzc2lvbih0aGlzLmNvbmZpZywge1xuICAgICAgdXNlcklkOiB0aGlzLmF1dGgudXNlci5pZCxcbiAgICAgIGNyZWF0ZWRXaXRoOiB7XG4gICAgICAgIGFjdGlvbjogJ2NyZWF0ZScsXG4gICAgICB9LFxuICAgICAgYWRkaXRpb25hbFNlc3Npb25EYXRhLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNyZWF0ZVNlc3Npb24oKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKCFyZXN1bHRzLnJlc3BvbnNlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdFcnJvciBjcmVhdGluZyBzZXNzaW9uLicpO1xuICAgICAgfVxuICAgICAgc2Vzc2lvbkRhdGFbJ29iamVjdElkJ10gPSByZXN1bHRzLnJlc3BvbnNlWydvYmplY3RJZCddO1xuICAgICAgdGhpcy5yZXNwb25zZSA9IHtcbiAgICAgICAgc3RhdHVzOiAyMDEsXG4gICAgICAgIGxvY2F0aW9uOiByZXN1bHRzLmxvY2F0aW9uLFxuICAgICAgICByZXNwb25zZTogc2Vzc2lvbkRhdGEsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59O1xuXG4vLyBIYW5kbGVzIHRoZSBfSW5zdGFsbGF0aW9uIGNsYXNzIHNwZWNpYWxuZXNzLlxuLy8gRG9lcyBub3RoaW5nIGlmIHRoaXMgaXNuJ3QgYW4gaW5zdGFsbGF0aW9uIG9iamVjdC5cbi8vIElmIGFuIGluc3RhbGxhdGlvbiBpcyBmb3VuZCwgdGhpcyBjYW4gbXV0YXRlIHRoaXMucXVlcnkgYW5kIHR1cm4gYSBjcmVhdGVcbi8vIGludG8gYW4gdXBkYXRlLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZW4gd2UncmUgZG9uZSBpZiBpdCBjYW4ndCBmaW5pc2ggdGhpcyB0aWNrLlxuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVJbnN0YWxsYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlc3BvbnNlIHx8IHRoaXMuY2xhc3NOYW1lICE9PSAnX0luc3RhbGxhdGlvbicpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoXG4gICAgIXRoaXMucXVlcnkgJiZcbiAgICAhdGhpcy5kYXRhLmRldmljZVRva2VuICYmXG4gICAgIXRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCAmJlxuICAgICF0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWRcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgMTM1LFxuICAgICAgJ2F0IGxlYXN0IG9uZSBJRCBmaWVsZCAoZGV2aWNlVG9rZW4sIGluc3RhbGxhdGlvbklkKSAnICsgJ211c3QgYmUgc3BlY2lmaWVkIGluIHRoaXMgb3BlcmF0aW9uJ1xuICAgICk7XG4gIH1cblxuICAvLyBJZiB0aGUgZGV2aWNlIHRva2VuIGlzIDY0IGNoYXJhY3RlcnMgbG9uZywgd2UgYXNzdW1lIGl0IGlzIGZvciBpT1NcbiAgLy8gYW5kIGxvd2VyY2FzZSBpdC5cbiAgaWYgKHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJiB0aGlzLmRhdGEuZGV2aWNlVG9rZW4ubGVuZ3RoID09IDY0KSB7XG4gICAgdGhpcy5kYXRhLmRldmljZVRva2VuID0gdGhpcy5kYXRhLmRldmljZVRva2VuLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvLyBXZSBsb3dlcmNhc2UgdGhlIGluc3RhbGxhdGlvbklkIGlmIHByZXNlbnRcbiAgaWYgKHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgIHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCA9IHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZC50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgbGV0IGluc3RhbGxhdGlvbklkID0gdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkO1xuXG4gIC8vIElmIGRhdGEuaW5zdGFsbGF0aW9uSWQgaXMgbm90IHNldCBhbmQgd2UncmUgbm90IG1hc3Rlciwgd2UgY2FuIGxvb2t1cCBpbiBhdXRoXG4gIGlmICghaW5zdGFsbGF0aW9uSWQgJiYgIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgIGluc3RhbGxhdGlvbklkID0gdGhpcy5hdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG5cbiAgaWYgKGluc3RhbGxhdGlvbklkKSB7XG4gICAgaW5zdGFsbGF0aW9uSWQgPSBpbnN0YWxsYXRpb25JZC50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLy8gVXBkYXRpbmcgX0luc3RhbGxhdGlvbiBidXQgbm90IHVwZGF0aW5nIGFueXRoaW5nIGNyaXRpY2FsXG4gIGlmICh0aGlzLnF1ZXJ5ICYmICF0aGlzLmRhdGEuZGV2aWNlVG9rZW4gJiYgIWluc3RhbGxhdGlvbklkICYmICF0aGlzLmRhdGEuZGV2aWNlVHlwZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgdmFyIGlkTWF0Y2g7IC8vIFdpbGwgYmUgYSBtYXRjaCBvbiBlaXRoZXIgb2JqZWN0SWQgb3IgaW5zdGFsbGF0aW9uSWRcbiAgdmFyIG9iamVjdElkTWF0Y2g7XG4gIHZhciBpbnN0YWxsYXRpb25JZE1hdGNoO1xuICB2YXIgZGV2aWNlVG9rZW5NYXRjaGVzID0gW107XG5cbiAgLy8gSW5zdGVhZCBvZiBpc3N1aW5nIDMgcmVhZHMsIGxldCdzIGRvIGl0IHdpdGggb25lIE9SLlxuICBjb25zdCBvclF1ZXJpZXMgPSBbXTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIG9yUXVlcmllcy5wdXNoKHtcbiAgICAgIG9iamVjdElkOiB0aGlzLnF1ZXJ5Lm9iamVjdElkLFxuICAgIH0pO1xuICB9XG4gIGlmIChpbnN0YWxsYXRpb25JZCkge1xuICAgIG9yUXVlcmllcy5wdXNoKHtcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcbiAgfVxuICBpZiAodGhpcy5kYXRhLmRldmljZVRva2VuKSB7XG4gICAgb3JRdWVyaWVzLnB1c2goeyBkZXZpY2VUb2tlbjogdGhpcy5kYXRhLmRldmljZVRva2VuIH0pO1xuICB9XG5cbiAgaWYgKG9yUXVlcmllcy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByb21pc2UgPSBwcm9taXNlXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQoXG4gICAgICAgICdfSW5zdGFsbGF0aW9uJyxcbiAgICAgICAge1xuICAgICAgICAgICRvcjogb3JRdWVyaWVzLFxuICAgICAgICB9LFxuICAgICAgICB7fVxuICAgICAgKTtcbiAgICB9KVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQgJiYgcmVzdWx0Lm9iamVjdElkID09IHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgICBvYmplY3RJZE1hdGNoID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQuaW5zdGFsbGF0aW9uSWQgPT0gaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZE1hdGNoID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQuZGV2aWNlVG9rZW4gPT0gdGhpcy5kYXRhLmRldmljZVRva2VuKSB7XG4gICAgICAgICAgZGV2aWNlVG9rZW5NYXRjaGVzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNhbml0eSBjaGVja3Mgd2hlbiBydW5uaW5nIGEgcXVlcnlcbiAgICAgIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgaWYgKCFvYmplY3RJZE1hdGNoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kIGZvciB1cGRhdGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCAmJlxuICAgICAgICAgIG9iamVjdElkTWF0Y2guaW5zdGFsbGF0aW9uSWQgJiZcbiAgICAgICAgICB0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQgIT09IG9iamVjdElkTWF0Y2guaW5zdGFsbGF0aW9uSWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgJ2luc3RhbGxhdGlvbklkIG1heSBub3QgYmUgY2hhbmdlZCBpbiB0aGlzICcgKyAnb3BlcmF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJlxuICAgICAgICAgIG9iamVjdElkTWF0Y2guZGV2aWNlVG9rZW4gJiZcbiAgICAgICAgICB0aGlzLmRhdGEuZGV2aWNlVG9rZW4gIT09IG9iamVjdElkTWF0Y2guZGV2aWNlVG9rZW4gJiZcbiAgICAgICAgICAhdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkICYmXG4gICAgICAgICAgIW9iamVjdElkTWF0Y2guaW5zdGFsbGF0aW9uSWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgJ2RldmljZVRva2VuIG1heSBub3QgYmUgY2hhbmdlZCBpbiB0aGlzICcgKyAnb3BlcmF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUeXBlICYmXG4gICAgICAgICAgdGhpcy5kYXRhLmRldmljZVR5cGUgJiZcbiAgICAgICAgICB0aGlzLmRhdGEuZGV2aWNlVHlwZSAhPT0gb2JqZWN0SWRNYXRjaC5kZXZpY2VUeXBlXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxMzYsICdkZXZpY2VUeXBlIG1heSBub3QgYmUgY2hhbmdlZCBpbiB0aGlzICcgKyAnb3BlcmF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCAmJiBvYmplY3RJZE1hdGNoKSB7XG4gICAgICAgIGlkTWF0Y2ggPSBvYmplY3RJZE1hdGNoO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5zdGFsbGF0aW9uSWQgJiYgaW5zdGFsbGF0aW9uSWRNYXRjaCkge1xuICAgICAgICBpZE1hdGNoID0gaW5zdGFsbGF0aW9uSWRNYXRjaDtcbiAgICAgIH1cbiAgICAgIC8vIG5lZWQgdG8gc3BlY2lmeSBkZXZpY2VUeXBlIG9ubHkgaWYgaXQncyBuZXdcbiAgICAgIGlmICghdGhpcy5xdWVyeSAmJiAhdGhpcy5kYXRhLmRldmljZVR5cGUgJiYgIWlkTWF0Y2gpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNSwgJ2RldmljZVR5cGUgbXVzdCBiZSBzcGVjaWZpZWQgaW4gdGhpcyBvcGVyYXRpb24nKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGlmICghaWRNYXRjaCkge1xuICAgICAgICBpZiAoIWRldmljZVRva2VuTWF0Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgZGV2aWNlVG9rZW5NYXRjaGVzLmxlbmd0aCA9PSAxICYmXG4gICAgICAgICAgKCFkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ2luc3RhbGxhdGlvbklkJ10gfHwgIWluc3RhbGxhdGlvbklkKVxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBTaW5nbGUgbWF0Y2ggb24gZGV2aWNlIHRva2VuIGJ1dCBub25lIG9uIGluc3RhbGxhdGlvbklkLCBhbmQgZWl0aGVyXG4gICAgICAgICAgLy8gdGhlIHBhc3NlZCBvYmplY3Qgb3IgdGhlIG1hdGNoIGlzIG1pc3NpbmcgYW4gaW5zdGFsbGF0aW9uSWQsIHNvIHdlXG4gICAgICAgICAgLy8gY2FuIGp1c3QgcmV0dXJuIHRoZSBtYXRjaC5cbiAgICAgICAgICByZXR1cm4gZGV2aWNlVG9rZW5NYXRjaGVzWzBdWydvYmplY3RJZCddO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAxMzIsXG4gICAgICAgICAgICAnTXVzdCBzcGVjaWZ5IGluc3RhbGxhdGlvbklkIHdoZW4gZGV2aWNlVG9rZW4gJyArXG4gICAgICAgICAgICAgICdtYXRjaGVzIG11bHRpcGxlIEluc3RhbGxhdGlvbiBvYmplY3RzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTXVsdGlwbGUgZGV2aWNlIHRva2VuIG1hdGNoZXMgYW5kIHdlIHNwZWNpZmllZCBhbiBpbnN0YWxsYXRpb24gSUQsXG4gICAgICAgICAgLy8gb3IgYSBzaW5nbGUgbWF0Y2ggd2hlcmUgYm90aCB0aGUgcGFzc2VkIGFuZCBtYXRjaGluZyBvYmplY3RzIGhhdmVcbiAgICAgICAgICAvLyBhbiBpbnN0YWxsYXRpb24gSUQuIFRyeSBjbGVhbmluZyBvdXQgb2xkIGluc3RhbGxhdGlvbnMgdGhhdCBtYXRjaFxuICAgICAgICAgIC8vIHRoZSBkZXZpY2VUb2tlbiwgYW5kIHJldHVybiBuaWwgdG8gc2lnbmFsIHRoYXQgYSBuZXcgb2JqZWN0IHNob3VsZFxuICAgICAgICAgIC8vIGJlIGNyZWF0ZWQuXG4gICAgICAgICAgdmFyIGRlbFF1ZXJ5ID0ge1xuICAgICAgICAgICAgZGV2aWNlVG9rZW46IHRoaXMuZGF0YS5kZXZpY2VUb2tlbixcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiB7XG4gICAgICAgICAgICAgICRuZTogaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHRoaXMuZGF0YS5hcHBJZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBkZWxRdWVyeVsnYXBwSWRlbnRpZmllciddID0gdGhpcy5kYXRhLmFwcElkZW50aWZpZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koJ19JbnN0YWxsYXRpb24nLCBkZWxRdWVyeSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICAgIC8vIG5vIGRlbGV0aW9ucyB3ZXJlIG1hZGUuIENhbiBiZSBpZ25vcmVkLlxuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByZXRocm93IHRoZSBlcnJvclxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRldmljZVRva2VuTWF0Y2hlcy5sZW5ndGggPT0gMSAmJiAhZGV2aWNlVG9rZW5NYXRjaGVzWzBdWydpbnN0YWxsYXRpb25JZCddKSB7XG4gICAgICAgICAgLy8gRXhhY3RseSBvbmUgZGV2aWNlIHRva2VuIG1hdGNoIGFuZCBpdCBkb2Vzbid0IGhhdmUgYW4gaW5zdGFsbGF0aW9uXG4gICAgICAgICAgLy8gSUQuIFRoaXMgaXMgdGhlIG9uZSBjYXNlIHdoZXJlIHdlIHdhbnQgdG8gbWVyZ2Ugd2l0aCB0aGUgZXhpc3RpbmdcbiAgICAgICAgICAvLyBvYmplY3QuXG4gICAgICAgICAgY29uc3QgZGVsUXVlcnkgPSB7IG9iamVjdElkOiBpZE1hdGNoLm9iamVjdElkIH07XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgICAgICAuZGVzdHJveSgnX0luc3RhbGxhdGlvbicsIGRlbFF1ZXJ5KVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlVG9rZW5NYXRjaGVzWzBdWydvYmplY3RJZCddO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICAgICAgICAgIC8vIG5vIGRlbGV0aW9ucyB3ZXJlIG1hZGUuIENhbiBiZSBpZ25vcmVkXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIHJldGhyb3cgdGhlIGVycm9yXG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmRhdGEuZGV2aWNlVG9rZW4gJiYgaWRNYXRjaC5kZXZpY2VUb2tlbiAhPSB0aGlzLmRhdGEuZGV2aWNlVG9rZW4pIHtcbiAgICAgICAgICAgIC8vIFdlJ3JlIHNldHRpbmcgdGhlIGRldmljZSB0b2tlbiBvbiBhbiBleGlzdGluZyBpbnN0YWxsYXRpb24sIHNvXG4gICAgICAgICAgICAvLyB3ZSBzaG91bGQgdHJ5IGNsZWFuaW5nIG91dCBvbGQgaW5zdGFsbGF0aW9ucyB0aGF0IG1hdGNoIHRoaXNcbiAgICAgICAgICAgIC8vIGRldmljZSB0b2tlbi5cbiAgICAgICAgICAgIGNvbnN0IGRlbFF1ZXJ5ID0ge1xuICAgICAgICAgICAgICBkZXZpY2VUb2tlbjogdGhpcy5kYXRhLmRldmljZVRva2VuLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFdlIGhhdmUgYSB1bmlxdWUgaW5zdGFsbCBJZCwgdXNlIHRoYXQgdG8gcHJlc2VydmVcbiAgICAgICAgICAgIC8vIHRoZSBpbnRlcmVzdGluZyBpbnN0YWxsYXRpb25cbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgICAgICAgZGVsUXVlcnlbJ2luc3RhbGxhdGlvbklkJ10gPSB7XG4gICAgICAgICAgICAgICAgJG5lOiB0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICBpZE1hdGNoLm9iamVjdElkICYmXG4gICAgICAgICAgICAgIHRoaXMuZGF0YS5vYmplY3RJZCAmJlxuICAgICAgICAgICAgICBpZE1hdGNoLm9iamVjdElkID09IHRoaXMuZGF0YS5vYmplY3RJZFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIC8vIHdlIHBhc3NlZCBhbiBvYmplY3RJZCwgcHJlc2VydmUgdGhhdCBpbnN0YWxhdGlvblxuICAgICAgICAgICAgICBkZWxRdWVyeVsnb2JqZWN0SWQnXSA9IHtcbiAgICAgICAgICAgICAgICAkbmU6IGlkTWF0Y2gub2JqZWN0SWQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBXaGF0IHRvIGRvIGhlcmU/IGNhbid0IHJlYWxseSBjbGVhbiB1cCBldmVyeXRoaW5nLi4uXG4gICAgICAgICAgICAgIHJldHVybiBpZE1hdGNoLm9iamVjdElkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5hcHBJZGVudGlmaWVyKSB7XG4gICAgICAgICAgICAgIGRlbFF1ZXJ5WydhcHBJZGVudGlmaWVyJ10gPSB0aGlzLmRhdGEuYXBwSWRlbnRpZmllcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koJ19JbnN0YWxsYXRpb24nLCBkZWxRdWVyeSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAgICAgICAvLyBubyBkZWxldGlvbnMgd2VyZSBtYWRlLiBDYW4gYmUgaWdub3JlZC5cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gcmV0aHJvdyB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEluIG5vbi1tZXJnZSBzY2VuYXJpb3MsIGp1c3QgcmV0dXJuIHRoZSBpbnN0YWxsYXRpb24gbWF0Y2ggaWRcbiAgICAgICAgICByZXR1cm4gaWRNYXRjaC5vYmplY3RJZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4ob2JqSWQgPT4ge1xuICAgICAgaWYgKG9iaklkKSB7XG4gICAgICAgIHRoaXMucXVlcnkgPSB7IG9iamVjdElkOiBvYmpJZCB9O1xuICAgICAgICBkZWxldGUgdGhpcy5kYXRhLm9iamVjdElkO1xuICAgICAgICBkZWxldGUgdGhpcy5kYXRhLmNyZWF0ZWRBdDtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE86IFZhbGlkYXRlIG9wcyAoYWRkL3JlbW92ZSBvbiBjaGFubmVscywgJGluYyBvbiBiYWRnZSwgZXRjLilcbiAgICB9KTtcbiAgcmV0dXJuIHByb21pc2U7XG59O1xuXG4vLyBJZiB3ZSBzaG9ydC1jaXJjdXRlZCB0aGUgb2JqZWN0IHJlc3BvbnNlIC0gdGhlbiB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB3ZSBleHBhbmQgYWxsIHRoZSBmaWxlcyxcbi8vIHNpbmNlIHRoaXMgbWlnaHQgbm90IGhhdmUgYSBxdWVyeSwgbWVhbmluZyBpdCB3b24ndCByZXR1cm4gdGhlIGZ1bGwgcmVzdWx0IGJhY2suXG4vLyBUT0RPOiAobmx1dHNlbmtvKSBUaGlzIHNob3VsZCBkaWUgd2hlbiB3ZSBtb3ZlIHRvIHBlci1jbGFzcyBiYXNlZCBjb250cm9sbGVycyBvbiBfU2Vzc2lvbi9fVXNlclxuUmVzdFdyaXRlLnByb3RvdHlwZS5leHBhbmRGaWxlc0ZvckV4aXN0aW5nT2JqZWN0cyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gQ2hlY2sgd2hldGhlciB3ZSBoYXZlIGEgc2hvcnQtY2lyY3VpdGVkIHJlc3BvbnNlIC0gb25seSB0aGVuIHJ1biBleHBhbnNpb24uXG4gIGlmICh0aGlzLnJlc3BvbnNlICYmIHRoaXMucmVzcG9uc2UucmVzcG9uc2UpIHtcbiAgICB0aGlzLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdCh0aGlzLmNvbmZpZywgdGhpcy5yZXNwb25zZS5yZXNwb25zZSk7XG4gIH1cbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUucnVuRGF0YWJhc2VPcGVyYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlc3BvbnNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1JvbGUnKSB7XG4gICAgdGhpcy5jb25maWcuY2FjaGVDb250cm9sbGVyLnJvbGUuY2xlYXIoKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiB0aGlzLnF1ZXJ5ICYmIHRoaXMuYXV0aC5pc1VuYXV0aGVudGljYXRlZCgpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuU0VTU0lPTl9NSVNTSU5HLFxuICAgICAgYENhbm5vdCBtb2RpZnkgdXNlciAke3RoaXMucXVlcnkub2JqZWN0SWR9LmBcbiAgICApO1xuICB9XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1Byb2R1Y3QnICYmIHRoaXMuZGF0YS5kb3dubG9hZCkge1xuICAgIHRoaXMuZGF0YS5kb3dubG9hZE5hbWUgPSB0aGlzLmRhdGEuZG93bmxvYWQubmFtZTtcbiAgfVxuXG4gIC8vIFRPRE86IEFkZCBiZXR0ZXIgZGV0ZWN0aW9uIGZvciBBQ0wsIGVuc3VyaW5nIGEgdXNlciBjYW4ndCBiZSBsb2NrZWQgZnJvbVxuICAvLyAgICAgICB0aGVpciBvd24gdXNlciByZWNvcmQuXG4gIGlmICh0aGlzLmRhdGEuQUNMICYmIHRoaXMuZGF0YS5BQ0xbJyp1bnJlc29sdmVkJ10pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9BQ0wsICdJbnZhbGlkIEFDTC4nKTtcbiAgfVxuXG4gIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgLy8gRm9yY2UgdGhlIHVzZXIgdG8gbm90IGxvY2tvdXRcbiAgICAvLyBNYXRjaGVkIHdpdGggcGFyc2UuY29tXG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmIHRoaXMuZGF0YS5BQ0wgJiYgdGhpcy5hdXRoLmlzTWFzdGVyICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLmRhdGEuQUNMW3RoaXMucXVlcnkub2JqZWN0SWRdID0geyByZWFkOiB0cnVlLCB3cml0ZTogdHJ1ZSB9O1xuICAgIH1cbiAgICAvLyB1cGRhdGUgcGFzc3dvcmQgdGltZXN0YW1wIGlmIHVzZXIgcGFzc3dvcmQgaXMgYmVpbmcgY2hhbmdlZFxuICAgIGlmIChcbiAgICAgIHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgICB0aGlzLmRhdGEuX2hhc2hlZF9wYXNzd29yZCAmJlxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlXG4gICAgKSB7XG4gICAgICB0aGlzLmRhdGEuX3Bhc3N3b3JkX2NoYW5nZWRfYXQgPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpO1xuICAgIH1cbiAgICAvLyBJZ25vcmUgY3JlYXRlZEF0IHdoZW4gdXBkYXRlXG4gICAgZGVsZXRlIHRoaXMuZGF0YS5jcmVhdGVkQXQ7XG5cbiAgICBsZXQgZGVmZXIgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAvLyBpZiBwYXNzd29yZCBoaXN0b3J5IGlzIGVuYWJsZWQgdGhlbiBzYXZlIHRoZSBjdXJyZW50IHBhc3N3b3JkIHRvIGhpc3RvcnlcbiAgICBpZiAoXG4gICAgICB0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJlxuICAgICAgdGhpcy5kYXRhLl9oYXNoZWRfcGFzc3dvcmQgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnlcbiAgICApIHtcbiAgICAgIGRlZmVyID0gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgLmZpbmQoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7IG9iamVjdElkOiB0aGlzLm9iamVjdElkKCkgfSxcbiAgICAgICAgICB7IGtleXM6IFsnX3Bhc3N3b3JkX2hpc3RvcnknLCAnX2hhc2hlZF9wYXNzd29yZCddIH1cbiAgICAgICAgKVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgICBsZXQgb2xkUGFzc3dvcmRzID0gW107XG4gICAgICAgICAgaWYgKHVzZXIuX3Bhc3N3b3JkX2hpc3RvcnkpIHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3JkcyA9IF8udGFrZShcbiAgICAgICAgICAgICAgdXNlci5fcGFzc3dvcmRfaGlzdG9yeSxcbiAgICAgICAgICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvL24tMSBwYXNzd29yZHMgZ28gaW50byBoaXN0b3J5IGluY2x1ZGluZyBsYXN0IHBhc3N3b3JkXG4gICAgICAgICAgd2hpbGUgKFxuICAgICAgICAgICAgb2xkUGFzc3dvcmRzLmxlbmd0aCA+IE1hdGgubWF4KDAsIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSAtIDIpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBvbGRQYXNzd29yZHMuc2hpZnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2xkUGFzc3dvcmRzLnB1c2godXNlci5wYXNzd29yZCk7XG4gICAgICAgICAgdGhpcy5kYXRhLl9wYXNzd29yZF9oaXN0b3J5ID0gb2xkUGFzc3dvcmRzO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVmZXIudGhlbigoKSA9PiB7XG4gICAgICAvLyBSdW4gYW4gdXBkYXRlXG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgLnVwZGF0ZShcbiAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICB0aGlzLnF1ZXJ5LFxuICAgICAgICAgIHRoaXMuZGF0YSxcbiAgICAgICAgICB0aGlzLnJ1bk9wdGlvbnMsXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXJcbiAgICAgICAgKVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgcmVzcG9uc2UudXBkYXRlZEF0ID0gdGhpcy51cGRhdGVkQXQ7XG4gICAgICAgICAgdGhpcy5fdXBkYXRlUmVzcG9uc2VXaXRoRGF0YShyZXNwb25zZSwgdGhpcy5kYXRhKTtcbiAgICAgICAgICB0aGlzLnJlc3BvbnNlID0geyByZXNwb25zZSB9O1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBTZXQgdGhlIGRlZmF1bHQgQUNMIGFuZCBwYXNzd29yZCB0aW1lc3RhbXAgZm9yIHRoZSBuZXcgX1VzZXJcbiAgICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgIHZhciBBQ0wgPSB0aGlzLmRhdGEuQUNMO1xuICAgICAgLy8gZGVmYXVsdCBwdWJsaWMgci93IEFDTFxuICAgICAgaWYgKCFBQ0wpIHtcbiAgICAgICAgQUNMID0ge307XG4gICAgICAgIEFDTFsnKiddID0geyByZWFkOiB0cnVlLCB3cml0ZTogZmFsc2UgfTtcbiAgICAgIH1cbiAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgdXNlciBpcyBub3QgbG9ja2VkIGRvd25cbiAgICAgIEFDTFt0aGlzLmRhdGEub2JqZWN0SWRdID0geyByZWFkOiB0cnVlLCB3cml0ZTogdHJ1ZSB9O1xuICAgICAgdGhpcy5kYXRhLkFDTCA9IEFDTDtcbiAgICAgIC8vIHBhc3N3b3JkIHRpbWVzdGFtcCB0byBiZSB1c2VkIHdoZW4gcGFzc3dvcmQgZXhwaXJ5IHBvbGljeSBpcyBlbmZvcmNlZFxuICAgICAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlKSB7XG4gICAgICAgIHRoaXMuZGF0YS5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUnVuIGEgY3JlYXRlXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuY3JlYXRlKHRoaXMuY2xhc3NOYW1lLCB0aGlzLmRhdGEsIHRoaXMucnVuT3B0aW9ucywgZmFsc2UsIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInIHx8IGVycm9yLmNvZGUgIT09IFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUXVpY2sgY2hlY2ssIGlmIHdlIHdlcmUgYWJsZSB0byBpbmZlciB0aGUgZHVwbGljYXRlZCBmaWVsZCBuYW1lXG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci51c2VySW5mbyAmJiBlcnJvci51c2VySW5mby5kdXBsaWNhdGVkX2ZpZWxkID09PSAndXNlcm5hbWUnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuVVNFUk5BTUVfVEFLRU4sXG4gICAgICAgICAgICAnQWNjb3VudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyB1c2VybmFtZS4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci51c2VySW5mbyAmJiBlcnJvci51c2VySW5mby5kdXBsaWNhdGVkX2ZpZWxkID09PSAnZW1haWwnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRU1BSUxfVEFLRU4sXG4gICAgICAgICAgICAnQWNjb3VudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyBlbWFpbCBhZGRyZXNzLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhpcyB3YXMgYSBmYWlsZWQgdXNlciBjcmVhdGlvbiBkdWUgdG8gdXNlcm5hbWUgb3IgZW1haWwgYWxyZWFkeSB0YWtlbiwgd2UgbmVlZCB0b1xuICAgICAgICAvLyBjaGVjayB3aGV0aGVyIGl0IHdhcyB1c2VybmFtZSBvciBlbWFpbCBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBlcnJvci5cbiAgICAgICAgLy8gRmFsbGJhY2sgdG8gdGhlIG9yaWdpbmFsIG1ldGhvZFxuICAgICAgICAvLyBUT0RPOiBTZWUgaWYgd2UgY2FuIGxhdGVyIGRvIHRoaXMgd2l0aG91dCBhZGRpdGlvbmFsIHF1ZXJpZXMgYnkgdXNpbmcgbmFtZWQgaW5kZXhlcy5cbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgICAgLmZpbmQoXG4gICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdXNlcm5hbWU6IHRoaXMuZGF0YS51c2VybmFtZSxcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IHsgJG5lOiB0aGlzLm9iamVjdElkKCkgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IGxpbWl0OiAxIH1cbiAgICAgICAgICApXG4gICAgICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5VU0VSTkFNRV9UQUtFTixcbiAgICAgICAgICAgICAgICAnQWNjb3VudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyB1c2VybmFtZS4nXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgIHsgZW1haWw6IHRoaXMuZGF0YS5lbWFpbCwgb2JqZWN0SWQ6IHsgJG5lOiB0aGlzLm9iamVjdElkKCkgfSB9LFxuICAgICAgICAgICAgICB7IGxpbWl0OiAxIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLkVNQUlMX1RBS0VOLFxuICAgICAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVtYWlsIGFkZHJlc3MuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJlc3BvbnNlLm9iamVjdElkID0gdGhpcy5kYXRhLm9iamVjdElkO1xuICAgICAgICByZXNwb25zZS5jcmVhdGVkQXQgPSB0aGlzLmRhdGEuY3JlYXRlZEF0O1xuXG4gICAgICAgIGlmICh0aGlzLnJlc3BvbnNlU2hvdWxkSGF2ZVVzZXJuYW1lKSB7XG4gICAgICAgICAgcmVzcG9uc2UudXNlcm5hbWUgPSB0aGlzLmRhdGEudXNlcm5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlUmVzcG9uc2VXaXRoRGF0YShyZXNwb25zZSwgdGhpcy5kYXRhKTtcbiAgICAgICAgdGhpcy5yZXNwb25zZSA9IHtcbiAgICAgICAgICBzdGF0dXM6IDIwMSxcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbigpLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cbn07XG5cbi8vIFJldHVybnMgbm90aGluZyAtIGRvZXNuJ3Qgd2FpdCBmb3IgdGhlIHRyaWdnZXIuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkFmdGVyU2F2ZVRyaWdnZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5yZXNwb25zZSB8fCAhdGhpcy5yZXNwb25zZS5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2FmdGVyU2F2ZScgdHJpZ2dlciBmb3IgdGhpcyBjbGFzcy5cbiAgY29uc3QgaGFzQWZ0ZXJTYXZlSG9vayA9IHRyaWdnZXJzLnRyaWdnZXJFeGlzdHMoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlLFxuICAgIHRoaXMuY29uZmlnLmFwcGxpY2F0aW9uSWRcbiAgKTtcbiAgY29uc3QgaGFzTGl2ZVF1ZXJ5ID0gdGhpcy5jb25maWcubGl2ZVF1ZXJ5Q29udHJvbGxlci5oYXNMaXZlUXVlcnkodGhpcy5jbGFzc05hbWUpO1xuICBpZiAoIWhhc0FmdGVyU2F2ZUhvb2sgJiYgIWhhc0xpdmVRdWVyeSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIHZhciBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIGV4dHJhRGF0YS5vYmplY3RJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gIH1cblxuICAvLyBCdWlsZCB0aGUgb3JpZ2luYWwgb2JqZWN0LCB3ZSBvbmx5IGRvIHRoaXMgZm9yIGEgdXBkYXRlIHdyaXRlLlxuICBsZXQgb3JpZ2luYWxPYmplY3Q7XG4gIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICBvcmlnaW5hbE9iamVjdCA9IHRyaWdnZXJzLmluZmxhdGUoZXh0cmFEYXRhLCB0aGlzLm9yaWdpbmFsRGF0YSk7XG4gIH1cblxuICAvLyBCdWlsZCB0aGUgaW5mbGF0ZWQgb2JqZWN0LCBkaWZmZXJlbnQgZnJvbSBiZWZvcmVTYXZlLCBvcmlnaW5hbERhdGEgaXMgbm90IGVtcHR5XG4gIC8vIHNpbmNlIGRldmVsb3BlcnMgY2FuIGNoYW5nZSBkYXRhIGluIHRoZSBiZWZvcmVTYXZlLlxuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdGhpcy5idWlsZFVwZGF0ZWRPYmplY3QoZXh0cmFEYXRhKTtcbiAgdXBkYXRlZE9iamVjdC5faGFuZGxlU2F2ZVJlc3BvbnNlKHRoaXMucmVzcG9uc2UucmVzcG9uc2UsIHRoaXMucmVzcG9uc2Uuc3RhdHVzIHx8IDIwMCk7XG5cbiAgdGhpcy5jb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSgpLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiB7XG4gICAgLy8gTm90aWZpeSBMaXZlUXVlcnlTZXJ2ZXIgaWYgcG9zc2libGVcbiAgICBjb25zdCBwZXJtcyA9IHNjaGVtYUNvbnRyb2xsZXIuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKHVwZGF0ZWRPYmplY3QuY2xhc3NOYW1lKTtcbiAgICB0aGlzLmNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLm9uQWZ0ZXJTYXZlKFxuICAgICAgdXBkYXRlZE9iamVjdC5jbGFzc05hbWUsXG4gICAgICB1cGRhdGVkT2JqZWN0LFxuICAgICAgb3JpZ2luYWxPYmplY3QsXG4gICAgICBwZXJtc1xuICAgICk7XG4gIH0pO1xuXG4gIC8vIFJ1biBhZnRlclNhdmUgdHJpZ2dlclxuICByZXR1cm4gdHJpZ2dlcnNcbiAgICAubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlLFxuICAgICAgdGhpcy5hdXRoLFxuICAgICAgdXBkYXRlZE9iamVjdCxcbiAgICAgIG9yaWdpbmFsT2JqZWN0LFxuICAgICAgdGhpcy5jb25maWcsXG4gICAgICB0aGlzLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGlmIChyZXN1bHQgJiYgdHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZXNwb25zZSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBsb2dnZXIud2FybignYWZ0ZXJTYXZlIGNhdWdodCBhbiBlcnJvcicsIGVycik7XG4gICAgfSk7XG59O1xuXG4vLyBBIGhlbHBlciB0byBmaWd1cmUgb3V0IHdoYXQgbG9jYXRpb24gdGhpcyBvcGVyYXRpb24gaGFwcGVucyBhdC5cblJlc3RXcml0ZS5wcm90b3R5cGUubG9jYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBtaWRkbGUgPSB0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyA/ICcvdXNlcnMvJyA6ICcvY2xhc3Nlcy8nICsgdGhpcy5jbGFzc05hbWUgKyAnLyc7XG4gIGNvbnN0IG1vdW50ID0gdGhpcy5jb25maWcubW91bnQgfHwgdGhpcy5jb25maWcuc2VydmVyVVJMO1xuICByZXR1cm4gbW91bnQgKyBtaWRkbGUgKyB0aGlzLmRhdGEub2JqZWN0SWQ7XG59O1xuXG4vLyBBIGhlbHBlciB0byBnZXQgdGhlIG9iamVjdCBpZCBmb3IgdGhpcyBvcGVyYXRpb24uXG4vLyBCZWNhdXNlIGl0IGNvdWxkIGJlIGVpdGhlciBvbiB0aGUgcXVlcnkgb3Igb24gdGhlIGRhdGFcblJlc3RXcml0ZS5wcm90b3R5cGUub2JqZWN0SWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLmRhdGEub2JqZWN0SWQgfHwgdGhpcy5xdWVyeS5vYmplY3RJZDtcbn07XG5cbi8vIFJldHVybnMgYSBjb3B5IG9mIHRoZSBkYXRhIGFuZCBkZWxldGUgYmFkIGtleXMgKF9hdXRoX2RhdGEsIF9oYXNoZWRfcGFzc3dvcmQuLi4pXG5SZXN0V3JpdGUucHJvdG90eXBlLnNhbml0aXplZERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGRhdGEgPSBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLnJlZHVjZSgoZGF0YSwga2V5KSA9PiB7XG4gICAgLy8gUmVnZXhwIGNvbWVzIGZyb20gUGFyc2UuT2JqZWN0LnByb3RvdHlwZS52YWxpZGF0ZVxuICAgIGlmICghL15bQS1aYS16XVswLTlBLVphLXpfXSokLy50ZXN0KGtleSkpIHtcbiAgICAgIGRlbGV0ZSBkYXRhW2tleV07XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9LCBkZWVwY29weSh0aGlzLmRhdGEpKTtcbiAgcmV0dXJuIFBhcnNlLl9kZWNvZGUodW5kZWZpbmVkLCBkYXRhKTtcbn07XG5cbi8vIFJldHVybnMgYW4gdXBkYXRlZCBjb3B5IG9mIHRoZSBvYmplY3RcblJlc3RXcml0ZS5wcm90b3R5cGUuYnVpbGRVcGRhdGVkT2JqZWN0ID0gZnVuY3Rpb24gKGV4dHJhRGF0YSkge1xuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdHJpZ2dlcnMuaW5mbGF0ZShleHRyYURhdGEsIHRoaXMub3JpZ2luYWxEYXRhKTtcbiAgT2JqZWN0LmtleXModGhpcy5kYXRhKS5yZWR1Y2UoZnVuY3Rpb24gKGRhdGEsIGtleSkge1xuICAgIGlmIChrZXkuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgLy8gc3ViZG9jdW1lbnQga2V5IHdpdGggZG90IG5vdGF0aW9uICgneC55Jzp2ID0+ICd4Jzp7J3knOnZ9KVxuICAgICAgY29uc3Qgc3BsaXR0ZWRLZXkgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICAgIGNvbnN0IHBhcmVudFByb3AgPSBzcGxpdHRlZEtleVswXTtcbiAgICAgIGxldCBwYXJlbnRWYWwgPSB1cGRhdGVkT2JqZWN0LmdldChwYXJlbnRQcm9wKTtcbiAgICAgIGlmICh0eXBlb2YgcGFyZW50VmFsICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBwYXJlbnRWYWwgPSB7fTtcbiAgICAgIH1cbiAgICAgIHBhcmVudFZhbFtzcGxpdHRlZEtleVsxXV0gPSBkYXRhW2tleV07XG4gICAgICB1cGRhdGVkT2JqZWN0LnNldChwYXJlbnRQcm9wLCBwYXJlbnRWYWwpO1xuICAgICAgZGVsZXRlIGRhdGFba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0sIGRlZXBjb3B5KHRoaXMuZGF0YSkpO1xuXG4gIHVwZGF0ZWRPYmplY3Quc2V0KHRoaXMuc2FuaXRpemVkRGF0YSgpKTtcbiAgcmV0dXJuIHVwZGF0ZWRPYmplY3Q7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmNsZWFuVXNlckF1dGhEYXRhID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSAmJiB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlICYmIHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgY29uc3QgdXNlciA9IHRoaXMucmVzcG9uc2UucmVzcG9uc2U7XG4gICAgaWYgKHVzZXIuYXV0aERhdGEpIHtcbiAgICAgIE9iamVjdC5rZXlzKHVzZXIuYXV0aERhdGEpLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgICAgICBpZiAodXNlci5hdXRoRGF0YVtwcm92aWRlcl0gPT09IG51bGwpIHtcbiAgICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHVzZXIuYXV0aERhdGEpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGRlbGV0ZSB1c2VyLmF1dGhEYXRhO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5fdXBkYXRlUmVzcG9uc2VXaXRoRGF0YSA9IGZ1bmN0aW9uIChyZXNwb25zZSwgZGF0YSkge1xuICBpZiAoXy5pc0VtcHR5KHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyKSkge1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuICBjb25zdCBjbGllbnRTdXBwb3J0c0RlbGV0ZSA9IENsaWVudFNESy5zdXBwb3J0c0ZvcndhcmREZWxldGUodGhpcy5jbGllbnRTREspO1xuICB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgY29uc3QgZGF0YVZhbHVlID0gZGF0YVtmaWVsZE5hbWVdO1xuXG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzcG9uc2UsIGZpZWxkTmFtZSkpIHtcbiAgICAgIHJlc3BvbnNlW2ZpZWxkTmFtZV0gPSBkYXRhVmFsdWU7XG4gICAgfVxuXG4gICAgLy8gU3RyaXBzIG9wZXJhdGlvbnMgZnJvbSByZXNwb25zZXNcbiAgICBpZiAocmVzcG9uc2VbZmllbGROYW1lXSAmJiByZXNwb25zZVtmaWVsZE5hbWVdLl9fb3ApIHtcbiAgICAgIGRlbGV0ZSByZXNwb25zZVtmaWVsZE5hbWVdO1xuICAgICAgaWYgKGNsaWVudFN1cHBvcnRzRGVsZXRlICYmIGRhdGFWYWx1ZS5fX29wID09ICdEZWxldGUnKSB7XG4gICAgICAgIHJlc3BvbnNlW2ZpZWxkTmFtZV0gPSBkYXRhVmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3BvbnNlO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgUmVzdFdyaXRlO1xubW9kdWxlLmV4cG9ydHMgPSBSZXN0V3JpdGU7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/AggregateRouter.js b/lib/Routers/AggregateRouter.js new file mode 100644 index 0000000000..7cd8518618 --- /dev/null +++ b/lib/Routers/AggregateRouter.js @@ -0,0 +1,153 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AggregateRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _UsersRouter = _interopRequireDefault(require("./UsersRouter")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const BASE_KEYS = ['where', 'distinct', 'pipeline', 'hint', 'explain']; +const PIPELINE_KEYS = ['addFields', 'bucket', 'bucketAuto', 'collStats', 'count', 'currentOp', 'facet', 'geoNear', 'graphLookup', 'group', 'indexStats', 'limit', 'listLocalSessions', 'listSessions', 'lookup', 'match', 'out', 'project', 'redact', 'replaceRoot', 'sample', 'skip', 'sort', 'sortByCount', 'unwind']; +const ALLOWED_KEYS = [...BASE_KEYS, ...PIPELINE_KEYS]; + +class AggregateRouter extends _ClassesRouter.default { + handleFind(req) { + const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); + const options = {}; + + if (body.distinct) { + options.distinct = String(body.distinct); + } + + if (body.hint) { + options.hint = body.hint; + delete body.hint; + } + + if (body.explain) { + options.explain = body.explain; + delete body.explain; + } + + if (body.readPreference) { + options.readPreference = body.readPreference; + delete body.readPreference; + } + + options.pipeline = AggregateRouter.getPipeline(body); + + if (typeof body.where === 'string') { + body.where = JSON.parse(body.where); + } + + return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { + for (const result of response.results) { + if (typeof result === 'object') { + _UsersRouter.default.removeHiddenProperties(result); + } + } + + return { + response + }; + }); + } + /* Builds a pipeline from the body. Originally the body could be passed as a single object, + * and now we support many options + * + * Array + * + * body: [{ + * group: { objectId: '$name' }, + * }] + * + * Object + * + * body: { + * group: { objectId: '$name' }, + * } + * + * + * Pipeline Operator with an Array or an Object + * + * body: { + * pipeline: { + * group: { objectId: '$name' }, + * } + * } + * + */ + + + static getPipeline(body) { + let pipeline = body.pipeline || body; + + if (!Array.isArray(pipeline)) { + pipeline = Object.keys(pipeline).map(key => { + return { + [key]: pipeline[key] + }; + }); + } + + return pipeline.map(stage => { + const keys = Object.keys(stage); + + if (keys.length != 1) { + throw new Error(`Pipeline stages should only have one key found ${keys.join(', ')}`); + } + + return AggregateRouter.transformStage(keys[0], stage); + }); + } + + static transformStage(stageName, stage) { + if (ALLOWED_KEYS.indexOf(stageName) === -1) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${stageName}`); + } + + if (stageName === 'group') { + if (Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. Please use objectId instead of _id`); + } + + if (!Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. objectId is required`); + } + + stage[stageName]._id = stage[stageName].objectId; + delete stage[stageName].objectId; + } + + return { + [`$${stageName}`]: stage[stageName] + }; + } + + mountRoutes() { + this.route('GET', '/aggregate/:className', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleFind(req); + }); + } + +} + +exports.AggregateRouter = AggregateRouter; +var _default = AggregateRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJCQVNFX0tFWVMiLCJQSVBFTElORV9LRVlTIiwiQUxMT1dFRF9LRVlTIiwiQWdncmVnYXRlUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImhhbmRsZUZpbmQiLCJyZXEiLCJib2R5IiwiT2JqZWN0IiwiYXNzaWduIiwiSlNPTkZyb21RdWVyeSIsInF1ZXJ5Iiwib3B0aW9ucyIsImRpc3RpbmN0IiwiU3RyaW5nIiwiaGludCIsImV4cGxhaW4iLCJyZWFkUHJlZmVyZW5jZSIsInBpcGVsaW5lIiwiZ2V0UGlwZWxpbmUiLCJ3aGVyZSIsIkpTT04iLCJwYXJzZSIsInJlc3QiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsImNsYXNzTmFtZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0IiwicmVzdWx0cyIsIlVzZXJzUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsIkFycmF5IiwiaXNBcnJheSIsImtleXMiLCJtYXAiLCJrZXkiLCJzdGFnZSIsImxlbmd0aCIsIkVycm9yIiwiam9pbiIsInRyYW5zZm9ybVN0YWdlIiwic3RhZ2VOYW1lIiwiaW5kZXhPZiIsIlBhcnNlIiwiSU5WQUxJRF9RVUVSWSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9pZCIsIm9iamVjdElkIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFNBQVMsR0FBRyxDQUFDLE9BQUQsRUFBVSxVQUFWLEVBQXNCLFVBQXRCLEVBQWtDLE1BQWxDLEVBQTBDLFNBQTFDLENBQWxCO0FBRUEsTUFBTUMsYUFBYSxHQUFHLENBQ3BCLFdBRG9C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bUU7QUFDakUsY0FBTSxJQUFJRSxjQUFNTCxLQUFWLENBQ0pLLGNBQU1MLEtBQU4sQ0FBWU0sYUFEUixFQUVILHdFQUZHLENBQU47QUFJRDs7QUFDRCxVQUFJLENBQUMxQyxNQUFNLENBQUMyQyxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNYLEtBQUssQ0FBQ0ssU0FBRCxDQUExQyxFQUF1RCxVQUF2RCxDQUFMLEVBQXlFO0FBQ3ZFLGNBQU0sSUFBSUUsY0FBTUwsS0FBVixDQUNKSyxjQUFNTCxLQUFOLENBQVlNLGFBRFIsRUFFSCwwREFGRyxDQUFOO0FBSUQ7O0FBQ0RSLE1BQUFBLEtBQUssQ0FBQ0ssU0FBRCxDQUFMLENBQWlCTyxHQUFqQixHQUF1QlosS0FBSyxDQUFDSyxTQUFELENBQUwsQ0FBaUJRLFFBQXhDO0FBQ0EsYUFBT2IsS0FBSyxDQUFDSyxTQUFELENBQUwsQ0FBaUJRLFFBQXhCO0FBQ0Q7O0FBQ0QsV0FBTztBQUFFLE9BQUUsSUFBR1IsU0FBVSxFQUFmLEdBQW1CTCxLQUFLLENBQUNLLFNBQUQ7QUFBMUIsS0FBUDtBQUNEOztBQUVEUyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQix1QkFBbEIsRUFBMkNDLFVBQVUsQ0FBQ0MsNkJBQXRELEVBQXFGckQsR0FBRyxJQUFJO0FBQzFGLGFBQU8sS0FBS0QsVUFBTCxDQUFnQkMsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUFoSGdEOzs7ZUFtSHBDSCxlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgVXNlcnNSb3V0ZXIgZnJvbSAnLi9Vc2Vyc1JvdXRlcic7XG5cbmNvbnN0IEJBU0VfS0VZUyA9IFsnd2hlcmUnLCAnZGlzdGluY3QnLCAncGlwZWxpbmUnLCAnaGludCcsICdleHBsYWluJ107XG5cbmNvbnN0IFBJUEVMSU5FX0tFWVMgPSBbXG4gICdhZGRGaWVsZHMnLFxuICAnYnVja2V0JyxcbiAgJ2J1Y2tldEF1dG8nLFxuICAnY29sbFN0YXRzJyxcbiAgJ2NvdW50JyxcbiAgJ2N1cnJlbnRPcCcsXG4gICdmYWNldCcsXG4gICdnZW9OZWFyJyxcbiAgJ2dyYXBoTG9va3VwJyxcbiAgJ2dyb3VwJyxcbiAgJ2luZGV4U3RhdHMnLFxuICAnbGltaXQnLFxuICAnbGlzdExvY2FsU2Vzc2lvbnMnLFxuICAnbGlzdFNlc3Npb25zJyxcbiAgJ2xvb2t1cCcsXG4gICdtYXRjaCcsXG4gICdvdXQnLFxuICAncHJvamVjdCcsXG4gICdyZWRhY3QnLFxuICAncmVwbGFjZVJvb3QnLFxuICAnc2FtcGxlJyxcbiAgJ3NraXAnLFxuICAnc29ydCcsXG4gICdzb3J0QnlDb3VudCcsXG4gICd1bndpbmQnLFxuXTtcblxuY29uc3QgQUxMT1dFRF9LRVlTID0gWy4uLkJBU0VfS0VZUywgLi4uUElQRUxJTkVfS0VZU107XG5cbmV4cG9ydCBjbGFzcyBBZ2dyZWdhdGVSb3V0ZXIgZXh0ZW5kcyBDbGFzc2VzUm91dGVyIHtcbiAgaGFuZGxlRmluZChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICBpZiAoYm9keS5kaXN0aW5jdCkge1xuICAgICAgb3B0aW9ucy5kaXN0aW5jdCA9IFN0cmluZyhib2R5LmRpc3RpbmN0KTtcbiAgICB9XG4gICAgaWYgKGJvZHkuaGludCkge1xuICAgICAgb3B0aW9ucy5oaW50ID0gYm9keS5oaW50O1xuICAgICAgZGVsZXRlIGJvZHkuaGludDtcbiAgICB9XG4gICAgaWYgKGJvZHkuZXhwbGFpbikge1xuICAgICAgb3B0aW9ucy5leHBsYWluID0gYm9keS5leHBsYWluO1xuICAgICAgZGVsZXRlIGJvZHkuZXhwbGFpbjtcbiAgICB9XG4gICAgaWYgKGJvZHkucmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSBib2R5LnJlYWRQcmVmZXJlbmNlO1xuICAgICAgZGVsZXRlIGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIG9wdGlvbnMucGlwZWxpbmUgPSBBZ2dyZWdhdGVSb3V0ZXIuZ2V0UGlwZWxpbmUoYm9keSk7XG4gICAgaWYgKHR5cGVvZiBib2R5LndoZXJlID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keS53aGVyZSA9IEpTT04ucGFyc2UoYm9keS53aGVyZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXNwb25zZS5yZXN1bHRzKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qIEJ1aWxkcyBhIHBpcGVsaW5lIGZyb20gdGhlIGJvZHkuIE9yaWdpbmFsbHkgdGhlIGJvZHkgY291bGQgYmUgcGFzc2VkIGFzIGEgc2luZ2xlIG9iamVjdCxcbiAgICogYW5kIG5vdyB3ZSBzdXBwb3J0IG1hbnkgb3B0aW9uc1xuICAgKlxuICAgKiBBcnJheVxuICAgKlxuICAgKiBib2R5OiBbe1xuICAgKiAgIGdyb3VwOiB7IG9iamVjdElkOiAnJG5hbWUnIH0sXG4gICAqIH1dXG4gICAqXG4gICAqIE9iamVjdFxuICAgKlxuICAgKiBib2R5OiB7XG4gICAqICAgZ3JvdXA6IHsgb2JqZWN0SWQ6ICckbmFtZScgfSxcbiAgICogfVxuICAgKlxuICAgKlxuICAgKiBQaXBlbGluZSBPcGVyYXRvciB3aXRoIGFuIEFycmF5IG9yIGFuIE9iamVjdFxuICAgKlxuICAgKiBib2R5OiB7XG4gICAqICAgcGlwZWxpbmU6IHtcbiAgICogICAgIGdyb3VwOiB7IG9iamVjdElkOiAnJG5hbWUnIH0sXG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqL1xuICBzdGF0aWMgZ2V0UGlwZWxpbmUoYm9keSkge1xuICAgIGxldCBwaXBlbGluZSA9IGJvZHkucGlwZWxpbmUgfHwgYm9keTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGlwZWxpbmUpKSB7XG4gICAgICBwaXBlbGluZSA9IE9iamVjdC5rZXlzKHBpcGVsaW5lKS5tYXAoa2V5ID0+IHtcbiAgICAgICAgcmV0dXJuIHsgW2tleV06IHBpcGVsaW5lW2tleV0gfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwaXBlbGluZS5tYXAoc3RhZ2UgPT4ge1xuICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHN0YWdlKTtcbiAgICAgIGlmIChrZXlzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUGlwZWxpbmUgc3RhZ2VzIHNob3VsZCBvbmx5IGhhdmUgb25lIGtleSBmb3VuZCAke2tleXMuam9pbignLCAnKX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBBZ2dyZWdhdGVSb3V0ZXIudHJhbnNmb3JtU3RhZ2Uoa2V5c1swXSwgc3RhZ2UpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zZm9ybVN0YWdlKHN0YWdlTmFtZSwgc3RhZ2UpIHtcbiAgICBpZiAoQUxMT1dFRF9LRVlTLmluZGV4T2Yoc3RhZ2VOYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCBgSW52YWxpZCBwYXJhbWV0ZXIgZm9yIHF1ZXJ5OiAke3N0YWdlTmFtZX1gKTtcbiAgICB9XG4gICAgaWYgKHN0YWdlTmFtZSA9PT0gJ2dyb3VwJykge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdGFnZVtzdGFnZU5hbWVdLCAnX2lkJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEludmFsaWQgcGFyYW1ldGVyIGZvciBxdWVyeTogZ3JvdXAuIFBsZWFzZSB1c2Ugb2JqZWN0SWQgaW5zdGVhZCBvZiBfaWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdGFnZVtzdGFnZU5hbWVdLCAnb2JqZWN0SWQnKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW52YWxpZCBwYXJhbWV0ZXIgZm9yIHF1ZXJ5OiBncm91cC4gb2JqZWN0SWQgaXMgcmVxdWlyZWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBzdGFnZVtzdGFnZU5hbWVdLl9pZCA9IHN0YWdlW3N0YWdlTmFtZV0ub2JqZWN0SWQ7XG4gICAgICBkZWxldGUgc3RhZ2Vbc3RhZ2VOYW1lXS5vYmplY3RJZDtcbiAgICB9XG4gICAgcmV0dXJuIHsgW2AkJHtzdGFnZU5hbWV9YF06IHN0YWdlW3N0YWdlTmFtZV0gfTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvYWdncmVnYXRlLzpjbGFzc05hbWUnLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFnZ3JlZ2F0ZVJvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/AnalyticsRouter.js b/lib/Routers/AnalyticsRouter.js new file mode 100644 index 0000000000..d37290b37f --- /dev/null +++ b/lib/Routers/AnalyticsRouter.js @@ -0,0 +1,32 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AnalyticsRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// AnalyticsRouter.js +function appOpened(req) { + const analyticsController = req.config.analyticsController; + return analyticsController.appOpened(req); +} + +function trackEvent(req) { + const analyticsController = req.config.analyticsController; + return analyticsController.trackEvent(req); +} + +class AnalyticsRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('POST', '/events/AppOpened', appOpened); + this.route('POST', '/events/:eventName', trackEvent); + } + +} + +exports.AnalyticsRouter = AnalyticsRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJhcHBPcGVuZWQiLCJyZXEiLCJhbmFseXRpY3NDb250cm9sbGVyIiwiY29uZmlnIiwidHJhY2tFdmVudCIsIkFuYWx5dGljc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFEQTtBQUdBLFNBQVNBLFNBQVQsQ0FBbUJDLEdBQW5CLEVBQXdCO0FBQ3RCLFFBQU1DLG1CQUFtQixHQUFHRCxHQUFHLENBQUNFLE1BQUosQ0FBV0QsbUJBQXZDO0FBQ0EsU0FBT0EsbUJBQW1CLENBQUNGLFNBQXBCLENBQThCQyxHQUE5QixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0csVUFBVCxDQUFvQkgsR0FBcEIsRUFBeUI7QUFDdkIsUUFBTUMsbUJBQW1CLEdBQUdELEdBQUcsQ0FBQ0UsTUFBSixDQUFXRCxtQkFBdkM7QUFDQSxTQUFPQSxtQkFBbUIsQ0FBQ0UsVUFBcEIsQ0FBK0JILEdBQS9CLENBQVA7QUFDRDs7QUFFTSxNQUFNSSxlQUFOLFNBQThCQyxzQkFBOUIsQ0FBNEM7QUFDakRDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLG1CQUFuQixFQUF3Q1IsU0FBeEM7QUFDQSxTQUFLUSxLQUFMLENBQVcsTUFBWCxFQUFtQixvQkFBbkIsRUFBeUNKLFVBQXpDO0FBQ0Q7O0FBSmdEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5hbHl0aWNzUm91dGVyLmpzXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcblxuZnVuY3Rpb24gYXBwT3BlbmVkKHJlcSkge1xuICBjb25zdCBhbmFseXRpY3NDb250cm9sbGVyID0gcmVxLmNvbmZpZy5hbmFseXRpY3NDb250cm9sbGVyO1xuICByZXR1cm4gYW5hbHl0aWNzQ29udHJvbGxlci5hcHBPcGVuZWQocmVxKTtcbn1cblxuZnVuY3Rpb24gdHJhY2tFdmVudChyZXEpIHtcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlciA9IHJlcS5jb25maWcuYW5hbHl0aWNzQ29udHJvbGxlcjtcbiAgcmV0dXJuIGFuYWx5dGljc0NvbnRyb2xsZXIudHJhY2tFdmVudChyZXEpO1xufVxuXG5leHBvcnQgY2xhc3MgQW5hbHl0aWNzUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy9BcHBPcGVuZWQnLCBhcHBPcGVuZWQpO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy86ZXZlbnROYW1lJywgdHJhY2tFdmVudCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/AudiencesRouter.js b/lib/Routers/AudiencesRouter.js new file mode 100644 index 0000000000..684d3e42a2 --- /dev/null +++ b/lib/Routers/AudiencesRouter.js @@ -0,0 +1,70 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AudiencesRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class AudiencesRouter extends _ClassesRouter.default { + className() { + return '_Audience'; + } + + handleFind(req) { + const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); + + const options = _ClassesRouter.default.optionsFromBody(body); + + return _rest.default.find(req.config, req.auth, '_Audience', body.where, options, req.info.clientSDK, req.info.context).then(response => { + response.results.forEach(item => { + item.query = JSON.parse(item.query); + }); + return { + response: response + }; + }); + } + + handleGet(req) { + return super.handleGet(req).then(data => { + data.response.query = JSON.parse(data.response.query); + return data; + }); + } + + mountRoutes() { + this.route('GET', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleFind(req); + }); + this.route('GET', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleGet(req); + }); + this.route('POST', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleCreate(req); + }); + this.route('PUT', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleDelete(req); + }); + } + +} + +exports.AudiencesRouter = AudiencesRouter; +var _default = AudiencesRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0F1ZGllbmNlc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJBdWRpZW5jZXNSb3V0ZXIiLCJDbGFzc2VzUm91dGVyIiwiY2xhc3NOYW1lIiwiaGFuZGxlRmluZCIsInJlcSIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwicmVzdCIsImZpbmQiLCJjb25maWciLCJhdXRoIiwid2hlcmUiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsInJlc3VsdHMiLCJmb3JFYWNoIiwiaXRlbSIsIkpTT04iLCJwYXJzZSIsImhhbmRsZUdldCIsImRhdGEiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRU8sTUFBTUEsZUFBTixTQUE4QkMsc0JBQTlCLENBQTRDO0FBQ2pEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFdBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUVBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILFdBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEJBLE1BQUFBLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQkMsT0FBakIsQ0FBeUJDLElBQUksSUFBSTtBQUMvQkEsUUFBQUEsSUFBSSxDQUFDZixLQUFMLEdBQWFnQixJQUFJLENBQUNDLEtBQUwsQ0FBV0YsSUFBSSxDQUFDZixLQUFoQixDQUFiO0FBQ0QsT0FGRDtBQUlBLGFBQU87QUFBRVksUUFBQUEsUUFBUSxFQUFFQTtBQUFaLE9BQVA7QUFDRCxLQWhCSSxDQUFQO0FBaUJEOztBQUVETSxFQUFBQSxTQUFTLENBQUN2QixHQUFELEVBQU07QUFDYixXQUFPLE1BQU11QixTQUFOLENBQWdCdkIsR0FBaEIsRUFBcUJnQixJQUFyQixDQUEwQlEsSUFBSSxJQUFJO0FBQ3ZDQSxNQUFBQSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBZCxHQUFzQmdCLElBQUksQ0FBQ0MsS0FBTCxDQUFXRSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBekIsQ0FBdEI7QUFFQSxhQUFPbUIsSUFBUDtBQUNELEtBSk0sQ0FBUDtBQUtEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixpQkFBbEIsRUFBcUNDLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFNUIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0QsVUFBTCxDQUFnQkMsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLMEIsS0FBTCxDQUNFLEtBREYsRUFFRSwyQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU1QixHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUt1QixTQUFMLENBQWV2QixHQUFmLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLGlCQUFuQixFQUFzQ0MsVUFBVSxDQUFDQyw2QkFBakQsRUFBZ0Y1QixHQUFHLElBQUk7QUFDckYsYUFBTyxLQUFLNkIsWUFBTCxDQUFrQjdCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBSzBCLEtBQUwsQ0FDRSxLQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLOEIsWUFBTCxDQUFrQjlCLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FDRSxRQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLK0IsWUFBTCxDQUFrQi9CLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUQ7O0FBbkVnRDs7O2VBc0VwQ0osZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgQXVkaWVuY2VzUm91dGVyIGV4dGVuZHMgQ2xhc3Nlc1JvdXRlciB7XG4gIGNsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ19BdWRpZW5jZSc7XG4gIH1cblxuICBoYW5kbGVGaW5kKHJlcSkge1xuICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHJlcS5ib2R5LCBDbGFzc2VzUm91dGVyLkpTT05Gcm9tUXVlcnkocmVxLnF1ZXJ5KSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IENsYXNzZXNSb3V0ZXIub3B0aW9uc0Zyb21Cb2R5KGJvZHkpO1xuXG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19BdWRpZW5jZScsXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bHRzLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgaXRlbS5xdWVyeSA9IEpTT04ucGFyc2UoaXRlbS5xdWVyeSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBoYW5kbGVHZXQocmVxKSB7XG4gICAgcmV0dXJuIHN1cGVyLmhhbmRsZUdldChyZXEpLnRoZW4oZGF0YSA9PiB7XG4gICAgICBkYXRhLnJlc3BvbnNlLnF1ZXJ5ID0gSlNPTi5wYXJzZShkYXRhLnJlc3BvbnNlLnF1ZXJ5KTtcblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3B1c2hfYXVkaWVuY2VzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlR2V0KHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9wdXNoX2F1ZGllbmNlcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVXBkYXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdWRpZW5jZXNSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/ClassesRouter.js b/lib/Routers/ClassesRouter.js new file mode 100644 index 0000000000..e3b3e93fd2 --- /dev/null +++ b/lib/Routers/ClassesRouter.js @@ -0,0 +1,231 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.ClassesRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _middlewares = require("../middlewares"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const ALLOWED_GET_QUERY_KEYS = ['keys', 'include', 'excludeKeys', 'readPreference', 'includeReadPreference', 'subqueryReadPreference']; + +class ClassesRouter extends _PromiseRouter.default { + className(req) { + return req.params.className; + } + + handleFind(req) { + const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); + const options = ClassesRouter.optionsFromBody(body); + + if (req.config.maxLimit && body.limit > req.config.maxLimit) { + // Silently replace the limit on the query with the max configured + options.limit = Number(req.config.maxLimit); + } + + if (body.redirectClassNameForKey) { + options.redirectClassNameForKey = String(body.redirectClassNameForKey); + } + + if (typeof body.where === 'string') { + body.where = JSON.parse(body.where); + } + + return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { + return { + response: response + }; + }); + } // Returns a promise for a {response} object. + + + handleGet(req) { + const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); + const options = {}; + + for (const key of Object.keys(body)) { + if (ALLOWED_GET_QUERY_KEYS.indexOf(key) === -1) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Improper encode of parameter'); + } + } + + if (typeof body.keys === 'string') { + options.keys = body.keys; + } + + if (body.include) { + options.include = String(body.include); + } + + if (typeof body.excludeKeys == 'string') { + options.excludeKeys = body.excludeKeys; + } + + if (typeof body.readPreference === 'string') { + options.readPreference = body.readPreference; + } + + if (typeof body.includeReadPreference === 'string') { + options.includeReadPreference = body.includeReadPreference; + } + + if (typeof body.subqueryReadPreference === 'string') { + options.subqueryReadPreference = body.subqueryReadPreference; + } + + return _rest.default.get(req.config, req.auth, this.className(req), req.params.objectId, options, req.info.clientSDK).then(response => { + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + if (this.className(req) === '_User') { + delete response.results[0].sessionToken; + const user = response.results[0]; + + if (req.auth.user && user.objectId == req.auth.user.id) { + // Force the session token + response.results[0].sessionToken = req.info.sessionToken; + } + } + + return { + response: response.results[0] + }; + }); + } + + handleCreate(req) { + return _rest.default.create(req.config, req.auth, this.className(req), req.body, req.info.clientSDK, req.info.context); + } + + handleUpdate(req) { + const where = { + objectId: req.params.objectId + }; + return _rest.default.update(req.config, req.auth, this.className(req), where, req.body, req.info.clientSDK, req.info.context); + } + + handleDelete(req) { + return _rest.default.del(req.config, req.auth, this.className(req), req.params.objectId, req.info.context).then(() => { + return { + response: {} + }; + }); + } + + static JSONFromQuery(query) { + const json = {}; + + for (const [key, value] of _lodash.default.entries(query)) { + try { + json[key] = JSON.parse(value); + } catch (e) { + json[key] = value; + } + } + + return json; + } + + static optionsFromBody(body) { + const allowConstraints = ['skip', 'limit', 'order', 'count', 'keys', 'excludeKeys', 'include', 'includeAll', 'redirectClassNameForKey', 'where', 'readPreference', 'includeReadPreference', 'subqueryReadPreference', 'hint', 'explain']; + + for (const key of Object.keys(body)) { + if (allowConstraints.indexOf(key) === -1) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${key}`); + } + } + + const options = {}; + + if (body.skip) { + options.skip = Number(body.skip); + } + + if (body.limit || body.limit === 0) { + options.limit = Number(body.limit); + } else { + options.limit = Number(100); + } + + if (body.order) { + options.order = String(body.order); + } + + if (body.count) { + options.count = true; + } + + if (typeof body.keys == 'string') { + options.keys = body.keys; + } + + if (typeof body.excludeKeys == 'string') { + options.excludeKeys = body.excludeKeys; + } + + if (body.include) { + options.include = String(body.include); + } + + if (body.includeAll) { + options.includeAll = true; + } + + if (typeof body.readPreference === 'string') { + options.readPreference = body.readPreference; + } + + if (typeof body.includeReadPreference === 'string') { + options.includeReadPreference = body.includeReadPreference; + } + + if (typeof body.subqueryReadPreference === 'string') { + options.subqueryReadPreference = body.subqueryReadPreference; + } + + if (body.hint && (typeof body.hint === 'string' || typeof body.hint === 'object')) { + options.hint = body.hint; + } + + if (body.explain) { + options.explain = body.explain; + } + + return options; + } + + mountRoutes() { + this.route('GET', '/classes/:className', req => { + return this.handleFind(req); + }); + this.route('GET', '/classes/:className/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/classes/:className', _middlewares.promiseEnsureIdempotency, req => { + return this.handleCreate(req); + }); + this.route('PUT', '/classes/:className/:objectId', _middlewares.promiseEnsureIdempotency, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/classes/:className/:objectId', req => { + return this.handleDelete(req); + }); + } + +} + +exports.ClassesRouter = ClassesRouter; +var _default = ClassesRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiQUxMT1dFRF9HRVRfUVVFUllfS0VZUyIsIkNsYXNzZXNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiY2xhc3NOYW1lIiwicmVxIiwicGFyYW1zIiwiaGFuZGxlRmluZCIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwiY29uZmlnIiwibWF4TGltaXQiLCJsaW1pdCIsIk51bWJlciIsInJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IiwiU3RyaW5nIiwid2hlcmUiLCJKU09OIiwicGFyc2UiLCJyZXN0IiwiZmluZCIsImF1dGgiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsImhhbmRsZUdldCIsImtleSIsImtleXMiLCJpbmRleE9mIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJpbmNsdWRlIiwiZXhjbHVkZUtleXMiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJnZXQiLCJvYmplY3RJZCIsInJlc3VsdHMiLCJsZW5ndGgiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwic2Vzc2lvblRva2VuIiwidXNlciIsImlkIiwiaGFuZGxlQ3JlYXRlIiwiY3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwidXBkYXRlIiwiaGFuZGxlRGVsZXRlIiwiZGVsIiwianNvbiIsInZhbHVlIiwiXyIsImVudHJpZXMiLCJlIiwiYWxsb3dDb25zdHJhaW50cyIsInNraXAiLCJvcmRlciIsImNvdW50IiwiaW5jbHVkZUFsbCIsImhpbnQiLCJleHBsYWluIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNB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cG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuY29uc3QgQUxMT1dFRF9HRVRfUVVFUllfS0VZUyA9IFtcbiAgJ2tleXMnLFxuICAnaW5jbHVkZScsXG4gICdleGNsdWRlS2V5cycsXG4gICdyZWFkUHJlZmVyZW5jZScsXG4gICdpbmNsdWRlUmVhZFByZWZlcmVuY2UnLFxuICAnc3VicXVlcnlSZWFkUHJlZmVyZW5jZScsXG5dO1xuXG5leHBvcnQgY2xhc3MgQ2xhc3Nlc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjbGFzc05hbWUocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICB9XG5cbiAgaGFuZGxlRmluZChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSBDbGFzc2VzUm91dGVyLm9wdGlvbnNGcm9tQm9keShib2R5KTtcbiAgICBpZiAocmVxLmNvbmZpZy5tYXhMaW1pdCAmJiBib2R5LmxpbWl0ID4gcmVxLmNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgLy8gU2lsZW50bHkgcmVwbGFjZSB0aGUgbGltaXQgb24gdGhlIHF1ZXJ5IHdpdGggdGhlIG1heCBjb25maWd1cmVkXG4gICAgICBvcHRpb25zLmxpbWl0ID0gTnVtYmVyKHJlcS5jb25maWcubWF4TGltaXQpO1xuICAgIH1cbiAgICBpZiAoYm9keS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSkge1xuICAgICAgb3B0aW9ucy5yZWRpcmVjdENsYXNzTmFtZUZvcktleSA9IFN0cmluZyhib2R5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LndoZXJlID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keS53aGVyZSA9IEpTT04ucGFyc2UoYm9keS53aGVyZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlfSBvYmplY3QuXG4gIGhhbmRsZUdldChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGJvZHkpKSB7XG4gICAgICBpZiAoQUxMT1dFRF9HRVRfUVVFUllfS0VZUy5pbmRleE9mKGtleSkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnSW1wcm9wZXIgZW5jb2RlIG9mIHBhcmFtZXRlcicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYm9keS5rZXlzID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5rZXlzID0gYm9keS5rZXlzO1xuICAgIH1cbiAgICBpZiAoYm9keS5pbmNsdWRlKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGUgPSBTdHJpbmcoYm9keS5pbmNsdWRlKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdFxuICAgICAgLmdldChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIHJlcS5wYXJhbXMub2JqZWN0SWQsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNES1xuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNsYXNzTmFtZShyZXEpID09PSAnX1VzZXInKSB7XG4gICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLnJlc3VsdHNbMF0uc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG5cbiAgICAgICAgICBpZiAocmVxLmF1dGgudXNlciAmJiB1c2VyLm9iamVjdElkID09IHJlcS5hdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSBzZXNzaW9uIHRva2VuXG4gICAgICAgICAgICByZXNwb25zZS5yZXN1bHRzWzBdLnNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlLnJlc3VsdHNbMF0gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlQ3JlYXRlKHJlcSkge1xuICAgIHJldHVybiByZXN0LmNyZWF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICByZXEuYm9keSxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlKHJlcSkge1xuICAgIGNvbnN0IHdoZXJlID0geyBvYmplY3RJZDogcmVxLnBhcmFtcy5vYmplY3RJZCB9O1xuICAgIHJldHVybiByZXN0LnVwZGF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICB3aGVyZSxcbiAgICAgIHJlcS5ib2R5LFxuICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5kZWwocmVxLmNvbmZpZywgcmVxLmF1dGgsIHRoaXMuY2xhc3NOYW1lKHJlcSksIHJlcS5wYXJhbXMub2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBzdGF0aWMgSlNPTkZyb21RdWVyeShxdWVyeSkge1xuICAgIGNvbnN0IGpzb24gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBfLmVudHJpZXMocXVlcnkpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBqc29uW2tleV0gPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAganNvbltrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgc3RhdGljIG9wdGlvbnNGcm9tQm9keShib2R5KSB7XG4gICAgY29uc3QgYWxsb3dDb25zdHJhaW50cyA9IFtcbiAgICAgICdza2lwJyxcbiAgICAgICdsaW1pdCcsXG4gICAgICAnb3JkZXInLFxuICAgICAgJ2NvdW50JyxcbiAgICAgICdrZXlzJyxcbiAgICAgICdleGNsdWRlS2V5cycsXG4gICAgICAnaW5jbHVkZScsXG4gICAgICAnaW5jbHVkZUFsbCcsXG4gICAgICAncmVkaXJlY3RDbGFzc05hbWVGb3JLZXknLFxuICAgICAgJ3doZXJlJyxcbiAgICAgICdyZWFkUHJlZmVyZW5jZScsXG4gICAgICAnaW5jbHVkZVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdzdWJxdWVyeVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdoaW50JyxcbiAgICAgICdleHBsYWluJyxcbiAgICBdO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYm9keSkpIHtcbiAgICAgIGlmIChhbGxvd0NvbnN0cmFpbnRzLmluZGV4T2Yoa2V5KSA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6ICR7a2V5fWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgaWYgKGJvZHkuc2tpcCkge1xuICAgICAgb3B0aW9ucy5za2lwID0gTnVtYmVyKGJvZHkuc2tpcCk7XG4gICAgfVxuICAgIGlmIChib2R5LmxpbWl0IHx8IGJvZHkubGltaXQgPT09IDApIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoYm9keS5saW1pdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoMTAwKTtcbiAgICB9XG4gICAgaWYgKGJvZHkub3JkZXIpIHtcbiAgICAgIG9wdGlvbnMub3JkZXIgPSBTdHJpbmcoYm9keS5vcmRlcik7XG4gICAgfVxuICAgIGlmIChib2R5LmNvdW50KSB7XG4gICAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmtleXMgPT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMua2V5cyA9IGJvZHkua2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKGJvZHkuaW5jbHVkZSkge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlID0gU3RyaW5nKGJvZHkuaW5jbHVkZSk7XG4gICAgfVxuICAgIGlmIChib2R5LmluY2x1ZGVBbGwpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5yZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSBib2R5LnJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSBib2R5LmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChib2R5LmhpbnQgJiYgKHR5cGVvZiBib2R5LmhpbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBib2R5LmhpbnQgPT09ICdvYmplY3QnKSkge1xuICAgICAgb3B0aW9ucy5oaW50ID0gYm9keS5oaW50O1xuICAgIH1cbiAgICBpZiAoYm9keS5leHBsYWluKSB7XG4gICAgICBvcHRpb25zLmV4cGxhaW4gPSBib2R5LmV4cGxhaW47XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvY2xhc3Nlcy86Y2xhc3NOYW1lLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2xhc3Nlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/CloudCodeRouter.js b/lib/Routers/CloudCodeRouter.js new file mode 100644 index 0000000000..423ee10a50 --- /dev/null +++ b/lib/Routers/CloudCodeRouter.js @@ -0,0 +1,105 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CloudCodeRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _rest = _interopRequireDefault(require("../rest")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const triggers = require('../triggers'); + +const middleware = require('../middlewares'); + +function formatJobSchedule(job_schedule) { + if (typeof job_schedule.startAfter === 'undefined') { + job_schedule.startAfter = new Date().toISOString(); + } + + return job_schedule; +} + +function validateJobSchedule(config, job_schedule) { + const jobs = triggers.getJobs(config.applicationId) || {}; + + if (job_schedule.jobName && !jobs[job_schedule.jobName]) { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Cannot Schedule a job that is not deployed'); + } +} + +class CloudCodeRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobs); + this.route('GET', '/cloud_code/jobs/data', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobsData); + this.route('POST', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.createJob); + this.route('PUT', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.editJob); + this.route('DELETE', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.deleteJob); + } + + static getJobs(req) { + return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { + return { + response: scheduledJobs.results + }; + }); + } + + static getJobsData(req) { + const config = req.config; + const jobs = triggers.getJobs(config.applicationId) || {}; + return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { + return { + response: { + in_use: scheduledJobs.results.map(job => job.jobName), + jobs: Object.keys(jobs) + } + }; + }); + } + + static createJob(req) { + const { + job_schedule + } = req.body; + validateJobSchedule(req.config, job_schedule); + return _rest.default.create(req.config, req.auth, '_JobSchedule', formatJobSchedule(job_schedule), req.client, req.info.context); + } + + static editJob(req) { + const { + objectId + } = req.params; + const { + job_schedule + } = req.body; + validateJobSchedule(req.config, job_schedule); + return _rest.default.update(req.config, req.auth, '_JobSchedule', { + objectId + }, formatJobSchedule(job_schedule), undefined, req.info.context).then(response => { + return { + response + }; + }); + } + + static deleteJob(req) { + const { + objectId + } = req.params; + return _rest.default.del(req.config, req.auth, '_JobSchedule', objectId, req.info.context).then(response => { + return { + response + }; + }); + } + +} + +exports.CloudCodeRouter = CloudCodeRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Nsb3VkQ29kZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJ0cmlnZ2VycyIsInJlcXVpcmUiLCJtaWRkbGV3YXJlIiwiZm9ybWF0Sm9iU2NoZWR1bGUiLCJqb2Jfc2NoZWR1bGUiLCJzdGFydEFmdGVyIiwiRGF0ZSIsInRvSVNPU3RyaW5nIiwidmFsaWRhdGVKb2JTY2hlZHVsZSIsImNvbmZpZyIsImpvYnMiLCJnZXRKb2JzIiwiYXBwbGljYXRpb25JZCIsImpvYk5hbWUiLCJQYXJzZSIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiQ2xvdWRDb2RlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImdldEpvYnNEYXRhIiwiY3JlYXRlSm9iIiwiZWRpdEpvYiIsImRlbGV0ZUpvYiIsInJlcSIsInJlc3QiLCJmaW5kIiwiYXV0aCIsInRoZW4iLCJzY2hlZHVsZWRKb2JzIiwicmVzcG9uc2UiLCJyZXN1bHRzIiwiaW5fdXNlIiwibWFwIiwiam9iIiwiT2JqZWN0Iiwia2V5cyIsImJvZHkiLCJjcmVhdGUiLCJjbGllbnQiLCJpbmZvIiwiY29udGV4dCIsIm9iamVjdElkIiwicGFyYW1zIiwidXBkYXRlIiwidW5kZWZpbmVkIiwiZGVsIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFDQSxNQUFNQSxRQUFRLEdBQUdDLE9BQU8sQ0FBQyxhQUFELENBQXhCOztBQUNBLE1BQU1DLFVBQVUsR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTFCOztBQUVBLFNBQVNFLGlCQUFULENBQTJCQyxZQUEzQixFQUF5QztBQUN2QyxNQUFJLE9BQU9BLFlBQVksQ0FBQ0MsVUFBcEIsS0FBbUMsV0FBdkMsRUFBb0Q7QUFDbERELElBQUFBLFlBQVksQ0FBQ0MsVUFBYixHQUEwQixJQUFJQyxJQUFKLEdBQVdDLFdBQVgsRUFB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dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5jb25zdCB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5jb25zdCBtaWRkbGV3YXJlID0gcmVxdWlyZSgnLi4vbWlkZGxld2FyZXMnKTtcblxuZnVuY3Rpb24gZm9ybWF0Sm9iU2NoZWR1bGUoam9iX3NjaGVkdWxlKSB7XG4gIGlmICh0eXBlb2Ygam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIGpvYl9zY2hlZHVsZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKb2JTY2hlZHVsZShjb25maWcsIGpvYl9zY2hlZHVsZSkge1xuICBjb25zdCBqb2JzID0gdHJpZ2dlcnMuZ2V0Sm9icyhjb25maWcuYXBwbGljYXRpb25JZCkgfHwge307XG4gIGlmIChqb2Jfc2NoZWR1bGUuam9iTmFtZSAmJiAham9ic1tqb2Jfc2NoZWR1bGUuam9iTmFtZV0pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAnQ2Fubm90IFNjaGVkdWxlIGEgam9iIHRoYXQgaXMgbm90IGRlcGxveWVkJ1xuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENsb3VkQ29kZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgQ2xvdWRDb2RlUm91dGVyLmdldEpvYnNcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnR0VUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzL2RhdGEnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5nZXRKb2JzRGF0YVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBDbG91ZENvZGVSb3V0ZXIuY3JlYXRlSm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5lZGl0Sm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5kZWxldGVKb2JcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnMocmVxKSB7XG4gICAgcmV0dXJuIHJlc3QuZmluZChyZXEuY29uZmlnLCByZXEuYXV0aCwgJ19Kb2JTY2hlZHVsZScsIHt9LCB7fSkudGhlbihzY2hlZHVsZWRKb2JzID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlOiBzY2hlZHVsZWRKb2JzLnJlc3VsdHMsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnNEYXRhKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3Qgam9icyA9IHRyaWdnZXJzLmdldEpvYnMoY29uZmlnLmFwcGxpY2F0aW9uSWQpIHx8IHt9O1xuICAgIHJldHVybiByZXN0LmZpbmQocmVxLmNvbmZpZywgcmVxLmF1dGgsICdfSm9iU2NoZWR1bGUnLCB7fSwge30pLnRoZW4oc2NoZWR1bGVkSm9icyA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGluX3VzZTogc2NoZWR1bGVkSm9icy5yZXN1bHRzLm1hcChqb2IgPT4gam9iLmpvYk5hbWUpLFxuICAgICAgICAgIGpvYnM6IE9iamVjdC5rZXlzKGpvYnMpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVKb2IocmVxKSB7XG4gICAgY29uc3QgeyBqb2Jfc2NoZWR1bGUgfSA9IHJlcS5ib2R5O1xuICAgIHZhbGlkYXRlSm9iU2NoZWR1bGUocmVxLmNvbmZpZywgam9iX3NjaGVkdWxlKTtcbiAgICByZXR1cm4gcmVzdC5jcmVhdGUoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgIGZvcm1hdEpvYlNjaGVkdWxlKGpvYl9zY2hlZHVsZSksXG4gICAgICByZXEuY2xpZW50LFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZWRpdEpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IHsgam9iX3NjaGVkdWxlIH0gPSByZXEuYm9keTtcbiAgICB2YWxpZGF0ZUpvYlNjaGVkdWxlKHJlcS5jb25maWcsIGpvYl9zY2hlZHVsZSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC51cGRhdGUoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIHJlcS5hdXRoLFxuICAgICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgICAgeyBvYmplY3RJZCB9LFxuICAgICAgICBmb3JtYXRKb2JTY2hlZHVsZShqb2Jfc2NoZWR1bGUpLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGRlbGV0ZUpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZGVsKHJlcS5jb25maWcsIHJlcS5hdXRoLCAnX0pvYlNjaGVkdWxlJywgb2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Routers/FeaturesRouter.js b/lib/Routers/FeaturesRouter.js new file mode 100644 index 0000000000..51c3c26849 --- /dev/null +++ b/lib/Routers/FeaturesRouter.js @@ -0,0 +1,79 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FeaturesRouter = void 0; + +var _package = require("../../package.json"); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class FeaturesRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/serverInfo', middleware.promiseEnforceMasterKeyAccess, req => { + const { + config + } = req; + const features = { + globalConfig: { + create: true, + read: true, + update: true, + delete: true + }, + hooks: { + create: true, + read: true, + update: true, + delete: true + }, + cloudCode: { + jobs: true + }, + logs: { + level: true, + size: true, + order: true, + until: true, + from: true + }, + push: { + immediatePush: config.hasPushSupport, + scheduledPush: config.hasPushScheduledSupport, + storedPushData: config.hasPushSupport, + pushAudiences: true, + localization: true + }, + schemas: { + addField: true, + removeField: true, + addClass: true, + removeClass: true, + clearAllDataFromClass: true, + exportClass: false, + editClassLevelPermissions: true, + editPointerPermissions: true + } + }; + return { + response: { + features: features, + parseServerVersion: _package.version + } + }; + }); + } + +} + +exports.FeaturesRouter = FeaturesRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZlYXR1cmVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkZlYXR1cmVzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXEiLCJjb25maWciLCJmZWF0dXJlcyIsImdsb2JhbENvbmZpZyIsImNyZWF0ZSIsInJlYWQiLCJ1cGRhdGUiLCJkZWxldGUiLCJob29rcyIsImNsb3VkQ29kZSIsImpvYnMiLCJsb2dzIiwibGV2ZWwiLCJzaXplIiwib3JkZXIiLCJ1bnRpbCIsImZyb20iLCJwdXNoIiwiaW1tZWRpYXRlUHVzaCIsImhhc1B1c2hTdXBwb3J0Iiwic2NoZWR1bGVkUHVzaCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0Iiwic3RvcmVkUHVzaERhdGEiLCJwdXNoQXVkaWVuY2VzIiwibG9jYWxpemF0aW9uIiwic2NoZW1hcyIsImFkZEZpZWxkIiwicmVtb3ZlRmllbGQiLCJhZGRDbGFzcyIsInJlbW92ZUNsYXNzIiwiY2xlYXJBbGxEYXRhRnJvbUNsYXNzIiwiZXhwb3J0Q2xhc3MiLCJlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiZWRpdFBvaW50ZXJQZXJtaXNzaW9ucyIsInJlc3BvbnNlIiwicGFyc2VTZXJ2ZXJWZXJzaW9uIiwidmVyc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVPLE1BQU1BLGNBQU4sU0FBNkJDLHNCQUE3QixDQUEyQztBQUNoREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsYUFBbEIsRUFBaUNDLFVBQVUsQ0FBQ0MsNkJBQTVDLEVBQTJFQyxHQUFHLElBQUk7QUFDaEYsWUFBTTtBQUFFQyxRQUFBQTtBQUFGLFVBQWFELEdBQW5CO0FBQ0EsWUFBTUUsUUFBUSxHQUFHO0FBQ2ZDLFFBQUFBLFlBQVksRUFBRTtBQUNaQyxVQUFBQSxNQUFNLEVBQUUsSUFESTtBQUVaQyxVQUFBQSxJQUFJLEVBQUUsSUFGTTtBQUdaQyxVQUFBQSxNQUFNLEVBQUUsSUFISTtBQUlaQyxVQUFBQSxNQUFNLEVBQUU7QUFKSSxTQURDO0FBT2ZDLFFBQUFBLEtBQUssRUFBRTtBQUNMSixVQUFBQSxNQUFNLEVBQUUsSUFESDtBQUVMQyxVQUFBQSxJQUFJLEVBQUUsSUFGRDtBQUdMQyxVQUFBQSxNQUFNLEVBQUUsSUFISDtBQUlMQyxVQUFBQSxNQUFNLEVBQUU7QUFKSCxTQVBRO0FBYWZFLFFBQUFBLFNBQVMsRUFBRTtBQUNUQyxVQUFBQSxJQUFJLEVBQUU7QUFERyxTQWJJO0FBZ0JmQyxRQUFBQSxJQUFJLEVBQUU7QUFDSkMsVUFBQUEsS0FBSyxFQUFFLElBREg7QUFFSkMsVUFBQUEsSUFBSSxFQUFFLElBRkY7QUFHSkMsVUFBQUEsS0FBSyxFQUFFLElBSEg7QUFJSkMsVUFBQUEsS0FBSyxFQUFFLElBSkg7QUFLSkMsVUFBQUEsSUFBSSxFQUFFO0FBTEYsU0FoQlM7QUF1QmZDLFFBQUFBLElBQUksRUFBRTtBQUNKQyxVQUFBQSxhQUFhLEVBQUVqQixNQUFNLENBQUNrQixjQURsQjtBQUVKQyxVQUFBQSxhQUFhLEVBQUVuQixNQUFNLENBQUNvQix1QkFGbEI7QUFHSkMsVUFBQUEsY0FBYyxFQUFFckIsTUFBTSxDQUFDa0IsY0FIbkI7QUFJSkksVUFBQUEsYUFBYSxFQUFFLElBSlg7QUFLSkMsVUFBQUEsWUFBWSxFQUFFO0FBTFYsU0F2QlM7QUE4QmZDLFFBQUFBLE9BQU8sRUFBRTtBQUNQQyxVQUFBQSxRQUFRLEVBQUUsSUFESDtBQUVQQyxVQUFBQSxXQUFXLEVBQUUsSUFGTjtBQUdQQyxVQUFBQSxRQUFRLEVBQUUsSUFISDtBQUlQQyxVQUFBQSxXQUFXLEVBQUUsSUFKTjtBQUtQQyxVQUFBQSxxQkFBcUIsRUFBRSxJQUxoQjtBQU1QQyxVQUFBQSxXQUFXLEVBQUUsS0FOTjtBQU9QQyxVQUFBQSx5QkFBeUIsRUFBRSxJQVBwQjtBQVFQQyxVQUFBQSxzQkFBc0IsRUFBRTtBQVJqQjtBQTlCTSxPQUFqQjtBQTBDQSxhQUFPO0FBQ0xDLFFBQUFBLFFBQVEsRUFBRTtBQUNSaEMsVUFBQUEsUUFBUSxFQUFFQSxRQURGO0FBRVJpQyxVQUFBQSxrQkFBa0IsRUFBRUM7QUFGWjtBQURMLE9BQVA7QUFNRCxLQWxERDtBQW1ERDs7QUFyRCtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgRmVhdHVyZXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zZXJ2ZXJJbmZvJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSByZXE7XG4gICAgICBjb25zdCBmZWF0dXJlcyA9IHtcbiAgICAgICAgZ2xvYmFsQ29uZmlnOiB7XG4gICAgICAgICAgY3JlYXRlOiB0cnVlLFxuICAgICAgICAgIHJlYWQ6IHRydWUsXG4gICAgICAgICAgdXBkYXRlOiB0cnVlLFxuICAgICAgICAgIGRlbGV0ZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgaG9va3M6IHtcbiAgICAgICAgICBjcmVhdGU6IHRydWUsXG4gICAgICAgICAgcmVhZDogdHJ1ZSxcbiAgICAgICAgICB1cGRhdGU6IHRydWUsXG4gICAgICAgICAgZGVsZXRlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjbG91ZENvZGU6IHtcbiAgICAgICAgICBqb2JzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBsb2dzOiB7XG4gICAgICAgICAgbGV2ZWw6IHRydWUsXG4gICAgICAgICAgc2l6ZTogdHJ1ZSxcbiAgICAgICAgICBvcmRlcjogdHJ1ZSxcbiAgICAgICAgICB1bnRpbDogdHJ1ZSxcbiAgICAgICAgICBmcm9tOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBwdXNoOiB7XG4gICAgICAgICAgaW1tZWRpYXRlUHVzaDogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHNjaGVkdWxlZFB1c2g6IGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICAgICAgICBzdG9yZWRQdXNoRGF0YTogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHB1c2hBdWRpZW5jZXM6IHRydWUsXG4gICAgICAgICAgbG9jYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgYWRkRmllbGQ6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlRmllbGQ6IHRydWUsXG4gICAgICAgICAgYWRkQ2xhc3M6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlQ2xhc3M6IHRydWUsXG4gICAgICAgICAgY2xlYXJBbGxEYXRhRnJvbUNsYXNzOiB0cnVlLFxuICAgICAgICAgIGV4cG9ydENsYXNzOiBmYWxzZSxcbiAgICAgICAgICBlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zOiB0cnVlLFxuICAgICAgICAgIGVkaXRQb2ludGVyUGVybWlzc2lvbnM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGZlYXR1cmVzOiBmZWF0dXJlcyxcbiAgICAgICAgICBwYXJzZVNlcnZlclZlcnNpb246IHZlcnNpb24sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/FilesRouter.js b/lib/Routers/FilesRouter.js new file mode 100644 index 0000000000..9927bbfe57 --- /dev/null +++ b/lib/Routers/FilesRouter.js @@ -0,0 +1,260 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FilesRouter = void 0; + +var _express = _interopRequireDefault(require("express")); + +var _bodyParser = _interopRequireDefault(require("body-parser")); + +var Middlewares = _interopRequireWildcard(require("../middlewares")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _mime = _interopRequireDefault(require("mime")); + +var _logger = _interopRequireDefault(require("../logger")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const triggers = require('../triggers'); + +const http = require('http'); + +const downloadFileFromURI = uri => { + return new Promise((res, rej) => { + http.get(uri, response => { + response.setDefaultEncoding('base64'); + let body = `data:${response.headers['content-type']};base64,`; + response.on('data', data => body += data); + response.on('end', () => res(body)); + }).on('error', e => { + rej(`Error downloading file from ${uri}: ${e.message}`); + }); + }); +}; + +const addFileDataIfNeeded = async file => { + if (file._source.format === 'uri') { + const base64 = await downloadFileFromURI(file._source.uri); + file._previousSave = file; + file._data = base64; + file._requestTask = null; + } + + return file; +}; + +class FilesRouter { + expressRouter({ + maxUploadSize = '20Mb' + } = {}) { + var router = _express.default.Router(); + + router.get('/files/:appId/:filename', this.getHandler); + router.get('/files/:appId/metadata/:filename', this.metadataHandler); + router.post('/files', function (req, res, next) { + next(new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename not provided.')); + }); + router.post('/files/:filename', _bodyParser.default.raw({ + type: () => { + return true; + }, + limit: maxUploadSize + }), // Allow uploads without Content-Type, or with any Content-Type. + Middlewares.handleParseHeaders, this.createHandler); + router.delete('/files/:filename', Middlewares.handleParseHeaders, Middlewares.enforceMasterKeyAccess, this.deleteHandler); + return router; + } + + getHandler(req, res) { + const config = _Config.default.get(req.params.appId); + + const filesController = config.filesController; + const filename = req.params.filename; + + const contentType = _mime.default.getType(filename); + + if (isFileStreamable(req, filesController)) { + filesController.handleFileStream(config, filename, req, res, contentType).catch(() => { + res.status(404); + res.set('Content-Type', 'text/plain'); + res.end('File not found.'); + }); + } else { + filesController.getFileData(config, filename).then(data => { + res.status(200); + res.set('Content-Type', contentType); + res.set('Content-Length', data.length); + res.end(data); + }).catch(() => { + res.status(404); + res.set('Content-Type', 'text/plain'); + res.end('File not found.'); + }); + } + } + + async createHandler(req, res, next) { + const config = req.config; + const filesController = config.filesController; + const { + filename + } = req.params; + const contentType = req.get('Content-type'); + + if (!req.body || !req.body.length) { + next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.')); + return; + } + + const error = filesController.validateFilename(filename); + + if (error) { + next(error); + return; + } + + const base64 = req.body.toString('base64'); + const file = new _node.default.File(filename, { + base64 + }, contentType); + const { + metadata = {}, + tags = {} + } = req.fileData || {}; + file.setTags(tags); + file.setMetadata(metadata); + const fileSize = Buffer.byteLength(req.body); + const fileObject = { + file, + fileSize + }; + + try { + // run beforeSaveFile trigger + const triggerResult = await triggers.maybeRunFileTrigger(triggers.Types.beforeSaveFile, fileObject, config, req.auth); + let saveResult; // if a new ParseFile is returned check if it's an already saved file + + if (triggerResult instanceof _node.default.File) { + fileObject.file = triggerResult; + + if (triggerResult.url()) { + // set fileSize to null because we wont know how big it is here + fileObject.fileSize = null; + saveResult = { + url: triggerResult.url(), + name: triggerResult._name + }; + } + } // if the file returned by the trigger has already been saved skip saving anything + + + if (!saveResult) { + // if the ParseFile returned is type uri, download the file before saving it + await addFileDataIfNeeded(fileObject.file); // update fileSize + + const bufferData = Buffer.from(fileObject.file._data, 'base64'); + fileObject.fileSize = Buffer.byteLength(bufferData); // save file + + const createFileResult = await filesController.createFile(config, fileObject.file._name, bufferData, fileObject.file._source.type, { + tags: fileObject.file._tags, + metadata: fileObject.file._metadata + }); // update file with new data + + fileObject.file._name = createFileResult.name; + fileObject.file._url = createFileResult.url; + fileObject.file._requestTask = null; + fileObject.file._previousSave = Promise.resolve(fileObject.file); + saveResult = { + url: createFileResult.url, + name: createFileResult.name + }; + } // run afterSaveFile trigger + + + await triggers.maybeRunFileTrigger(triggers.Types.afterSaveFile, fileObject, config, req.auth); + res.status(201); + res.set('Location', saveResult.url); + res.json(saveResult); + } catch (e) { + _logger.default.error('Error creating a file: ', e); + + const error = triggers.resolveError(e, { + code: _node.default.Error.FILE_SAVE_ERROR, + message: `Could not store file: ${fileObject.file._name}.` + }); + next(error); + } + } + + async deleteHandler(req, res, next) { + try { + const { + filesController + } = req.config; + const { + filename + } = req.params; // run beforeDeleteFile trigger + + const file = new _node.default.File(filename); + file._url = filesController.adapter.getFileLocation(req.config, filename); + const fileObject = { + file, + fileSize: null + }; + await triggers.maybeRunFileTrigger(triggers.Types.beforeDeleteFile, fileObject, req.config, req.auth); // delete file + + await filesController.deleteFile(req.config, filename); // run afterDeleteFile trigger + + await triggers.maybeRunFileTrigger(triggers.Types.afterDeleteFile, fileObject, req.config, req.auth); + res.status(200); // TODO: return useful JSON here? + + res.end(); + } catch (e) { + _logger.default.error('Error deleting a file: ', e); + + const error = triggers.resolveError(e, { + code: _node.default.Error.FILE_DELETE_ERROR, + message: 'Could not delete file.' + }); + next(error); + } + } + + async metadataHandler(req, res) { + const config = _Config.default.get(req.params.appId); + + const { + filesController + } = config; + const { + filename + } = req.params; + + try { + const data = await filesController.getMetadata(filename); + res.status(200); + res.json(data); + } catch (e) { + res.status(200); + res.json({}); + } + } + +} + +exports.FilesRouter = FilesRouter; + +function isFileStreamable(req, filesController) { + return req.get('Range') && typeof filesController.adapter.handleFileStream === 'function'; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZpbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbInRyaWdnZXJzIiwicmVxdWlyZSIsImh0dHAiLCJkb3dubG9hZEZpbGVGcm9tVVJJIiwidXJpIiwiUHJvbWlzZSIsInJlcyIsInJlaiIsImdldCIsInJlc3BvbnNlIiwic2V0RGVmYXVsdEVuY29kaW5nIiwiYm9keSIsImhlYWRlcnMiLCJvbiIsImRhdGEiLCJlIiwibWVzc2FnZSIsImFkZEZpbGVEYXRhSWZOZWVkZWQiLCJmaWxlIiwiX3NvdXJjZSIsImZvcm1hdCIsImJhc2U2NCIsIl9wcmV2aW91c1NhdmUiLCJfZGF0YSIsIl9yZXF1ZXN0VGFzayIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsIm1heFVwbG9hZFNpemUiLCJyb3V0ZXIiLCJleHByZXNzIiwiUm91dGVyIiwiZ2V0SGFuZGxlciIsIm1ldGFkYXRhSGFuZGxlciIsInBvc3QiLCJyZXEiLCJuZXh0IiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIiwiQm9keVBhcnNlciIsInJhdyIsInR5cGUiLCJsaW1pdCIsIk1pZGRsZXdhcmVzIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiY3JlYXRlSGFuZGxlciIsImRlbGV0ZSIsImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJkZWxldGVIYW5kbGVyIiwiY29uZmlnIiwiQ29uZmlnIiwicGFyYW1zIiwiYXBwSWQiLCJmaWxlc0NvbnRyb2xsZXIiLCJmaWxlbmFtZSIsImNvbnRlbnRUeXBlIiwibWltZSIsImdldFR5cGUiLCJpc0ZpbGVTdHJlYW1hYmxlIiwiaGFuZGxlRmlsZVN0cmVhbSIsImNhdGNoIiwic3RhdHVzIiwic2V0IiwiZW5kIiwiZ2V0RmlsZURhdGEiLCJ0aGVuIiwibGVuZ3RoIiwiRklMRV9TQVZFX0VSUk9SIiwiZXJyb3IiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwidG9TdHJpbmciLCJGaWxlIiwibWV0YWRhdGEiLCJ0YWdzIiwiZmlsZURhdGEiLCJzZXRUYWdzIiwic2V0TWV0YWRhdGEiLCJmaWxlU2l6ZSIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJmaWxlT2JqZWN0IiwidHJpZ2dlclJlc3VsdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJUeXBlcyIsImJlZm9yZVNhdmVGaWxlIiwiYXV0aCIsInNhdmVSZXN1bHQiLCJ1cmwiLCJuYW1lIiwiX25hbWUiLCJidWZmZXJEYXRhIiwiZnJvbSIsImNyZWF0ZUZpbGVSZXN1bHQiLCJjcmVhdGVGaWxlIiwiX3RhZ3MiLCJfbWV0YWRhdGEiLCJfdXJsIiwicmVzb2x2ZSIsImFmdGVyU2F2ZUZpbGUiLCJqc29uIiwibG9nZ2VyIiwicmVzb2x2ZUVycm9yIiwiY29kZSIsImFkYXB0ZXIiLCJnZXRGaWxlTG9jYXRpb24iLCJiZWZvcmVEZWxldGVGaWxlIiwiZGVsZXRlRmlsZSIsImFmdGVyRGVsZXRlRmlsZSIsIkZJTEVfREVMRVRFX0VSUk9SIiwiZ2V0TWV0YWRhdGEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFDQSxNQUFNQSxRQUFRLEdBQUdDLE9BQU8sQ0FBQyxhQUFELENBQXhCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLE1BQUQsQ0FBcEI7O0FBRUEsTUFBTUUsbUJBQW1CLEdBQUdDLEdBQUcsSUFBSTtBQUNqQyxTQUFPLElBQUlDLE9BQUosQ0FBWSxDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUMvQkwsSUFBQUEsSUFBSSxDQUNETSxHQURILENBQ09KLEdBRFAsRUFDWUssUUFBUSxJQUFJO0FBQ3BCQSxNQUFBQSxRQUFRLENBQUNDLGtCQUFULENBQTRCLFFBQTVCO0FBQ0EsVUFBSUMsSUFBSSxHQUFJLFFBQU9GLFFBQVEsQ0FBQ0csT0FBVCxDQUFpQixjQUFqQixDQUFpQyxVQUFwRDtBQUNBSCxNQUFBQSxRQUFRLENBQUNJLEVBQVQsQ0FBWSxNQUFaLEVBQW9CQyxJQUFJLElBQUtILElBQUksSUFBSUcsSUFBckM7QUFDQUwsTUFBQUEsUUFBUSxDQUFDSSxFQUFULENBQVksS0FBWixFQUFtQixNQUFNUCxHQUFHLENBQUNLLElBQUQsQ0FBNUI7QUFDRCxLQU5ILEVBT0dFLEVBUEgsQ0FPTSxPQVBOLEVBT2VFLENBQUMsSUFBSTtBQUNoQlIsTUFBQUEsR0FBRyxDQUFFLCtCQUE4QkgsR0FBSSxLQUFJVyxDQUFDLENBQUNDLE9BQVEsRUFBbEQsQ0FBSDtBQUNELEtBVEg7QUFVRCxHQVhNLENBQVA7QUFZRCxDQWJEOztBQWVBLE1BQU1DLG1CQUFtQixHQUFHLE1BQU1DLElBQU4sSUFBYztBQUN4QyxNQUFJQSxJQUFJLENBQUNDLE9BQUwsQ0FBYUMsTUFBYixLQUF3QixLQUE1QixFQUFtQztBQUNqQyxVQUFNQyxNQUFNLEdBQUcsTUFBTWxCLG1CQUFtQixDQUFDZSxJQUFJLENBQUNDLE9BQUwsQ0FBYWYsR0FBZCxDQUF4QztBQUNBYyxJQUFBQSxJQUFJLENBQUNJLGFBQUwsR0FBcUJKLElBQXJCO0FBQ0FBLElBQUFBLElBQUksQ0FBQ0ssS0FBTCxHQUFhRixNQUFiO0FBQ0FILElBQUFBLElBQUksQ0FBQ00sWUFBTCxHQUFvQixJQUFwQjtBQUNEOztBQUNELFNBQU9OLElBQVA7QUFDRCxDQVJEOztBQVVPLE1BQU1PLFdBQU4sQ0FBa0I7QUFDdkJDLEVBQUFBLGFBQWEsQ0FBQztBQUFFQyxJQUFBQSxhQUFhLEdBQUc7QUFBbEIsTUFBNkIsRUFBOUIsRUFBa0M7QUFDN0MsUUFBSUMsTUFBTSxHQUFHQyxpQkFBUUMsTUFBUixFQUFiOztBQUNBRixJQUFBQSxNQUFNLENBQUNwQixHQUFQLENBQVcseUJBQVgsRUFBc0MsS0FBS3VCLFVBQTNDO0FBQ0FILElBQUFBLE1BQU0sQ0FBQ3BCLEdBQVAsQ0FBVyxrQ0FBWCxFQUErQyxLQUFLd0IsZUFBcEQ7QUFFQUosSUFBQUEsTUFBTSxDQUFDSyxJQUFQLENBQVksUUFBWixFQUFzQixVQUFVQyxHQUFWLEVBQWU1QixHQUFmLEVBQW9CNkIsSUFBcEIsRUFBMEI7QUFDOUNBLE1BQUFBLElBQUksQ0FBQyxJQUFJQyxjQUFNQyxLQUFWLENBQWdCRCxjQUFNQyxLQUFOLENBQVlDLGlCQUE1QixFQUErQyx3QkFBL0MsQ0FBRCxDQUFKO0FBQ0QsS0FGRDtBQUlBVixJQUFBQSxNQUFNLENBQUNLLElBQVAsQ0FDRSxrQkFERixFQUVFTSxvQkFBV0MsR0FBWCxDQUFlO0FBQ2JDLE1BQUFBLElBQUksRUFBRSxNQUFNO0FBQ1YsZUFBTyxJQUFQO0FBQ0QsT0FIWTtBQUliQyxNQUFBQSxLQUFLLEVBQUVmO0FBSk0sS0FBZixDQUZGLEVBT007QUFDSmdCLElBQUFBLFdBQVcsQ0FBQ0Msa0JBUmQsRUFTRSxLQUFLQyxhQVRQO0FBWUFqQixJQUFBQSxNQUFNLENBQUNrQixNQUFQLENBQ0Usa0JBREYsRUFFRUgsV0FBVyxDQUFDQyxrQkFGZCxFQUdFRCxXQUFXLENBQUNJLHNCQUhkLEVBSUUsS0FBS0MsYUFKUDtBQU1BLFdBQU9wQixNQUFQO0FBQ0Q7O0FBRURHLEVBQUFBLFVBQVUsQ0FBQ0csR0FBRCxFQUFNNUIsR0FBTixFQUFXO0FBQ25CLFVBQU0yQyxNQUFNLEdBQUdDLGdCQUFPMUMsR0FBUCxDQUFXMEIsR0FBRyxDQUFDaUIsTUFBSixDQUFXQyxLQUF0QixDQUFmOztBQUNBLFVBQU1DLGVBQWUsR0FBR0osTUFBTSxDQUFDSSxlQUEvQjtBQUNBLFVBQU1DLFFBQVEsR0FBR3BCLEdBQUcsQ0FBQ2lCLE1BQUosQ0FBV0csUUFBNUI7O0FBQ0EsVUFBTUMsV0FBVyxHQUFHQyxjQUFLQyxPQUFMLENBQWFILFFBQWIsQ0FBcEI7O0FBQ0EsUUFBSUksZ0JBQWdCLENBQUN4QixHQUFELEVBQU1tQixlQUFOLENBQXBCLEVBQTRDO0FBQzFDQSxNQUFBQSxlQUFlLENBQUNNLGdCQUFoQixDQUFpQ1YsTUFBakMsRUFBeUNLLFFBQXpDLEVBQW1EcEIsR0FBbkQsRUFBd0Q1QixHQUF4RCxFQUE2RGlELFdBQTdELEVBQTBFSyxLQUExRSxDQUFnRixNQUFNO0FBQ3BGdEQsUUFBQUEsR0FBRyxDQUFDdUQsTUFBSixDQUFXLEdBQVg7QUFDQXZELFFBQUFBLEdBQUcsQ0FBQ3dELEdBQUosQ0FBUSxjQUFSLEVBQXdCLFlBQXhCO0FBQ0F4RCxRQUFBQSxHQUFHLENBQUN5RCxHQUFKLENBQVEsaUJBQVI7QUFDRCxPQUpEO0FBS0QsS0FORCxNQU1PO0FBQ0xWLE1BQUFBLGVBQWUsQ0FDWlcsV0FESCxDQUNlZixNQURmLEVBQ3VCSyxRQUR2QixFQUVHVyxJQUZILENBRVFuRCxJQUFJLElBQUk7QUFDWlIsUUFBQUEsR0FBRyxDQUFDdUQsTUFBSixDQUFXLEdBQVg7QUFDQXZELFFBQUFBLEdBQUcsQ0FBQ3dELEdBQUosQ0FBUSxjQUFSLEVBQXdCUCxXQUF4QjtBQUNBakQsUUFBQUEsR0FBRyxDQUFDd0QsR0FBSixDQUFRLGdCQUFSLEVBQTBCaEQsSUFBSSxDQUFDb0QsTUFBL0I7QUFDQTVELFFBQUFBLEdBQUcsQ0FBQ3lELEdBQUosQ0FBUWpELElBQVI7QUFDRCxPQVBILEVBUUc4QyxLQVJILENBUVMsTUFBTTtBQUNYdEQsUUFBQUEsR0FBRyxDQUFDdUQsTUFBSixDQUFXLEdBQVg7QUFDQXZELFFBQUFBLEdBQUcsQ0FBQ3dELEdBQUosQ0FBUSxjQUFSLEVBQXdCLFlBQXhCO0FBQ0F4RCxRQUFBQSxHQUFHLENBQUN5RCxHQUFKLENBQVEsaUJBQVI7QUFDRCxPQVpIO0FBYUQ7QUFDRjs7QUFFRCxRQUFNbEIsYUFBTixDQUFvQlgsR0FBcEIsRUFBeUI1QixHQUF6QixFQUE4QjZCLElBQTlCLEVBQW9DO0FBQ2xDLFVBQU1jLE1BQU0sR0FBR2YsR0FBRyxDQUFDZSxNQUFuQjtBQUNBLFVBQU1JLGVBQWUsR0FBR0osTUFBTSxDQUFDSSxlQUEvQjtBQUNBLFVBQU07QUFBRUMsTUFBQUE7QUFBRixRQUFlcEIsR0FBRyxDQUFDaUIsTUFBekI7QUFDQSxVQUFNSSxXQUFXLEdBQUdyQixHQUFHLENBQUMxQixHQUFKLENBQVEsY0FBUixDQUFwQjs7QUFFQSxRQUFJLENBQUMwQixHQUFHLENBQUN2QixJQUFMLElBQWEsQ0FBQ3VCLEdBQUcsQ0FBQ3ZCLElBQUosQ0FBU3VELE1BQTNCLEVBQW1DO0FBQ2pDL0IsTUFBQUEsSUFBSSxDQUFDLElBQUlDLGNBQU1DLEtBQVYsQ0FBZ0JELGNBQU1DLEtBQU4sQ0FBWThCLGVBQTVCLEVBQTZDLHNCQUE3QyxDQUFELENBQUo7QUFDQTtBQUNEOztBQUVELFVBQU1DLEtBQUssR0FBR2YsZUFBZSxDQUFDZ0IsZ0JBQWhCLENBQWlDZixRQUFqQyxDQUFkOztBQUNBLFFBQUljLEtBQUosRUFBVztBQUNUakMsTUFBQUEsSUFBSSxDQUFDaUMsS0FBRCxDQUFKO0FBQ0E7QUFDRDs7QUFFRCxVQUFNL0MsTUFBTSxHQUFHYSxHQUFHLENBQUN2QixJQUFKLENBQVMyRCxRQUFULENBQWtCLFFBQWxCLENBQWY7QUFDQSxVQUFNcEQsSUFBSSxHQUFHLElBQUlrQixjQUFNbUMsSUFBVixDQUFlakIsUUFBZixFQUF5QjtBQUFFakMsTUFBQUE7QUFBRixLQUF6QixFQUFxQ2tDLFdBQXJDLENBQWI7QUFDQSxVQUFNO0FBQUVpQixNQUFBQSxRQUFRLEdBQUcsRUFBYjtBQUFpQkMsTUFBQUEsSUFBSSxHQUFHO0FBQXhCLFFBQStCdkMsR0FBRyxDQUFDd0MsUUFBSixJQUFnQixFQUFyRDtBQUNBeEQsSUFBQUEsSUFBSSxDQUFDeUQsT0FBTCxDQUFhRixJQUFiO0FBQ0F2RCxJQUFBQSxJQUFJLENBQUMwRCxXQUFMLENBQWlCSixRQUFqQjtBQUNBLFVBQU1LLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxVQUFQLENBQWtCN0MsR0FBRyxDQUFDdkIsSUFBdEIsQ0FBakI7QUFDQSxVQUFNcUUsVUFBVSxHQUFHO0FBQUU5RCxNQUFBQSxJQUFGO0FBQVEyRCxNQUFBQTtBQUFSLEtBQW5COztBQUNBLFFBQUk7QUFDRjtBQUNBLFlBQU1JLGFBQWEsR0FBRyxNQUFNakYsUUFBUSxDQUFDa0YsbUJBQVQsQ0FDMUJsRixRQUFRLENBQUNtRixLQUFULENBQWVDLGNBRFcsRUFFMUJKLFVBRjBCLEVBRzFCL0IsTUFIMEIsRUFJMUJmLEdBQUcsQ0FBQ21ELElBSnNCLENBQTVCO0FBTUEsVUFBSUMsVUFBSixDQVJFLENBU0Y7O0FBQ0EsVUFBSUwsYUFBYSxZQUFZN0MsY0FBTW1DLElBQW5DLEVBQXlDO0FBQ3ZDUyxRQUFBQSxVQUFVLENBQUM5RCxJQUFYLEdBQWtCK0QsYUFBbEI7O0FBQ0EsWUFBSUEsYUFBYSxDQUFDTSxHQUFkLEVBQUosRUFBeUI7QUFDdkI7QUFDQVAsVUFBQUEsVUFBVSxDQUFDSCxRQUFYLEdBQXNCLElBQXRCO0FBQ0FTLFVBQUFBLFVBQVUsR0FBRztBQUNYQyxZQUFBQSxHQUFHLEVBQUVOLGFBQWEsQ0FBQ00sR0FBZCxFQURNO0FBRVhDLFlBQUFBLElBQUksRUFBRVAsYUFBYSxDQUFDUTtBQUZULFdBQWI7QUFJRDtBQUNGLE9BcEJDLENBcUJGOzs7QUFDQSxVQUFJLENBQUNILFVBQUwsRUFBaUI7QUFDZjtBQUNBLGNBQU1yRSxtQkFBbUIsQ0FBQytELFVBQVUsQ0FBQzlELElBQVosQ0FBekIsQ0FGZSxDQUdmOztBQUNBLGNBQU13RSxVQUFVLEdBQUdaLE1BQU0sQ0FBQ2EsSUFBUCxDQUFZWCxVQUFVLENBQUM5RCxJQUFYLENBQWdCSyxLQUE1QixFQUFtQyxRQUFuQyxDQUFuQjtBQUNBeUQsUUFBQUEsVUFBVSxDQUFDSCxRQUFYLEdBQXNCQyxNQUFNLENBQUNDLFVBQVAsQ0FBa0JXLFVBQWxCLENBQXRCLENBTGUsQ0FNZjs7QUFDQSxjQUFNRSxnQkFBZ0IsR0FBRyxNQUFNdkMsZUFBZSxDQUFDd0MsVUFBaEIsQ0FDN0I1QyxNQUQ2QixFQUU3QitCLFVBQVUsQ0FBQzlELElBQVgsQ0FBZ0J1RSxLQUZhLEVBRzdCQyxVQUg2QixFQUk3QlYsVUFBVSxDQUFDOUQsSUFBWCxDQUFnQkMsT0FBaEIsQ0FBd0JzQixJQUpLLEVBSzdCO0FBQ0VnQyxVQUFBQSxJQUFJLEVBQUVPLFVBQVUsQ0FBQzlELElBQVgsQ0FBZ0I0RSxLQUR4QjtBQUVFdEIsVUFBQUEsUUFBUSxFQUFFUSxVQUFVLENBQUM5RCxJQUFYLENBQWdCNkU7QUFGNUIsU0FMNkIsQ0FBL0IsQ0FQZSxDQWlCZjs7QUFDQWYsUUFBQUEsVUFBVSxDQUFDOUQsSUFBWCxDQUFnQnVFLEtBQWhCLEdBQXdCRyxnQkFBZ0IsQ0FBQ0osSUFBekM7QUFDQVIsUUFBQUEsVUFBVSxDQUFDOUQsSUFBWCxDQUFnQjhFLElBQWhCLEdBQXVCSixnQkFBZ0IsQ0FBQ0wsR0FBeEM7QUFDQVAsUUFBQUEsVUFBVSxDQUFDOUQsSUFBWCxDQUFnQk0sWUFBaEIsR0FBK0IsSUFBL0I7QUFDQXdELFFBQUFBLFVBQVUsQ0FBQzlELElBQVgsQ0FBZ0JJLGFBQWhCLEdBQWdDakIsT0FBTyxDQUFDNEYsT0FBUixDQUFnQmpCLFVBQVUsQ0FBQzlELElBQTNCLENBQWhDO0FBQ0FvRSxRQUFBQSxVQUFVLEdBQUc7QUFDWEMsVUFBQUEsR0FBRyxFQUFFSyxnQkFBZ0IsQ0FBQ0wsR0FEWDtBQUVYQyxVQUFBQSxJQUFJLEVBQUVJLGdCQUFnQixDQUFDSjtBQUZaLFNBQWI7QUFJRCxPQWhEQyxDQWlERjs7O0FBQ0EsWUFBTXhGLFFBQVEsQ0FBQ2tGLG1CQUFULENBQ0psRixRQUFRLENBQUNtRixLQUFULENBQWVlLGFBRFgsRUFFSmxCLFVBRkksRUFHSi9CLE1BSEksRUFJSmYsR0FBRyxDQUFDbUQsSUFKQSxDQUFOO0FBTUEvRSxNQUFBQSxHQUFHLENBQUN1RCxNQUFKLENBQVcsR0FBWDtBQUNBdkQsTUFBQUEsR0FBRyxDQUFDd0QsR0FBSixDQUFRLFVBQVIsRUFBb0J3QixVQUFVLENBQUNDLEdBQS9CO0FBQ0FqRixNQUFBQSxHQUFHLENBQUM2RixJQUFKLENBQVNiLFVBQVQ7QUFDRCxLQTNERCxDQTJERSxPQUFPdkUsQ0FBUCxFQUFVO0FBQ1ZxRixzQkFBT2hDLEtBQVAsQ0FBYSx5QkFBYixFQUF3Q3JELENBQXhDOztBQUNBLFlBQU1xRCxLQUFLLEdBQUdwRSxRQUFRLENBQUNxRyxZQUFULENBQXNCdEYsQ0FBdEIsRUFBeUI7QUFDckN1RixRQUFBQSxJQUFJLEVBQUVsRSxjQUFNQyxLQUFOLENBQVk4QixlQURtQjtBQUVyQ25ELFFBQUFBLE9BQU8sRUFBRyx5QkFBd0JnRSxVQUFVLENBQUM5RCxJQUFYLENBQWdCdUUsS0FBTTtBQUZuQixPQUF6QixDQUFkO0FBSUF0RCxNQUFBQSxJQUFJLENBQUNpQyxLQUFELENBQUo7QUFDRDtBQUNGOztBQUVELFFBQU1wQixhQUFOLENBQW9CZCxHQUFwQixFQUF5QjVCLEdBQXpCLEVBQThCNkIsSUFBOUIsRUFBb0M7QUFDbEMsUUFBSTtBQUNGLFlBQU07QUFBRWtCLFFBQUFBO0FBQUYsVUFBc0JuQixHQUFHLENBQUNlLE1BQWhDO0FBQ0EsWUFBTTtBQUFFSyxRQUFBQTtBQUFGLFVBQWVwQixHQUFHLENBQUNpQixNQUF6QixDQUZFLENBR0Y7O0FBQ0EsWUFBTWpDLElBQUksR0FBRyxJQUFJa0IsY0FBTW1DLElBQVYsQ0FBZWpCLFFBQWYsQ0FBYjtBQUNBcEMsTUFBQUEsSUFBSSxDQUFDOEUsSUFBTCxHQUFZM0MsZUFBZSxDQUFDa0QsT0FBaEIsQ0FBd0JDLGVBQXhCLENBQXdDdEUsR0FBRyxDQUFDZSxNQUE1QyxFQUFvREssUUFBcEQsQ0FBWjtBQUNBLFlBQU0wQixVQUFVLEdBQUc7QUFBRTlELFFBQUFBLElBQUY7QUFBUTJELFFBQUFBLFFBQVEsRUFBRTtBQUFsQixPQUFuQjtBQUNBLFlBQU03RSxRQUFRLENBQUNrRixtQkFBVCxDQUNKbEYsUUFBUSxDQUFDbUYsS0FBVCxDQUFlc0IsZ0JBRFgsRUFFSnpCLFVBRkksRUFHSjlDLEdBQUcsQ0FBQ2UsTUFIQSxFQUlKZixHQUFHLENBQUNtRCxJQUpBLENBQU4sQ0FQRSxDQWFGOztBQUNBLFlBQU1oQyxlQUFlLENBQUNxRCxVQUFoQixDQUEyQnhFLEdBQUcsQ0FBQ2UsTUFBL0IsRUFBdUNLLFFBQXZDLENBQU4sQ0FkRSxDQWVGOztBQUNBLFlBQU10RCxRQUFRLENBQUNrRixtQkFBVCxDQUNKbEYsUUFBUSxDQUFDbUYsS0FBVCxDQUFld0IsZUFEWCxFQUVKM0IsVUFGSSxFQUdKOUMsR0FBRyxDQUFDZSxNQUhBLEVBSUpmLEdBQUcsQ0FBQ21ELElBSkEsQ0FBTjtBQU1BL0UsTUFBQUEsR0FBRyxDQUFDdUQsTUFBSixDQUFXLEdBQVgsRUF0QkUsQ0F1QkY7O0FBQ0F2RCxNQUFBQSxHQUFHLENBQUN5RCxHQUFKO0FBQ0QsS0F6QkQsQ0F5QkUsT0FBT2hELENBQVAsRUFBVTtBQUNWcUYsc0JBQU9oQyxLQUFQLENBQWEseUJBQWIsRUFBd0NyRCxDQUF4Qzs7QUFDQSxZQUFNcUQsS0FBSyxHQUFHcEUsUUFBUSxDQUFDcUcsWUFBVCxDQUFzQnRGLENBQXRCLEVBQXlCO0FBQ3JDdUYsUUFBQUEsSUFBSSxFQUFFbEUsY0FBTUMsS0FBTixDQUFZdUUsaUJBRG1CO0FBRXJDNUYsUUFBQUEsT0FBTyxFQUFFO0FBRjRCLE9BQXpCLENBQWQ7QUFJQW1CLE1BQUFBLElBQUksQ0FBQ2lDLEtBQUQsQ0FBSjtBQUNEO0FBQ0Y7O0FBRUQsUUFBTXBDLGVBQU4sQ0FBc0JFLEdBQXRCLEVBQTJCNUIsR0FBM0IsRUFBZ0M7QUFDOUIsVUFBTTJDLE1BQU0sR0FBR0MsZ0JBQU8xQyxHQUFQLENBQVcwQixHQUFHLENBQUNpQixNQUFKLENBQVdDLEtBQXRCLENBQWY7O0FBQ0EsVUFBTTtBQUFFQyxNQUFBQTtBQUFGLFFBQXNCSixNQUE1QjtBQUNBLFVBQU07QUFBRUssTUFBQUE7QUFBRixRQUFlcEIsR0FBRyxDQUFDaUIsTUFBekI7O0FBQ0EsUUFBSTtBQUNGLFlBQU1yQyxJQUFJLEdBQUcsTUFBTXVDLGVBQWUsQ0FBQ3dELFdBQWhCLENBQTRCdkQsUUFBNUIsQ0FBbkI7QUFDQWhELE1BQUFBLEdBQUcsQ0FBQ3VELE1BQUosQ0FBVyxHQUFYO0FBQ0F2RCxNQUFBQSxHQUFHLENBQUM2RixJQUFKLENBQVNyRixJQUFUO0FBQ0QsS0FKRCxDQUlFLE9BQU9DLENBQVAsRUFBVTtBQUNWVCxNQUFBQSxHQUFHLENBQUN1RCxNQUFKLENBQVcsR0FBWDtBQUNBdkQsTUFBQUEsR0FBRyxDQUFDNkYsSUFBSixDQUFTLEVBQVQ7QUFDRDtBQUNGOztBQXhNc0I7Ozs7QUEyTXpCLFNBQVN6QyxnQkFBVCxDQUEwQnhCLEdBQTFCLEVBQStCbUIsZUFBL0IsRUFBZ0Q7QUFDOUMsU0FBT25CLEdBQUcsQ0FBQzFCLEdBQUosQ0FBUSxPQUFSLEtBQW9CLE9BQU82QyxlQUFlLENBQUNrRCxPQUFoQixDQUF3QjVDLGdCQUEvQixLQUFvRCxVQUEvRTtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgQm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQgKiBhcyBNaWRkbGV3YXJlcyBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgbWltZSBmcm9tICdtaW1lJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmNvbnN0IHRyaWdnZXJzID0gcmVxdWlyZSgnLi4vdHJpZ2dlcnMnKTtcbmNvbnN0IGh0dHAgPSByZXF1aXJlKCdodHRwJyk7XG5cbmNvbnN0IGRvd25sb2FkRmlsZUZyb21VUkkgPSB1cmkgPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlcywgcmVqKSA9PiB7XG4gICAgaHR0cFxuICAgICAgLmdldCh1cmksIHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmVzcG9uc2Uuc2V0RGVmYXVsdEVuY29kaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgbGV0IGJvZHkgPSBgZGF0YToke3Jlc3BvbnNlLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddfTtiYXNlNjQsYDtcbiAgICAgICAgcmVzcG9uc2Uub24oJ2RhdGEnLCBkYXRhID0+IChib2R5ICs9IGRhdGEpKTtcbiAgICAgICAgcmVzcG9uc2Uub24oJ2VuZCcsICgpID0+IHJlcyhib2R5KSk7XG4gICAgICB9KVxuICAgICAgLm9uKCdlcnJvcicsIGUgPT4ge1xuICAgICAgICByZWooYEVycm9yIGRvd25sb2FkaW5nIGZpbGUgZnJvbSAke3VyaX06ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfSk7XG4gIH0pO1xufTtcblxuY29uc3QgYWRkRmlsZURhdGFJZk5lZWRlZCA9IGFzeW5jIGZpbGUgPT4ge1xuICBpZiAoZmlsZS5fc291cmNlLmZvcm1hdCA9PT0gJ3VyaScpIHtcbiAgICBjb25zdCBiYXNlNjQgPSBhd2FpdCBkb3dubG9hZEZpbGVGcm9tVVJJKGZpbGUuX3NvdXJjZS51cmkpO1xuICAgIGZpbGUuX3ByZXZpb3VzU2F2ZSA9IGZpbGU7XG4gICAgZmlsZS5fZGF0YSA9IGJhc2U2NDtcbiAgICBmaWxlLl9yZXF1ZXN0VGFzayA9IG51bGw7XG4gIH1cbiAgcmV0dXJuIGZpbGU7XG59O1xuXG5leHBvcnQgY2xhc3MgRmlsZXNSb3V0ZXIge1xuICBleHByZXNzUm91dGVyKHsgbWF4VXBsb2FkU2l6ZSA9ICcyME1iJyB9ID0ge30pIHtcbiAgICB2YXIgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIuZ2V0KCcvZmlsZXMvOmFwcElkLzpmaWxlbmFtZScsIHRoaXMuZ2V0SGFuZGxlcik7XG4gICAgcm91dGVyLmdldCgnL2ZpbGVzLzphcHBJZC9tZXRhZGF0YS86ZmlsZW5hbWUnLCB0aGlzLm1ldGFkYXRhSGFuZGxlcik7XG5cbiAgICByb3V0ZXIucG9zdCgnL2ZpbGVzJywgZnVuY3Rpb24gKHJlcSwgcmVzLCBuZXh0KSB7XG4gICAgICBuZXh0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSwgJ0ZpbGVuYW1lIG5vdCBwcm92aWRlZC4nKSk7XG4gICAgfSk7XG5cbiAgICByb3V0ZXIucG9zdChcbiAgICAgICcvZmlsZXMvOmZpbGVuYW1lJyxcbiAgICAgIEJvZHlQYXJzZXIucmF3KHtcbiAgICAgICAgdHlwZTogKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBsaW1pdDogbWF4VXBsb2FkU2l6ZSxcbiAgICAgIH0pLCAvLyBBbGxvdyB1cGxvYWRzIHdpdGhvdXQgQ29udGVudC1UeXBlLCBvciB3aXRoIGFueSBDb250ZW50LVR5cGUuXG4gICAgICBNaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUhlYWRlcnMsXG4gICAgICB0aGlzLmNyZWF0ZUhhbmRsZXJcbiAgICApO1xuXG4gICAgcm91dGVyLmRlbGV0ZShcbiAgICAgICcvZmlsZXMvOmZpbGVuYW1lJyxcbiAgICAgIE1pZGRsZXdhcmVzLmhhbmRsZVBhcnNlSGVhZGVycyxcbiAgICAgIE1pZGRsZXdhcmVzLmVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmRlbGV0ZUhhbmRsZXJcbiAgICApO1xuICAgIHJldHVybiByb3V0ZXI7XG4gIH1cblxuICBnZXRIYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChyZXEucGFyYW1zLmFwcElkKTtcbiAgICBjb25zdCBmaWxlc0NvbnRyb2xsZXIgPSBjb25maWcuZmlsZXNDb250cm9sbGVyO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gcmVxLnBhcmFtcy5maWxlbmFtZTtcbiAgICBjb25zdCBjb250ZW50VHlwZSA9IG1pbWUuZ2V0VHlwZShmaWxlbmFtZSk7XG4gICAgaWYgKGlzRmlsZVN0cmVhbWFibGUocmVxLCBmaWxlc0NvbnRyb2xsZXIpKSB7XG4gICAgICBmaWxlc0NvbnRyb2xsZXIuaGFuZGxlRmlsZVN0cmVhbShjb25maWcsIGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDQpO1xuICAgICAgICByZXMuc2V0KCdDb250ZW50LVR5cGUnLCAndGV4dC9wbGFpbicpO1xuICAgICAgICByZXMuZW5kKCdGaWxlIG5vdCBmb3VuZC4nKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaWxlc0NvbnRyb2xsZXJcbiAgICAgICAgLmdldEZpbGVEYXRhKGNvbmZpZywgZmlsZW5hbWUpXG4gICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgICAgICByZXMuc2V0KCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG4gICAgICAgICAgcmVzLnNldCgnQ29udGVudC1MZW5ndGgnLCBkYXRhLmxlbmd0aCk7XG4gICAgICAgICAgcmVzLmVuZChkYXRhKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwNCk7XG4gICAgICAgICAgcmVzLnNldCgnQ29udGVudC1UeXBlJywgJ3RleHQvcGxhaW4nKTtcbiAgICAgICAgICByZXMuZW5kKCdGaWxlIG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY3JlYXRlSGFuZGxlcihyZXEsIHJlcywgbmV4dCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgZmlsZXNDb250cm9sbGVyID0gY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVxLmdldCgnQ29udGVudC10eXBlJyk7XG5cbiAgICBpZiAoIXJlcS5ib2R5IHx8ICFyZXEuYm9keS5sZW5ndGgpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUiwgJ0ludmFsaWQgZmlsZSB1cGxvYWQuJykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVycm9yID0gZmlsZXNDb250cm9sbGVyLnZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZTY0ID0gcmVxLmJvZHkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGZpbGUgPSBuZXcgUGFyc2UuRmlsZShmaWxlbmFtZSwgeyBiYXNlNjQgfSwgY29udGVudFR5cGUpO1xuICAgIGNvbnN0IHsgbWV0YWRhdGEgPSB7fSwgdGFncyA9IHt9IH0gPSByZXEuZmlsZURhdGEgfHwge307XG4gICAgZmlsZS5zZXRUYWdzKHRhZ3MpO1xuICAgIGZpbGUuc2V0TWV0YWRhdGEobWV0YWRhdGEpO1xuICAgIGNvbnN0IGZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgocmVxLmJvZHkpO1xuICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplIH07XG4gICAgdHJ5IHtcbiAgICAgIC8vIHJ1biBiZWZvcmVTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCB0cmlnZ2VyUmVzdWx0ID0gYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5GaWxlVHJpZ2dlcihcbiAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZUZpbGUsXG4gICAgICAgIGZpbGVPYmplY3QsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICBsZXQgc2F2ZVJlc3VsdDtcbiAgICAgIC8vIGlmIGEgbmV3IFBhcnNlRmlsZSBpcyByZXR1cm5lZCBjaGVjayBpZiBpdCdzIGFuIGFscmVhZHkgc2F2ZWQgZmlsZVxuICAgICAgaWYgKHRyaWdnZXJSZXN1bHQgaW5zdGFuY2VvZiBQYXJzZS5GaWxlKSB7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZSA9IHRyaWdnZXJSZXN1bHQ7XG4gICAgICAgIGlmICh0cmlnZ2VyUmVzdWx0LnVybCgpKSB7XG4gICAgICAgICAgLy8gc2V0IGZpbGVTaXplIHRvIG51bGwgYmVjYXVzZSB3ZSB3b250IGtub3cgaG93IGJpZyBpdCBpcyBoZXJlXG4gICAgICAgICAgZmlsZU9iamVjdC5maWxlU2l6ZSA9IG51bGw7XG4gICAgICAgICAgc2F2ZVJlc3VsdCA9IHtcbiAgICAgICAgICAgIHVybDogdHJpZ2dlclJlc3VsdC51cmwoKSxcbiAgICAgICAgICAgIG5hbWU6IHRyaWdnZXJSZXN1bHQuX25hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gaWYgdGhlIGZpbGUgcmV0dXJuZWQgYnkgdGhlIHRyaWdnZXIgaGFzIGFscmVhZHkgYmVlbiBzYXZlZCBza2lwIHNhdmluZyBhbnl0aGluZ1xuICAgICAgaWYgKCFzYXZlUmVzdWx0KSB7XG4gICAgICAgIC8vIGlmIHRoZSBQYXJzZUZpbGUgcmV0dXJuZWQgaXMgdHlwZSB1cmksIGRvd25sb2FkIHRoZSBmaWxlIGJlZm9yZSBzYXZpbmcgaXRcbiAgICAgICAgYXdhaXQgYWRkRmlsZURhdGFJZk5lZWRlZChmaWxlT2JqZWN0LmZpbGUpO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZVNpemVcbiAgICAgICAgY29uc3QgYnVmZmVyRGF0YSA9IEJ1ZmZlci5mcm9tKGZpbGVPYmplY3QuZmlsZS5fZGF0YSwgJ2Jhc2U2NCcpO1xuICAgICAgICBmaWxlT2JqZWN0LmZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgoYnVmZmVyRGF0YSk7XG4gICAgICAgIC8vIHNhdmUgZmlsZVxuICAgICAgICBjb25zdCBjcmVhdGVGaWxlUmVzdWx0ID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmNyZWF0ZUZpbGUoXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSxcbiAgICAgICAgICBidWZmZXJEYXRhLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fc291cmNlLnR5cGUsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGFnczogZmlsZU9iamVjdC5maWxlLl90YWdzLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGZpbGVPYmplY3QuZmlsZS5fbWV0YWRhdGEsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZSB3aXRoIG5ldyBkYXRhXG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSA9IGNyZWF0ZUZpbGVSZXN1bHQubmFtZTtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl91cmwgPSBjcmVhdGVGaWxlUmVzdWx0LnVybDtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl9yZXF1ZXN0VGFzayA9IG51bGw7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fcHJldmlvdXNTYXZlID0gUHJvbWlzZS5yZXNvbHZlKGZpbGVPYmplY3QuZmlsZSk7XG4gICAgICAgIHNhdmVSZXN1bHQgPSB7XG4gICAgICAgICAgdXJsOiBjcmVhdGVGaWxlUmVzdWx0LnVybCxcbiAgICAgICAgICBuYW1lOiBjcmVhdGVGaWxlUmVzdWx0Lm5hbWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBydW4gYWZ0ZXJTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcS5hdXRoXG4gICAgICApO1xuICAgICAgcmVzLnN0YXR1cygyMDEpO1xuICAgICAgcmVzLnNldCgnTG9jYXRpb24nLCBzYXZlUmVzdWx0LnVybCk7XG4gICAgICByZXMuanNvbihzYXZlUmVzdWx0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUixcbiAgICAgICAgbWVzc2FnZTogYENvdWxkIG5vdCBzdG9yZSBmaWxlOiAke2ZpbGVPYmplY3QuZmlsZS5fbmFtZX0uYCxcbiAgICAgIH0pO1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGVsZXRlSGFuZGxlcihyZXEsIHJlcywgbmV4dCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZpbGVzQ29udHJvbGxlciB9ID0gcmVxLmNvbmZpZztcbiAgICAgIGNvbnN0IHsgZmlsZW5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICAvLyBydW4gYmVmb3JlRGVsZXRlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCBmaWxlID0gbmV3IFBhcnNlLkZpbGUoZmlsZW5hbWUpO1xuICAgICAgZmlsZS5fdXJsID0gZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKHJlcS5jb25maWcsIGZpbGVuYW1lKTtcbiAgICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplOiBudWxsIH07XG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVEZWxldGVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aFxuICAgICAgKTtcbiAgICAgIC8vIGRlbGV0ZSBmaWxlXG4gICAgICBhd2FpdCBmaWxlc0NvbnRyb2xsZXIuZGVsZXRlRmlsZShyZXEuY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgICAvLyBydW4gYWZ0ZXJEZWxldGVGaWxlIHRyaWdnZXJcbiAgICAgIGF3YWl0IHRyaWdnZXJzLm1heWJlUnVuRmlsZVRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlRmlsZSxcbiAgICAgICAgZmlsZU9iamVjdCxcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICByZXMuc3RhdHVzKDIwMCk7XG4gICAgICAvLyBUT0RPOiByZXR1cm4gdXNlZnVsIEpTT04gaGVyZT9cbiAgICAgIHJlcy5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGRlbGV0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfREVMRVRFX0VSUk9SLFxuICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlbGV0ZSBmaWxlLicsXG4gICAgICB9KTtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG1ldGFkYXRhSGFuZGxlcihyZXEsIHJlcykge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCk7XG4gICAgY29uc3QgeyBmaWxlc0NvbnRyb2xsZXIgfSA9IGNvbmZpZztcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmdldE1ldGFkYXRhKGZpbGVuYW1lKTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKHt9KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNGaWxlU3RyZWFtYWJsZShyZXEsIGZpbGVzQ29udHJvbGxlcikge1xuICByZXR1cm4gcmVxLmdldCgnUmFuZ2UnKSAmJiB0eXBlb2YgZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuaGFuZGxlRmlsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/FunctionsRouter.js b/lib/Routers/FunctionsRouter.js new file mode 100644 index 0000000000..0e5c6b67d3 --- /dev/null +++ b/lib/Routers/FunctionsRouter.js @@ -0,0 +1,181 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FunctionsRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _middlewares = require("../middlewares"); + +var _StatusHandler = require("../StatusHandler"); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _logger = require("../logger"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// FunctionsRouter.js +var Parse = require('parse/node').Parse, + triggers = require('../triggers'); + +function parseObject(obj) { + if (Array.isArray(obj)) { + return obj.map(item => { + return parseObject(item); + }); + } else if (obj && obj.__type == 'Date') { + return Object.assign(new Date(obj.iso), obj); + } else if (obj && obj.__type == 'File') { + return Parse.File.fromJSON(obj); + } else if (obj && typeof obj === 'object') { + return parseParams(obj); + } else { + return obj; + } +} + +function parseParams(params) { + return _lodash.default.mapValues(params, parseObject); +} + +class FunctionsRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('POST', '/functions/:functionName', _middlewares.promiseEnsureIdempotency, FunctionsRouter.handleCloudFunction); + this.route('POST', '/jobs/:jobName', _middlewares.promiseEnsureIdempotency, _middlewares.promiseEnforceMasterKeyAccess, function (req) { + return FunctionsRouter.handleCloudJob(req); + }); + this.route('POST', '/jobs', _middlewares.promiseEnforceMasterKeyAccess, function (req) { + return FunctionsRouter.handleCloudJob(req); + }); + } + + static handleCloudJob(req) { + const jobName = req.params.jobName || req.body.jobName; + const applicationId = req.config.applicationId; + const jobHandler = (0, _StatusHandler.jobStatusHandler)(req.config); + const jobFunction = triggers.getJob(jobName, applicationId); + + if (!jobFunction) { + throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid job.'); + } + + let params = Object.assign({}, req.body, req.query); + params = parseParams(params); + const request = { + params: params, + log: req.config.loggerController, + headers: req.config.headers, + ip: req.config.ip, + jobName, + message: jobHandler.setMessage.bind(jobHandler) + }; + return jobHandler.setRunning(jobName, params).then(jobStatus => { + request.jobId = jobStatus.objectId; // run the function async + + process.nextTick(() => { + Promise.resolve().then(() => { + return jobFunction(request); + }).then(result => { + jobHandler.setSucceeded(result); + }, error => { + jobHandler.setFailed(error); + }); + }); + return { + headers: { + 'X-Parse-Job-Status-Id': jobStatus.objectId + }, + response: {} + }; + }); + } + + static createResponseObject(resolve, reject) { + return { + success: function (result) { + resolve({ + response: { + result: Parse._encode(result) + } + }); + }, + error: function (message) { + const error = triggers.resolveError(message); + reject(error); + } + }; + } + + static handleCloudFunction(req) { + const functionName = req.params.functionName; + const applicationId = req.config.applicationId; + const theFunction = triggers.getFunction(functionName, applicationId); + + if (!theFunction) { + throw new Parse.Error(Parse.Error.SCRIPT_FAILED, `Invalid function: "${functionName}"`); + } + + let params = Object.assign({}, req.body, req.query); + params = parseParams(params); + const request = { + params: params, + master: req.auth && req.auth.isMaster, + user: req.auth && req.auth.user, + installationId: req.info.installationId, + log: req.config.loggerController, + headers: req.config.headers, + ip: req.config.ip, + functionName, + context: req.info.context + }; + return new Promise(function (resolve, reject) { + const userString = req.auth && req.auth.user ? req.auth.user.id : undefined; + + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(params)); + + const { + success, + error + } = FunctionsRouter.createResponseObject(result => { + try { + const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result.response.result)); + + _logger.logger.info(`Ran cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { + functionName, + params, + user: userString + }); + + resolve(result); + } catch (e) { + reject(e); + } + }, error => { + try { + _logger.logger.error(`Failed running cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Error: ` + JSON.stringify(error), { + functionName, + error, + params, + user: userString + }); + + reject(error); + } catch (e) { + reject(e); + } + }); + return Promise.resolve().then(() => { + return triggers.maybeRunValidator(request, functionName); + }).then(() => { + return theFunction(request); + }).then(success, error); + }); + } + +} + +exports.FunctionsRouter = FunctionsRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ0cmlnZ2VycyIsInBhcnNlT2JqZWN0Iiwib2JqIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwiaXRlbSIsIl9fdHlwZSIsIk9iamVjdCIsImFzc2lnbiIsIkRhdGUiLCJpc28iLCJGaWxlIiwiZnJvbUpTT04iLCJwYXJzZVBhcmFtcyIsInBhcmFtcyIsIl8iLCJtYXBWYWx1ZXMiLCJGdW5jdGlvbnNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInJlcSIsImhhbmRsZUNsb3VkSm9iIiwiam9iTmFtZSIsImJvZHkiLCJhcHBsaWNhdGlvbklkIiwiY29uZmlnIiwiam9iSGFuZGxlciIsImpvYkZ1bmN0aW9uIiwiZ2V0Sm9iIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwicXVlcnkiLCJyZXF1ZXN0IiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImhlYWRlcnMiLCJpcCIsIm1lc3NhZ2UiLCJzZXRNZXNzYWdlIiwiYmluZCIsInNldFJ1bm5pbmciLCJ0aGVuIiwiam9iU3RhdHVzIiwiam9iSWQiLCJvYmplY3RJZCIsInByb2Nlc3MiLCJuZXh0VGljayIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0Iiwic2V0U3VjY2VlZGVkIiwiZXJyb3IiLCJzZXRGYWlsZWQiLCJyZXNwb25zZSIsImNyZWF0ZVJlc3BvbnNlT2JqZWN0IiwicmVqZWN0Iiwic3VjY2VzcyIsIl9lbmNvZGUiLCJyZXNvbHZlRXJyb3IiLCJmdW5jdGlvbk5hbWUiLCJ0aGVGdW5jdGlvbiIsImdldEZ1bmN0aW9uIiwibWFzdGVyIiwiYXV0aCIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwiaW5mbyIsImNvbnRleHQiLCJ1c2VyU3RyaW5nIiwiaWQiLCJ1bmRlZmluZWQiLCJjbGVhbklucHV0IiwibG9nZ2VyIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsImNsZWFuUmVzdWx0IiwiZSIsIm1heWJlUnVuVmFsaWRhdG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFUQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxRQUFRLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBRHBCOztBQVNBLFNBQVNFLFdBQVQsQ0FBcUJDLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlDLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBRyxDQUFDRyxHQUFKLENBQVFDLElBQUksSUFBSTtBQUNyQixhQUFPTCxXQUFXLENBQUNLLElBQUQsQ0FBbEI7QUFDRCxLQUZNLENBQVA7QUFHRCxHQUpELE1BSU8sSUFBSUosR0FBRyxJQUFJQSxHQUFHLENBQUNLLE1BQUosSUFBYyxNQUF6QixFQUFpQztBQUN0QyxXQUFPQyxNQUFNLENBQUNDLE1BQVAsQ0FBYyxJQUFJQyxJQUFKLENBQVNSLEdBQUcsQ0FBQ1MsR0FBYixDQUFkLEVBQWlDVCxHQUFqQyxDQUFQO0FBQ0QsR0FGTSxNQUVBLElBQUlBLEdBQUcsSUFBSUEsR0FBRyxDQUFDSyxNQUFKLElBQWMsTUFBekIsRUFBaUM7QUFDdEMsV0FBT1QsS0FBSyxDQUFDYyxJQUFOLENBQVdDLFFBQVgsQ0FBb0JYLEdBQXBCLENBQVA7QUFDRCxHQUZNLE1BRUEsSUFBSUEsR0FBRyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUExQixFQUFvQztBQUN6QyxXQUFPWSxXQUFXLENBQUNaLEdBQUQsQ0FBbEI7QUFDRCxHQUZNLE1BRUE7QUFDTCxXQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7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LEVBQW9DMkIsWUFBcEMsQ0FBUDtBQUNELE9BSEksRUFJSmxCLElBSkksQ0FJQyxNQUFNO0FBQ1YsZUFBT21CLFdBQVcsQ0FBQzVCLE9BQUQsQ0FBbEI7QUFDRCxPQU5JLEVBT0pTLElBUEksQ0FPQ2UsT0FQRCxFQU9VTCxLQVBWLENBQVA7QUFRRCxLQTlDTSxDQUFQO0FBK0NEOztBQXZKZ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBGdW5jdGlvbnNSb3V0ZXIuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5cbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHsgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCB7IGpvYlN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuXG5mdW5jdGlvbiBwYXJzZU9iamVjdChvYmopIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBvYmoubWFwKGl0ZW0gPT4ge1xuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0KGl0ZW0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdEYXRlJykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBEYXRlKG9iai5pc28pLCBvYmopO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdGaWxlJykge1xuICAgIHJldHVybiBQYXJzZS5GaWxlLmZyb21KU09OKG9iaik7XG4gIH0gZWxzZSBpZiAob2JqICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHBhcnNlUGFyYW1zKG9iaik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtcyhwYXJhbXMpIHtcbiAgcmV0dXJuIF8ubWFwVmFsdWVzKHBhcmFtcywgcGFyc2VPYmplY3QpO1xufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25zUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIEZ1bmN0aW9uc1JvdXRlci5oYW5kbGVDbG91ZEZ1bmN0aW9uXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9qb2JzLzpqb2JOYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgZnVuY3Rpb24gKHJlcSkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkSm9iKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9qb2JzJywgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAgIHJldHVybiBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRKb2IocmVxKTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVDbG91ZEpvYihyZXEpIHtcbiAgICBjb25zdCBqb2JOYW1lID0gcmVxLnBhcmFtcy5qb2JOYW1lIHx8IHJlcS5ib2R5LmpvYk5hbWU7XG4gICAgY29uc3QgYXBwbGljYXRpb25JZCA9IHJlcS5jb25maWcuYXBwbGljYXRpb25JZDtcbiAgICBjb25zdCBqb2JIYW5kbGVyID0gam9iU3RhdHVzSGFuZGxlcihyZXEuY29uZmlnKTtcbiAgICBjb25zdCBqb2JGdW5jdGlvbiA9IHRyaWdnZXJzLmdldEpvYihqb2JOYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgICBpZiAoIWpvYkZ1bmN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCwgJ0ludmFsaWQgam9iLicpO1xuICAgIH1cbiAgICBsZXQgcGFyYW1zID0gT2JqZWN0LmFzc2lnbih7fSwgcmVxLmJvZHksIHJlcS5xdWVyeSk7XG4gICAgcGFyYW1zID0gcGFyc2VQYXJhbXMocGFyYW1zKTtcbiAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICBsb2c6IHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICAgIGhlYWRlcnM6IHJlcS5jb25maWcuaGVhZGVycyxcbiAgICAgIGlwOiByZXEuY29uZmlnLmlwLFxuICAgICAgam9iTmFtZSxcbiAgICAgIG1lc3NhZ2U6IGpvYkhhbmRsZXIuc2V0TWVzc2FnZS5iaW5kKGpvYkhhbmRsZXIpLFxuICAgIH07XG5cbiAgICByZXR1cm4gam9iSGFuZGxlci5zZXRSdW5uaW5nKGpvYk5hbWUsIHBhcmFtcykudGhlbihqb2JTdGF0dXMgPT4ge1xuICAgICAgcmVxdWVzdC5qb2JJZCA9IGpvYlN0YXR1cy5vYmplY3RJZDtcbiAgICAgIC8vIHJ1biB0aGUgZnVuY3Rpb24gYXN5bmNcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBqb2JGdW5jdGlvbihyZXF1ZXN0KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgam9iSGFuZGxlci5zZXRTdWNjZWVkZWQocmVzdWx0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIGpvYkhhbmRsZXIuc2V0RmFpbGVkKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCc6IGpvYlN0YXR1cy5vYmplY3RJZCxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSZXNwb25zZU9iamVjdChyZXNvbHZlLCByZWplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgcmVzdWx0OiBQYXJzZS5fZW5jb2RlKHJlc3VsdCksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gdHJpZ2dlcnMucmVzb2x2ZUVycm9yKG1lc3NhZ2UpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBoYW5kbGVDbG91ZEZ1bmN0aW9uKHJlcSkge1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgIGNvbnN0IGFwcGxpY2F0aW9uSWQgPSByZXEuY29uZmlnLmFwcGxpY2F0aW9uSWQ7XG4gICAgY29uc3QgdGhlRnVuY3Rpb24gPSB0cmlnZ2Vycy5nZXRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuXG4gICAgaWYgKCF0aGVGdW5jdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsIGBJbnZhbGlkIGZ1bmN0aW9uOiBcIiR7ZnVuY3Rpb25OYW1lfVwiYCk7XG4gICAgfVxuICAgIGxldCBwYXJhbXMgPSBPYmplY3QuYXNzaWduKHt9LCByZXEuYm9keSwgcmVxLnF1ZXJ5KTtcbiAgICBwYXJhbXMgPSBwYXJzZVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgIG1hc3RlcjogcmVxLmF1dGggJiYgcmVxLmF1dGguaXNNYXN0ZXIsXG4gICAgICB1c2VyOiByZXEuYXV0aCAmJiByZXEuYXV0aC51c2VyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5pbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgbG9nOiByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgICBoZWFkZXJzOiByZXEuY29uZmlnLmhlYWRlcnMsXG4gICAgICBpcDogcmVxLmNvbmZpZy5pcCxcbiAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgIGNvbnRleHQ6IHJlcS5pbmZvLmNvbnRleHQsXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBjb25zdCB1c2VyU3RyaW5nID0gcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgIGNvbnN0IHsgc3VjY2VzcywgZXJyb3IgfSA9IEZ1bmN0aW9uc1JvdXRlci5jcmVhdGVSZXNwb25zZU9iamVjdChcbiAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY2xlYW5SZXN1bHQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KHJlc3VsdC5yZXNwb25zZS5yZXN1bHQpKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICBgUmFuIGNsb3VkIGZ1bmN0aW9uICR7ZnVuY3Rpb25OYW1lfSBmb3IgdXNlciAke3VzZXJTdHJpbmd9IHdpdGg6XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBjbG91ZCBmdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX0gZm9yIHVzZXIgJHt1c2VyU3RyaW5nfSB3aXRoOlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvciksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBmdW5jdGlvbk5hbWUpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoZUZ1bmN0aW9uKHJlcXVlc3QpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/GlobalConfigRouter.js b/lib/Routers/GlobalConfigRouter.js new file mode 100644 index 0000000000..7156f27974 --- /dev/null +++ b/lib/Routers/GlobalConfigRouter.js @@ -0,0 +1,95 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GlobalConfigRouter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// global_config.js +class GlobalConfigRouter extends _PromiseRouter.default { + getGlobalConfig(req) { + return req.config.database.find('_GlobalConfig', { + objectId: '1' + }, { + limit: 1 + }).then(results => { + if (results.length != 1) { + // If there is no config in the database - return empty config. + return { + response: { + params: {} + } + }; + } + + const globalConfig = results[0]; + + if (!req.auth.isMaster && globalConfig.masterKeyOnly !== undefined) { + for (const param in globalConfig.params) { + if (globalConfig.masterKeyOnly[param]) { + delete globalConfig.params[param]; + delete globalConfig.masterKeyOnly[param]; + } + } + } + + return { + response: { + params: globalConfig.params, + masterKeyOnly: globalConfig.masterKeyOnly + } + }; + }); + } + + updateGlobalConfig(req) { + if (req.auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the config."); + } + + const params = req.body.params; + const masterKeyOnly = req.body.masterKeyOnly || {}; // Transform in dot notation to make sure it works + + const update = Object.keys(params).reduce((acc, key) => { + acc[`params.${key}`] = params[key]; + acc[`masterKeyOnly.${key}`] = masterKeyOnly[key] || false; + return acc; + }, {}); + return req.config.database.update('_GlobalConfig', { + objectId: '1' + }, update, { + upsert: true + }).then(() => ({ + response: { + result: true + } + })); + } + + mountRoutes() { + this.route('GET', '/config', req => { + return this.getGlobalConfig(req); + }); + this.route('PUT', '/config', middleware.promiseEnforceMasterKeyAccess, req => { + return this.updateGlobalConfig(req); + }); + } + +} + +exports.GlobalConfigRouter = GlobalConfigRouter; +var _default = GlobalConfigRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dsb2JhbENvbmZpZ1JvdXRlci5qcyJdLCJuYW1lcyI6WyJHbG9iYWxDb25maWdSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiZ2V0R2xvYmFsQ29uZmlnIiwicmVxIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwib2JqZWN0SWQiLCJsaW1pdCIsInRoZW4iLCJyZXN1bHRzIiwibGVuZ3RoIiwicmVzcG9uc2UiLCJwYXJhbXMiLCJnbG9iYWxDb25maWciLCJhdXRoIiwiaXNNYXN0ZXIiLCJtYXN0ZXJLZXlPbmx5IiwidW5kZWZpbmVkIiwicGFyYW0iLCJ1cGRhdGVHbG9iYWxDb25maWciLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwidXBkYXRlIiwiT2JqZWN0Iiwia2V5cyIsInJlZHVjZSIsImFjYyIsImtleSIsInVwc2VydCIsInJlc3VsdCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFIQTtBQUtPLE1BQU1BLGtCQUFOLFNBQWlDQyxzQkFBakMsQ0FBK0M7QUFDcERDLEVBQUFBLGVBQWUsQ0FBQ0MsR0FBRCxFQUFNO0FBQ25CLFdBQU9BLEdBQUcsQ0FBQ0MsTUFBSixDQUFXQyxRQUFYLENBQ0pDLElBREksQ0FDQyxlQURELEVBQ2tCO0FBQUVDLE1BQUFBLFFBQVEsRUFBRTtBQUFaLEtBRGxCLEVBQ3FDO0FBQUVDLE1BQUFBLEtBQUssRUFBRTtBQUFULEtBRHJDLEVBRUpDLElBRkksQ0FFQ0MsT0FBTyxJQUFJO0FBQ2YsVUFBSUEsT0FBTyxDQUFDQyxNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCO0FBQ0EsZUFBTztBQUFFQyxVQUFBQSxRQUFRLEVBQUU7QUFBRUMsWUFBQUEsTUFBTSxFQUFFO0FBQVY7QUFBWixTQUFQO0FBQ0Q7O0FBQ0QsWUFBTUMsWUFBWSxHQUFHSixPQUFPLENBQUMsQ0FBRCxDQUE1Qjs7QUFDQSxVQUFJLENBQUNQLEdBQUcsQ0FBQ1ksSUFBSixDQUFTQyxRQUFWLElBQXNCRixZQUFZLENBQUNHLGFBQWIsS0FBK0JDLFNBQXpELEVBQW9FO0FBQ2xFLGFBQUssTUFBTUMsS0FBWCxJQUFvQkwsWUFBWSxDQUFDRCxNQUFqQyxFQUF5QztBQUN2QyxjQUFJQyxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQUosRUFBdUM7QUFDckMsbUJBQU9MLFlBQVksQ0FBQ0QsTUFBYixDQUFvQk0sS0FBcEIsQ0FBUDtBQUNBLG1CQUFPTCxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsYUFBTztBQUNMUCxRQUFBQSxRQUFRLEVBQUU7QUFDUkMsVUFBQUEsTUFBTSxFQUFFQyxZQUFZLENBQUNELE1BRGI7QUFFUkksVUFBQUEsYUFBYSxFQUFFSCxZQUFZLENBQUNHO0FBRnBCO0FBREwsT0FBUDtBQU1ELEtBdEJJLENBQVA7QUF1QkQ7O0FBRURHLEVBQUFBLGtCQUFrQixDQUFDakIsR0FBRCxFQUFNO0FBQ3RCLFFBQUlBLEdBQUcsQ0FBQ1ksSUFBSixDQUFTTSxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUoseURBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1YLE1BQU0sR0FBR1YsR0FBRyxDQUFDc0IsSUFBSixDQUFTWixNQUF4QjtBQUNBLFVBQU1JLGFBQWEsR0FBR2QsR0FBRyxDQUFDc0IsSUFBSixDQUFTUixhQUFULElBQTBCLEVBQWhELENBUnNCLENBU3RCOztBQUNBLFVBQU1TLE1BQU0sR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlmLE1BQVosRUFBb0JnQixNQUFwQixDQUEyQixDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUN0REQsTUFBQUEsR0FBRyxDQUFFLFVBQVNDLEdBQUksRUFBZixDQUFILEdBQXVCbEIsTUFBTSxDQUFDa0IsR0FBRCxDQUE3QjtBQUNBRCxNQUFBQSxHQUFHLENBQUUsaUJBQWdCQyxHQUFJLEVBQXRCLENBQUgsR0FBOEJkLGFBQWEsQ0FBQ2MsR0FBRCxDQUFiLElBQXNCLEtBQXBEO0FBQ0EsYUFBT0QsR0FBUDtBQUNELEtBSmMsRUFJWixFQUpZLENBQWY7QUFLQSxXQUFPM0IsR0FBRyxDQUFDQyxNQUFKLENBQVdDLFFBQVgsQ0FDSnFCLE1BREksQ0FDRyxlQURILEVBQ29CO0FBQUVuQixNQUFBQSxRQUFRLEVBQUU7QUFBWixLQURwQixFQUN1Q21CLE1BRHZDLEVBQytDO0FBQUVNLE1BQUFBLE1BQU0sRUFBRTtBQUFWLEtBRC9DLEVBRUp2QixJQUZJLENBRUMsT0FBTztBQUFFRyxNQUFBQSxRQUFRLEVBQUU7QUFBRXFCLFFBQUFBLE1BQU0sRUFBRTtBQUFWO0FBQVosS0FBUCxDQUZELENBQVA7QUFHRDs7QUFFREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsU0FBbEIsRUFBNkJoQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRCxlQUFMLENBQXFCQyxHQUFyQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtnQyxLQUFMLENBQVcsS0FBWCxFQUFrQixTQUFsQixFQUE2QkMsVUFBVSxDQUFDQyw2QkFBeEMsRUFBdUVsQyxHQUFHLElBQUk7QUFDNUUsYUFBTyxLQUFLaUIsa0JBQUwsQ0FBd0JqQixHQUF4QixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQXREbUQ7OztlQXlEdkNILGtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZ2xvYmFsX2NvbmZpZy5qc1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgKiBhcyBtaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuZXhwb3J0IGNsYXNzIEdsb2JhbENvbmZpZ1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBnZXRHbG9iYWxDb25maWcocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5maW5kKCdfR2xvYmFsQ29uZmlnJywgeyBvYmplY3RJZDogJzEnIH0sIHsgbGltaXQ6IDEgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNvbmZpZyBpbiB0aGUgZGF0YWJhc2UgLSByZXR1cm4gZW1wdHkgY29uZmlnLlxuICAgICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7IHBhcmFtczoge30gfSB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdsb2JhbENvbmZpZyA9IHJlc3VsdHNbMF07XG4gICAgICAgIGlmICghcmVxLmF1dGguaXNNYXN0ZXIgJiYgZ2xvYmFsQ29uZmlnLm1hc3RlcktleU9ubHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcGFyYW0gaW4gZ2xvYmFsQ29uZmlnLnBhcmFtcykge1xuICAgICAgICAgICAgaWYgKGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5W3BhcmFtXSkge1xuICAgICAgICAgICAgICBkZWxldGUgZ2xvYmFsQ29uZmlnLnBhcmFtc1twYXJhbV07XG4gICAgICAgICAgICAgIGRlbGV0ZSBnbG9iYWxDb25maWcubWFzdGVyS2V5T25seVtwYXJhbV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHBhcmFtczogZ2xvYmFsQ29uZmlnLnBhcmFtcyxcbiAgICAgICAgICAgIG1hc3RlcktleU9ubHk6IGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUdsb2JhbENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIGNvbmZpZy5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zID0gcmVxLmJvZHkucGFyYW1zO1xuICAgIGNvbnN0IG1hc3RlcktleU9ubHkgPSByZXEuYm9keS5tYXN0ZXJLZXlPbmx5IHx8IHt9O1xuICAgIC8vIFRyYW5zZm9ybSBpbiBkb3Qgbm90YXRpb24gdG8gbWFrZSBzdXJlIGl0IHdvcmtzXG4gICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMocGFyYW1zKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBhY2NbYHBhcmFtcy4ke2tleX1gXSA9IHBhcmFtc1trZXldO1xuICAgICAgYWNjW2BtYXN0ZXJLZXlPbmx5LiR7a2V5fWBdID0gbWFzdGVyS2V5T25seVtrZXldIHx8IGZhbHNlO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC51cGRhdGUoJ19HbG9iYWxDb25maWcnLCB7IG9iamVjdElkOiAnMScgfSwgdXBkYXRlLCB7IHVwc2VydDogdHJ1ZSB9KVxuICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHsgcmVzdWx0OiB0cnVlIH0gfSkpO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jb25maWcnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9jb25maWcnLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR2xvYmFsQ29uZmlnUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/GraphQLRouter.js b/lib/Routers/GraphQLRouter.js new file mode 100644 index 0000000000..67a92b3032 --- /dev/null +++ b/lib/Routers/GraphQLRouter.js @@ -0,0 +1,55 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GraphQLRouter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const GraphQLConfigPath = '/graphql-config'; + +class GraphQLRouter extends _PromiseRouter.default { + async getGraphQLConfig(req) { + const result = await req.config.parseGraphQLController.getGraphQLConfig(); + return { + response: result + }; + } + + async updateGraphQLConfig(req) { + if (req.auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the GraphQL config."); + } + + const data = await req.config.parseGraphQLController.updateGraphQLConfig(req.body.params); + return { + response: data + }; + } + + mountRoutes() { + this.route('GET', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { + return this.getGraphQLConfig(req); + }); + this.route('PUT', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { + return this.updateGraphQLConfig(req); + }); + } + +} + +exports.GraphQLRouter = GraphQLRouter; +var _default = GraphQLRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dyYXBoUUxSb3V0ZXIuanMiXSwibmFtZXMiOlsiR3JhcGhRTENvbmZpZ1BhdGgiLCJHcmFwaFFMUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImdldEdyYXBoUUxDb25maWciLCJyZXEiLCJyZXN1bHQiLCJjb25maWciLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwicmVzcG9uc2UiLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImRhdGEiLCJib2R5IiwicGFyYW1zIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLGlCQUFpQixHQUFHLGlCQUExQjs7QUFFTyxNQUFNQyxhQUFOLFNBQTRCQyxzQkFBNUIsQ0FBMEM7QUFDL0MsUUFBTUMsZ0JBQU4sQ0FBdUJDLEdBQXZCLEVBQTRCO0FBQzFCLFVBQU1DLE1BQU0sR0FBRyxNQUFNRCxHQUFHLENBQUNFLE1BQUosQ0FBV0Msc0JBQVgsQ0FBa0NKLGdCQUFsQyxFQUFyQjtBQUNBLFdBQU87QUFDTEssTUFBQUEsUUFBUSxFQUFFSDtBQURMLEtBQVA7QUFHRDs7QUFFRCxRQUFNSSxtQkFBTixDQUEwQkwsR0FBMUIsRUFBK0I7QUFDN0IsUUFBSUEsR0FBRyxDQUFDTSxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixpRUFGSSxDQUFOO0FBSUQ7O0FBQ0QsVUFBTUMsSUFBSSxHQUFHLE1BQU1YLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxzQkFBWCxDQUFrQ0UsbUJBQWxDLENBQXNETCxHQUFHLENBQUNZLElBQUosQ0FBU0MsTUFBL0QsQ0FBbkI7QUFDQSxXQUFPO0FBQ0xULE1BQUFBLFFBQVEsRUFBRU87QUFETCxLQUFQO0FBR0Q7O0FBRURHLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxLQUFYLEVBQWtCbkIsaUJBQWxCLEVBQXFDb0IsVUFBVSxDQUFDQyw2QkFBaEQsRUFBK0VqQixHQUFHLElBQUk7QUFDcEYsYUFBTyxLQUFLRCxnQkFBTCxDQUFzQkMsR0FBdEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLZSxLQUFMLENBQVcsS0FBWCxFQUFrQm5CLGlCQUFsQixFQUFxQ29CLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFakIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0ssbUJBQUwsQ0FBeUJMLEdBQXpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBNUI4Qzs7O2VBK0JsQ0gsYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmNvbnN0IEdyYXBoUUxDb25maWdQYXRoID0gJy9ncmFwaHFsLWNvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBHcmFwaFFMUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIGFzeW5jIGdldEdyYXBoUUxDb25maWcocmVxKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLmdldEdyYXBoUUxDb25maWcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IHJlc3VsdCxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIEdyYXBoUUwgY29uZmlnLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcocmVxLmJvZHkucGFyYW1zKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IGRhdGEsXG4gICAgfTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BVVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdyYXBoUUxSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/HooksRouter.js b/lib/Routers/HooksRouter.js new file mode 100644 index 0000000000..b93d5e0543 --- /dev/null +++ b/lib/Routers/HooksRouter.js @@ -0,0 +1,144 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.HooksRouter = void 0; + +var _node = require("parse/node"); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class HooksRouter extends _PromiseRouter.default { + createHook(aHook, config) { + return config.hooksController.createHook(aHook).then(hook => ({ + response: hook + })); + } + + updateHook(aHook, config) { + return config.hooksController.updateHook(aHook).then(hook => ({ + response: hook + })); + } + + handlePost(req) { + return this.createHook(req.body, req.config); + } + + handleGetFunctions(req) { + var hooksController = req.config.hooksController; + + if (req.params.functionName) { + return hooksController.getFunction(req.params.functionName).then(foundFunction => { + if (!foundFunction) { + throw new _node.Parse.Error(143, `no function named: ${req.params.functionName} is defined`); + } + + return Promise.resolve({ + response: foundFunction + }); + }); + } + + return hooksController.getFunctions().then(functions => { + return { + response: functions || [] + }; + }, err => { + throw err; + }); + } + + handleGetTriggers(req) { + var hooksController = req.config.hooksController; + + if (req.params.className && req.params.triggerName) { + return hooksController.getTrigger(req.params.className, req.params.triggerName).then(foundTrigger => { + if (!foundTrigger) { + throw new _node.Parse.Error(143, `class ${req.params.className} does not exist`); + } + + return Promise.resolve({ + response: foundTrigger + }); + }); + } + + return hooksController.getTriggers().then(triggers => ({ + response: triggers || [] + })); + } + + handleDelete(req) { + var hooksController = req.config.hooksController; + + if (req.params.functionName) { + return hooksController.deleteFunction(req.params.functionName).then(() => ({ + response: {} + })); + } else if (req.params.className && req.params.triggerName) { + return hooksController.deleteTrigger(req.params.className, req.params.triggerName).then(() => ({ + response: {} + })); + } + + return Promise.resolve({ + response: {} + }); + } + + handleUpdate(req) { + var hook; + + if (req.params.functionName && req.body.url) { + hook = {}; + hook.functionName = req.params.functionName; + hook.url = req.body.url; + } else if (req.params.className && req.params.triggerName && req.body.url) { + hook = {}; + hook.className = req.params.className; + hook.triggerName = req.params.triggerName; + hook.url = req.body.url; + } else { + throw new _node.Parse.Error(143, 'invalid hook declaration'); + } + + return this.updateHook(hook, req.config); + } + + handlePut(req) { + var body = req.body; + + if (body.__op == 'Delete') { + return this.handleDelete(req); + } else { + return this.handleUpdate(req); + } + } + + mountRoutes() { + this.route('GET', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); + this.route('GET', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); + this.route('GET', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); + this.route('GET', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); + this.route('POST', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); + this.route('POST', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); + this.route('PUT', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); + this.route('PUT', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); + } + +} + +exports.HooksRouter = HooksRouter; +var _default = HooksRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0hvb2tzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkhvb2tzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImNyZWF0ZUhvb2siLCJhSG9vayIsImNvbmZpZyIsImhvb2tzQ29udHJvbGxlciIsInRoZW4iLCJob29rIiwicmVzcG9uc2UiLCJ1cGRhdGVIb29rIiwiaGFuZGxlUG9zdCIsInJlcSIsImJvZHkiLCJoYW5kbGVHZXRGdW5jdGlvbnMiLCJwYXJhbXMiLCJmdW5jdGlvbk5hbWUiLCJnZXRGdW5jdGlvbiIsImZvdW5kRnVuY3Rpb24iLCJQYXJzZSIsIkVycm9yIiwiUHJvbWlzZSIsInJlc29sdmUiLCJnZXRGdW5jdGlvbnMiLCJmdW5jdGlvbnMiLCJlcnIiLCJoYW5kbGVHZXRUcmlnZ2VycyIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlciIsImZvdW5kVHJpZ2dlciIsImdldFRyaWdnZXJzIiwidHJpZ2dlcnMiLCJoYW5kbGVEZWxldGUiLCJkZWxldGVGdW5jdGlvbiIsImRlbGV0ZVRyaWdnZXIiLCJoYW5kbGVVcGRhdGUiLCJ1cmwiLCJoYW5kbGVQdXQiLCJfX29wIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImJpbmQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFVBQVUsQ0FBQ0MsS0FBRCxFQUFRQyxNQUFSLEVBQWdCO0FBQ3hCLFdBQU9BLE1BQU0sQ0FBQ0MsZUFBUCxDQUF1QkgsVUFBdkIsQ0FBa0NDLEtBQWxDLEVBQXlDRyxJQUF6QyxDQUE4Q0MsSUFBSSxLQUFLO0FBQUVDLE1BQUFBLFFBQVEsRUFBRUQ7QUFBWixLQUFMLENBQWxELENBQVA7QUFDRDs7QUFFREUsRUFBQUEsVUFBVSxDQUFDTixLQUFELEVBQVFDLE1BQVIsRUFBZ0I7QUFDeEIsV0FBT0EsTUFBTSxDQUFDQyxlQUFQLENBQXVCSSxVQUF2QixDQUFrQ04sS0FBbEMsRUFBeUNHLElBQXpDLENBQThDQyxJQUFJLEtBQUs7QUFBRUMsTUFBQUEsUUFBUSxFQUFFRDtBQUFaLEtBQUwsQ0FBbEQsQ0FBUDtBQUNEOztBQUVERyxFQUFBQSxVQUFVLENBQUNDLEdBQUQsRUFBTTtBQUNkLFdBQU8sS0FBS1QsVUFBTCxDQUFnQlMsR0FBRyxDQUFDQyxJQUFwQixFQUEwQkQsR0FBRyxDQUFDUCxNQUE5QixDQUFQO0FBQ0Q7O0FBRURTLEVBQUFBLGtCQUFrQixDQUFDRixHQUFELEVBQU07QUFDdEIsUUFBSU4sZUFBZSxHQUFHTSxHQUFHLENBQUNQLE1BQUosQ0FBV0MsZUFBakM7O0FBQ0EsUUFBSU0sR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQWYsRUFBNkI7QUFDM0IsYUFBT1YsZUFBZSxDQUFDVyxXQUFoQixDQUE0QkwsR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQXZDLEVBQXFEVCxJQUFyRCxDQUEwRFcsYUFBYSxJQUFJO0FBQ2hGLFlBQUksQ0FBQ0EsYUFBTCxFQUFvQjtBQUNsQixnQkFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCLEdBQWhCLEVBQXNCLHNCQUFxQlIsR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQWEsYUFBbkUsQ0FBTjtBQUNEOztBQUNELGVBQU9LLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUFFYixVQUFBQSxRQUFRLEVBQUVTO0FBQVosU0FBaEIsQ0FBUDtBQUNELE9BTE0sQ0FBUDtBQU1EOztBQUVELFdBQU9aLGVBQWUsQ0FBQ2lCLFlBQWhCLEdBQStCaEIsSUFBL0IsQ0FDTGlCLFNBQVMsSUFBSTtBQUNYLGFBQU87QUFBRWYsUUFBQUEsUUFBUSxFQUFFZSxTQUFTLElBQUk7QUFBekIsT0FBUDtBQUNELEtBSEksRUFJTEMsR0FBRyxJQUFJO0FBQ0wsWUFBTUEsR0FBTjtBQUNELEtBTkksQ0FBUDtBQVFEOztBQUVEQyxFQUFBQSxpQkFBaUIsQ0FBQ2QsR0FBRCxFQUFNO0FBQ3JCLFFBQUlOLGVBQWUsR0FBR00sR0FBRyxDQUFDUCxNQUFKLENBQVdDLGVBQWpDOztBQUNBLFFBQUlNLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQUFYLElBQXdCZixHQUFHLENBQUNHLE1BQUosQ0FBV2EsV0FBdkMsRUFBb0Q7QUFDbEQsYUFBT3RCLGVBQWUsQ0FDbkJ1QixVQURJLENBQ09qQixHQUFHLENBQUNHLE1BQUosQ0FBV1ksU0FEbEIsRUFDNkJmLEdBQUcsQ0FBQ0csTUFBSixDQUFXYSxXQUR4QyxFQUVKckIsSUFGSSxDQUVDdUIsWUFBWSxJQUFJO0FBQ3BCLFlBQUksQ0FBQ0EsWUFBTCxFQUFtQjtBQUNqQixnQkFBTSxJQUFJWCxZQUFNQyxLQUFWLENBQWdCLEdBQWhCLEVBQXNCLFNBQVFSLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQUFVLGlCQUFuRCxDQUFOO0FBQ0Q7O0FBQ0QsZUFBT04sT0FBTyxDQUFDQyxPQUFSLENBQWdCO0FBQUViLFVBQUFBLFFBQVEsRUFBRXFCO0FBQVosU0FBaEIsQ0FBUDtBQUNELE9BUEksQ0FBUDtBQVFEOztBQUVELFdBQU94QixlQUFlLENBQUN5QixXQUFoQixHQUE4QnhCLElBQTlCLENBQW1DeUIsUUFBUSxLQUFLO0FBQUV2QixNQUFBQSxRQUFRLEVBQUV1QixRQUFRLElBQUk7QUFBeEIsS0FBTCxDQUEzQyxDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLFlBQVksQ0FBQ3JCLEdBQUQsRUFBTTtBQUNoQixRQUFJTixlQUFlLEdBQUdNLEdBQUcsQ0FBQ1AsTUFBSixDQUFXQyxlQUFqQzs7QUFDQSxRQUFJTSxHQUFHLENBQUNHLE1BQUosQ0FBV0MsWUFBZixFQUE2QjtBQUMzQixhQUFPVixlQUFlLENBQUM0QixjQUFoQixDQUErQnRCLEdBQUcsQ0FBQ0csTUFBSixDQUFXQyxZQUExQyxFQUF3RFQsSUFBeEQsQ0FBNkQsT0FBTztBQUFFRSxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQLENBQTdELENBQVA7QUFDRCxLQUZELE1BRU8sSUFBSUcsR0FBRyxDQUFDRyxNQUFKLENBQVdZLFNBQVgsSUFBd0JmLEdBQUcsQ0FBQ0csTUFBSixDQUFXYSxXQUF2QyxFQUFvRDtBQUN6RCxhQUFPdEIsZUFBZSxDQUNuQjZCLGFBREksQ0FDVXZCLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQURyQixFQUNnQ2YsR0FBRyxDQUFDRyxNQUFKLENBQVdhLFdBRDNDLEVBRUpyQixJQUZJLENBRUMsT0FBTztBQUFFRSxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQLENBRkQsQ0FBUDtBQUdEOztBQUNELFdBQU9ZLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUFFYixNQUFBQSxRQUFRLEVBQUU7QUFBWixLQUFoQixDQUFQO0FBQ0Q7O0FBRUQyQixFQUFBQSxZQUFZLENBQUN4QixHQUFELEVBQU07QUFDaEIsUUFBSUosSUFBSjs7QUFDQSxRQUFJSSxHQUFHLENBQUNHLE1BQUosQ0FBV0MsWUFBWCxJQUEyQkosR0FBRyxDQUFDQyxJQUFKLENBQVN3QixHQUF4QyxFQUE2QztBQUMzQzdCLE1BQUFBLElBQUksR0FBRyxFQUFQO0FBQ0FBLE1BQUFBLElBQUksQ0FBQ1EsWUFBTCxHQUFvQkosR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQS9CO0FBQ0FSLE1BQUFBLElBQUksQ0FBQzZCLEdBQUwsR0FBV3pCLEdBQUcsQ0FBQ0MsSUFBSixDQUFTd0IsR0FBcEI7QUFDRCxLQUpELE1BSU8sSUFBSXpCLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQUFYLElBQXdCZixHQUFHLENBQUNHLE1BQUosQ0FBV2EsV0FBbkMsSUFBa0RoQixHQUFHLENBQUNDLElBQUosQ0FBU3dCLEdBQS9ELEVBQW9FO0FBQ3pFN0IsTUFBQUEsSUFBSSxHQUFHLEVBQVA7QUFDQUEsTUFBQUEsSUFBSSxDQUFDbUIsU0FBTCxHQUFpQmYsR0FBRyxDQUFDRyxNQUFKLENBQVdZLFNBQTVCO0FBQ0FuQixNQUFBQSxJQUFJLENBQUNvQixXQUFMLEdBQW1CaEIsR0FBRyxDQUFDRyxNQUFKLENBQVdhLFdBQTlCO0FBQ0FwQixNQUFBQSxJQUFJLENBQUM2QixHQUFMLEdBQVd6QixHQUFHLENBQUNDLElBQUosQ0FBU3dCLEdBQXBCO0FBQ0QsS0FMTSxNQUtBO0FBQ0wsWUFBTSxJQUFJbEIsWUFBTUMsS0FBVixDQUFnQixHQUFoQixFQUFxQiwwQkFBckIsQ0FBTjtBQUNEOztBQUNELFdBQU8sS0FBS1YsVUFBTCxDQUFnQkYsSUFBaEIsRUFBc0JJLEdBQUcsQ0FBQ1AsTUFBMUIsQ0FBUDtBQUNEOztBQUVEaUMsRUFBQUEsU0FBUyxDQUFDMUIsR0FBRCxFQUFNO0FBQ2IsUUFBSUMsSUFBSSxHQUFHRCxHQUFHLENBQUNDLElBQWY7O0FBQ0EsUUFBSUEsSUFBSSxDQUFDMEIsSUFBTCxJQUFhLFFBQWpCLEVBQTJCO0FBQ3pCLGFBQU8sS0FBS04sWUFBTCxDQUFrQnJCLEdBQWxCLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPLEtBQUt3QixZQUFMLENBQWtCeEIsR0FBbEIsQ0FBUDtBQUNEO0FBQ0Y7O0FBRUQ0QixFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQ0UsS0FERixFQUVFLGtCQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLN0Isa0JBQUwsQ0FBd0I4QixJQUF4QixDQUE2QixJQUE3QixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLEtBREYsRUFFRSxpQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2pCLGlCQUFMLENBQXVCa0IsSUFBdkIsQ0FBNEIsSUFBNUIsQ0FKRjtBQU1BLFNBQUtILEtBQUwsQ0FDRSxLQURGLEVBRUUsZ0NBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFLEtBQUs3QixrQkFBTCxDQUF3QjhCLElBQXhCLENBQTZCLElBQTdCLENBSkY7QUFNQSxTQUFLSCxLQUFMLENBQ0UsS0FERixFQUVFLHlDQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLakIsaUJBQUwsQ0FBdUJrQixJQUF2QixDQUE0QixJQUE1QixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxrQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxpQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLEtBREYsRUFFRSxnQ0FGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0wsU0FBTCxDQUFlTSxJQUFmLENBQW9CLElBQXBCLENBSkY7QUFNQSxTQUFLSCxLQUFMLENBQ0UsS0FERixFQUVFLHlDQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLTCxTQUFMLENBQWVNLElBQWYsQ0FBb0IsSUFBcEIsQ0FKRjtBQU1EOztBQXpJNEM7OztlQTRJaEMzQyxXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmV4cG9ydCBjbGFzcyBIb29rc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjcmVhdGVIb29rKGFIb29rLCBjb25maWcpIHtcbiAgICByZXR1cm4gY29uZmlnLmhvb2tzQ29udHJvbGxlci5jcmVhdGVIb29rKGFIb29rKS50aGVuKGhvb2sgPT4gKHsgcmVzcG9uc2U6IGhvb2sgfSkpO1xuICB9XG5cbiAgdXBkYXRlSG9vayhhSG9vaywgY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ob29rc0NvbnRyb2xsZXIudXBkYXRlSG9vayhhSG9vaykudGhlbihob29rID0+ICh7IHJlc3BvbnNlOiBob29rIH0pKTtcbiAgfVxuXG4gIGhhbmRsZVBvc3QocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlSG9vayhyZXEuYm9keSwgcmVxLmNvbmZpZyk7XG4gIH1cblxuICBoYW5kbGVHZXRGdW5jdGlvbnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbihmb3VuZEZ1bmN0aW9uID0+IHtcbiAgICAgICAgaWYgKCFmb3VuZEZ1bmN0aW9uKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgYG5vIGZ1bmN0aW9uIG5hbWVkOiAke3JlcS5wYXJhbXMuZnVuY3Rpb25OYW1lfSBpcyBkZWZpbmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZEZ1bmN0aW9uIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbnMoKS50aGVuKFxuICAgICAgZnVuY3Rpb25zID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IGZ1bmN0aW9ucyB8fCBbXSB9O1xuICAgICAgfSxcbiAgICAgIGVyciA9PiB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlR2V0VHJpZ2dlcnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gaG9va3NDb250cm9sbGVyXG4gICAgICAgIC5nZXRUcmlnZ2VyKHJlcS5wYXJhbXMuY2xhc3NOYW1lLCByZXEucGFyYW1zLnRyaWdnZXJOYW1lKVxuICAgICAgICAudGhlbihmb3VuZFRyaWdnZXIgPT4ge1xuICAgICAgICAgIGlmICghZm91bmRUcmlnZ2VyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgY2xhc3MgJHtyZXEucGFyYW1zLmNsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZFRyaWdnZXIgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBob29rc0NvbnRyb2xsZXIuZ2V0VHJpZ2dlcnMoKS50aGVuKHRyaWdnZXJzID0+ICh7IHJlc3BvbnNlOiB0cmlnZ2VycyB8fCBbXSB9KSk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5kZWxldGVGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xuICAgIH0gZWxzZSBpZiAocmVxLnBhcmFtcy5jbGFzc05hbWUgJiYgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlclxuICAgICAgICAuZGVsZXRlVHJpZ2dlcihyZXEucGFyYW1zLmNsYXNzTmFtZSwgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSlcbiAgICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHt9IH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiB7fSB9KTtcbiAgfVxuXG4gIGhhbmRsZVVwZGF0ZShyZXEpIHtcbiAgICB2YXIgaG9vaztcbiAgICBpZiAocmVxLnBhcmFtcy5mdW5jdGlvbk5hbWUgJiYgcmVxLmJvZHkudXJsKSB7XG4gICAgICBob29rID0ge307XG4gICAgICBob29rLmZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lICYmIHJlcS5ib2R5LnVybCkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5jbGFzc05hbWUgPSByZXEucGFyYW1zLmNsYXNzTmFtZTtcbiAgICAgIGhvb2sudHJpZ2dlck5hbWUgPSByZXEucGFyYW1zLnRyaWdnZXJOYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlSG9vayhob29rLCByZXEuY29uZmlnKTtcbiAgfVxuXG4gIGhhbmRsZVB1dChyZXEpIHtcbiAgICB2YXIgYm9keSA9IHJlcS5ib2R5O1xuICAgIGlmIChib2R5Ll9fb3AgPT0gJ0RlbGV0ZScpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRGdW5jdGlvbnMuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2VycycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRUcmlnZ2Vycy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldEZ1bmN0aW9ucy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzLzpjbGFzc05hbWUvOnRyaWdnZXJOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldFRyaWdnZXJzLmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQb3N0LmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZVBvc3QuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy9mdW5jdGlvbnMvOmZ1bmN0aW9uTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2Vycy86Y2xhc3NOYW1lLzp0cmlnZ2VyTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSG9va3NSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/IAPValidationRouter.js b/lib/Routers/IAPValidationRouter.js new file mode 100644 index 0000000000..f0ba814941 --- /dev/null +++ b/lib/Routers/IAPValidationRouter.js @@ -0,0 +1,136 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.IAPValidationRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const request = require('../request'); + +const rest = require('../rest'); + +// TODO move validation logic in IAPValidationController +const IAP_SANDBOX_URL = 'https://sandbox.itunes.apple.com/verifyReceipt'; +const IAP_PRODUCTION_URL = 'https://buy.itunes.apple.com/verifyReceipt'; +const APP_STORE_ERRORS = { + 21000: 'The App Store could not read the JSON object you provided.', + 21002: 'The data in the receipt-data property was malformed or missing.', + 21003: 'The receipt could not be authenticated.', + 21004: 'The shared secret you provided does not match the shared secret on file for your account.', + 21005: 'The receipt server is not currently available.', + 21006: 'This receipt is valid but the subscription has expired.', + 21007: 'This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.', + 21008: 'This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.' +}; + +function appStoreError(status) { + status = parseInt(status); + var errorString = APP_STORE_ERRORS[status] || 'unknown error.'; + return { + status: status, + error: errorString + }; +} + +function validateWithAppStore(url, receipt) { + return request({ + url: url, + method: 'POST', + body: { + 'receipt-data': receipt + }, + headers: { + 'Content-Type': 'application/json' + } + }).then(httpResponse => { + const body = httpResponse.data; + + if (body && body.status === 0) { + // No need to pass anything, status is OK + return; + } // receipt is from test and should go to test + + + throw body; + }); +} + +function getFileForProductIdentifier(productIdentifier, req) { + return rest.find(req.config, req.auth, '_Product', { + productIdentifier: productIdentifier + }, undefined, req.info.clientSDK, req.info.context).then(function (result) { + const products = result.results; + + if (!products || products.length != 1) { + // Error not found or too many + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + var download = products[0].download; + return Promise.resolve({ + response: download + }); + }); +} + +class IAPValidationRouter extends _PromiseRouter.default { + handleRequest(req) { + let receipt = req.body.receipt; + const productIdentifier = req.body.productIdentifier; + + if (!receipt || !productIdentifier) { + // TODO: Error, malformed request + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'missing receipt or productIdentifier'); + } // Transform the object if there + // otherwise assume it's in Base64 already + + + if (typeof receipt == 'object') { + if (receipt['__type'] == 'Bytes') { + receipt = receipt.base64; + } + } + + if (process.env.TESTING == '1' && req.body.bypassAppStoreValidation) { + return getFileForProductIdentifier(productIdentifier, req); + } + + function successCallback() { + return getFileForProductIdentifier(productIdentifier, req); + } + + function errorCallback(error) { + return Promise.resolve({ + response: appStoreError(error.status) + }); + } + + return validateWithAppStore(IAP_PRODUCTION_URL, receipt).then(() => { + return successCallback(); + }, error => { + if (error.status == 21007) { + return validateWithAppStore(IAP_SANDBOX_URL, receipt).then(() => { + return successCallback(); + }, error => { + return errorCallback(error); + }); + } + + return errorCallback(error); + }); + } + + mountRoutes() { + this.route('POST', '/validate_purchase', this.handleRequest); + } + +} + +exports.IAPValidationRouter = IAPValidationRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXIuanMiXSwibmFtZXMiOlsicmVxdWVzdCIsInJlcXVpcmUiLCJyZXN0IiwiSUFQX1NBTkRCT1hfVVJMIiwiSUFQX1BST0RVQ1RJT05fVVJMIiwiQVBQX1NUT1JFX0VSUk9SUyIsImFwcFN0b3JlRXJyb3IiLCJzdGF0dXMiLCJwYXJzZUludCIsImVycm9yU3RyaW5nIiwiZXJyb3IiLCJ2YWxpZGF0ZVdpdGhBcHBTdG9yZSIsInVybCIsInJlY2VpcHQiLCJtZXRob2QiLCJib2R5IiwiaGVhZGVycyIsInRoZW4iLCJodHRwUmVzcG9uc2UiLCJkYXRhIiwiZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyIiwicHJvZHVjdElkZW50aWZpZXIiLCJyZXEiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsInVuZGVmaW5lZCIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzdWx0IiwicHJvZHVjdHMiLCJyZXN1bHRzIiwibGVuZ3RoIiwiUGFyc2UiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJkb3dubG9hZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiLCJJQVBWYWxpZGF0aW9uUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJJTlZBTElEX0pTT04iLCJiYXNlNjQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsImJ5cGFzc0FwcFN0b3JlVmFsaWRhdGlvbiIsInN1Y2Nlc3NDYWxsYmFjayIsImVycm9yQ2FsbGJhY2siLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBR0E7Ozs7QUFGQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQXZCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLFNBQUQsQ0FBcEI7O0FBR0E7QUFDQSxNQUFNRSxlQUFlLEdBQUcsZ0RBQXhCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsNENBQTNCO0FBRUEsTUFBTUMsZ0JBQWdCLEdBQUc7QUFDdkIsU0FBTyw0REFEZ0I7QUFFdkIsU0FBTyxpRUFGZ0I7QUFHdkIsU0FBTyx5Q0FIZ0I7QUFJdkIsU0FBTywyRkFKZ0I7QUFLdkIsU0FBTyxnREFMZ0I7QUFNdkIsU0FBTyx5REFOZ0I7QUFPdkIsU0FBTyxxSkFQZ0I7QUFRdkIsU0FBTztBQVJnQixDQUF6Qjs7QUFXQSxTQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQjtBQUM3QkEsRUFBQUEsTUFBTSxHQUFHQyxRQUFRLENBQUNELE1BQUQsQ0FBakI7QUFDQSxNQUFJRSxXQUFXLEdBQUdKLGdCQUFnQixDQUFDRSxNQUFELENBQWhCLElBQTRCLGdCQUE5QztBQUNBLFNBQU87QUFBRUEsSUFBQUEsTUFBTSxFQUFFQSxNQUFWO0FBQWtCRyxJQUFBQSxLQUFLLEVBQUVEO0FBQXpCLEdBQVA7QUFDRDs7QUFFRCxTQUFTRSxvQkFBVCxDQUE4QkMsR0FBOUIsRUFBbUNDLE9BQW5DLEVBQTRDO0FBQzFDLFNBQU9iLE9BQU8sQ0FBQztBQUNiWSxJQUFBQSxHQUFHLEVBQUVBLEdBRFE7QUFFYkUsSUFBQUEsTUFBTSxFQUFFLE1BRks7QUFHYkMsSUFBQUEsSUFBSSxFQUFFO0FBQUUsc0JBQWdCRjtBQUFsQixLQUhPO0FBSWJHLElBQUFBLE9BQU8sRUFBRTtBQUNQLHNCQUFnQjtBQURUO0FBSkksR0FBRCxDQUFQLENBT0pDLElBUEksQ0FPQ0MsWUFBWSxJQUFJO0FBQ3RCLFVBQU1ILElBQUksR0FBR0csWUFBWSxDQUFDQyxJQUExQjs7QUFDQSxRQUFJSixJQUFJLElBQUlBLElBQUksQ0FBQ1IsTUFBTCxLQUFnQixDQUE1QixFQUErQjtBQUM3QjtBQUNBO0FBQ0QsS0FMcUIsQ0FNdEI7OztBQUNBLFVBQU1RLElBQU47QUFDRCxHQWZNLENBQVA7QUFnQkQ7O0FBRUQsU0FBU0ssMkJBQVQsQ0FBcUNDLGlCQUFyQyxFQUF3REMsR0FBeEQsRUFBNkQ7QUFDM0QsU0FBT3BCLElBQUksQ0FDUnFCLElBREksQ0FFSEQsR0FBRyxDQUFDRSxNQUZELEVBR0hGLEdBQUcsQ0FBQ0csSUFIRCxFQUlILFVBSkcsRUFLSDtBQUFFSixJQUFBQSxpQkFBaUIsRUFBRUE7QUFBckIsR0FMRyxFQU1ISyxTQU5HLEVBT0hKLEdBQUcsQ0FBQ0ssSUFBSixDQUFTQyxTQVBOLEVBUUhOLEdBQUcsQ0FBQ0ssSUFBSixDQUFTRSxPQVJOLEVBVUpaLElBVkksQ0FVQyxVQUFVYSxNQUFWLEVBQWtCO0FBQ3RCLFVBQU1DLFFBQVEsR0FBR0QsTUFBTSxDQUFDRSxPQUF4Qjs7QUFDQSxRQUFJLENBQUNELFFBQUQsSUFBYUEsUUFBUSxDQUFDRSxNQUFULElBQW1CLENBQXBDLEVBQXVDO0FBQ3JDO0FBQ0EsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQWdCRCxjQUFNQyxLQUFOLENBQVlDLGdCQUE1QixFQUE4QyxtQkFBOUMsQ0FBTjtBQUNEOztBQUVELFFBQUlDLFFBQVEsR0FBR04sUUFBUSxDQUFDLENBQUQsQ0FBUixDQUFZTSxRQUEzQjtBQUNBLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUFFQyxNQUFBQSxRQUFRLEVBQUVIO0FBQVosS0FBaEIsQ0FBUDtBQUNELEdBbkJJLENBQVA7QUFvQkQ7O0FBRU0sTUFBTUksbUJBQU4sU0FBa0NDLHNCQUFsQyxDQUFnRDtBQUNyREMsRUFBQUEsYUFBYSxDQUFDckIsR0FBRCxFQUFNO0FBQ2pCLFFBQUlULE9BQU8sR0FBR1MsR0FBRyxDQUFDUCxJQUFKLENBQVNGLE9BQXZCO0FBQ0EsVUFBTVEsaUJBQWlCLEdBQUdDLEdBQUcsQ0FBQ1AsSUFBSixDQUFTTSxpQkFBbkM7O0FBRUEsUUFBSSxDQUFDUixPQUFELElBQVksQ0FBQ1EsaUJBQWpCLEVBQW9DO0FBQ2xDO0FBQ0EsWUFBTSxJQUFJYSxjQUFNQyxLQUFWLENBQWdCRCxjQUFNQyxLQUFOLENBQVlTLFlBQTVCLEVBQTBDLHNDQUExQyxDQUFOO0FBQ0QsS0FQZ0IsQ0FTakI7QUFDQTs7O0FBQ0EsUUFBSSxPQUFPL0IsT0FBUCxJQUFrQixRQUF0QixFQUFnQztBQUM5QixVQUFJQSxPQUFPLENBQUMsUUFBRCxDQUFQLElBQXFCLE9BQXpCLEVBQWtDO0FBQ2hDQSxRQUFBQSxPQUFPLEdBQUdBLE9BQU8sQ0FBQ2dDLE1BQWxCO0FBQ0Q7QUFDRjs7QUFFRCxRQUFJQyxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBWixJQUF1QixHQUF2QixJQUE4QjFCLEdBQUcsQ0FBQ1AsSUFBSixDQUFTa0Msd0JBQTNDLEVBQXFFO0FBQ25FLGFBQU83QiwyQkFBMkIsQ0FBQ0MsaUJBQUQsRUFBb0JDLEdBQXBCLENBQWxDO0FBQ0Q7O0FBRUQsYUFBUzRCLGVBQVQsR0FBMkI7QUFDekIsYUFBTzlCLDJCQUEyQixDQUFDQyxpQkFBRCxFQUFvQkMsR0FBcEIsQ0FBbEM7QUFDRDs7QUFFRCxhQUFTNkIsYUFBVCxDQUF1QnpDLEtBQXZCLEVBQThCO0FBQzVCLGFBQU80QixPQUFPLENBQUNDLE9BQVIsQ0FBZ0I7QUFBRUMsUUFBQUEsUUFBUSxFQUFFbEMsYUFBYSxDQUFDSSxLQUFLLENBQUNILE1BQVA7QUFBekIsT0FBaEIsQ0FBUDtBQUNEOztBQUVELFdBQU9JLG9CQUFvQixDQUFDUCxrQkFBRCxFQUFxQlMsT0FBckIsQ0FBcEIsQ0FBa0RJLElBQWxELENBQ0wsTUFBTTtBQUNKLGFBQU9pQyxlQUFlLEVBQXRCO0FBQ0QsS0FISSxFQUlMeEMsS0FBSyxJQUFJO0FBQ1AsVUFBSUEsS0FBSyxDQUFDSCxNQUFOLElBQWdCLEtBQXBCLEVBQTJCO0FBQ3pCLGVBQU9JLG9CQUFvQixDQUFDUixlQUFELEVBQWtCVSxPQUFsQixDQUFwQixDQUErQ0ksSUFBL0MsQ0FDTCxNQUFNO0FBQ0osaUJBQU9pQyxlQUFlLEVBQXRCO0FBQ0QsU0FISSxFQUlMeEMsS0FBSyxJQUFJO0FBQ1AsaUJBQU95QyxhQUFhLENBQUN6QyxLQUFELENBQXBCO0FBQ0QsU0FOSSxDQUFQO0FBUUQ7O0FBRUQsYUFBT3lDLGFBQWEsQ0FBQ3pDLEtBQUQsQ0FBcEI7QUFDRCxLQWpCSSxDQUFQO0FBbUJEOztBQUVEMEMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsb0JBQW5CLEVBQXlDLEtBQUtWLGFBQTlDO0FBQ0Q7O0FBckRvRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4uL3JlcXVlc3QnKTtcbmNvbnN0IHJlc3QgPSByZXF1aXJlKCcuLi9yZXN0Jyk7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8vIFRPRE8gbW92ZSB2YWxpZGF0aW9uIGxvZ2ljIGluIElBUFZhbGlkYXRpb25Db250cm9sbGVyXG5jb25zdCBJQVBfU0FOREJPWF9VUkwgPSAnaHR0cHM6Ly9zYW5kYm94Lml0dW5lcy5hcHBsZS5jb20vdmVyaWZ5UmVjZWlwdCc7XG5jb25zdCBJQVBfUFJPRFVDVElPTl9VUkwgPSAnaHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS92ZXJpZnlSZWNlaXB0JztcblxuY29uc3QgQVBQX1NUT1JFX0VSUk9SUyA9IHtcbiAgMjEwMDA6ICdUaGUgQXBwIFN0b3JlIGNvdWxkIG5vdCByZWFkIHRoZSBKU09OIG9iamVjdCB5b3UgcHJvdmlkZWQuJyxcbiAgMjEwMDI6ICdUaGUgZGF0YSBpbiB0aGUgcmVjZWlwdC1kYXRhIHByb3BlcnR5IHdhcyBtYWxmb3JtZWQgb3IgbWlzc2luZy4nLFxuICAyMTAwMzogJ1RoZSByZWNlaXB0IGNvdWxkIG5vdCBiZSBhdXRoZW50aWNhdGVkLicsXG4gIDIxMDA0OiAnVGhlIHNoYXJlZCBzZWNyZXQgeW91IHByb3ZpZGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaGFyZWQgc2VjcmV0IG9uIGZpbGUgZm9yIHlvdXIgYWNjb3VudC4nLFxuICAyMTAwNTogJ1RoZSByZWNlaXB0IHNlcnZlciBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS4nLFxuICAyMTAwNjogJ1RoaXMgcmVjZWlwdCBpcyB2YWxpZCBidXQgdGhlIHN1YnNjcmlwdGlvbiBoYXMgZXhwaXJlZC4nLFxuICAyMTAwNzogJ1RoaXMgcmVjZWlwdCBpcyBmcm9tIHRoZSB0ZXN0IGVudmlyb25tZW50LCBidXQgaXQgd2FzIHNlbnQgdG8gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQgZm9yIHZlcmlmaWNhdGlvbi4gU2VuZCBpdCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBpbnN0ZWFkLicsXG4gIDIxMDA4OiAnVGhpcyByZWNlaXB0IGlzIGZyb20gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQsIGJ1dCBpdCB3YXMgc2VudCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBmb3IgdmVyaWZpY2F0aW9uLiBTZW5kIGl0IHRvIHRoZSBwcm9kdWN0aW9uIGVudmlyb25tZW50IGluc3RlYWQuJyxcbn07XG5cbmZ1bmN0aW9uIGFwcFN0b3JlRXJyb3Ioc3RhdHVzKSB7XG4gIHN0YXR1cyA9IHBhcnNlSW50KHN0YXR1cyk7XG4gIHZhciBlcnJvclN0cmluZyA9IEFQUF9TVE9SRV9FUlJPUlNbc3RhdHVzXSB8fCAndW5rbm93biBlcnJvci4nO1xuICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cywgZXJyb3I6IGVycm9yU3RyaW5nIH07XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlV2l0aEFwcFN0b3JlKHVybCwgcmVjZWlwdCkge1xuICByZXR1cm4gcmVxdWVzdCh7XG4gICAgdXJsOiB1cmwsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgYm9keTogeyAncmVjZWlwdC1kYXRhJzogcmVjZWlwdCB9LFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfSxcbiAgfSkudGhlbihodHRwUmVzcG9uc2UgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBodHRwUmVzcG9uc2UuZGF0YTtcbiAgICBpZiAoYm9keSAmJiBib2R5LnN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gTm8gbmVlZCB0byBwYXNzIGFueXRoaW5nLCBzdGF0dXMgaXMgT0tcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gcmVjZWlwdCBpcyBmcm9tIHRlc3QgYW5kIHNob3VsZCBnbyB0byB0ZXN0XG4gICAgdGhyb3cgYm9keTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVGb3JQcm9kdWN0SWRlbnRpZmllcihwcm9kdWN0SWRlbnRpZmllciwgcmVxKSB7XG4gIHJldHVybiByZXN0XG4gICAgLmZpbmQoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX1Byb2R1Y3QnLFxuICAgICAgeyBwcm9kdWN0SWRlbnRpZmllcjogcHJvZHVjdElkZW50aWZpZXIgfSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgY29uc3QgcHJvZHVjdHMgPSByZXN1bHQucmVzdWx0cztcbiAgICAgIGlmICghcHJvZHVjdHMgfHwgcHJvZHVjdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgLy8gRXJyb3Igbm90IGZvdW5kIG9yIHRvbyBtYW55XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGRvd25sb2FkID0gcHJvZHVjdHNbMF0uZG93bmxvYWQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgcmVzcG9uc2U6IGRvd25sb2FkIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgSUFQVmFsaWRhdGlvblJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVSZXF1ZXN0KHJlcSkge1xuICAgIGxldCByZWNlaXB0ID0gcmVxLmJvZHkucmVjZWlwdDtcbiAgICBjb25zdCBwcm9kdWN0SWRlbnRpZmllciA9IHJlcS5ib2R5LnByb2R1Y3RJZGVudGlmaWVyO1xuXG4gICAgaWYgKCFyZWNlaXB0IHx8ICFwcm9kdWN0SWRlbnRpZmllcikge1xuICAgICAgLy8gVE9ETzogRXJyb3IsIG1hbGZvcm1lZCByZXF1ZXN0XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnbWlzc2luZyByZWNlaXB0IG9yIHByb2R1Y3RJZGVudGlmaWVyJyk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIHRoZSBvYmplY3QgaWYgdGhlcmVcbiAgICAvLyBvdGhlcndpc2UgYXNzdW1lIGl0J3MgaW4gQmFzZTY0IGFscmVhZHlcbiAgICBpZiAodHlwZW9mIHJlY2VpcHQgPT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChyZWNlaXB0WydfX3R5cGUnXSA9PSAnQnl0ZXMnKSB7XG4gICAgICAgIHJlY2VpcHQgPSByZWNlaXB0LmJhc2U2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyA9PSAnMScgJiYgcmVxLmJvZHkuYnlwYXNzQXBwU3RvcmVWYWxpZGF0aW9uKSB7XG4gICAgICByZXR1cm4gZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyKHByb2R1Y3RJZGVudGlmaWVyLCByZXEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Y2Nlc3NDYWxsYmFjaygpIHtcbiAgICAgIHJldHVybiBnZXRGaWxlRm9yUHJvZHVjdElkZW50aWZpZXIocHJvZHVjdElkZW50aWZpZXIsIHJlcSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JDYWxsYmFjayhlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBhcHBTdG9yZUVycm9yKGVycm9yLnN0YXR1cykgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlV2l0aEFwcFN0b3JlKElBUF9QUk9EVUNUSU9OX1VSTCwgcmVjZWlwdCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NDYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSAyMTAwNykge1xuICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVdpdGhBcHBTdG9yZShJQVBfU0FOREJPWF9VUkwsIHJlY2VpcHQpLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzQ2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvckNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92YWxpZGF0ZV9wdXJjaGFzZScsIHRoaXMuaGFuZGxlUmVxdWVzdCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/InstallationsRouter.js b/lib/Routers/InstallationsRouter.js new file mode 100644 index 0000000000..62b677126a --- /dev/null +++ b/lib/Routers/InstallationsRouter.js @@ -0,0 +1,57 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.InstallationsRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _middlewares = require("../middlewares"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// InstallationsRouter.js +class InstallationsRouter extends _ClassesRouter.default { + className() { + return '_Installation'; + } + + handleFind(req) { + const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); + + const options = _ClassesRouter.default.optionsFromBody(body); + + return _rest.default.find(req.config, req.auth, '_Installation', body.where, options, req.info.clientSDK, req.info.context).then(response => { + return { + response: response + }; + }); + } + + mountRoutes() { + this.route('GET', '/installations', req => { + return this.handleFind(req); + }); + this.route('GET', '/installations/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/installations', _middlewares.promiseEnsureIdempotency, req => { + return this.handleCreate(req); + }); + this.route('PUT', '/installations/:objectId', _middlewares.promiseEnsureIdempotency, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/installations/:objectId', req => { + return this.handleDelete(req); + }); + } + +} + +exports.InstallationsRouter = InstallationsRouter; +var _default = InstallationsRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0luc3RhbGxhdGlvbnNSb3V0ZXIuanMiXSwibmFtZXMiOlsiSW5zdGFsbGF0aW9uc1JvdXRlciIsIkNsYXNzZXNSb3V0ZXIiLCJjbGFzc05hbWUiLCJoYW5kbGVGaW5kIiwicmVxIiwiYm9keSIsIk9iamVjdCIsImFzc2lnbiIsIkpTT05Gcm9tUXVlcnkiLCJxdWVyeSIsIm9wdGlvbnMiLCJvcHRpb25zRnJvbUJvZHkiLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsImF1dGgiLCJ3aGVyZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUdldCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOztBQUNBOztBQUNBOzs7O0FBSkE7QUFNTyxNQUFNQSxtQkFBTixTQUFrQ0Msc0JBQWxDLENBQWdEO0FBQ3JEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLGVBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUNBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILGVBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBO0FBQVosT0FBUDtBQUNELEtBWkksQ0FBUDtBQWFEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixnQkFBbEIsRUFBb0NuQixHQUFHLElBQUk7QUFDekMsYUFBTyxLQUFLRCxVQUFMLENBQWdCQyxHQUFoQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsS0FBWCxFQUFrQiwwQkFBbEIsRUFBOENuQixHQUFHLElBQUk7QUFDbkQsYUFBTyxLQUFLb0IsU0FBTCxDQUFlcEIsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsTUFBWCxFQUFtQixnQkFBbkIsRUFBcUNFLHFDQUFyQyxFQUErRHJCLEdBQUcsSUFBSTtBQUNwRSxhQUFPLEtBQUtzQixZQUFMLENBQWtCdEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLbUIsS0FBTCxDQUFXLEtBQVgsRUFBa0IsMEJBQWxCLEVBQThDRSxxQ0FBOUMsRUFBd0VyQixHQUFHLElBQUk7QUFDN0UsYUFBTyxLQUFLdUIsWUFBTCxDQUFrQnZCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS21CLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLDBCQUFyQixFQUFpRG5CLEdBQUcsSUFBSTtBQUN0RCxhQUFPLEtBQUt3QixZQUFMLENBQWtCeEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF2Q29EOzs7ZUEwQ3hDSixtQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEluc3RhbGxhdGlvbnNSb3V0ZXIuanNcblxuaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IH0gZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgSW5zdGFsbGF0aW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfSW5zdGFsbGF0aW9uJztcbiAgfVxuXG4gIGhhbmRsZUZpbmQocmVxKSB7XG4gICAgY29uc3QgYm9keSA9IE9iamVjdC5hc3NpZ24ocmVxLmJvZHksIENsYXNzZXNSb3V0ZXIuSlNPTkZyb21RdWVyeShyZXEucXVlcnkpKTtcbiAgICBjb25zdCBvcHRpb25zID0gQ2xhc3Nlc1JvdXRlci5vcHRpb25zRnJvbUJvZHkoYm9keSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICBib2R5LndoZXJlLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvaW5zdGFsbGF0aW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVGaW5kKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9pbnN0YWxsYXRpb25zJywgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5LCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQ3JlYXRlKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvaW5zdGFsbGF0aW9ucy86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5zdGFsbGF0aW9uc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/LogsRouter.js b/lib/Routers/LogsRouter.js new file mode 100644 index 0000000000..4399b717f5 --- /dev/null +++ b/lib/Routers/LogsRouter.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LogsRouter = void 0; + +var _node = require("parse/node"); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class LogsRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/scriptlog', middleware.promiseEnforceMasterKeyAccess, this.validateRequest, req => { + return this.handleGET(req); + }); + } + + validateRequest(req) { + if (!req.config || !req.config.loggerController) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); + } + } // Returns a promise for a {response} object. + // query params: + // level (optional) Level of logging you want to query for (info || error) + // from (optional) Start time for the search. Defaults to 1 week ago. + // until (optional) End time for the search. Defaults to current time. + // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. + // size (optional) Number of rows returned by search. Defaults to 10 + // n same as size, overrides size if set + + + handleGET(req) { + const from = req.query.from; + const until = req.query.until; + let size = req.query.size; + + if (req.query.n) { + size = req.query.n; + } + + const order = req.query.order; + const level = req.query.level; + const options = { + from, + until, + size, + order, + level + }; + return req.config.loggerController.getLogs(options).then(result => { + return Promise.resolve({ + response: result + }); + }); + } + +} + +exports.LogsRouter = LogsRouter; +var _default = LogsRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0xvZ3NSb3V0ZXIuanMiXSwibmFtZXMiOlsiTG9nc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwidmFsaWRhdGVSZXF1ZXN0IiwicmVxIiwiaGFuZGxlR0VUIiwiY29uZmlnIiwibG9nZ2VyQ29udHJvbGxlciIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJmcm9tIiwicXVlcnkiLCJ1bnRpbCIsInNpemUiLCJuIiwib3JkZXIiLCJsZXZlbCIsIm9wdGlvbnMiLCJnZXRMb2dzIiwidGhlbiIsInJlc3VsdCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FDRSxLQURGLEVBRUUsWUFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0MsZUFKUCxFQUtFQyxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtDLFNBQUwsQ0FBZUQsR0FBZixDQUFQO0FBQ0QsS0FQSDtBQVNEOztBQUVERCxFQUFBQSxlQUFlLENBQUNDLEdBQUQsRUFBTTtBQUNuQixRQUFJLENBQUNBLEdBQUcsQ0FBQ0UsTUFBTCxJQUFlLENBQUNGLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBL0IsRUFBaUQ7QUFDL0MsWUFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEO0FBQ0YsR0FqQjJDLENBbUI1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQUwsRUFBQUEsU0FBUyxDQUFDRCxHQUFELEVBQU07QUFDYixVQUFNTyxJQUFJLEdBQUdQLEdBQUcsQ0FBQ1EsS0FBSixDQUFVRCxJQUF2QjtBQUNBLFVBQU1FLEtBQUssR0FBR1QsR0FBRyxDQUFDUSxLQUFKLENBQVVDLEtBQXhCO0FBQ0EsUUFBSUMsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUUsSUFBckI7O0FBQ0EsUUFBSVYsR0FBRyxDQUFDUSxLQUFKLENBQVVHLENBQWQsRUFBaUI7QUFDZkQsTUFBQUEsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUcsQ0FBakI7QUFDRDs7QUFFRCxVQUFNQyxLQUFLLEdBQUdaLEdBQUcsQ0FBQ1EsS0FBSixDQUFVSSxLQUF4QjtBQUNBLFVBQU1DLEtBQUssR0FBR2IsR0FBRyxDQUFDUSxLQUFKLENBQVVLLEtBQXhCO0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RQLE1BQUFBLElBRGM7QUFFZEUsTUFBQUEsS0FGYztBQUdkQyxNQUFBQSxJQUhjO0FBSWRFLE1BQUFBLEtBSmM7QUFLZEMsTUFBQUE7QUFMYyxLQUFoQjtBQVFBLFdBQU9iLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBWCxDQUE0QlksT0FBNUIsQ0FBb0NELE9BQXBDLEVBQTZDRSxJQUE3QyxDQUFrREMsTUFBTSxJQUFJO0FBQ2pFLGFBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUNyQkMsUUFBQUEsUUFBUSxFQUFFSDtBQURXLE9BQWhCLENBQVA7QUFHRCxLQUpNLENBQVA7QUFLRDs7QUFsRDJDOzs7ZUFxRC9CeEIsVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgTG9nc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3NjcmlwdGxvZycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy52YWxpZGF0ZVJlcXVlc3QsXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVHRVQocmVxKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVSZXF1ZXN0KHJlcSkge1xuICAgIGlmICghcmVxLmNvbmZpZyB8fCAhcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTG9nZ2VyIGFkYXB0ZXIgaXMgbm90IGF2YWlsYWJsZScpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZX0gb2JqZWN0LlxuICAvLyBxdWVyeSBwYXJhbXM6XG4gIC8vIGxldmVsIChvcHRpb25hbCkgTGV2ZWwgb2YgbG9nZ2luZyB5b3Ugd2FudCB0byBxdWVyeSBmb3IgKGluZm8gfHwgZXJyb3IpXG4gIC8vIGZyb20gKG9wdGlvbmFsKSBTdGFydCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byAxIHdlZWsgYWdvLlxuICAvLyB1bnRpbCAob3B0aW9uYWwpIEVuZCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byBjdXJyZW50IHRpbWUuXG4gIC8vIG9yZGVyIChvcHRpb25hbCkgRGlyZWN0aW9uIG9mIHJlc3VsdHMgcmV0dXJuZWQsIGVpdGhlciDigJxhc2PigJ0gb3Ig4oCcZGVzY+KAnS4gRGVmYXVsdHMgdG8g4oCcZGVzY+KAnS5cbiAgLy8gc2l6ZSAob3B0aW9uYWwpIE51bWJlciBvZiByb3dzIHJldHVybmVkIGJ5IHNlYXJjaC4gRGVmYXVsdHMgdG8gMTBcbiAgLy8gbiBzYW1lIGFzIHNpemUsIG92ZXJyaWRlcyBzaXplIGlmIHNldFxuICBoYW5kbGVHRVQocmVxKSB7XG4gICAgY29uc3QgZnJvbSA9IHJlcS5xdWVyeS5mcm9tO1xuICAgIGNvbnN0IHVudGlsID0gcmVxLnF1ZXJ5LnVudGlsO1xuICAgIGxldCBzaXplID0gcmVxLnF1ZXJ5LnNpemU7XG4gICAgaWYgKHJlcS5xdWVyeS5uKSB7XG4gICAgICBzaXplID0gcmVxLnF1ZXJ5Lm47XG4gICAgfVxuXG4gICAgY29uc3Qgb3JkZXIgPSByZXEucXVlcnkub3JkZXI7XG4gICAgY29uc3QgbGV2ZWwgPSByZXEucXVlcnkubGV2ZWw7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmdldExvZ3Mob3B0aW9ucykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgIHJlc3BvbnNlOiByZXN1bHQsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PublicAPIRouter.js b/lib/Routers/PublicAPIRouter.js new file mode 100644 index 0000000000..1ee21b99b2 --- /dev/null +++ b/lib/Routers/PublicAPIRouter.js @@ -0,0 +1,322 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PublicAPIRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _express = _interopRequireDefault(require("express")); + +var _path = _interopRequireDefault(require("path")); + +var _fs = _interopRequireDefault(require("fs")); + +var _querystring = _interopRequireDefault(require("querystring")); + +var _node = require("parse/node"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const public_html = _path.default.resolve(__dirname, '../../public_html'); + +const views = _path.default.resolve(__dirname, '../../views'); + +class PublicAPIRouter extends _PromiseRouter.default { + verifyEmail(req) { + const { + username, + token: rawToken + } = req.query; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + const appId = req.params.appId; + + const config = _Config.default.get(appId); + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + if (!token || !username) { + return this.invalidLink(req); + } + + const userController = config.userController; + return userController.verifyEmail(username, token).then(() => { + const params = _querystring.default.stringify({ + username + }); + + return Promise.resolve({ + status: 302, + location: `${config.verifyEmailSuccessURL}?${params}` + }); + }, () => { + return this.invalidVerificationLink(req); + }); + } + + resendVerificationEmail(req) { + const username = req.body.username; + const appId = req.params.appId; + + const config = _Config.default.get(appId); + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + if (!username) { + return this.invalidLink(req); + } + + const userController = config.userController; + return userController.resendVerificationEmail(username).then(() => { + return Promise.resolve({ + status: 302, + location: `${config.linkSendSuccessURL}` + }); + }, () => { + return Promise.resolve({ + status: 302, + location: `${config.linkSendFailURL}` + }); + }); + } + + changePassword(req) { + return new Promise((resolve, reject) => { + const config = _Config.default.get(req.query.id); + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return resolve({ + status: 404, + text: 'Not found.' + }); + } // Should we keep the file in memory or leave like that? + + + _fs.default.readFile(_path.default.resolve(views, 'choose_password'), 'utf-8', (err, data) => { + if (err) { + return reject(err); + } + + data = data.replace('PARSE_SERVER_URL', `'${config.publicServerURL}'`); + resolve({ + text: data + }); + }); + }); + } + + requestResetPassword(req) { + const config = req.config; + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + const { + username, + token: rawToken + } = req.query; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if (!username || !token) { + return this.invalidLink(req); + } + + return config.userController.checkResetTokenValidity(username, token).then(() => { + const params = _querystring.default.stringify({ + token, + id: config.applicationId, + username, + app: config.appName + }); + + return Promise.resolve({ + status: 302, + location: `${config.choosePasswordURL}?${params}` + }); + }, () => { + return this.invalidLink(req); + }); + } + + resetPassword(req) { + const config = req.config; + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + const { + username, + new_password, + token: rawToken + } = req.body; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if ((!username || !token || !new_password) && req.xhr === false) { + return this.invalidLink(req); + } + + if (!username) { + throw new _node.Parse.Error(_node.Parse.Error.USERNAME_MISSING, 'Missing username'); + } + + if (!token) { + throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, 'Missing token'); + } + + if (!new_password) { + throw new _node.Parse.Error(_node.Parse.Error.PASSWORD_MISSING, 'Missing password'); + } + + return config.userController.updatePassword(username, token, new_password).then(() => { + return Promise.resolve({ + success: true + }); + }, err => { + return Promise.resolve({ + success: false, + err + }); + }).then(result => { + const params = _querystring.default.stringify({ + username: username, + token: token, + id: config.applicationId, + error: result.err, + app: config.appName + }); + + if (req.xhr) { + if (result.success) { + return Promise.resolve({ + status: 200, + response: 'Password successfully reset' + }); + } + + if (result.err) { + throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, `${result.err}`); + } + } + + const encodedUsername = encodeURIComponent(username); + const location = result.success ? `${config.passwordResetSuccessURL}?username=${encodedUsername}` : `${config.choosePasswordURL}?${params}`; + return Promise.resolve({ + status: 302, + location + }); + }); + } + + invalidLink(req) { + return Promise.resolve({ + status: 302, + location: req.config.invalidLinkURL + }); + } + + invalidVerificationLink(req) { + const config = req.config; + + if (req.query.username && req.params.appId) { + const params = _querystring.default.stringify({ + username: req.query.username, + appId: req.params.appId + }); + + return Promise.resolve({ + status: 302, + location: `${config.invalidVerificationLinkURL}?${params}` + }); + } else { + return this.invalidLink(req); + } + } + + missingPublicServerURL() { + return Promise.resolve({ + text: 'Not found.', + status: 404 + }); + } + + invalidRequest() { + const error = new Error(); + error.status = 403; + error.message = 'unauthorized'; + throw error; + } + + setConfig(req) { + req.config = _Config.default.get(req.params.appId); + return Promise.resolve(); + } + + mountRoutes() { + this.route('GET', '/apps/:appId/verify_email', req => { + this.setConfig(req); + }, req => { + return this.verifyEmail(req); + }); + this.route('POST', '/apps/:appId/resend_verification_email', req => { + this.setConfig(req); + }, req => { + return this.resendVerificationEmail(req); + }); + this.route('GET', '/apps/choose_password', req => { + return this.changePassword(req); + }); + this.route('POST', '/apps/:appId/request_password_reset', req => { + this.setConfig(req); + }, req => { + return this.resetPassword(req); + }); + this.route('GET', '/apps/:appId/request_password_reset', req => { + this.setConfig(req); + }, req => { + return this.requestResetPassword(req); + }); + } + + expressRouter() { + const router = _express.default.Router(); + + router.use('/apps', _express.default.static(public_html)); + router.use('/', super.expressRouter()); + return router; + } + +} + +exports.PublicAPIRouter = PublicAPIRouter; +var _default = PublicAPIRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1YmxpY0FQSVJvdXRlci5qcyJdLCJuYW1lcyI6WyJwdWJsaWNfaHRtbCIsInBhdGgiLCJyZXNvbHZlIiwiX19kaXJuYW1lIiwidmlld3MiLCJQdWJsaWNBUElSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwidmVyaWZ5RW1haWwiLCJyZXEiLCJ1c2VybmFtZSIsInRva2VuIiwicmF3VG9rZW4iLCJxdWVyeSIsInRvU3RyaW5nIiwiYXBwSWQiLCJwYXJhbXMiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJpbnZhbGlkUmVxdWVzdCIsInB1YmxpY1NlcnZlclVSTCIsIm1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwiLCJpbnZhbGlkTGluayIsInVzZXJDb250cm9sbGVyIiwidGhlbiIsInFzIiwic3RyaW5naWZ5IiwiUHJvbWlzZSIsInN0YXR1cyIsImxvY2F0aW9uIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImJvZHkiLCJsaW5rU2VuZFN1Y2Nlc3NVUkwiLCJsaW5rU2VuZEZhaWxVUkwiLCJjaGFuZ2VQYXNzd29yZCIsInJlamVjdCIsImlkIiwidGV4dCIsImZzIiwicmVhZEZpbGUiLCJlcnIiLCJkYXRhIiwicmVwbGFjZSIsInJlcXVlc3RSZXNldFBhc3N3b3JkIiwiY2hlY2tSZXNldFRva2VuVmFsaWRpdHkiLCJhcHBsaWNhdGlvbklkIiwiYXBwIiwiYXBwTmFtZSIsImNob29zZVBhc3N3b3JkVVJMIiwicmVzZXRQYXNzd29yZCIsIm5ld19wYXNzd29yZCIsInhociIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiT1RIRVJfQ0FVU0UiLCJQQVNTV09SRF9NSVNTSU5HIiwidXBkYXRlUGFzc3dvcmQiLCJzdWNjZXNzIiwicmVzdWx0IiwiZXJyb3IiLCJyZXNwb25zZSIsImVuY29kZWRVc2VybmFtZSIsImVuY29kZVVSSUNvbXBvbmVudCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwiaW52YWxpZExpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsIm1lc3NhZ2UiLCJzZXRDb25maWciLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiZXhwcmVzc1JvdXRlciIsInJvdXRlciIsImV4cHJlc3MiLCJSb3V0ZXIiLCJ1c2UiLCJzdGF0aWMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLFdBQVcsR0FBR0MsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLG1CQUF4QixDQUFwQjs7QUFDQSxNQUFNQyxLQUFLLEdBQUdILGNBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixhQUF4QixDQUFkOztBQUVPLE1BQU1FLGVBQU4sU0FBOEJDLHNCQUE5QixDQUE0QztBQUNqREMsRUFBQUEsV0FBVyxDQUFDQyxHQUFELEVBQU07QUFDZixVQUFNO0FBQUVDLE1BQUFBLFFBQUY7QUFBWUMsTUFBQUEsS0FBSyxFQUFFQztBQUFuQixRQUFnQ0gsR0FBRyxDQUFDSSxLQUExQztBQUNBLFVBQU1GLEtBQUssR0FBR0MsUUFBUSxJQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBaEMsR0FBMkNBLFFBQVEsQ0FBQ0UsUUFBVCxFQUEzQyxHQUFpRUYsUUFBL0U7QUFFQSxVQUFNRyxLQUFLLEdBQUdOLEdBQUcsQ0FBQ08sTUFBSixDQUFXRCxLQUF6Qjs7QUFDQSxVQUFNRSxNQUFNLEdBQUdDLGdCQUFPQyxHQUFQLENBQVdKLEtBQVgsQ0FBZjs7QUFFQSxRQUFJLENBQUNFLE1BQUwsRUFBYTtBQUNYLFdBQUtHLGNBQUw7QUFDRDs7QUFFRCxRQUFJLENBQUNILE1BQU0sQ0FBQ0ksZUFBWixFQUE2QjtBQUMzQixhQUFPLEtBQUtDLHNCQUFMLEVBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUNYLEtBQUQsSUFBVSxDQUFDRCxRQUFmLEVBQXlCO0FBQ3ZCLGFBQU8sS0FBS2EsV0FBTCxDQUFpQmQsR0FBakIsQ0FBUDtBQUNEOztBQUVELFVBQU1lLGNBQWMsR0FBR1AsTUFBTSxDQUFDTyxjQUE5QjtBQUNBLFdBQU9BLGNBQWMsQ0FBQ2hCLFdBQWYsQ0FBMkJFLFFBQTNCLEVBQXFDQyxLQUFyQyxFQUE0Q2MsSUFBNUMsQ0FDTCxNQUFNO0FBQ0osWUFBTVQsTUFBTSxHQUFHVSxxQkFBR0MsU0FBSCxDQUFhO0FBQUVqQixRQUFBQTtBQUFGLE9BQWIsQ0FBZjs7QUFDQSxhQUFPa0IsT0FBTyxDQUFDekIsT0FBUixDQUFnQjtBQUNyQjBCLFFBQUFBLE1BQU0sRUFBRSxHQURhO0FBRXJCQyxRQUFBQSxRQUFRLEVBQUcsR0FBRWIsTUFBTSxDQUFDYyxxQkFBc0IsSUFBR2YsTUFBTztBQUYvQixPQUFoQixDQUFQO0FBSUQsS0FQSSxFQVFMLE1BQU07QUFDSixhQUFPLEtBQUtnQix1QkFBTCxDQUE2QnZCLEdBQTdCLENBQVA7QUFDRCxLQVZJLENBQVA7QUFZRDs7QUFFRHdCLEVBQUFBLHVCQUF1QixDQUFDeEIsR0FBRCxFQUFNO0FBQzNCLFVBQU1DLFFBQVEsR0FBR0QsR0FBRyxDQUFDeUIsSUFBSixDQUFTeEIsUUFBMUI7QUFDQSxVQUFNSyxLQUFLLEdBQUdOLEdBQUcsQ0FBQ08sTUFBSixDQUFXRCxLQUF6Qjs7QUFDQSxVQUFNRSxNQUFNLEdBQUdDLGdCQUFPQyxHQUFQLENBQVdKLEtBQVgsQ0FBZjs7QUFFQSxRQUFJLENBQUNFLE1BQUwsRUFBYTtBQUNYLFdBQUtHLGNBQUw7QUFDRDs7QUFFRCxRQUFJLENBQUNILE1BQU0sQ0FBQ0ksZUFBWixFQUE2QjtBQUMzQixhQUFPLEtBQUtDLHNCQUFMLEVBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUNaLFFBQUwsRUFBZTtBQUNiLGFBQU8sS0FBS2EsV0FBTCxDQUFpQmQsR0FBakIsQ0FBUDtBQUNEOztBQUVELFVBQU1lLGNBQWMsR0FBR1AsTUFBTSxDQUFDTyxjQUE5QjtBQUVBLFdBQU9BLGNBQWMsQ0FBQ1MsdUJBQWYsQ0FBdUN2QixRQUF2QyxFQUFpRGUsSUFBakQsQ0FDTCxNQUFNO0FBQ0osYUFBT0csT0FBTyxDQUFDekIsT0FBUixDQUFnQjtBQUNyQjBCLFFBQUFBLE1BQU0sRUFBRSxHQURhO0FBRXJCQyxRQUFBQSxRQUFRLEVBQUcsR0FBRWIsTUFBTSxDQUFDa0Isa0JBQW1CO0FBRmxCLE9BQWhCLENBQVA7QUFJRCxLQU5JLEVBT0wsTUFBTTtBQUNKLGFBQU9QLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwQixRQUFBQSxNQUFNLEVBQUUsR0FEYTtBQUVyQkMsUUFBQUEsUUFBUSxFQUFHLEdBQUViLE1BQU0sQ0FBQ21CLGVBQWdCO0FBRmYsT0FBaEIsQ0FBUDtBQUlELEtBWkksQ0FBUDtBQWNEOztBQUVEQyxFQUFBQSxjQUFjLENBQUM1QixHQUFELEVBQU07QUFDbEIsV0FBTyxJQUFJbUIsT0FBSixDQUFZLENBQUN6QixPQUFELEVBQVVtQyxNQUFWLEtBQXFCO0FBQ3RDLFlBQU1yQixNQUFNLEdBQUdDLGdCQUFPQyxHQUFQLENBQVdWLEdBQUcsQ0FBQ0ksS0FBSixDQUFVMEIsRUFBckIsQ0FBZjs7QUFFQSxVQUFJLENBQUN0QixNQUFMLEVBQWE7QUFDWCxhQUFLRyxjQUFMO0FBQ0Q7O0FBRUQsVUFBSSxDQUFDSCxNQUFNLENBQUNJLGVBQVosRUFBNkI7QUFDM0IsZUFBT2xCLE9BQU8sQ0FBQztBQUNiMEIsVUFBQUEsTUFBTSxFQUFFLEdBREs7QUFFYlcsVUFBQUEsSUFBSSxFQUFFO0FBRk8sU0FBRCxDQUFkO0FBSUQsT0FacUMsQ0FhdEM7OztBQUNBQyxrQkFBR0MsUUFBSCxDQUFZeEMsY0FBS0MsT0FBTCxDQUFhRSxLQUFiLEVBQW9CLGlCQUFwQixDQUFaLEVBQW9ELE9BQXBELEVBQTZELENBQUNzQyxHQUFELEVBQU1DLElBQU4sS0FBZTtBQUMxRSxZQUFJRCxHQUFKLEVBQVM7QUFDUCxpQkFBT0wsTUFBTSxDQUFDSyxHQUFELENBQWI7QUFDRDs7QUFDREMsUUFBQUEsSUFBSSxHQUFHQSxJQUFJLENBQUNDLE9BQUwsQ0FBYSxrQkFBYixFQUFrQyxJQUFHNUIsTUFBTSxDQUFDSSxlQUFnQixHQUE1RCxDQUFQO0FBQ0FsQixRQUFBQSxPQUFPLENBQUM7QUFDTnFDLFVBQUFBLElBQUksRUFBRUk7QUFEQSxTQUFELENBQVA7QUFHRCxPQVJEO0FBU0QsS0F2Qk0sQ0FBUDtBQXdCRDs7QUFFREUsRUFBQUEsb0JBQW9CLENBQUNyQyxHQUFELEVBQU07QUFDeEIsVUFBTVEsTUFBTSxHQUFHUixHQUFHLENBQUNRLE1BQW5COztBQUVBLFFBQUksQ0FBQ0EsTUFBTCxFQUFhO0FBQ1gsV0FBS0csY0FBTDtBQUNEOztBQUVELFFBQUksQ0FBQ0gsTUFBTSxDQUFDSSxlQUFaLEVBQTZCO0FBQzNCLGFBQU8sS0FBS0Msc0JBQUwsRUFBUDtBQUNEOztBQUVELFVBQU07QUFBRVosTUFBQUEsUUFBRjtBQUFZQyxNQUFBQSxLQUFLLEVBQUVDO0FBQW5CLFFBQWdDSCxHQUFHLENBQUNJLEtBQTFDO0FBQ0EsVUFBTUYsS0FBSyxHQUFHQyxRQUFRLElBQUksT0FBT0EsUUFBUCxLQUFvQixRQUFoQyxHQUEyQ0EsUUFBUSxDQUFDRSxRQUFULEVBQTNDLEdBQWlFRixRQUEvRTs7QUFFQSxRQUFJLENBQUNGLFFBQUQsSUFBYSxDQUFDQyxLQUFsQixFQUF5QjtBQUN2QixhQUFPLEtBQUtZLFdBQUwsQ0FBaUJkLEdBQWpCLENBQVA7QUFDRDs7QUFFRCxXQUFPUSxNQUFNLENBQUNPLGNBQVAsQ0FBc0J1Qix1QkFBdEIsQ0FBOENyQyxRQUE5QyxFQUF3REMsS0FBeEQsRUFBK0RjLElBQS9ELENBQ0wsTUFBTTtBQUNKLFlBQU1ULE1BQU0sR0FBR1UscUJBQUdDLFNBQUgsQ0FBYTtBQUMxQmhCLFFBQUFBLEtBRDBCO0FBRTFCNEIsUUFBQUEsRUFBRSxFQUFFdEIsTUFBTSxDQUFDK0IsYUFGZTtBQUcxQnRDLFFBQUFBLFFBSDBCO0FBSTFCdUMsUUFBQUEsR0FBRyxFQUFFaEMsTUFBTSxDQUFDaUM7QUFKYyxPQUFiLENBQWY7O0FBTUEsYUFBT3RCLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwQixRQUFBQSxNQUFNLEVBQUUsR0FEYTtBQUVyQkMsUUFBQUEsUUFBUSxFQUFHLEdBQUViLE1BQU0sQ0FBQ2tDLGlCQUFrQixJQUFHbkMsTUFBTztBQUYzQixPQUFoQixDQUFQO0FBSUQsS0FaSSxFQWFMLE1BQU07QUFDSixhQUFPLEtBQUtPLFdBQUwsQ0FBaUJkLEdBQWpCLENBQVA7QUFDRCxLQWZJLENBQVA7QUFpQkQ7O0FBRUQyQyxFQUFBQSxhQUFhLENBQUMzQyxHQUFELEVBQU07QUFDakIsVUFBTVEsTUFBTSxHQUFHUixHQUFHLENBQUNRLE1BQW5COztBQUVBLFFBQUksQ0FBQ0EsTUFBTCxFQUFhO0FBQ1gsV0FBS0csY0FBTDtBQUNEOztBQUVELFFBQUksQ0FBQ0gsTUFBTSxDQUFDSSxlQUFaLEVBQTZCO0FBQzNCLGFBQU8sS0FBS0Msc0JBQUwsRUFBUDtBQUNEOztBQUVELFVBQU07QUFBRVosTUFBQUEsUUFBRjtBQUFZMkMsTUFBQUEsWUFBWjtBQUEwQjFDLE1BQUFBLEtBQUssRUFBRUM7QUFBakMsUUFBOENILEdBQUcsQ0FBQ3lCLElBQXhEO0FBQ0EsVUFBTXZCLEtBQUssR0FBR0MsUUFBUSxJQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBaEMsR0FBMkNBLFFBQVEsQ0FBQ0UsUUFBVCxFQUEzQyxHQUFpRUYsUUFBL0U7O0FBRUEsUUFBSSxDQUFDLENBQUNGLFFBQUQsSUFBYSxDQUFDQyxLQUFkLElBQXVCLENBQUMwQyxZQUF6QixLQUEwQzVDLEdBQUcsQ0FBQzZDLEdBQUosS0FBWSxLQUExRCxFQUFpRTtBQUMvRCxhQUFPLEtBQUsvQixXQUFMLENBQWlCZCxHQUFqQixDQUFQO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDQyxRQUFMLEVBQWU7QUFDYixZQUFNLElBQUk2QyxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGdCQUE1QixFQUE4QyxrQkFBOUMsQ0FBTjtBQUNEOztBQUVELFFBQUksQ0FBQzlDLEtBQUwsRUFBWTtBQUNWLFlBQU0sSUFBSTRDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUUsV0FBNUIsRUFBeUMsZUFBekMsQ0FBTjtBQUNEOztBQUVELFFBQUksQ0FBQ0wsWUFBTCxFQUFtQjtBQUNqQixZQUFNLElBQUlFLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUcsZ0JBQTVCLEVBQThDLGtCQUE5QyxDQUFOO0FBQ0Q7O0FBRUQsV0FBTzFDLE1BQU0sQ0FBQ08sY0FBUCxDQUNKb0MsY0FESSxDQUNXbEQsUUFEWCxFQUNxQkMsS0FEckIsRUFDNEIwQyxZQUQ1QixFQUVKNUIsSUFGSSxDQUdILE1BQU07QUFDSixhQUFPRyxPQUFPLENBQUN6QixPQUFSLENBQWdCO0FBQ3JCMEQsUUFBQUEsT0FBTyxFQUFFO0FBRFksT0FBaEIsQ0FBUDtBQUdELEtBUEUsRUFRSGxCLEdBQUcsSUFBSTtBQUNMLGFBQU9mLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwRCxRQUFBQSxPQUFPLEVBQUUsS0FEWTtBQUVyQmxCLFFBQUFBO0FBRnFCLE9BQWhCLENBQVA7QUFJRCxLQWJFLEVBZUpsQixJQWZJLENBZUNxQyxNQUFNLElBQUk7QUFDZCxZQUFNOUMsTUFBTSxHQUFHVSxxQkFBR0MsU0FBSCxDQUFhO0FBQzFCakIsUUFBQUEsUUFBUSxFQUFFQSxRQURnQjtBQUUxQkMsUUFBQUEsS0FBSyxFQUFFQSxLQUZtQjtBQUcxQjRCLFFBQUFBLEVBQUUsRUFBRXRCLE1BQU0sQ0FBQytCLGFBSGU7QUFJMUJlLFFBQUFBLEtBQUssRUFBRUQsTUFBTSxDQUFDbkIsR0FKWTtBQUsxQk0sUUFBQUEsR0FBRyxFQUFFaEMsTUFBTSxDQUFDaUM7QUFMYyxPQUFiLENBQWY7O0FBUUEsVUFBSXpDLEdBQUcsQ0FBQzZDLEdBQVIsRUFBYTtBQUNYLFlBQUlRLE1BQU0sQ0FBQ0QsT0FBWCxFQUFvQjtBQUNsQixpQkFBT2pDLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwQixZQUFBQSxNQUFNLEVBQUUsR0FEYTtBQUVyQm1DLFlBQUFBLFFBQVEsRUFBRTtBQUZXLFdBQWhCLENBQVA7QUFJRDs7QUFDRCxZQUFJRixNQUFNLENBQUNuQixHQUFYLEVBQWdCO0FBQ2QsZ0JBQU0sSUFBSVksWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZRSxXQUE1QixFQUEwQyxHQUFFSSxNQUFNLENBQUNuQixHQUFJLEVBQXZELENBQU47QUFDRDtBQUNGOztBQUVELFlBQU1zQixlQUFlLEdBQUdDLGtCQUFrQixDQUFDeEQsUUFBRCxDQUExQztBQUNBLFlBQU1vQixRQUFRLEdBQUdnQyxNQUFNLENBQUNELE9BQVAsR0FDWixHQUFFNUMsTUFBTSxDQUFDa0QsdUJBQXdCLGFBQVlGLGVBQWdCLEVBRGpELEdBRVosR0FBRWhELE1BQU0sQ0FBQ2tDLGlCQUFrQixJQUFHbkMsTUFBTyxFQUYxQztBQUlBLGFBQU9ZLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwQixRQUFBQSxNQUFNLEVBQUUsR0FEYTtBQUVyQkMsUUFBQUE7QUFGcUIsT0FBaEIsQ0FBUDtBQUlELEtBN0NJLENBQVA7QUE4Q0Q7O0FBRURQLEVBQUFBLFdBQVcsQ0FBQ2QsR0FBRCxFQUFNO0FBQ2YsV0FBT21CLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwQixNQUFBQSxNQUFNLEVBQUUsR0FEYTtBQUVyQkMsTUFBQUEsUUFBUSxFQUFFckIsR0FBRyxDQUFDUSxNQUFKLENBQVdtRDtBQUZBLEtBQWhCLENBQVA7QUFJRDs7QUFFRHBDLEVBQUFBLHVCQUF1QixDQUFDdkIsR0FBRCxFQUFNO0FBQzNCLFVBQU1RLE1BQU0sR0FBR1IsR0FBRyxDQUFDUSxNQUFuQjs7QUFDQSxRQUFJUixHQUFHLENBQUNJLEtBQUosQ0FBVUgsUUFBVixJQUFzQkQsR0FBRyxDQUFDTyxNQUFKLENBQVdELEtBQXJDLEVBQTRDO0FBQzFDLFlBQU1DLE1BQU0sR0FBR1UscUJBQUdDLFNBQUgsQ0FBYTtBQUMxQmpCLFFBQUFBLFFBQVEsRUFBRUQsR0FBRyxDQUFDSSxLQUFKLENBQVVILFFBRE07QUFFMUJLLFFBQUFBLEtBQUssRUFBRU4sR0FBRyxDQUFDTyxNQUFKLENBQVdEO0FBRlEsT0FBYixDQUFmOztBQUlBLGFBQU9hLE9BQU8sQ0FBQ3pCLE9BQVIsQ0FBZ0I7QUFDckIwQixRQUFBQSxNQUFNLEVBQUUsR0FEYTtBQUVyQkMsUUFBQUEsUUFBUSxFQUFHLEdBQUViLE1BQU0sQ0FBQ29ELDBCQUEyQixJQUFHckQsTUFBTztBQUZwQyxPQUFoQixDQUFQO0FBSUQsS0FURCxNQVNPO0FBQ0wsYUFBTyxLQUFLTyxXQUFMLENBQWlCZCxHQUFqQixDQUFQO0FBQ0Q7QUFDRjs7QUFFRGEsRUFBQUEsc0JBQXNCLEdBQUc7QUFDdkIsV0FBT00sT0FBTyxDQUFDekIsT0FBUixDQUFnQjtBQUNyQnFDLE1BQUFBLElBQUksRUFBRSxZQURlO0FBRXJCWCxNQUFBQSxNQUFNLEVBQUU7QUFGYSxLQUFoQixDQUFQO0FBSUQ7O0FBRURULEVBQUFBLGNBQWMsR0FBRztBQUNmLFVBQU0yQyxLQUFLLEdBQUcsSUFBSVAsS0FBSixFQUFkO0FBQ0FPLElBQUFBLEtBQUssQ0FBQ2xDLE1BQU4sR0FBZSxHQUFmO0FBQ0FrQyxJQUFBQSxLQUFLLENBQUNPLE9BQU4sR0FBZ0IsY0FBaEI7QUFDQSxVQUFNUCxLQUFOO0FBQ0Q7O0FBRURRLEVBQUFBLFNBQVMsQ0FBQzlELEdBQUQsRUFBTTtBQUNiQSxJQUFBQSxHQUFHLENBQUNRLE1BQUosR0FBYUMsZ0JBQU9DLEdBQVAsQ0FBV1YsR0FBRyxDQUFDTyxNQUFKLENBQVdELEtBQXRCLENBQWI7QUFDQSxXQUFPYSxPQUFPLENBQUN6QixPQUFSLEVBQVA7QUFDRDs7QUFFRHFFLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FDRSxLQURGLEVBRUUsMkJBRkYsRUFHRWhFLEdBQUcsSUFBSTtBQUNMLFdBQUs4RCxTQUFMLENBQWU5RCxHQUFmO0FBQ0QsS0FMSCxFQU1FQSxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtELFdBQUwsQ0FBaUJDLEdBQWpCLENBQVA7QUFDRCxLQVJIO0FBV0EsU0FBS2dFLEtBQUwsQ0FDRSxNQURGLEVBRUUsd0NBRkYsRUFHRWhFLEdBQUcsSUFBSTtBQUNMLFdBQUs4RCxTQUFMLENBQWU5RCxHQUFmO0FBQ0QsS0FMSCxFQU1FQSxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUt3Qix1QkFBTCxDQUE2QnhCLEdBQTdCLENBQVA7QUFDRCxLQVJIO0FBV0EsU0FBS2dFLEtBQUwsQ0FBVyxLQUFYLEVBQWtCLHVCQUFsQixFQUEyQ2hFLEdBQUcsSUFBSTtBQUNoRCxhQUFPLEtBQUs0QixjQUFMLENBQW9CNUIsR0FBcEIsQ0FBUDtBQUNELEtBRkQ7QUFJQSxTQUFLZ0UsS0FBTCxDQUNFLE1BREYsRUFFRSxxQ0FGRixFQUdFaEUsR0FBRyxJQUFJO0FBQ0wsV0FBSzhELFNBQUwsQ0FBZTlELEdBQWY7QUFDRCxLQUxILEVBTUVBLEdBQUcsSUFBSTtBQUNMLGFBQU8sS0FBSzJDLGFBQUwsQ0FBbUIzQyxHQUFuQixDQUFQO0FBQ0QsS0FSSDtBQVdBLFNBQUtnRSxLQUFMLENBQ0UsS0FERixFQUVFLHFDQUZGLEVBR0VoRSxHQUFHLElBQUk7QUFDTCxXQUFLOEQsU0FBTCxDQUFlOUQsR0FBZjtBQUNELEtBTEgsRUFNRUEsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLcUMsb0JBQUwsQ0FBMEJyQyxHQUExQixDQUFQO0FBQ0QsS0FSSDtBQVVEOztBQUVEaUUsRUFBQUEsYUFBYSxHQUFHO0FBQ2QsVUFBTUMsTUFBTSxHQUFHQyxpQkFBUUMsTUFBUixFQUFmOztBQUNBRixJQUFBQSxNQUFNLENBQUNHLEdBQVAsQ0FBVyxPQUFYLEVBQW9CRixpQkFBUUcsTUFBUixDQUFlOUUsV0FBZixDQUFwQjtBQUNBMEUsSUFBQUEsTUFBTSxDQUFDRyxHQUFQLENBQVcsR0FBWCxFQUFnQixNQUFNSixhQUFOLEVBQWhCO0FBQ0EsV0FBT0MsTUFBUDtBQUNEOztBQXJUZ0Q7OztlQXdUcENyRSxlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBxcyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuXG5jb25zdCBwdWJsaWNfaHRtbCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi8uLi9wdWJsaWNfaHRtbCcpO1xuY29uc3Qgdmlld3MgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vLi4vdmlld3MnKTtcblxuZXhwb3J0IGNsYXNzIFB1YmxpY0FQSVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICB2ZXJpZnlFbWFpbChyZXEpIHtcbiAgICBjb25zdCB7IHVzZXJuYW1lLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5xdWVyeTtcbiAgICBjb25zdCB0b2tlbiA9IHJhd1Rva2VuICYmIHR5cGVvZiByYXdUb2tlbiAhPT0gJ3N0cmluZycgPyByYXdUb2tlbi50b1N0cmluZygpIDogcmF3VG9rZW47XG5cbiAgICBjb25zdCBhcHBJZCA9IHJlcS5wYXJhbXMuYXBwSWQ7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBJZCk7XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLnB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgcmV0dXJuIHRoaXMubWlzc2luZ1B1YmxpY1NlcnZlclVSTCgpO1xuICAgIH1cblxuICAgIGlmICghdG9rZW4gfHwgIXVzZXJuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci52ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7IHVzZXJuYW1lIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLnZlcmlmeUVtYWlsU3VjY2Vzc1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpIHtcbiAgICBjb25zdCB1c2VybmFtZSA9IHJlcS5ib2R5LnVzZXJuYW1lO1xuICAgIGNvbnN0IGFwcElkID0gcmVxLnBhcmFtcy5hcHBJZDtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KGFwcElkKTtcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyQ29udHJvbGxlciA9IGNvbmZpZy51c2VyQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5saW5rU2VuZFN1Y2Nlc3NVUkx9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmxpbmtTZW5kRmFpbFVSTH1gLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgY2hhbmdlUGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnF1ZXJ5LmlkKTtcblxuICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xuICAgICAgICAgIHN0YXR1czogNDA0LFxuICAgICAgICAgIHRleHQ6ICdOb3QgZm91bmQuJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBTaG91bGQgd2Uga2VlcCB0aGUgZmlsZSBpbiBtZW1vcnkgb3IgbGVhdmUgbGlrZSB0aGF0P1xuICAgICAgZnMucmVhZEZpbGUocGF0aC5yZXNvbHZlKHZpZXdzLCAnY2hvb3NlX3Bhc3N3b3JkJyksICd1dGYtOCcsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gZGF0YS5yZXBsYWNlKCdQQVJTRV9TRVJWRVJfVVJMJywgYCcke2NvbmZpZy5wdWJsaWNTZXJ2ZXJVUkx9J2ApO1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICB0ZXh0OiBkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmVxdWVzdFJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgdG9rZW46IHJhd1Rva2VuIH0gPSByZXEucXVlcnk7XG4gICAgY29uc3QgdG9rZW4gPSByYXdUb2tlbiAmJiB0eXBlb2YgcmF3VG9rZW4gIT09ICdzdHJpbmcnID8gcmF3VG9rZW4udG9TdHJpbmcoKSA6IHJhd1Rva2VuO1xuXG4gICAgaWYgKCF1c2VybmFtZSB8fCAhdG9rZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZy51c2VyQ29udHJvbGxlci5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgaWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgIGFwcDogY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmNob29zZVBhc3N3b3JkVVJMfT8ke3BhcmFtc31gLFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgbmV3X3Bhc3N3b3JkLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5ib2R5O1xuICAgIGNvbnN0IHRva2VuID0gcmF3VG9rZW4gJiYgdHlwZW9mIHJhd1Rva2VuICE9PSAnc3RyaW5nJyA/IHJhd1Rva2VuLnRvU3RyaW5nKCkgOiByYXdUb2tlbjtcblxuICAgIGlmICgoIXVzZXJuYW1lIHx8ICF0b2tlbiB8fCAhbmV3X3Bhc3N3b3JkKSAmJiByZXEueGhyID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBpZiAoIXVzZXJuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVVNFUk5BTUVfTUlTU0lORywgJ01pc3NpbmcgdXNlcm5hbWUnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsICdNaXNzaW5nIHRva2VuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFuZXdfcGFzc3dvcmQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAnTWlzc2luZyBwYXNzd29yZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25maWcudXNlckNvbnRyb2xsZXJcbiAgICAgIC51cGRhdGVQYXNzd29yZCh1c2VybmFtZSwgdG9rZW4sIG5ld19wYXNzd29yZClcbiAgICAgIC50aGVuKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdXNlcm5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHRva2VuOiB0b2tlbixcbiAgICAgICAgICBpZDogY29uZmlnLmFwcGxpY2F0aW9uSWQsXG4gICAgICAgICAgZXJyb3I6IHJlc3VsdC5lcnIsXG4gICAgICAgICAgYXBwOiBjb25maWcuYXBwTmFtZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcS54aHIpIHtcbiAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICAgICAgcmVzcG9uc2U6ICdQYXNzd29yZCBzdWNjZXNzZnVsbHkgcmVzZXQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXN1bHQuZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsIGAke3Jlc3VsdC5lcnJ9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW5jb2RlZFVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXJuYW1lKTtcbiAgICAgICAgY29uc3QgbG9jYXRpb24gPSByZXN1bHQuc3VjY2Vzc1xuICAgICAgICAgID8gYCR7Y29uZmlnLnBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMfT91c2VybmFtZT0ke2VuY29kZWRVc2VybmFtZX1gXG4gICAgICAgICAgOiBgJHtjb25maWcuY2hvb3NlUGFzc3dvcmRVUkx9PyR7cGFyYW1zfWA7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBpbnZhbGlkTGluayhyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHN0YXR1czogMzAyLFxuICAgICAgbG9jYXRpb246IHJlcS5jb25maWcuaW52YWxpZExpbmtVUkwsXG4gICAgfSk7XG4gIH1cblxuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICAgIGlmIChyZXEucXVlcnkudXNlcm5hbWUgJiYgcmVxLnBhcmFtcy5hcHBJZCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gcXMuc3RyaW5naWZ5KHtcbiAgICAgICAgdXNlcm5hbWU6IHJlcS5xdWVyeS51c2VybmFtZSxcbiAgICAgICAgYXBwSWQ6IHJlcS5wYXJhbXMuYXBwSWQsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5pbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cbiAgfVxuXG4gIG1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICB0ZXh0OiAnTm90IGZvdW5kLicsXG4gICAgICBzdGF0dXM6IDQwNCxcbiAgICB9KTtcbiAgfVxuXG4gIGludmFsaWRSZXF1ZXN0KCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSAndW5hdXRob3JpemVkJztcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHNldENvbmZpZyhyZXEpIHtcbiAgICByZXEuY29uZmlnID0gQ29uZmlnLmdldChyZXEucGFyYW1zLmFwcElkKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3ZlcmlmeV9lbWFpbCcsXG4gICAgICByZXEgPT4ge1xuICAgICAgICB0aGlzLnNldENvbmZpZyhyZXEpO1xuICAgICAgfSxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUVtYWlsKHJlcSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3Jlc2VuZF92ZXJpZmljYXRpb25fZW1haWwnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL2FwcHMvY2hvb3NlX3Bhc3N3b3JkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNoYW5nZVBhc3N3b3JkKHJlcSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9hcHBzLzphcHBJZC9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0JyxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3JlcXVlc3RfcGFzc3dvcmRfcmVzZXQnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0UmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBleHByZXNzUm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLnVzZSgnL2FwcHMnLCBleHByZXNzLnN0YXRpYyhwdWJsaWNfaHRtbCkpO1xuICAgIHJvdXRlci51c2UoJy8nLCBzdXBlci5leHByZXNzUm91dGVyKCkpO1xuICAgIHJldHVybiByb3V0ZXI7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVibGljQVBJUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PurgeRouter.js b/lib/Routers/PurgeRouter.js new file mode 100644 index 0000000000..503d9eb543 --- /dev/null +++ b/lib/Routers/PurgeRouter.js @@ -0,0 +1,60 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PurgeRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PurgeRouter extends _PromiseRouter.default { + handlePurge(req) { + if (req.auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to purge a schema."); + } + + return req.config.database.purgeCollection(req.params.className).then(() => { + var cacheAdapter = req.config.cacheController; + + if (req.params.className == '_Session') { + cacheAdapter.user.clear(); + } else if (req.params.className == '_Role') { + cacheAdapter.role.clear(); + } + + return { + response: {} + }; + }).catch(error => { + if (!error || error && error.code === _node.default.Error.OBJECT_NOT_FOUND) { + return { + response: {} + }; + } + + throw error; + }); + } + + mountRoutes() { + this.route('DELETE', '/purge/:className', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handlePurge(req); + }); + } + +} + +exports.PurgeRouter = PurgeRouter; +var _default = PurgeRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1cmdlUm91dGVyLmpzIl0sIm5hbWVzIjpbIlB1cmdlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVB1cmdlIiwicmVxIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImNvbmZpZyIsImRhdGFiYXNlIiwicHVyZ2VDb2xsZWN0aW9uIiwicGFyYW1zIiwiY2xhc3NOYW1lIiwidGhlbiIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsInVzZXIiLCJjbGVhciIsInJvbGUiLCJyZXNwb25zZSIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiT0JKRUNUX05PVF9GT1VORCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ2YsUUFBSUEsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixzREFGSSxDQUFOO0FBSUQ7O0FBQ0QsV0FBT0wsR0FBRyxDQUFDTSxNQUFKLENBQVdDLFFBQVgsQ0FDSkMsZUFESSxDQUNZUixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FEdkIsRUFFSkMsSUFGSSxDQUVDLE1BQU07QUFDVixVQUFJQyxZQUFZLEdBQUdaLEdBQUcsQ0FBQ00sTUFBSixDQUFXTyxlQUE5Qjs7QUFDQSxVQUFJYixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixVQUE1QixFQUF3QztBQUN0Q0UsUUFBQUEsWUFBWSxDQUFDRSxJQUFiLENBQWtCQyxLQUFsQjtBQUNELE9BRkQsTUFFTyxJQUFJZixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixPQUE1QixFQUFxQztBQUMxQ0UsUUFBQUEsWUFBWSxDQUFDSSxJQUFiLENBQWtCRCxLQUFsQjtBQUNEOztBQUNELGFBQU87QUFBRUUsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVkksRUFXSkMsS0FYSSxDQVdFQyxLQUFLLElBQUk7QUFDZCxVQUFJLENBQUNBLEtBQUQsSUFBV0EsS0FBSyxJQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZWpCLGNBQU1DLEtBQU4sQ0FBWWlCLGdCQUFuRCxFQUFzRTtBQUNwRSxlQUFPO0FBQUVKLFVBQUFBLFFBQVEsRUFBRTtBQUFaLFNBQVA7QUFDRDs7QUFDRCxZQUFNRSxLQUFOO0FBQ0QsS0FoQkksQ0FBUDtBQWlCRDs7QUFFREcsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLFFBQVgsRUFBcUIsbUJBQXJCLEVBQTBDQyxVQUFVLENBQUNDLDZCQUFyRCxFQUFvRnpCLEdBQUcsSUFBSTtBQUN6RixhQUFPLEtBQUtELFdBQUwsQ0FBaUJDLEdBQWpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBL0I0Qzs7O2VBa0NoQ0gsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmV4cG9ydCBjbGFzcyBQdXJnZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVQdXJnZShyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBwdXJnZSBhIHNjaGVtYS5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5wdXJnZUNvbGxlY3Rpb24ocmVxLnBhcmFtcy5jbGFzc05hbWUpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHZhciBjYWNoZUFkYXB0ZXIgPSByZXEuY29uZmlnLmNhY2hlQ29udHJvbGxlcjtcbiAgICAgICAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5jbGVhcigpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfUm9sZScpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIucm9sZS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHt9IH07XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvcHVyZ2UvOmNsYXNzTmFtZScsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVQdXJnZShyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1cmdlUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PushRouter.js b/lib/Routers/PushRouter.js new file mode 100644 index 0000000000..f0b17383c3 --- /dev/null +++ b/lib/Routers/PushRouter.js @@ -0,0 +1,92 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +var _node = require("parse/node"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PushRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('POST', '/push', middleware.promiseEnforceMasterKeyAccess, PushRouter.handlePOST); + } + + static handlePOST(req) { + if (req.auth.isReadOnly) { + throw new _node.Parse.Error(_node.Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to send push notifications."); + } + + const pushController = req.config.pushController; + + if (!pushController) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Push controller is not set'); + } + + const where = PushRouter.getQueryCondition(req); + let resolve; + const promise = new Promise(_resolve => { + resolve = _resolve; + }); + let pushStatusId; + pushController.sendPush(req.body, where, req.config, req.auth, objectId => { + pushStatusId = objectId; + resolve({ + headers: { + 'X-Parse-Push-Status-Id': pushStatusId + }, + response: { + result: true + } + }); + }).catch(err => { + req.config.loggerController.error(`_PushStatus ${pushStatusId}: error while sending push`, err); + }); + return promise; + } + /** + * Get query condition from the request body. + * @param {Object} req A request object + * @returns {Object} The query condition, the where field in a query api call + */ + + + static getQueryCondition(req) { + const body = req.body || {}; + const hasWhere = typeof body.where !== 'undefined'; + const hasChannels = typeof body.channels !== 'undefined'; + let where; + + if (hasWhere && hasChannels) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Channels and query can not be set at the same time.'); + } else if (hasWhere) { + where = body.where; + } else if (hasChannels) { + where = { + channels: { + $in: body.channels + } + }; + } else { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Sending a push requires either "channels" or a "where" query.'); + } + + return where; + } + +} + +exports.PushRouter = PushRouter; +var _default = PushRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1c2hSb3V0ZXIuanMiXSwibmFtZXMiOlsiUHVzaFJvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlUE9TVCIsInJlcSIsImF1dGgiLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJwdXNoQ29udHJvbGxlciIsImNvbmZpZyIsIlBVU0hfTUlTQ09ORklHVVJFRCIsIndoZXJlIiwiZ2V0UXVlcnlDb25kaXRpb24iLCJyZXNvbHZlIiwicHJvbWlzZSIsIlByb21pc2UiLCJfcmVzb2x2ZSIsInB1c2hTdGF0dXNJZCIsInNlbmRQdXNoIiwiYm9keSIsIm9iamVjdElkIiwiaGVhZGVycyIsInJlc3BvbnNlIiwicmVzdWx0IiwiY2F0Y2giLCJlcnIiLCJsb2dnZXJDb250cm9sbGVyIiwiZXJyb3IiLCJoYXNXaGVyZSIsImhhc0NoYW5uZWxzIiwiY2hhbm5lbHMiLCIkaW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLE9BQW5CLEVBQTRCQyxVQUFVLENBQUNDLDZCQUF2QyxFQUFzRUwsVUFBVSxDQUFDTSxVQUFqRjtBQUNEOztBQUVELFNBQU9BLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQXVCO0FBQ3JCLFFBQUlBLEdBQUcsQ0FBQ0MsSUFBSixDQUFTQyxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1DLGNBQWMsR0FBR04sR0FBRyxDQUFDTyxNQUFKLENBQVdELGNBQWxDOztBQUNBLFFBQUksQ0FBQ0EsY0FBTCxFQUFxQjtBQUNuQixZQUFNLElBQUlILFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUksa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0Q7O0FBRUQsVUFBTUMsS0FBSyxHQUFHaEIsVUFBVSxDQUFDaUIsaUJBQVgsQ0FBNkJWLEdBQTdCLENBQWQ7QUFDQSxRQUFJVyxPQUFKO0FBQ0EsVUFBTUMsT0FBTyxHQUFHLElBQUlDLE9BQUosQ0FBWUMsUUFBUSxJQUFJO0FBQ3RDSCxNQUFBQSxPQUFPLEdBQUdHLFFBQVY7QUFDRCxLQUZlLENBQWhCO0FBR0EsUUFBSUMsWUFBSjtBQUNBVCxJQUFBQSxjQUFjLENBQ1hVLFFBREgsQ0FDWWhCLEdBQUcsQ0FBQ2lCLElBRGhCLEVBQ3NCUixLQUR0QixFQUM2QlQsR0FBRyxDQUFDTyxNQURqQyxFQUN5Q1AsR0FBRyxDQUFDQyxJQUQ3QyxFQUNtRGlCLFFBQVEsSUFBSTtBQUMzREgsTUFBQUEsWUFBWSxHQUFHRyxRQUFmO0FBQ0FQLE1BQUFBLE9BQU8sQ0FBQztBQUNOUSxRQUFBQSxPQUFPLEVBQUU7QUFDUCxvQ0FBMEJKO0FBRG5CLFNBREg7QUFJTkssUUFBQUEsUUFBUSxFQUFFO0FBQ1JDLFVBQUFBLE1BQU0sRUFBRTtBQURBO0FBSkosT0FBRCxDQUFQO0FBUUQsS0FYSCxFQVlHQyxLQVpILENBWVNDLEdBQUcsSUFBSTtBQUNadkIsTUFBQUEsR0FBRyxDQUFDTyxNQUFKLENBQVdpQixnQkFBWCxDQUE0QkMsS0FBNUIsQ0FDRyxlQUFjVixZQUFhLDRCQUQ5QixFQUVFUSxHQUZGO0FBSUQsS0FqQkg7QUFrQkEsV0FBT1gsT0FBUDtBQUNEO0FBRUQ7Ozs7Ozs7QUFLQSxTQUFPRixpQkFBUCxDQUF5QlYsR0FBekIsRUFBOEI7QUFDNUIsVUFBTWlCLElBQUksR0FBR2pCLEdBQUcsQ0FBQ2lCLElBQUosSUFBWSxFQUF6QjtBQUNBLFVBQU1TLFFBQVEsR0FBRyxPQUFPVCxJQUFJLENBQUNSLEtBQVosS0FBc0IsV0FBdkM7QUFDQSxVQUFNa0IsV0FBVyxHQUFHLE9BQU9WLElBQUksQ0FBQ1csUUFBWixLQUF5QixXQUE3QztBQUVBLFFBQUluQixLQUFKOztBQUNBLFFBQUlpQixRQUFRLElBQUlDLFdBQWhCLEVBQTZCO0FBQzNCLFlBQU0sSUFBSXhCLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZSSxrQkFEUixFQUVKLHFEQUZJLENBQU47QUFJRCxLQUxELE1BS08sSUFBSWtCLFFBQUosRUFBYztBQUNuQmpCLE1BQUFBLEtBQUssR0FBR1EsSUFBSSxDQUFDUixLQUFiO0FBQ0QsS0FGTSxNQUVBLElBQUlrQixXQUFKLEVBQWlCO0FBQ3RCbEIsTUFBQUEsS0FBSyxHQUFHO0FBQ05tQixRQUFBQSxRQUFRLEVBQUU7QUFDUkMsVUFBQUEsR0FBRyxFQUFFWixJQUFJLENBQUNXO0FBREY7QUFESixPQUFSO0FBS0QsS0FOTSxNQU1BO0FBQ0wsWUFBTSxJQUFJekIsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlJLGtCQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFdBQU9DLEtBQVA7QUFDRDs7QUEzRTJDOzs7ZUE4RS9CaEIsVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuXG5leHBvcnQgY2xhc3MgUHVzaFJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9wdXNoJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgUHVzaFJvdXRlci5oYW5kbGVQT1NUKTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVQT1NUKHJlcSkge1xuICAgIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHNlbmQgcHVzaCBub3RpZmljYXRpb25zLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBwdXNoQ29udHJvbGxlciA9IHJlcS5jb25maWcucHVzaENvbnRyb2xsZXI7XG4gICAgaWYgKCFwdXNoQ29udHJvbGxlcikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCwgJ1B1c2ggY29udHJvbGxlciBpcyBub3Qgc2V0Jyk7XG4gICAgfVxuXG4gICAgY29uc3Qgd2hlcmUgPSBQdXNoUm91dGVyLmdldFF1ZXJ5Q29uZGl0aW9uKHJlcSk7XG4gICAgbGV0IHJlc29sdmU7XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKF9yZXNvbHZlID0+IHtcbiAgICAgIHJlc29sdmUgPSBfcmVzb2x2ZTtcbiAgICB9KTtcbiAgICBsZXQgcHVzaFN0YXR1c0lkO1xuICAgIHB1c2hDb250cm9sbGVyXG4gICAgICAuc2VuZFB1c2gocmVxLmJvZHksIHdoZXJlLCByZXEuY29uZmlnLCByZXEuYXV0aCwgb2JqZWN0SWQgPT4ge1xuICAgICAgICBwdXNoU3RhdHVzSWQgPSBvYmplY3RJZDtcbiAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ1gtUGFyc2UtUHVzaC1TdGF0dXMtSWQnOiBwdXNoU3RhdHVzSWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgcmVzdWx0OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIuZXJyb3IoXG4gICAgICAgICAgYF9QdXNoU3RhdHVzICR7cHVzaFN0YXR1c0lkfTogZXJyb3Igd2hpbGUgc2VuZGluZyBwdXNoYCxcbiAgICAgICAgICBlcnJcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBxdWVyeSBjb25kaXRpb24gZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIEEgcmVxdWVzdCBvYmplY3RcbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIHF1ZXJ5IGNvbmRpdGlvbiwgdGhlIHdoZXJlIGZpZWxkIGluIGEgcXVlcnkgYXBpIGNhbGxcbiAgICovXG4gIHN0YXRpYyBnZXRRdWVyeUNvbmRpdGlvbihyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gcmVxLmJvZHkgfHwge307XG4gICAgY29uc3QgaGFzV2hlcmUgPSB0eXBlb2YgYm9keS53aGVyZSAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgY29uc3QgaGFzQ2hhbm5lbHMgPSB0eXBlb2YgYm9keS5jaGFubmVscyAhPT0gJ3VuZGVmaW5lZCc7XG5cbiAgICBsZXQgd2hlcmU7XG4gICAgaWYgKGhhc1doZXJlICYmIGhhc0NoYW5uZWxzKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ0NoYW5uZWxzIGFuZCBxdWVyeSBjYW4gbm90IGJlIHNldCBhdCB0aGUgc2FtZSB0aW1lLidcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChoYXNXaGVyZSkge1xuICAgICAgd2hlcmUgPSBib2R5LndoZXJlO1xuICAgIH0gZWxzZSBpZiAoaGFzQ2hhbm5lbHMpIHtcbiAgICAgIHdoZXJlID0ge1xuICAgICAgICBjaGFubmVsczoge1xuICAgICAgICAgICRpbjogYm9keS5jaGFubmVscyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnU2VuZGluZyBhIHB1c2ggcmVxdWlyZXMgZWl0aGVyIFwiY2hhbm5lbHNcIiBvciBhIFwid2hlcmVcIiBxdWVyeS4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gd2hlcmU7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaFJvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/RolesRouter.js b/lib/Routers/RolesRouter.js new file mode 100644 index 0000000000..10fd6e7942 --- /dev/null +++ b/lib/Routers/RolesRouter.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.RolesRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RolesRouter extends _ClassesRouter.default { + className() { + return '_Role'; + } + + mountRoutes() { + this.route('GET', '/roles', req => { + return this.handleFind(req); + }); + this.route('GET', '/roles/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/roles', req => { + return this.handleCreate(req); + }); + this.route('PUT', '/roles/:objectId', req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/roles/:objectId', req => { + return this.handleDelete(req); + }); + } + +} + +exports.RolesRouter = RolesRouter; +var _default = RolesRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1JvbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlJvbGVzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsIm1vdW50Um91dGVzIiwicm91dGUiLCJyZXEiLCJoYW5kbGVGaW5kIiwiaGFuZGxlR2V0IiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFNBQVMsR0FBRztBQUNWLFdBQU8sT0FBUDtBQUNEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixRQUFsQixFQUE0QkMsR0FBRyxJQUFJO0FBQ2pDLGFBQU8sS0FBS0MsVUFBTCxDQUFnQkQsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsS0FBWCxFQUFrQixrQkFBbEIsRUFBc0NDLEdBQUcsSUFBSTtBQUMzQyxhQUFPLEtBQUtFLFNBQUwsQ0FBZUYsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFFBQW5CLEVBQTZCQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRyxZQUFMLENBQWtCSCxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxLQUFYLEVBQWtCLGtCQUFsQixFQUFzQ0MsR0FBRyxJQUFJO0FBQzNDLGFBQU8sS0FBS0ksWUFBTCxDQUFrQkosR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsUUFBWCxFQUFxQixrQkFBckIsRUFBeUNDLEdBQUcsSUFBSTtBQUM5QyxhQUFPLEtBQUtLLFlBQUwsQ0FBa0JMLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBckI0Qzs7O2VBd0JoQ0wsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5cbmV4cG9ydCBjbGFzcyBSb2xlc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfUm9sZSc7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yb2xlcycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSb2xlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/SchemasRouter.js b/lib/Routers/SchemasRouter.js new file mode 100644 index 0000000000..04681476df --- /dev/null +++ b/lib/Routers/SchemasRouter.js @@ -0,0 +1,120 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SchemasRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// schemas.js +var Parse = require('parse/node').Parse, + SchemaController = require('../Controllers/SchemaController'); + +function classNameMismatchResponse(bodyClass, pathClass) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class name mismatch between ${bodyClass} and ${pathClass}.`); +} + +function getAllSchemas(req) { + return req.config.database.loadSchema({ + clearCache: true + }).then(schemaController => schemaController.getAllClasses(true)).then(schemas => ({ + response: { + results: schemas + } + })); +} + +function getOneSchema(req) { + const className = req.params.className; + return req.config.database.loadSchema({ + clearCache: true + }).then(schemaController => schemaController.getOneSchema(className, true)).then(schema => ({ + response: schema + })).catch(error => { + if (error === undefined) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); + } else { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); + } + }); +} + +function createSchema(req) { + if (req.auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); + } + + if (req.params.className && req.body.className) { + if (req.params.className != req.body.className) { + return classNameMismatchResponse(req.body.className, req.params.className); + } + } + + const className = req.params.className || req.body.className; + + if (!className) { + throw new Parse.Error(135, `POST ${req.path} needs a class name.`); + } + + return req.config.database.loadSchema({ + clearCache: true + }).then(schema => schema.addClassIfNotExists(className, req.body.fields, req.body.classLevelPermissions, req.body.indexes)).then(schema => ({ + response: schema + })); +} + +function modifySchema(req) { + if (req.auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); + } + + if (req.body.className && req.body.className != req.params.className) { + return classNameMismatchResponse(req.body.className, req.params.className); + } + + const submittedFields = req.body.fields || {}; + const className = req.params.className; + return req.config.database.loadSchema({ + clearCache: true + }).then(schema => schema.updateClass(className, submittedFields, req.body.classLevelPermissions, req.body.indexes, req.config.database)).then(result => ({ + response: result + })); +} + +const deleteSchema = req => { + if (req.auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); + } + + if (!SchemaController.classNameIsValid(req.params.className)) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, SchemaController.invalidClassNameMessage(req.params.className)); + } + + return req.config.database.deleteSchema(req.params.className).then(() => ({ + response: {} + })); +}; + +class SchemasRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/schemas', middleware.promiseEnforceMasterKeyAccess, getAllSchemas); + this.route('GET', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, getOneSchema); + this.route('POST', '/schemas', middleware.promiseEnforceMasterKeyAccess, createSchema); + this.route('POST', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, createSchema); + this.route('PUT', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, modifySchema); + this.route('DELETE', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, deleteSchema); + } + +} + +exports.SchemasRouter = SchemasRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1NjaGVtYXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZU1pc21hdGNoUmVzcG9uc2UiLCJib2R5Q2xhc3MiLCJwYXRoQ2xhc3MiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsImdldEFsbFNjaGVtYXMiLCJyZXEiLCJjb25maWciLCJkYXRhYmFzZSIsImxvYWRTY2hlbWEiLCJjbGVhckNhY2hlIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hcyIsInJlc3BvbnNlIiwicmVzdWx0cyIsImdldE9uZVNjaGVtYSIsImNsYXNzTmFtZSIsInBhcmFtcyIsInNjaGVtYSIsImNhdGNoIiwiZXJyb3IiLCJ1bmRlZmluZWQiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjcmVhdGVTY2hlbWEiLCJhdXRoIiwiaXNSZWFkT25seSIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwicGF0aCIsImFkZENsYXNzSWZOb3RFeGlzdHMiLCJmaWVsZHMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJpbmRleGVzIiwibW9kaWZ5U2NoZW1hIiwic3VibWl0dGVkRmllbGRzIiwidXBkYXRlQ2xhc3MiLCJyZXN1bHQiLCJkZWxldGVTY2hlbWEiLCJjbGFzc05hbWVJc1ZhbGlkIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJTY2hlbWFzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFLQTs7QUFDQTs7Ozs7Ozs7QUFOQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxnQkFBZ0IsR0FBR0Qs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QXdFMUMsYUFBeEU7QUFDQSxTQUFLd0MsS0FBTCxDQUNFLEtBREYsRUFFRSxxQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU5QixZQUpGO0FBTUEsU0FBSzRCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFVBQW5CLEVBQStCQyxVQUFVLENBQUNDLDZCQUExQyxFQUF5RXRCLFlBQXpFO0FBQ0EsU0FBS29CLEtBQUwsQ0FDRSxNQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFdEIsWUFKRjtBQU1BLFNBQUtvQixLQUFMLENBQ0UsS0FERixFQUVFLHFCQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRVosWUFKRjtBQU1BLFNBQUtVLEtBQUwsQ0FDRSxRQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFUixZQUpGO0FBTUQ7O0FBNUI4QyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNjaGVtYXMuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICBTY2hlbWFDb250cm9sbGVyID0gcmVxdWlyZSgnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xuXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5mdW5jdGlvbiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKGJvZHlDbGFzcywgcGF0aENsYXNzKSB7XG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgYENsYXNzIG5hbWUgbWlzbWF0Y2ggYmV0d2VlbiAke2JvZHlDbGFzc30gYW5kICR7cGF0aENsYXNzfS5gXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEFsbFNjaGVtYXMocmVxKSB7XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoeyBjbGVhckNhY2hlOiB0cnVlIH0pXG4gICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmdldEFsbENsYXNzZXModHJ1ZSkpXG4gICAgLnRoZW4oc2NoZW1hcyA9PiAoeyByZXNwb25zZTogeyByZXN1bHRzOiBzY2hlbWFzIH0gfSkpO1xufVxuXG5mdW5jdGlvbiBnZXRPbmVTY2hlbWEocmVxKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCB0cnVlKSlcbiAgICAudGhlbihzY2hlbWEgPT4gKHsgcmVzcG9uc2U6IHNjaGVtYSB9KSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yLicpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGNyZWF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lICYmIHJlcS5ib2R5LmNsYXNzTmFtZSkge1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAhPSByZXEuYm9keS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKHJlcS5ib2R5LmNsYXNzTmFtZSwgcmVxLnBhcmFtcy5jbGFzc05hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lIHx8IHJlcS5ib2R5LmNsYXNzTmFtZTtcbiAgaWYgKCFjbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM1LCBgUE9TVCAke3JlcS5wYXRofSBuZWVkcyBhIGNsYXNzIG5hbWUuYCk7XG4gIH1cblxuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYSA9PlxuICAgICAgc2NoZW1hLmFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgcmVxLmJvZHkuZmllbGRzLFxuICAgICAgICByZXEuYm9keS5jbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgIHJlcS5ib2R5LmluZGV4ZXNcbiAgICAgIClcbiAgICApXG4gICAgLnRoZW4oc2NoZW1hID0+ICh7IHJlc3BvbnNlOiBzY2hlbWEgfSkpO1xufVxuXG5mdW5jdGlvbiBtb2RpZnlTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHVwZGF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5ib2R5LmNsYXNzTmFtZSAmJiByZXEuYm9keS5jbGFzc05hbWUgIT0gcmVxLnBhcmFtcy5jbGFzc05hbWUpIHtcbiAgICByZXR1cm4gY2xhc3NOYW1lTWlzbWF0Y2hSZXNwb25zZShyZXEuYm9keS5jbGFzc05hbWUsIHJlcS5wYXJhbXMuY2xhc3NOYW1lKTtcbiAgfVxuXG4gIGNvbnN0IHN1Ym1pdHRlZEZpZWxkcyA9IHJlcS5ib2R5LmZpZWxkcyB8fCB7fTtcbiAgY29uc3QgY2xhc3NOYW1lID0gcmVxLnBhcmFtcy5jbGFzc05hbWU7XG5cbiAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAudGhlbihzY2hlbWEgPT5cbiAgICAgIHNjaGVtYS51cGRhdGVDbGFzcyhcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBzdWJtaXR0ZWRGaWVsZHMsXG4gICAgICAgIHJlcS5ib2R5LmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgcmVxLmJvZHkuaW5kZXhlcyxcbiAgICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgKVxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4gKHsgcmVzcG9uc2U6IHJlc3VsdCB9KSk7XG59XG5cbmNvbnN0IGRlbGV0ZVNjaGVtYSA9IHJlcSA9PiB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGRlbGV0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKCFTY2hlbWFDb250cm9sbGVyLmNsYXNzTmFtZUlzVmFsaWQocmVxLnBhcmFtcy5jbGFzc05hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgU2NoZW1hQ29udHJvbGxlci5pbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShyZXEucGFyYW1zLmNsYXNzTmFtZSlcbiAgICApO1xuICB9XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShyZXEucGFyYW1zLmNsYXNzTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xufTtcblxuZXhwb3J0IGNsYXNzIFNjaGVtYXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zY2hlbWFzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgZ2V0QWxsU2NoZW1hcyk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9zY2hlbWFzLzpjbGFzc05hbWUnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIGdldE9uZVNjaGVtYVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvc2NoZW1hcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGNyZWF0ZVNjaGVtYSk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBjcmVhdGVTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUFVUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBtb2RpZnlTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnREVMRVRFJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBkZWxldGVTY2hlbWFcbiAgICApO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/SessionsRouter.js b/lib/Routers/SessionsRouter.js new file mode 100644 index 0000000000..de4bdcd2e0 --- /dev/null +++ b/lib/Routers/SessionsRouter.js @@ -0,0 +1,107 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.SessionsRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _Auth = _interopRequireDefault(require("../Auth")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class SessionsRouter extends _ClassesRouter.default { + className() { + return '_Session'; + } + + handleMe(req) { + // TODO: Verify correct behavior + if (!req.info || !req.info.sessionToken) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token required.'); + } + + return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { + sessionToken: req.info.sessionToken + }, undefined, req.info.clientSDK, req.info.context).then(response => { + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token not found.'); + } + + return { + response: response.results[0] + }; + }); + } + + handleUpdateToRevocableSession(req) { + const config = req.config; + const user = req.auth.user; // Issue #2720 + // Calling without a session token would result in a not found user + + if (!user) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'invalid session'); + } + + const { + sessionData, + createSession + } = _Auth.default.createSession(config, { + userId: user.id, + createdWith: { + action: 'upgrade' + }, + installationId: req.auth.installationId + }); + + return createSession().then(() => { + // delete the session token, use the db to skip beforeSave + return config.database.update('_User', { + objectId: user.id + }, { + sessionToken: { + __op: 'Delete' + } + }); + }).then(() => { + return Promise.resolve({ + response: sessionData + }); + }); + } + + mountRoutes() { + this.route('GET', '/sessions/me', req => { + return this.handleMe(req); + }); + this.route('GET', '/sessions', req => { + return this.handleFind(req); + }); + this.route('GET', '/sessions/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/sessions', req => { + return this.handleCreate(req); + }); + this.route('PUT', '/sessions/:objectId', req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/sessions/:objectId', req => { + return this.handleDelete(req); + }); + this.route('POST', '/upgradeToRevocableSession', req => { + return this.handleUpdateToRevocableSession(req); + }); + } + +} + +exports.SessionsRouter = SessionsRouter; +var _default = SessionsRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyLmpzIl0sIm5hbWVzIjpbIlNlc3Npb25zUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsImhhbmRsZU1lIiwicmVxIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsIkF1dGgiLCJtYXN0ZXIiLCJ1bmRlZmluZWQiLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0cyIsImxlbmd0aCIsImhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbiIsInVzZXIiLCJhdXRoIiwiT0JKRUNUX05PVF9GT1VORCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsImlkIiwiY3JlYXRlZFdpdGgiLCJhY3Rpb24iLCJpbnN0YWxsYXRpb25JZCIsImRhdGFiYXNlIiwidXBkYXRlIiwib2JqZWN0SWQiLCJfX29wIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsImhhbmRsZUdldCIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixTQUE2QkMsc0JBQTdCLENBQTJDO0FBQ2hEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFVBQVA7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxDQUFDQyxHQUFELEVBQU07QUFDWjtBQUNBLFFBQUksQ0FBQ0EsR0FBRyxDQUFDQyxJQUFMLElBQWEsQ0FBQ0QsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFlBQTNCLEVBQXlDO0FBQ3ZDLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxx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QUFJO0FBQ3JDLGFBQU8sS0FBS3VDLFlBQUwsQ0FBa0J2QyxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtvQyxLQUFMLENBQVcsS0FBWCxFQUFrQixxQkFBbEIsRUFBeUNwQyxHQUFHLElBQUk7QUFDOUMsYUFBTyxLQUFLd0MsWUFBTCxDQUFrQnhDLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS29DLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLHFCQUFyQixFQUE0Q3BDLEdBQUcsSUFBSTtBQUNqRCxhQUFPLEtBQUt5QyxZQUFMLENBQWtCekMsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLb0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsNEJBQW5CLEVBQWlEcEMsR0FBRyxJQUFJO0FBQ3RELGFBQU8sS0FBS2tCLDhCQUFMLENBQW9DbEIsR0FBcEMsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF0RitDOzs7ZUF5Rm5DSixjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IEF1dGggZnJvbSAnLi4vQXV0aCc7XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfU2Vzc2lvbic7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICAvLyBUT0RPOiBWZXJpZnkgY29ycmVjdCBiZWhhdmlvclxuICAgIGlmICghcmVxLmluZm8gfHwgIXJlcS5pbmZvLnNlc3Npb25Ub2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuOiByZXEuaW5mby5zZXNzaW9uVG9rZW4gfSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnU2Vzc2lvbiB0b2tlbiBub3QgZm91bmQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2UucmVzdWx0c1swXSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlVG9SZXZvY2FibGVTZXNzaW9uKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgdXNlciA9IHJlcS5hdXRoLnVzZXI7XG4gICAgLy8gSXNzdWUgIzI3MjBcbiAgICAvLyBDYWxsaW5nIHdpdGhvdXQgYSBzZXNzaW9uIHRva2VuIHdvdWxkIHJlc3VsdCBpbiBhIG5vdCBmb3VuZCB1c2VyXG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ2ludmFsaWQgc2Vzc2lvbicpO1xuICAgIH1cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24oY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIuaWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICd1cGdyYWRlJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmF1dGguaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGRlbGV0ZSB0aGUgc2Vzc2lvbiB0b2tlbiwgdXNlIHRoZSBkYiB0byBza2lwIGJlZm9yZVNhdmVcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvYmplY3RJZDogdXNlci5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyByZXNwb25zZTogc2Vzc2lvbkRhdGEgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvc2Vzc2lvbnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9zZXNzaW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91cGdyYWRlVG9SZXZvY2FibGVTZXNzaW9uJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbihyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNlc3Npb25zUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/UsersRouter.js b/lib/Routers/UsersRouter.js new file mode 100644 index 0000000000..e8a18d53f0 --- /dev/null +++ b/lib/Routers/UsersRouter.js @@ -0,0 +1,436 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.UsersRouter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _AccountLockout = _interopRequireDefault(require("../AccountLockout")); + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _Auth = _interopRequireDefault(require("../Auth")); + +var _password = _interopRequireDefault(require("../password")); + +var _triggers = require("../triggers"); + +var _middlewares = require("../middlewares"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +class UsersRouter extends _ClassesRouter.default { + className() { + return '_User'; + } + /** + * Removes all "_" prefixed properties from an object, except "__type" + * @param {Object} obj An object. + */ + + + static removeHiddenProperties(obj) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + // Regexp comes from Parse.Object.prototype.validate + if (key !== '__type' && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { + delete obj[key]; + } + } + } + } + /** + * Validates a password request in login and verifyPassword + * @param {Object} req The request + * @returns {Object} User object + * @private + */ + + + _authenticateUserFromRequest(req) { + return new Promise((resolve, reject) => { + // Use query parameters instead if provided in url + let payload = req.body; + + if (!payload.username && req.query && req.query.username || !payload.email && req.query && req.query.email) { + payload = req.query; + } + + const { + username, + email, + password + } = payload; // TODO: use the right error codes / descriptions. + + if (!username && !email) { + throw new _node.default.Error(_node.default.Error.USERNAME_MISSING, 'username/email is required.'); + } + + if (!password) { + throw new _node.default.Error(_node.default.Error.PASSWORD_MISSING, 'password is required.'); + } + + if (typeof password !== 'string' || email && typeof email !== 'string' || username && typeof username !== 'string') { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + + let user; + let isValidPassword = false; + let query; + + if (email && username) { + query = { + email, + username + }; + } else if (email) { + query = { + email + }; + } else { + query = { + $or: [{ + username + }, { + email: username + }] + }; + } + + return req.config.database.find('_User', query).then(results => { + if (!results.length) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + + if (results.length > 1) { + // corner case where user1 has username == user2 email + req.config.loggerController.warn("There is a user which email is the same as another user's username, logging in based on username"); + user = results.filter(user => user.username === username)[0]; + } else { + user = results[0]; + } + + return _password.default.compare(password, user.password); + }).then(correct => { + isValidPassword = correct; + const accountLockoutPolicy = new _AccountLockout.default(user, req.config); + return accountLockoutPolicy.handleLoginAttempt(isValidPassword); + }).then(() => { + if (!isValidPassword) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } // Ensure the user isn't locked out + // A locked out user won't be able to login + // To lock a user out, just set the ACL to `masterKey` only ({}). + // Empty ACL is OK + + + if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + + if (req.config.verifyUserEmails && req.config.preventLoginWithUnverifiedEmail && !user.emailVerified) { + throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); + } + + delete user.password; // Sometimes the authData still has null on that keys + // https://github.com/parse-community/parse-server/issues/935 + + if (user.authData) { + Object.keys(user.authData).forEach(provider => { + if (user.authData[provider] === null) { + delete user.authData[provider]; + } + }); + + if (Object.keys(user.authData).length == 0) { + delete user.authData; + } + } + + return resolve(user); + }).catch(error => { + return reject(error); + }); + }); + } + + handleMe(req) { + if (!req.info || !req.info.sessionToken) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + const sessionToken = req.info.sessionToken; + return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { + sessionToken + }, { + include: 'user' + }, req.info.clientSDK, req.info.context).then(response => { + if (!response.results || response.results.length == 0 || !response.results[0].user) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } else { + const user = response.results[0].user; // Send token back on the login, because SDKs expect that. + + user.sessionToken = sessionToken; // Remove hidden properties. + + UsersRouter.removeHiddenProperties(user); + return { + response: user + }; + } + }); + } + + async handleLogIn(req) { + const user = await this._authenticateUserFromRequest(req); // handle password expiry policy + + if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { + let changedAt = user._password_changed_at; + + if (!changedAt) { + // password was created before expiry policy was enabled. + // simply update _User object so that it will start enforcing from now + changedAt = new Date(); + req.config.database.update('_User', { + username: user.username + }, { + _password_changed_at: _node.default._encode(changedAt) + }); + } else { + // check whether the password has expired + if (changedAt.__type == 'Date') { + changedAt = new Date(changedAt.iso); + } // Calculate the expiry time. + + + const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge); + if (expiresAt < new Date()) // fail of current time is past password expiry time + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.'); + } + } // Remove hidden properties. + + + UsersRouter.removeHiddenProperties(user); + req.config.filesController.expandFilesInObject(req.config, user); // Before login trigger; throws if failure + + await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforeLogin, req.auth, _node.default.User.fromJSON(Object.assign({ + className: '_User' + }, user)), null, req.config); + + const { + sessionData, + createSession + } = _Auth.default.createSession(req.config, { + userId: user.objectId, + createdWith: { + action: 'login', + authProvider: 'password' + }, + installationId: req.info.installationId + }); + + user.sessionToken = sessionData.sessionToken; + await createSession(); + + const afterLoginUser = _node.default.User.fromJSON(Object.assign({ + className: '_User' + }, user)); + + (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogin, _objectSpread(_objectSpread({}, req.auth), {}, { + user: afterLoginUser + }), afterLoginUser, null, req.config); + return { + response: user + }; + } + + handleVerifyPassword(req) { + return this._authenticateUserFromRequest(req).then(user => { + // Remove hidden properties. + UsersRouter.removeHiddenProperties(user); + return { + response: user + }; + }).catch(error => { + throw error; + }); + } + + handleLogOut(req) { + const success = { + response: {} + }; + + if (req.info && req.info.sessionToken) { + return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { + sessionToken: req.info.sessionToken + }, undefined, req.info.clientSDK, req.info.context).then(records => { + if (records.results && records.results.length) { + return _rest.default.del(req.config, _Auth.default.master(req.config), '_Session', records.results[0].objectId, req.info.context).then(() => { + this._runAfterLogoutTrigger(req, records.results[0]); + + return Promise.resolve(success); + }); + } + + return Promise.resolve(success); + }); + } + + return Promise.resolve(success); + } + + _runAfterLogoutTrigger(req, session) { + // After logout trigger + (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogout, req.auth, _node.default.Session.fromJSON(Object.assign({ + className: '_Session' + }, session)), null, req.config); + } + + _throwOnBadEmailConfig(req) { + try { + _Config.default.validateEmailConfiguration({ + emailAdapter: req.config.userController.adapter, + appName: req.config.appName, + publicServerURL: req.config.publicServerURL, + emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration + }); + } catch (e) { + if (typeof e === 'string') { + // Maybe we need a Bad Configuration error, but the SDKs won't understand it. For now, Internal Server Error. + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.'); + } else { + throw e; + } + } + } + + handleResetRequest(req) { + this._throwOnBadEmailConfig(req); + + const { + email + } = req.body; + + if (!email) { + throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); + } + + if (typeof email !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); + } + + const userController = req.config.userController; + return userController.sendPasswordResetEmail(email).then(() => { + return Promise.resolve({ + response: {} + }); + }, err => { + if (err.code === _node.default.Error.OBJECT_NOT_FOUND) { + // Return success so that this endpoint can't + // be used to enumerate valid emails + return Promise.resolve({ + response: {} + }); + } else { + throw err; + } + }); + } + + handleVerificationEmailRequest(req) { + this._throwOnBadEmailConfig(req); + + const { + email + } = req.body; + + if (!email) { + throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); + } + + if (typeof email !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); + } + + return req.config.database.find('_User', { + email: email + }).then(results => { + if (!results.length || results.length < 1) { + throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); + } + + const user = results[0]; // remove password field, messes with saving on postgres + + delete user.password; + + if (user.emailVerified) { + throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`); + } + + const userController = req.config.userController; + return userController.regenerateEmailVerifyToken(user).then(() => { + userController.sendVerificationEmail(user); + return { + response: {} + }; + }); + }); + } + + mountRoutes() { + this.route('GET', '/users', req => { + return this.handleFind(req); + }); + this.route('POST', '/users', _middlewares.promiseEnsureIdempotency, req => { + return this.handleCreate(req); + }); + this.route('GET', '/users/me', req => { + return this.handleMe(req); + }); + this.route('GET', '/users/:objectId', req => { + return this.handleGet(req); + }); + this.route('PUT', '/users/:objectId', _middlewares.promiseEnsureIdempotency, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/users/:objectId', req => { + return this.handleDelete(req); + }); + this.route('GET', '/login', req => { + return this.handleLogIn(req); + }); + this.route('POST', '/login', req => { + return this.handleLogIn(req); + }); + this.route('POST', '/logout', req => { + return this.handleLogOut(req); + }); + this.route('POST', '/requestPasswordReset', req => { + return this.handleResetRequest(req); + }); + this.route('POST', '/verificationEmailRequest', req => { + return this.handleVerificationEmailRequest(req); + }); + this.route('GET', '/verifyPassword', req => { + return this.handleVerifyPassword(req); + }); + } + +} + +exports.UsersRouter = UsersRouter; +var _default = UsersRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1VzZXJzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlVzZXJzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsInJlbW92ZUhpZGRlblByb3BlcnRpZXMiLCJvYmoiLCJrZXkiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJ0ZXN0IiwiX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdCIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicGF5bG9hZCIsImJvZHkiLCJ1c2VybmFtZSIsInF1ZXJ5IiwiZW1haWwiLCJwYXNzd29yZCIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiUEFTU1dPUkRfTUlTU0lORyIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1c2VyIiwiaXNWYWxpZFBhc3N3b3JkIiwiJG9yIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2dnZXJDb250cm9sbGVyIiwid2FybiIsImZpbHRlciIsInBhc3N3b3JkQ3J5cHRvIiwiY29tcGFyZSIsImNvcnJlY3QiLCJhY2NvdW50TG9ja291dFBvbGljeSIsIkFjY291bnRMb2Nrb3V0IiwiaGFuZGxlTG9naW5BdHRlbXB0IiwiYXV0aCIsImlzTWFzdGVyIiwiQUNMIiwia2V5cyIsInZlcmlmeVVzZXJFbWFpbHMiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwiZW1haWxWZXJpZmllZCIsIkVNQUlMX05PVF9GT1VORCIsImF1dGhEYXRhIiwiZm9yRWFjaCIsInByb3ZpZGVyIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZU1lIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsInJlc3QiLCJBdXRoIiwibWFzdGVyIiwiaW5jbHVkZSIsImNsaWVudFNESyIsImNvbnRleHQiLCJyZXNwb25zZSIsImhhbmRsZUxvZ0luIiwicGFzc3dvcmRQb2xpY3kiLCJtYXhQYXNzd29yZEFnZSIsImNoYW5nZWRBdCIsIl9wYXNzd29yZF9jaGFuZ2VkX2F0IiwiRGF0ZSIsInVwZGF0ZSIsIl9lbmNvZGUiLCJfX3R5cGUiLCJpc28iLCJleHBpcmVzQXQiLCJnZXRUaW1lIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsIlRyaWdnZXJUeXBlcyIsImJlZm9yZUxvZ2luIiwiVXNlciIsImZyb21KU09OIiwiYXNzaWduIiwic2Vzc2lvbkRhdGEiLCJjcmVhdGVTZXNzaW9uIiwidXNlcklkIiwib2JqZWN0SWQiLCJjcmVhdGVkV2l0aCIsImFjdGlvbiIsImF1dGhQcm92aWRlciIsImluc3RhbGxhdGlvbklkIiwiYWZ0ZXJMb2dpblVzZXIiLCJhZnRlckxvZ2luIiwiaGFuZGxlVmVyaWZ5UGFzc3dvcmQiLCJoYW5kbGVMb2dPdXQiLCJzdWNjZXNzIiwidW5kZWZpbmVkIiwicmVjb3JkcyIsImRlbCIsIl9ydW5BZnRlckxvZ291dFRyaWdnZXIiLCJzZXNzaW9uIiwiYWZ0ZXJMb2dvdXQiLCJTZXNzaW9uIiwiX3Rocm93T25CYWRFbWFpbENvbmZpZyIsIkNvbmZpZyIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImhhbmRsZVJlc2V0UmVxdWVzdCIsIkVNQUlMX01JU1NJTkciLCJJTlZBTElEX0VNQUlMX0FERFJFU1MiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwiZXJyIiwiY29kZSIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCIsIk9USEVSX0NBVVNFIiwicmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4iLCJzZW5kVmVyaWZpY2F0aW9uRW1haWwiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZUdldCIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7O0FBRU8sTUFBTUEsV0FBTixTQUEwQkMsc0JBQTFCLENBQXdDO0FBQzdDQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLE9BQVA7QUFDRDtBQUVEOzs7Ozs7QUFJQSxTQUFPQyxzQkFBUCxDQUE4QkMsR0FBOUIsRUFBbUM7QUFDakMsU0FBSyxJQUFJQyxHQUFULElBQWdCRCxHQUFoQixFQUFxQjtBQUNuQixVQUFJRSxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0wsR0FBckMsRUFBMENDLEdBQTFDLENBQUosRUFBb0Q7QUFDbEQ7QUFDQSxZQUFJQSxHQUFHLEtBQUssUUFBUixJQUFvQixDQUFDLDBCQUEwQkssSUFBMUIsQ0FBK0JMLEdBQS9CLENBQXpCLEVBQThEO0FBQzVELGlCQUFPRCxHQUFHLENBQUNDLEdBQUQsQ0FBVjtBQUNEO0FBQ0Y7QUFDRjtBQUNGO0FBRUQ7Ozs7Ozs7O0FBTUFNLEVBQUFBLDRCQUE0QixDQUFDQyxHQUFELEVBQU07QUFDaEMsV0FBTyxJQUFJQyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDO0FBQ0EsVUFBSUMsT0FBTyxHQUFHSixHQUFHLENBQUNLLElBQWxCOztBQUNBLFVBQ0csQ0FBQ0QsT0FBTyxDQUFDRSxRQUFULElBQXFCTixHQUFHLENBQUNPLEtBQXpCLElBQWtDUCxHQUFHLENBQUNPLEtBQUosQ0FBVUQsUUFBN0MsSUFDQyxDQUFDRixPQUFPLENBQUNJLEtBQVQsSUFBa0JSLEdBQUcsQ0FBQ08sS0FBdEIsSUFBK0JQLEdB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TCxDQUFrQnZGLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS3NILEtBQUwsQ0FBVyxNQUFYLEVBQW1CLHVCQUFuQixFQUE0Q3RILEdBQUcsSUFBSTtBQUNqRCxhQUFPLEtBQUsyRyxrQkFBTCxDQUF3QjNHLEdBQXhCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS3NILEtBQUwsQ0FBVyxNQUFYLEVBQW1CLDJCQUFuQixFQUFnRHRILEdBQUcsSUFBSTtBQUNyRCxhQUFPLEtBQUtpSCw4QkFBTCxDQUFvQ2pILEdBQXBDLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS3NILEtBQUwsQ0FBVyxLQUFYLEVBQWtCLGlCQUFsQixFQUFxQ3RILEdBQUcsSUFBSTtBQUMxQyxhQUFPLEtBQUtzRixvQkFBTCxDQUEwQnRGLEdBQTFCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBbGE0Qzs7O2VBcWFoQ1osVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRoZXNlIG1ldGhvZHMgaGFuZGxlIHRoZSBVc2VyLXJlbGF0ZWQgcm91dGVzLlxuXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgQWNjb3VudExvY2tvdXQgZnJvbSAnLi4vQWNjb3VudExvY2tvdXQnO1xuaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IEF1dGggZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgcGFzc3dvcmRDcnlwdG8gZnJvbSAnLi4vcGFzc3dvcmQnO1xuaW1wb3J0IHsgbWF5YmVSdW5UcmlnZ2VyLCBUeXBlcyBhcyBUcmlnZ2VyVHlwZXMgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kgfSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmV4cG9ydCBjbGFzcyBVc2Vyc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfVXNlcic7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgXCJfXCIgcHJlZml4ZWQgcHJvcGVydGllcyBmcm9tIGFuIG9iamVjdCwgZXhjZXB0IFwiX190eXBlXCJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iaiBBbiBvYmplY3QuXG4gICAqL1xuICBzdGF0aWMgcmVtb3ZlSGlkZGVuUHJvcGVydGllcyhvYmopIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAvLyBSZWdleHAgY29tZXMgZnJvbSBQYXJzZS5PYmplY3QucHJvdG90eXBlLnZhbGlkYXRlXG4gICAgICAgIGlmIChrZXkgIT09ICdfX3R5cGUnICYmICEvXltBLVphLXpdWzAtOUEtWmEtel9dKiQvLnRlc3Qoa2V5KSkge1xuICAgICAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBwYXNzd29yZCByZXF1ZXN0IGluIGxvZ2luIGFuZCB2ZXJpZnlQYXNzd29yZFxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFVzZXIgb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBVc2UgcXVlcnkgcGFyYW1ldGVycyBpbnN0ZWFkIGlmIHByb3ZpZGVkIGluIHVybFxuICAgICAgbGV0IHBheWxvYWQgPSByZXEuYm9keTtcbiAgICAgIGlmIChcbiAgICAgICAgKCFwYXlsb2FkLnVzZXJuYW1lICYmIHJlcS5xdWVyeSAmJiByZXEucXVlcnkudXNlcm5hbWUpIHx8XG4gICAgICAgICghcGF5bG9hZC5lbWFpbCAmJiByZXEucXVlcnkgJiYgcmVxLnF1ZXJ5LmVtYWlsKVxuICAgICAgKSB7XG4gICAgICAgIHBheWxvYWQgPSByZXEucXVlcnk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHVzZXJuYW1lLCBlbWFpbCwgcGFzc3dvcmQgfSA9IHBheWxvYWQ7XG5cbiAgICAgIC8vIFRPRE86IHVzZSB0aGUgcmlnaHQgZXJyb3IgY29kZXMgLyBkZXNjcmlwdGlvbnMuXG4gICAgICBpZiAoIXVzZXJuYW1lICYmICFlbWFpbCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVVNFUk5BTUVfTUlTU0lORywgJ3VzZXJuYW1lL2VtYWlsIGlzIHJlcXVpcmVkLicpO1xuICAgICAgfVxuICAgICAgaWYgKCFwYXNzd29yZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUEFTU1dPUkRfTUlTU0lORywgJ3Bhc3N3b3JkIGlzIHJlcXVpcmVkLicpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgcGFzc3dvcmQgIT09ICdzdHJpbmcnIHx8XG4gICAgICAgIChlbWFpbCAmJiB0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB8fFxuICAgICAgICAodXNlcm5hbWUgJiYgdHlwZW9mIHVzZXJuYW1lICE9PSAnc3RyaW5nJylcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICB9XG5cbiAgICAgIGxldCB1c2VyO1xuICAgICAgbGV0IGlzVmFsaWRQYXNzd29yZCA9IGZhbHNlO1xuICAgICAgbGV0IHF1ZXJ5O1xuICAgICAgaWYgKGVtYWlsICYmIHVzZXJuYW1lKSB7XG4gICAgICAgIHF1ZXJ5ID0geyBlbWFpbCwgdXNlcm5hbWUgfTtcbiAgICAgIH0gZWxzZSBpZiAoZW1haWwpIHtcbiAgICAgICAgcXVlcnkgPSB7IGVtYWlsIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeSA9IHsgJG9yOiBbeyB1c2VybmFtZSB9LCB7IGVtYWlsOiB1c2VybmFtZSB9XSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgLmZpbmQoJ19Vc2VyJywgcXVlcnkpXG4gICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAvLyBjb3JuZXIgY2FzZSB3aGVyZSB1c2VyMSBoYXMgdXNlcm5hbWUgPT0gdXNlcjIgZW1haWxcbiAgICAgICAgICAgIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlci53YXJuKFxuICAgICAgICAgICAgICBcIlRoZXJlIGlzIGEgdXNlciB3aGljaCBlbWFpbCBpcyB0aGUgc2FtZSBhcyBhbm90aGVyIHVzZXIncyB1c2VybmFtZSwgbG9nZ2luZyBpbiBiYXNlZCBvbiB1c2VybmFtZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdXNlciA9IHJlc3VsdHMuZmlsdGVyKHVzZXIgPT4gdXNlci51c2VybmFtZSA9PT0gdXNlcm5hbWUpWzBdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFzc3dvcmRDcnlwdG8uY29tcGFyZShwYXNzd29yZCwgdXNlci5wYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNvcnJlY3QgPT4ge1xuICAgICAgICAgIGlzVmFsaWRQYXNzd29yZCA9IGNvcnJlY3Q7XG4gICAgICAgICAgY29uc3QgYWNjb3VudExvY2tvdXRQb2xpY3kgPSBuZXcgQWNjb3VudExvY2tvdXQodXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICAgICAgcmV0dXJuIGFjY291bnRMb2Nrb3V0UG9saWN5LmhhbmRsZUxvZ2luQXR0ZW1wdChpc1ZhbGlkUGFzc3dvcmQpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgaWYgKCFpc1ZhbGlkUGFzc3dvcmQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gRW5zdXJlIHRoZSB1c2VyIGlzbid0IGxvY2tlZCBvdXRcbiAgICAgICAgICAvLyBBIGxvY2tlZCBvdXQgdXNlciB3b24ndCBiZSBhYmxlIHRvIGxvZ2luXG4gICAgICAgICAgLy8gVG8gbG9jayBhIHVzZXIgb3V0LCBqdXN0IHNldCB0aGUgQUNMIHRvIGBtYXN0ZXJLZXlgIG9ubHkgICh7fSkuXG4gICAgICAgICAgLy8gRW1wdHkgQUNMIGlzIE9LXG4gICAgICAgICAgaWYgKCFyZXEuYXV0aC5pc01hc3RlciAmJiB1c2VyLkFDTCAmJiBPYmplY3Qua2V5cyh1c2VyLkFDTCkubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVxLmNvbmZpZy52ZXJpZnlVc2VyRW1haWxzICYmXG4gICAgICAgICAgICByZXEuY29uZmlnLnByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwgJiZcbiAgICAgICAgICAgICF1c2VyLmVtYWlsVmVyaWZpZWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsICdVc2VyIGVtYWlsIGlzIG5vdCB2ZXJpZmllZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWxldGUgdXNlci5wYXNzd29yZDtcblxuICAgICAgICAgIC8vIFNvbWV0aW1lcyB0aGUgYXV0aERhdGEgc3RpbGwgaGFzIG51bGwgb24gdGhhdCBrZXlzXG4gICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BhcnNlLWNvbW11bml0eS9wYXJzZS1zZXJ2ZXIvaXNzdWVzLzkzNVxuICAgICAgICAgIGlmICh1c2VyLmF1dGhEYXRhKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgICAgICAgaWYgKHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh1c2VyKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICBpZiAoIXJlcS5pbmZvIHx8ICFyZXEuaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2Vzc2lvblRva2VuID0gcmVxLmluZm8uc2Vzc2lvblRva2VuO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuIH0sXG4gICAgICAgIHsgaW5jbHVkZTogJ3VzZXInIH0sXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCB8fCAhcmVzcG9uc2UucmVzdWx0c1swXS51c2VyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXNwb25zZS5yZXN1bHRzWzBdLnVzZXI7XG4gICAgICAgICAgLy8gU2VuZCB0b2tlbiBiYWNrIG9uIHRoZSBsb2dpbiwgYmVjYXVzZSBTREtzIGV4cGVjdCB0aGF0LlxuICAgICAgICAgIHVzZXIuc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG5cbiAgICAgICAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUxvZ0luKHJlcSkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKTtcblxuICAgIC8vIGhhbmRsZSBwYXNzd29yZCBleHBpcnkgcG9saWN5XG4gICAgaWYgKHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgcmVxLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSkge1xuICAgICAgbGV0IGNoYW5nZWRBdCA9IHVzZXIuX3Bhc3N3b3JkX2NoYW5nZWRfYXQ7XG5cbiAgICAgIGlmICghY2hhbmdlZEF0KSB7XG4gICAgICAgIC8vIHBhc3N3b3JkIHdhcyBjcmVhdGVkIGJlZm9yZSBleHBpcnkgcG9saWN5IHdhcyBlbmFibGVkLlxuICAgICAgICAvLyBzaW1wbHkgdXBkYXRlIF9Vc2VyIG9iamVjdCBzbyB0aGF0IGl0IHdpbGwgc3RhcnQgZW5mb3JjaW5nIGZyb20gbm93XG4gICAgICAgIGNoYW5nZWRBdCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIHJlcS5jb25maWcuZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgeyB1c2VybmFtZTogdXNlci51c2VybmFtZSB9LFxuICAgICAgICAgIHsgX3Bhc3N3b3JkX2NoYW5nZWRfYXQ6IFBhcnNlLl9lbmNvZGUoY2hhbmdlZEF0KSB9XG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBwYXNzd29yZCBoYXMgZXhwaXJlZFxuICAgICAgICBpZiAoY2hhbmdlZEF0Ll9fdHlwZSA9PSAnRGF0ZScpIHtcbiAgICAgICAgICBjaGFuZ2VkQXQgPSBuZXcgRGF0ZShjaGFuZ2VkQXQuaXNvKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGV4cGlyeSB0aW1lLlxuICAgICAgICBjb25zdCBleHBpcmVzQXQgPSBuZXcgRGF0ZShcbiAgICAgICAgICBjaGFuZ2VkQXQuZ2V0VGltZSgpICsgODY0MDAwMDAgKiByZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlXG4gICAgICAgICk7XG4gICAgICAgIGlmIChleHBpcmVzQXQgPCBuZXcgRGF0ZSgpKVxuICAgICAgICAgIC8vIGZhaWwgb2YgY3VycmVudCB0aW1lIGlzIHBhc3QgcGFzc3dvcmQgZXhwaXJ5IHRpbWVcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICAgJ1lvdXIgcGFzc3dvcmQgaGFzIGV4cGlyZWQuIFBsZWFzZSByZXNldCB5b3VyIHBhc3N3b3JkLidcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgcmVxLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdChyZXEuY29uZmlnLCB1c2VyKTtcblxuICAgIC8vIEJlZm9yZSBsb2dpbiB0cmlnZ2VyOyB0aHJvd3MgaWYgZmFpbHVyZVxuICAgIGF3YWl0IG1heWJlUnVuVHJpZ2dlcihcbiAgICAgIFRyaWdnZXJUeXBlcy5iZWZvcmVMb2dpbixcbiAgICAgIHJlcS5hdXRoLFxuICAgICAgUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKSxcbiAgICAgIG51bGwsXG4gICAgICByZXEuY29uZmlnXG4gICAgKTtcblxuICAgIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IEF1dGguY3JlYXRlU2Vzc2lvbihyZXEuY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIub2JqZWN0SWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICdsb2dpbicsXG4gICAgICAgIGF1dGhQcm92aWRlcjogJ3Bhc3N3b3JkJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25EYXRhLnNlc3Npb25Ub2tlbjtcblxuICAgIGF3YWl0IGNyZWF0ZVNlc3Npb24oKTtcblxuICAgIGNvbnN0IGFmdGVyTG9naW5Vc2VyID0gUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKTtcbiAgICBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYWZ0ZXJMb2dpbixcbiAgICAgIHsgLi4ucmVxLmF1dGgsIHVzZXI6IGFmdGVyTG9naW5Vc2VyIH0sXG4gICAgICBhZnRlckxvZ2luVXNlcixcbiAgICAgIG51bGwsXG4gICAgICByZXEuY29uZmlnXG4gICAgKTtcblxuICAgIHJldHVybiB7IHJlc3BvbnNlOiB1c2VyIH07XG4gIH1cblxuICBoYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSlcbiAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG5cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlTG9nT3V0KHJlcSkge1xuICAgIGNvbnN0IHN1Y2Nlc3MgPSB7IHJlc3BvbnNlOiB7fSB9O1xuICAgIGlmIChyZXEuaW5mbyAmJiByZXEuaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHJldHVybiByZXN0XG4gICAgICAgIC5maW5kKFxuICAgICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICAgJ19TZXNzaW9uJyxcbiAgICAgICAgICB7IHNlc3Npb25Ub2tlbjogcmVxLmluZm8uc2Vzc2lvblRva2VuIH0sXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICAgIClcbiAgICAgICAgLnRoZW4ocmVjb3JkcyA9PiB7XG4gICAgICAgICAgaWYgKHJlY29yZHMucmVzdWx0cyAmJiByZWNvcmRzLnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdFxuICAgICAgICAgICAgICAuZGVsKFxuICAgICAgICAgICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgICAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICAgICAgICAgJ19TZXNzaW9uJyxcbiAgICAgICAgICAgICAgICByZWNvcmRzLnJlc3VsdHNbMF0ub2JqZWN0SWQsXG4gICAgICAgICAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ydW5BZnRlckxvZ291dFRyaWdnZXIocmVxLCByZWNvcmRzLnJlc3VsdHNbMF0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc3VjY2Vzcyk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHN1Y2Nlc3MpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzdWNjZXNzKTtcbiAgfVxuXG4gIF9ydW5BZnRlckxvZ291dFRyaWdnZXIocmVxLCBzZXNzaW9uKSB7XG4gICAgLy8gQWZ0ZXIgbG9nb3V0IHRyaWdnZXJcbiAgICBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYWZ0ZXJMb2dvdXQsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIFBhcnNlLlNlc3Npb24uZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19TZXNzaW9uJyB9LCBzZXNzaW9uKSksXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG4gIH1cblxuICBfdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSkge1xuICAgIHRyeSB7XG4gICAgICBDb25maWcudmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgICAgICBlbWFpbEFkYXB0ZXI6IHJlcS5jb25maWcudXNlckNvbnRyb2xsZXIuYWRhcHRlcixcbiAgICAgICAgYXBwTmFtZTogcmVxLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBwdWJsaWNTZXJ2ZXJVUkw6IHJlcS5jb25maWcucHVibGljU2VydmVyVVJMLFxuICAgICAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjogcmVxLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmICh0eXBlb2YgZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gTWF5YmUgd2UgbmVlZCBhIEJhZCBDb25maWd1cmF0aW9uIGVycm9yLCBidXQgdGhlIFNES3Mgd29uJ3QgdW5kZXJzdGFuZCBpdC4gRm9yIG5vdywgSW50ZXJuYWwgU2VydmVyIEVycm9yLlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdBbiBhcHBOYW1lLCBwdWJsaWNTZXJ2ZXJVUkwsIGFuZCBlbWFpbEFkYXB0ZXIgYXJlIHJlcXVpcmVkIGZvciBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uIGZ1bmN0aW9uYWxpdHkuJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVSZXNldFJlcXVlc3QocmVxKSB7XG4gICAgdGhpcy5fdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSk7XG5cbiAgICBjb25zdCB7IGVtYWlsIH0gPSByZXEuYm9keTtcbiAgICBpZiAoIWVtYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTUlTU0lORywgJ3lvdSBtdXN0IHByb3ZpZGUgYW4gZW1haWwnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLFxuICAgICAgICAneW91IG11c3QgcHJvdmlkZSBhIHZhbGlkIGVtYWlsIHN0cmluZydcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlcjtcbiAgICByZXR1cm4gdXNlckNvbnRyb2xsZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAvLyBSZXR1cm4gc3VjY2VzcyBzbyB0aGF0IHRoaXMgZW5kcG9pbnQgY2FuJ3RcbiAgICAgICAgICAvLyBiZSB1c2VkIHRvIGVudW1lcmF0ZSB2YWxpZCBlbWFpbHNcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsICd5b3UgbXVzdCBwcm92aWRlIGFuIGVtYWlsJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUyxcbiAgICAgICAgJ3lvdSBtdXN0IHByb3ZpZGUgYSB2YWxpZCBlbWFpbCBzdHJpbmcnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBlbWFpbDogZW1haWwgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGggfHwgcmVzdWx0cy5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsIGBObyB1c2VyIGZvdW5kIHdpdGggZW1haWwgJHtlbWFpbH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuXG4gICAgICAvLyByZW1vdmUgcGFzc3dvcmQgZmllbGQsIG1lc3NlcyB3aXRoIHNhdmluZyBvbiBwb3N0Z3Jlc1xuICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgIGlmICh1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCBgRW1haWwgJHtlbWFpbH0gaXMgYWxyZWFkeSB2ZXJpZmllZC5gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgICAgcmV0dXJuIHVzZXJDb250cm9sbGVyLnJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKHVzZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICB1c2VyQ29udHJvbGxlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcik7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvdXNlcnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvdXNlcnMvOm9iamVjdElkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvbG9naW4nLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9sb2dpbicsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dJbihyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ291dCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dPdXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yZXF1ZXN0UGFzc3dvcmRSZXNldCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldFJlcXVlc3QocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92ZXJpZmljYXRpb25FbWFpbFJlcXVlc3QnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy92ZXJpZnlQYXNzd29yZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/StatusHandler.js b/lib/StatusHandler.js new file mode 100644 index 0000000000..708d04b1b0 --- /dev/null +++ b/lib/StatusHandler.js @@ -0,0 +1,386 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.flatten = flatten; +exports.jobStatusHandler = jobStatusHandler; +exports.pushStatusHandler = pushStatusHandler; + +var _cryptoUtils = require("./cryptoUtils"); + +var _logger = require("./logger"); + +var _rest = _interopRequireDefault(require("./rest")); + +var _Auth = _interopRequireDefault(require("./Auth")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PUSH_STATUS_COLLECTION = '_PushStatus'; +const JOB_STATUS_COLLECTION = '_JobStatus'; + +const incrementOp = function (object = {}, key, amount = 1) { + if (!object[key]) { + object[key] = { + __op: 'Increment', + amount: amount + }; + } else { + object[key].amount += amount; + } + + return object[key]; +}; + +function flatten(array) { + var flattened = []; + + for (var i = 0; i < array.length; i++) { + if (Array.isArray(array[i])) { + flattened = flattened.concat(flatten(array[i])); + } else { + flattened.push(array[i]); + } + } + + return flattened; +} + +function statusHandler(className, database) { + let lastPromise = Promise.resolve(); + + function create(object) { + lastPromise = lastPromise.then(() => { + return database.create(className, object).then(() => { + return Promise.resolve(object); + }); + }); + return lastPromise; + } + + function update(where, object) { + lastPromise = lastPromise.then(() => { + return database.update(className, where, object); + }); + return lastPromise; + } + + return Object.freeze({ + create, + update + }); +} + +function restStatusHandler(className, config) { + let lastPromise = Promise.resolve(); + + const auth = _Auth.default.master(config); + + function create(object) { + lastPromise = lastPromise.then(() => { + return _rest.default.create(config, auth, className, object).then(({ + response + }) => { + // merge the objects + return Promise.resolve(Object.assign({}, object, response)); + }); + }); + return lastPromise; + } + + function update(where, object) { + // TODO: when we have updateWhere, use that for proper interfacing + lastPromise = lastPromise.then(() => { + return _rest.default.update(config, auth, className, { + objectId: where.objectId + }, object).then(({ + response + }) => { + // merge the objects + return Promise.resolve(Object.assign({}, object, response)); + }); + }); + return lastPromise; + } + + return Object.freeze({ + create, + update + }); +} + +function jobStatusHandler(config) { + let jobStatus; + const objectId = (0, _cryptoUtils.newObjectId)(config.objectIdSize); + const database = config.database; + const handler = statusHandler(JOB_STATUS_COLLECTION, database); + + const setRunning = function (jobName, params) { + const now = new Date(); + jobStatus = { + objectId, + jobName, + params, + status: 'running', + source: 'api', + createdAt: now, + // lockdown! + ACL: {} + }; + return handler.create(jobStatus); + }; + + const setMessage = function (message) { + if (!message || typeof message !== 'string') { + return Promise.resolve(); + } + + return handler.update({ + objectId + }, { + message + }); + }; + + const setSucceeded = function (message) { + return setFinalStatus('succeeded', message); + }; + + const setFailed = function (message) { + return setFinalStatus('failed', message); + }; + + const setFinalStatus = function (status, message = undefined) { + const finishedAt = new Date(); + const update = { + status, + finishedAt + }; + + if (message && typeof message === 'string') { + update.message = message; + } + + if (message instanceof Error && typeof message.message === 'string') { + update.message = message.message; + } + + return handler.update({ + objectId + }, update); + }; + + return Object.freeze({ + setRunning, + setSucceeded, + setMessage, + setFailed + }); +} + +function pushStatusHandler(config, existingObjectId) { + let pushStatus; + const database = config.database; + const handler = restStatusHandler(PUSH_STATUS_COLLECTION, config); + let objectId = existingObjectId; + + const setInitial = function (body = {}, where, options = { + source: 'rest' + }) { + const now = new Date(); + let pushTime = now.toISOString(); + let status = 'pending'; + + if (Object.prototype.hasOwnProperty.call(body, 'push_time')) { + if (config.hasPushScheduledSupport) { + pushTime = body.push_time; + status = 'scheduled'; + } else { + _logger.logger.warn('Trying to schedule a push while server is not configured.'); + + _logger.logger.warn('Push will be sent immediately'); + } + } + + const data = body.data || {}; + const payloadString = JSON.stringify(data); + let pushHash; + + if (typeof data.alert === 'string') { + pushHash = (0, _cryptoUtils.md5Hash)(data.alert); + } else if (typeof data.alert === 'object') { + pushHash = (0, _cryptoUtils.md5Hash)(JSON.stringify(data.alert)); + } else { + pushHash = 'd41d8cd98f00b204e9800998ecf8427e'; + } + + const object = { + pushTime, + query: JSON.stringify(where), + payload: payloadString, + source: options.source, + title: options.title, + expiry: body.expiration_time, + expiration_interval: body.expiration_interval, + status: status, + numSent: 0, + pushHash, + // lockdown! + ACL: {} + }; + return handler.create(object).then(result => { + objectId = result.objectId; + pushStatus = { + objectId + }; + return Promise.resolve(pushStatus); + }); + }; + + const setRunning = function (batches) { + _logger.logger.verbose(`_PushStatus ${objectId}: sending push to installations with %d batches`, batches); + + return handler.update({ + status: 'pending', + objectId: objectId + }, { + status: 'running', + count: batches + }); + }; + + const trackSent = function (results, UTCOffset, cleanupInstallations = process.env.PARSE_SERVER_CLEANUP_INVALID_INSTALLATIONS) { + const update = { + numSent: 0, + numFailed: 0 + }; + const devicesToRemove = []; + + if (Array.isArray(results)) { + results = flatten(results); + results.reduce((memo, result) => { + // Cannot handle that + if (!result || !result.device || !result.device.deviceType) { + return memo; + } + + const deviceType = result.device.deviceType; + const key = result.transmitted ? `sentPerType.${deviceType}` : `failedPerType.${deviceType}`; + memo[key] = incrementOp(memo, key); + + if (typeof UTCOffset !== 'undefined') { + const offsetKey = result.transmitted ? `sentPerUTCOffset.${UTCOffset}` : `failedPerUTCOffset.${UTCOffset}`; + memo[offsetKey] = incrementOp(memo, offsetKey); + } + + if (result.transmitted) { + memo.numSent++; + } else { + if (result && result.response && result.response.error && result.device && result.device.deviceToken) { + const token = result.device.deviceToken; + const error = result.response.error; // GCM errors + + if (error === 'NotRegistered' || error === 'InvalidRegistration') { + devicesToRemove.push(token); + } // APNS errors + + + if (error === 'Unregistered' || error === 'BadDeviceToken') { + devicesToRemove.push(token); + } + } + + memo.numFailed++; + } + + return memo; + }, update); + } + + _logger.logger.verbose(`_PushStatus ${objectId}: sent push! %d success, %d failures`, update.numSent, update.numFailed); + + _logger.logger.verbose(`_PushStatus ${objectId}: needs cleanup`, { + devicesToRemove + }); + + ['numSent', 'numFailed'].forEach(key => { + if (update[key] > 0) { + update[key] = { + __op: 'Increment', + amount: update[key] + }; + } else { + delete update[key]; + } + }); + + if (devicesToRemove.length > 0 && cleanupInstallations) { + _logger.logger.info(`Removing device tokens on ${devicesToRemove.length} _Installations`); + + database.update('_Installation', { + deviceToken: { + $in: devicesToRemove + } + }, { + deviceToken: { + __op: 'Delete' + } + }, { + acl: undefined, + many: true + }); + } // indicate this batch is complete + + + incrementOp(update, 'count', -1); + return handler.update({ + objectId + }, update).then(res => { + if (res && res.count === 0) { + return this.complete(); + } + }); + }; + + const complete = function () { + return handler.update({ + objectId + }, { + status: 'succeeded', + count: { + __op: 'Delete' + } + }); + }; + + const fail = function (err) { + if (typeof err === 'string') { + err = { + message: err + }; + } + + const update = { + errorMessage: err, + status: 'failed' + }; + return handler.update({ + objectId + }, update); + }; + + const rval = { + setInitial, + setRunning, + trackSent, + complete, + fail + }; // define objectId to be dynamic + + Object.defineProperty(rval, 'objectId', { + get: () => objectId + }); + return Object.freeze(rval); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TdGF0dXNIYW5kbGVyLmpzIl0sIm5hbWVzIjpbIlBVU0hfU1RBVFVTX0NPTExFQ1RJT04iLCJKT0JfU1RBVFVTX0NPTExFQ1RJT04iLCJpbmNyZW1lbnRPcCIsIm9iamVjdCIsImtleSIsImFtb3VudCIsIl9fb3AiLCJmbGF0dGVuIiwiYXJyYXkiLCJmbGF0dGVuZWQiLCJpIiwibGVuZ3RoIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uY2F0IiwicHVzaCIsInN0YXR1c0hhbmRsZXIiLCJjbGFzc05hbWUiLCJkYXRhYmFzZSIsImxhc3RQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjcmVhdGUiLCJ0aGVuIiwidXBkYXRlIiwid2hlcmUiLCJPYmplY3QiLCJmcmVlemUiLCJyZXN0U3RhdHVzSGFuZGxlciIsImNvbmZpZyIsImF1dGgiLCJBdXRoIiwibWFzdGVyIiwicmVzdCIsInJlc3BvbnNlIiwiYXNzaWduIiwib2JqZWN0SWQiLCJqb2JTdGF0dXNIYW5kbGVyIiwiam9iU3RhdHVzIiwib2JqZWN0SWRTaXplIiwiaGFuZGxlciIsInNldFJ1bm5pbmciLCJqb2JOYW1lIiwicGFyYW1zIiwibm93IiwiRGF0ZSIsInN0YXR1cyIsInNvdXJjZSIsImNyZWF0ZWRBdCIsIkFDTCIsInNldE1lc3NhZ2UiLCJtZXNzYWdlIiwic2V0U3VjY2VlZGVkIiwic2V0RmluYWxTdGF0dXMiLCJzZXRGYWlsZWQiLCJ1bmRlZmluZWQiLCJmaW5pc2hlZEF0IiwiRXJyb3IiLCJwdXNoU3RhdHVzSGFuZGxlciIsImV4aXN0aW5nT2JqZWN0SWQiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsImJvZHkiLCJvcHRpb25zIiwicHVzaFRpbWUiLCJ0b0lTT1N0cmluZyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwicHVzaF90aW1lIiwibG9nZ2VyIiwid2FybiIsImRhdGEiLCJwYXlsb2FkU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1c2hIYXNoIiwiYWxlcnQiLCJxdWVyeSIsInBheWxvYWQiLCJ0aXRsZSIsImV4cGlyeSIsImV4cGlyYXRpb25fdGltZSIsImV4cGlyYXRpb25faW50ZXJ2YWwiLCJudW1TZW50IiwicmVzdWx0IiwiYmF0Y2hlcyIsInZlcmJvc2UiLCJjb3VudCIsInRyYWNrU2VudCIsInJlc3VsdHMiLCJVVENPZmZzZXQiLCJjbGVhbnVwSW5zdGFsbGF0aW9ucyIsInByb2Nlc3MiLCJlbnYiLCJQQVJTRV9TRVJWRVJfQ0xFQU5VUF9JTlZBTElEX0lOU1RBTExBVElPTlMiLCJudW1GYWlsZWQiLCJkZXZpY2VzVG9SZW1vdmUiLCJyZWR1Y2UiLCJtZW1vIiwiZGV2aWNlIiwiZGV2aWNlVHlwZSIsInRyYW5zbWl0dGVkIiwib2Zmc2V0S2V5IiwiZXJyb3IiLCJkZXZpY2VUb2tlbiIsInRva2VuIiwiZm9yRWFjaCIsImluZm8iLCIkaW4iLCJhY2wiLCJtYW55IiwicmVzIiwiY29tcGxldGUiLCJmYWlsIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicnZhbCIsImRlZmluZVByb3BlcnR5IiwiZ2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHNCQUFzQixHQUFHLGFBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsWUFBOUI7O0FBRUEsTUFBTUMsV0FBVyxHQUFHLFVBQVVDLE1BQU0sR0FBRyxFQUFuQixFQUF1QkMsR0FBdkIsRUFBNEJDLE1BQU0sR0FBRyxDQUFyQyxFQUF3QztBQUMxRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0MsR0FBRCxDQUFYLEVBQWtCO0FBQ2hCRCxJQUFBQSxNQUFNLENBQUNDLEdBQUQsQ0FBTixHQUFjO0FBQUVFLE1BQUFBLElBQUksRUFBRSxXQUFSO0FBQXFCRCxNQUFBQSxNQUFNLEVBQUVBO0FBQTdCLEtBQWQ7QUFDRCxHQUZELE1BRU87QUFDTEYsSUFBQUEsTUFBTSxDQUFDQyxHQUFELENBQU4sQ0FBWUMsTUFBWixJQUFzQkEsTUFBdEI7QUFDRDs7QUFDRCxTQUFPRixNQUFNLENBQUNDLEdBQUQsQ0FBYjtBQUNELENBUEQ7O0FBU08sU0FBU0csT0FBVCxDQUFpQkMsS0FBakIsRUFBd0I7QUFDN0IsTUFBSUMsU0FBUyxHQUFHLEVBQWhCOztBQUNBLE9BQUssSUFBSUMsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0YsS0FBSyxDQUFDRyxNQUExQixFQUFrQ0QsQ0FBQyxFQUFuQyxFQUF1QztBQUNyQyxRQUFJRSxLQUFLLENBQUNDLE9BQU4sQ0FBY0wsS0FBSyxDQUFDRSxDQUFELENBQW5CLENBQUosRUFBNkI7QUFDM0JELE1BQUFBLFNBQVMsR0FBR0EsU0FBUyxDQUFDSyxNQUFWLENBQWlCUCxPQUFPLENBQUNDLEtBQUssQ0FBQ0UsQ0FBRCxDQUFOLENBQXhCLENBQVo7QUFDRCxLQUZELE1BRU87QUFDTEQsTUFBQUEsU0FBUyxDQUFDTSxJQUFWLENBQWVQLEtBQUssQ0FBQ0UsQ0FBRCxDQUFwQjtBQUNEO0FBQ0Y7O0FBQ0QsU0FBT0QsU0FBUDtBQUNEOztBQUVELFNBQVNPLGFBQVQsQ0FBdUJDLFNBQXZCLEVBQWtDQyxRQUFsQyxFQUE0QztBQUMxQyxNQUFJQyxXQUFXLEdBQUdDLE9BQU8sQ0FBQ0MsT0FBUixFQUFsQjs7QUFFQSxXQUFTQyxNQUFULENBQWdCbkIsTUFBaEIsRUFBd0I7QUFDdEJnQixJQUFBQSxXQUFXLEdBQUdBLFdBQVcsQ0FBQ0ksSUFBWixDQUFpQixNQUFNO0FBQ25DLGFBQU9MLFFBQVEsQ0FBQ0ksTUFBVCxDQUFnQkwsU0FBaEIsRUFBMkJkLE1BQTNCLEVBQW1Db0IsSUFBbkMsQ0FBd0MsTUFBTTtBQUNuRCxlQUFPSCxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JsQixNQUFoQixDQUFQO0FBQ0QsT0FGTSxDQUFQO0FBR0QsS0FKYSxDQUFkO0FBS0EsV0FBT2dCLFdBQVA7QUFDRDs7QUFFRCxXQUFTSyxNQUFULENBQWdCQyxLQUFoQixFQUF1QnRCLE1BQXZCLEVBQStCO0FBQzdCZ0IsSUFBQUEsV0FBVyxHQUFHQSxXQUFXLENBQUNJLElBQVosQ0FBaUIsTUFBTTtBQUNuQyxhQUFPTCxRQUFRLENBQUNNLE1BQVQsQ0FBZ0JQLFNBQWhCLEVBQTJCUSxLQUEzQixFQUFrQ3RCLE1BQWxDLENBQVA7QUFDRCxLQUZhLENBQWQ7QUFHQSxXQUFPZ0IsV0FBUDtBQUNEOztBQUVELFNBQU9PLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjO0FBQ25CTCxJQUFBQSxNQURtQjtBQUVuQkUsSUFBQUE7QUFGbUIsR0FBZCxDQUFQO0FBSUQ7O0FBRUQsU0FBU0ksaUJBQVQsQ0FBMkJYLFNBQTNCLEVBQXNDWSxNQUF0QyxFQUE4QztBQUM1QyxNQUFJVixXQUFXLEdBQUdDLE9BQU8sQ0FBQ0MsT0FBUixFQUFsQjs7QUFDQSxRQUFNUyxJQUFJLEdBQUdDLGNBQUtDLE1BQUwsQ0FBWUgsTUFBWixDQUFiOztBQUNBLFdBQVNQLE1BQVQsQ0FBZ0JuQixNQUFoQixFQUF3QjtBQUN0QmdCLElBQUFBLFdBQVcsR0FBR0EsV0FBVyxDQUFDSSxJQUFaLENBQWlCLE1BQU07QUFDbkMsYUFBT1UsY0FBS1gsTUFBTCxDQUFZTyxNQUFaLEVBQW9CQyxJQUFwQixFQUEwQmIsU0FBMUIsRUFBcUNkLE1BQXJDLEVBQTZDb0IsSUFBN0MsQ0FBa0QsQ0FBQztBQUFFVyxRQUFBQTtBQUFGLE9BQUQsS0FBa0I7QUFDekU7QUFDQSxlQUFPZCxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JLLE1BQU0sQ0FBQ1MsTUFBUCxDQUFjLEVBQWQsRUFBa0JoQyxNQUFsQixFQUEwQitCLFFBQTFCLENBQWhCLENBQVA7QUFDRCxPQUhNLENBQVA7QUFJRCxLQUxhLENBQWQ7QUFNQSxXQUFPZixXQUFQO0FBQ0Q7O0FBRUQsV0FBU0ssTUFBVCxDQUFnQkMsS0FBaEIsRUFBdUJ0QixNQUF2QixFQUErQjtBQUM3QjtBQUNBZ0IsSUFBQUEsV0FBVyxHQUFHQSxXQUFXLENBQUNJLElBQVosQ0FBaUIsTUFBTTtBQUNuQyxhQUFPVSxjQUNKVCxNQURJLENBQ0dLLE1BREgsRUFDV0MsSUFEWCxFQUNpQmIsU0FEakIsRUFDNEI7QUFBRW1CLFFBQUFBLFFBQVEsRUFBRVgsS0FBSyxDQUFDVztBQUFsQixPQUQ1QixFQUMwRGpDLE1BRDFELEVBRUpvQixJQUZJLENBRUMsQ0FBQztBQUFFVyxRQUFBQTtBQUFGLE9BQUQsS0FBa0I7QUFDdEI7QUFDQSxlQUFPZCxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JLLE1BQU0sQ0FBQ1MsTUFBUCxDQUFjLEVBQWQsRUFBa0JoQyxNQUFsQixFQUEwQitCLFFBQTFCLENBQWhCLENBQVA7QUFDRCxPQUxJLENBQVA7QUFNRCxLQVBhLENBQWQ7QUFRQSxXQUFPZixXQUFQO0FBQ0Q7O0FBRUQsU0FBT08sTUFBTSxDQUFDQyxNQUFQLENBQWM7QUFDbkJMLElBQUFBLE1BRG1CO0FBRW5CRSxJQUFBQTtBQUZtQixHQUFkLENBQVA7QUFJRDs7QUFFTSxTQUFTYSxnQkFBVCxDQUEwQlIsTUFBMUIsRUFBa0M7QUFDdkMsTUFBSVMsU0FBSjtBQUNBLFFBQU1GLFFBQVEsR0FBRyw4QkFBWVAsTUFBTSxDQUFDVSxZQUFuQixDQUFqQjtBQUNBLFFBQU1yQixRQUFRLEdBQUdXLE1BQU0sQ0FBQ1gsUUFBeEI7QUFDQSxRQUFNc0IsT0FBTyxHQUFHeEIsYUFBYSxDQUFDZixxQkFBRCxFQUF3QmlCLFFBQXhCLENBQTdCOztBQUNBLFFBQU11QixVQUFVLEdBQUcsVUFBVUMsT0FBVixFQUFtQkMsTUFBbkIsRUFBMkI7QUFDNUMsVUFBTUMsR0FBRyxHQUFHLElBQUlDLElBQUosRUFBWjtBQUNBUCxJQUFBQSxTQUFTLEdBQUc7QUFDVkYsTUFBQUEsUUFEVTtBQUVWTSxNQUFBQSxPQUZVO0FBR1ZDLE1BQUFBLE1BSFU7QUFJVkcsTUFBQUEsTUFBTSxFQUFFLFNBSkU7QUFLVkMsTUFBQUEsTUFBTSxFQUFFLEtBTEU7QUFNVkMsTUFBQUEsU0FBUyxFQUFFSixHQU5EO0FBT1Y7QUFDQUssTUFBQUEsR0FBRyxFQUFFO0FBUkssS0FBWjtBQVdBLFdBQU9ULE9BQU8sQ0FBQ2xCLE1BQVIsQ0FBZWdCLFNBQWYsQ0FBUDtBQUNELEdBZEQ7O0FBZ0JBLFFBQU1ZLFVBQVUsR0FBRyxVQUFVQyxPQUFWLEVBQW1CO0FBQ3BDLFFBQUksQ0FBQ0EsT0FBRCxJQUFZLE9BQU9BLE9BQVAsS0FBbUIsUUFBbkMsRUFBNkM7QUFDM0MsYUFBTy9CLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBQ0QsV0FBT21CLE9BQU8sQ0FBQ2hCLE1BQVIsQ0FBZTtBQUFFWSxNQUFBQTtBQUFGLEtBQWYsRUFBNkI7QUFBRWUsTUFBQUE7QUFBRixLQUE3QixDQUFQO0FBQ0QsR0FMRDs7QUFPQSxRQUFNQyxZQUFZLEdBQUcsVUFBVUQsT0FBVixFQUFtQjtBQUN0QyxXQUFPRSxjQUFjLENBQUMsV0FBRCxFQUFjRixPQUFkLENBQXJCO0FBQ0QsR0FGRDs7QUFJQSxRQUFNRyxTQUFTLEdBQUcsVUFBVUgsT0FBVixFQUFtQjtBQUNuQyxXQUFPRSxjQUFjLENBQUMsUUFBRCxFQUFXRixPQUFYLENBQXJCO0FBQ0QsR0FGRDs7QUFJQSxRQUFNRSxjQUFjLEdBQUcsVUFBVVAsTUFBVixFQUFrQkssT0FBTyxHQUFHSSxTQUE1QixFQUF1QztBQUM1RCxVQUFNQyxVQUFVLEdBQUcsSUFBSVgsSUFBSixFQUFuQjtBQUNBLFVBQU1yQixNQUFNLEdBQUc7QUFBRXNCLE1BQUFBLE1BQUY7QUFBVVUsTUFBQUE7QUFBVixLQUFmOztBQUNBLFFBQUlMLE9BQU8sSUFBSSxPQUFPQSxPQUFQLEtBQW1CLFFBQWxDLEVBQTRDO0FBQzFDM0IsTUFBQUEsTUFBTSxDQUFDMkIsT0FBUCxHQUFpQkEsT0FBakI7QUFDRDs7QUFDRCxRQUFJQSxPQUFPLFlBQVlNLEtBQW5CLElBQTRCLE9BQU9OLE9BQU8sQ0FBQ0EsT0FBZixLQUEyQixRQUEzRCxFQUFxRTtBQUNuRTNCLE1BQUFBLE1BQU0sQ0FBQzJCLE9BQVAsR0FBaUJBLE9BQU8sQ0FBQ0EsT0FBekI7QUFDRDs7QUFDRCxXQUFPWCxPQUFPLENBQUNoQixNQUFSLENBQWU7QUFBRVksTUFBQUE7QUFBRixLQUFmLEVBQTZCWixNQUE3QixDQUFQO0FBQ0QsR0FWRDs7QUFZQSxTQUFPRSxNQUFNLENBQUNDLE1BQVAsQ0FBYztBQUNuQmMsSUFBQUEsVUFEbUI7QUFFbkJXLElBQUFBLFlBRm1CO0FBR25CRixJQUFBQSxVQUhtQjtBQUluQkksSUFBQUE7QUFKbUIsR0FBZCxDQUFQO0FBTUQ7O0FBRU0sU0FBU0ksaUJBQVQsQ0FBMkI3QixNQUEzQixFQUFtQzhCLGdCQUFuQyxFQUFxRDtBQUMxRCxNQUFJQyxVQUFKO0FBQ0EsUUFBTTFDLFFBQVEsR0FBR1csTUFBTSxDQUFDWCxRQUF4QjtBQUNBLFFBQU1zQixPQUFPLEdBQUdaLGlCQUFpQixDQUFDNUIsc0JBQUQsRUFBeUI2QixNQUF6QixDQUFqQztBQUNBLE1BQUlPLFFBQVEsR0FBR3VCLGdCQUFmOztBQUNBLFFBQU1FLFVBQVUsR0FBRyxVQUFVQyxJQUFJLEdBQUcsRUFBakIsRUFBcUJyQyxLQUFyQixFQUE0QnNDLE9BQU8sR0FBRztBQUFFaEIsSUFBQUEsTUFBTSxFQUFFO0FBQVYsR0FBdEMsRUFBMEQ7QUFDM0UsVUFBTUgsR0FBRyxHQUFHLElBQUlDLElBQUosRUFBWjtBQUNBLFFBQUltQixRQUFRLEdBQUdwQixHQUFHLENBQUNxQixXQUFKLEVBQWY7QUFDQSxRQUFJbkIsTUFBTSxHQUFHLFNBQWI7O0FBQ0EsUUFBSXBCLE1BQU0sQ0FBQ3dDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ04sSUFBckMsRUFBMkMsV0FBM0MsQ0FBSixFQUE2RDtBQUMzRCxVQUFJakMsTUFBTSxDQUFDd0MsdUJBQVgsRUFBb0M7QUFDbENMLFFBQUFBLFFBQVEsR0FBR0YsSUFBSSxDQUFDUSxTQUFoQjtBQUNBeEIsUUFBQUEsTUFBTSxHQUFHLFdBQVQ7QUFDRCxPQUhELE1BR087QUFDTHlCLHVCQUFPQyxJQUFQLENBQVksMkRBQVo7O0FBQ0FELHVCQUFPQyxJQUFQLENBQVksK0JBQVo7QUFDRDtBQUNGOztBQUVELFVBQU1DLElBQUksR0FBR1gsSUFBSSxDQUFDVyxJQUFMLElBQWEsRUFBMUI7QUFDQSxVQUFNQyxhQUFhLEdBQUdDLElBQUksQ0FBQ0MsU0FBTCxDQUFlSCxJQUFmLENBQXRCO0FBQ0EsUUFBSUksUUFBSjs7QUFDQSxRQUFJLE9BQU9KLElBQUksQ0FBQ0ssS0FBWixLQUFzQixRQUExQixFQUFvQztBQUNsQ0QsTUFBQUEsUUFBUSxHQUFHLDBCQUFRSixJQUFJLENBQUNLLEtBQWIsQ0FBWDtBQUNELEtBRkQsTUFFTyxJQUFJLE9BQU9MLElBQUksQ0FBQ0ssS0FBWixLQUFzQixRQUExQixFQUFvQztBQUN6Q0QsTUFBQUEsUUFBUSxHQUFHLDBCQUFRRixJQUFJLENBQUNDLFNBQUwsQ0FBZUgsSUFBSSxDQUFDSyxLQUFwQixDQUFSLENBQVg7QUFDRCxLQUZNLE1BRUE7QUFDTEQsTUFBQUEsUUFBUSxHQUFHLGtDQUFYO0FBQ0Q7O0FBQ0QsVUFBTTFFLE1BQU0sR0FBRztBQUNiNkQsTUFBQUEsUUFEYTtBQUViZSxNQUFBQSxLQUFLLEVBQUVKLElBQUksQ0FBQ0MsU0FBTCxDQUFlbkQsS0FBZixDQUZNO0FBR2J1RCxNQUFBQSxPQUFPLEVBQUVOLGFBSEk7QUFJYjNCLE1BQUFBLE1BQU0sRUFBRWdCLE9BQU8sQ0FBQ2hCLE1BSkg7QUFLYmtDLE1BQUFBLEtBQUssRUFBRWxCLE9BQU8sQ0FBQ2tCLEtBTEY7QUFNYkMsTUFBQUEsTUFBTSxFQUFFcEIsSUFBSSxDQUFDcUIsZUFOQTtBQU9iQyxNQUFBQSxtQkFBbUIsRUFBRXRCLElBQUksQ0FBQ3NCLG1CQVBiO0FBUWJ0QyxNQUFBQSxNQUFNLEVBQUVBLE1BUks7QUFTYnVDLE1BQUFBLE9BQU8sRUFBRSxDQVRJO0FBVWJSLE1BQUFBLFFBVmE7QUFXYjtBQUNBNUIsTUFBQUEsR0FBRyxFQUFFO0FBWlEsS0FBZjtBQWNBLFdBQU9ULE9BQU8sQ0FBQ2xCLE1BQVIsQ0FBZW5CLE1BQWYsRUFBdUJvQixJQUF2QixDQUE0QitELE1BQU0sSUFBSTtBQUMzQ2xELE1BQUFBLFFBQVEsR0FBR2tELE1BQU0sQ0FBQ2xELFFBQWxCO0FBQ0F3QixNQUFBQSxVQUFVLEdBQUc7QUFDWHhCLFFBQUFBO0FBRFcsT0FBYjtBQUdBLGFBQU9oQixPQUFPLENBQUNDLE9BQVIsQ0FBZ0J1QyxVQUFoQixDQUFQO0FBQ0QsS0FOTSxDQUFQO0FBT0QsR0E3Q0Q7O0FBK0NBLFFBQU1uQixVQUFVLEdBQUcsVUFBVThDLE9BQVYsRUFBbUI7QUFDcENoQixtQkFBT2lCLE9BQVAsQ0FDRyxlQUFjcEQsUUFBUyxpREFEMUIsRUFFRW1ELE9BRkY7O0FBSUEsV0FBTy9DLE9BQU8sQ0FBQ2hCLE1BQVIsQ0FDTDtBQUNFc0IsTUFBQUEsTUFBTSxFQUFFLFNBRFY7QUFFRVYsTUFBQUEsUUFBUSxFQUFFQTtBQUZaLEtBREssRUFLTDtBQUNFVSxNQUFBQSxNQUFNLEVBQUUsU0FEVjtBQUVFMkMsTUFBQUEsS0FBSyxFQUFFRjtBQUZULEtBTEssQ0FBUDtBQVVELEdBZkQ7O0FBaUJBLFFBQU1HLFNBQVMsR0FBRyxVQUNoQkMsT0FEZ0IsRUFFaEJDLFNBRmdCLEVBR2hCQyxvQkFBb0IsR0FBR0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLDBDQUhuQixFQUloQjtBQUNBLFVBQU14RSxNQUFNLEdBQUc7QUFDYjZELE1BQUFBLE9BQU8sRUFBRSxDQURJO0FBRWJZLE1BQUFBLFNBQVMsRUFBRTtBQUZFLEtBQWY7QUFJQSxVQUFNQyxlQUFlLEdBQUcsRUFBeEI7O0FBQ0EsUUFBSXRGLEtBQUssQ0FBQ0MsT0FBTixDQUFjOEUsT0FBZCxDQUFKLEVBQTRCO0FBQzFCQSxNQUFBQSxPQUFPLEdBQUdwRixPQUFPLENBQUNvRixPQUFELENBQWpCO0FBQ0FBLE1BQUFBLE9BQU8sQ0FBQ1EsTUFBUixDQUFlLENBQUNDLElBQUQsRUFBT2QsTUFBUCxLQUFrQjtBQUMvQjtBQUNBLFlBQUksQ0FBQ0EsTUFBRCxJQUFXLENBQUNBLE1BQU0sQ0FBQ2UsTUFBbkIsSUFBNkIsQ0FBQ2YsTUFBTSxDQUFDZSxNQUFQLENBQWNDLFVBQWhELEVBQTREO0FBQzFELGlCQUFPRixJQUFQO0FBQ0Q7O0FBQ0QsY0FBTUUsVUFBVSxHQUFHaEIsTUFBTSxDQUFDZSxNQUFQLENBQWNDLFVBQWpDO0FBQ0EsY0FBTWxHLEdBQUcsR0FBR2tGLE1BQU0sQ0FBQ2lCLFdBQVAsR0FDUCxlQUFjRCxVQUFXLEVBRGxCLEdBRVAsaUJBQWdCQSxVQUFXLEVBRmhDO0FBR0FGLFFBQUFBLElBQUksQ0FBQ2hHLEdBQUQsQ0FBSixHQUFZRixXQUFXLENBQUNrRyxJQUFELEVBQU9oRyxHQUFQLENBQXZCOztBQUNBLFlBQUksT0FBT3dGLFNBQVAsS0FBcUIsV0FBekIsRUFBc0M7QUFDcEMsZ0JBQU1ZLFNBQVMsR0FBR2xCLE1BQU0sQ0FBQ2lCLFdBQVAsR0FDYixvQkFBbUJYLFNBQVUsRUFEaEIsR0FFYixzQkFBcUJBLFNBQVUsRUFGcEM7QUFHQVEsVUFBQUEsSUFBSSxDQUFDSSxTQUFELENBQUosR0FBa0J0RyxXQUFXLENBQUNrRyxJQUFELEVBQU9JLFNBQVAsQ0FBN0I7QUFDRDs7QUFDRCxZQUFJbEIsTUFBTSxDQUFDaUIsV0FBWCxFQUF3QjtBQUN0QkgsVUFBQUEsSUFBSSxDQUFDZixPQUFMO0FBQ0QsU0FGRCxNQUVPO0FBQ0wsY0FDRUMsTUFBTSxJQUNOQSxNQUFNLENBQUNwRCxRQURQLElBRUFvRCxNQUFNLENBQUNwRCxRQUFQLENBQWdCdUUsS0FGaEIsSUFHQW5CLE1BQU0sQ0FBQ2UsTUFIUCxJQUlBZixNQUFNLENBQUNlLE1BQVAsQ0FBY0ssV0FMaEIsRUFNRTtBQUNBLGtCQUFNQyxLQUFLLEdBQUdyQixNQUFNLENBQUNlLE1BQVAsQ0FBY0ssV0FBNUI7QUFDQSxrQkFBTUQsS0FBSyxHQUFHbkIsTUFBTSxDQUFDcEQsUUFBUCxDQUFnQnVFLEtBQTlCLENBRkEsQ0FHQTs7QUFDQSxnQkFBSUEsS0FBSyxLQUFLLGVBQVYsSUFBNkJBLEtBQUssS0FBSyxxQkFBM0MsRUFBa0U7QUFDaEVQLGNBQUFBLGVBQWUsQ0FBQ25GLElBQWhCLENBQXFCNEYsS0FBckI7QUFDRCxhQU5ELENBT0E7OztBQUNBLGdCQUFJRixLQUFLLEtBQUssY0FBVixJQUE0QkEsS0FBSyxLQUFLLGdCQUExQyxFQUE0RDtBQUMxRFAsY0FBQUEsZUFBZSxDQUFDbkYsSUFBaEIsQ0FBcUI0RixLQUFyQjtBQUNEO0FBQ0Y7O0FBQ0RQLFVBQUFBLElBQUksQ0FBQ0gsU0FBTDtBQUNEOztBQUNELGVBQU9HLElBQVA7QUFDRCxPQXhDRCxFQXdDRzVFLE1BeENIO0FBeUNEOztBQUVEK0MsbUJBQU9pQixPQUFQLENBQ0csZUFBY3BELFFBQVMsc0NBRDFCLEVBRUVaLE1BQU0sQ0FBQzZELE9BRlQsRUFHRTdELE1BQU0sQ0FBQ3lFLFNBSFQ7O0FBS0ExQixtQkFBT2lCLE9BQVAsQ0FBZ0IsZUFBY3BELFFBQVMsaUJBQXZDLEVBQXlEO0FBQ3ZEOEQsTUFBQUE7QUFEdUQsS0FBekQ7O0FBR0EsS0FBQyxTQUFELEVBQVksV0FBWixFQUF5QlUsT0FBekIsQ0FBaUN4RyxHQUFHLElBQUk7QUFDdEMsVUFBSW9CLE1BQU0sQ0FBQ3BCLEdBQUQsQ0FBTixHQUFjLENBQWxCLEVBQXFCO0FBQ25Cb0IsUUFBQUEsTUFBTSxDQUFDcEIsR0FBRCxDQUFOLEdBQWM7QUFDWkUsVUFBQUEsSUFBSSxFQUFFLFdBRE07QUFFWkQsVUFBQUEsTUFBTSxFQUFFbUIsTUFBTSxDQUFDcEIsR0FBRDtBQUZGLFNBQWQ7QUFJRCxPQUxELE1BS087QUFDTCxlQUFPb0IsTUFBTSxDQUFDcEIsR0FBRCxDQUFiO0FBQ0Q7QUFDRixLQVREOztBQVdBLFFBQUk4RixlQUFlLENBQUN2RixNQUFoQixHQUF5QixDQUF6QixJQUE4QmtGLG9CQUFsQyxFQUF3RDtBQUN0RHRCLHFCQUFPc0MsSUFBUCxDQUFhLDZCQUE0QlgsZUFBZSxDQUFDdkYsTUFBTyxpQkFBaEU7O0FBQ0FPLE1BQUFBLFFBQVEsQ0FBQ00sTUFBVCxDQUNFLGVBREYsRUFFRTtBQUFFa0YsUUFBQUEsV0FBVyxFQUFFO0FBQUVJLFVBQUFBLEdBQUcsRUFBRVo7QUFBUDtBQUFmLE9BRkYsRUFHRTtBQUFFUSxRQUFBQSxXQUFXLEVBQUU7QUFBRXBHLFVBQUFBLElBQUksRUFBRTtBQUFSO0FBQWYsT0FIRixFQUlFO0FBQ0V5RyxRQUFBQSxHQUFHLEVBQUV4RCxTQURQO0FBRUV5RCxRQUFBQSxJQUFJLEVBQUU7QUFGUixPQUpGO0FBU0QsS0FqRkQsQ0FtRkE7OztBQUNBOUcsSUFBQUEsV0FBVyxDQUFDc0IsTUFBRCxFQUFTLE9BQVQsRUFBa0IsQ0FBQyxDQUFuQixDQUFYO0FBRUEsV0FBT2dCLE9BQU8sQ0FBQ2hCLE1BQVIsQ0FBZTtBQUFFWSxNQUFBQTtBQUFGLEtBQWYsRUFBNkJaLE1BQTdCLEVBQXFDRCxJQUFyQyxDQUEwQzBGLEdBQUcsSUFBSTtBQUN0RCxVQUFJQSxHQUFHLElBQUlBLEdBQUcsQ0FBQ3hCLEtBQUosS0FBYyxDQUF6QixFQUE0QjtBQUMxQixlQUFPLEtBQUt5QixRQUFMLEVBQVA7QUFDRDtBQUNGLEtBSk0sQ0FBUDtBQUtELEdBL0ZEOztBQWlHQSxRQUFNQSxRQUFRLEdBQUcsWUFBWTtBQUMzQixXQUFPMUUsT0FBTyxDQUFDaEIsTUFBUixDQUNMO0FBQUVZLE1BQUFBO0FBQUYsS0FESyxFQUVMO0FBQ0VVLE1BQUFBLE1BQU0sRUFBRSxXQURWO0FBRUUyQyxNQUFBQSxLQUFLLEVBQUU7QUFBRW5GLFFBQUFBLElBQUksRUFBRTtBQUFSO0FBRlQsS0FGSyxDQUFQO0FBT0QsR0FSRDs7QUFVQSxRQUFNNkcsSUFBSSxHQUFHLFVBQVVDLEdBQVYsRUFBZTtBQUMxQixRQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUMzQkEsTUFBQUEsR0FBRyxHQUFHO0FBQUVqRSxRQUFBQSxPQUFPLEVBQUVpRTtBQUFYLE9BQU47QUFDRDs7QUFDRCxVQUFNNUYsTUFBTSxHQUFHO0FBQ2I2RixNQUFBQSxZQUFZLEVBQUVELEdBREQ7QUFFYnRFLE1BQUFBLE1BQU0sRUFBRTtBQUZLLEtBQWY7QUFJQSxXQUFPTixPQUFPLENBQUNoQixNQUFSLENBQWU7QUFBRVksTUFBQUE7QUFBRixLQUFmLEVBQTZCWixNQUE3QixDQUFQO0FBQ0QsR0FURDs7QUFXQSxRQUFNOEYsSUFBSSxHQUFHO0FBQ1h6RCxJQUFBQSxVQURXO0FBRVhwQixJQUFBQSxVQUZXO0FBR1hpRCxJQUFBQSxTQUhXO0FBSVh3QixJQUFBQSxRQUpXO0FBS1hDLElBQUFBO0FBTFcsR0FBYixDQTNMMEQsQ0FtTTFEOztBQUNBekYsRUFBQUEsTUFBTSxDQUFDNkYsY0FBUCxDQUFzQkQsSUFBdEIsRUFBNEIsVUFBNUIsRUFBd0M7QUFDdENFLElBQUFBLEdBQUcsRUFBRSxNQUFNcEY7QUFEMkIsR0FBeEM7QUFJQSxTQUFPVixNQUFNLENBQUNDLE1BQVAsQ0FBYzJGLElBQWQsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWQ1SGFzaCwgbmV3T2JqZWN0SWQgfSBmcm9tICcuL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuL0F1dGgnO1xuXG5jb25zdCBQVVNIX1NUQVRVU19DT0xMRUNUSU9OID0gJ19QdXNoU3RhdHVzJztcbmNvbnN0IEpPQl9TVEFUVVNfQ09MTEVDVElPTiA9ICdfSm9iU3RhdHVzJztcblxuY29uc3QgaW5jcmVtZW50T3AgPSBmdW5jdGlvbiAob2JqZWN0ID0ge30sIGtleSwgYW1vdW50ID0gMSkge1xuICBpZiAoIW9iamVjdFtrZXldKSB7XG4gICAgb2JqZWN0W2tleV0gPSB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGFtb3VudCB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldLmFtb3VudCArPSBhbW91bnQ7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFtrZXldO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHtcbiAgdmFyIGZsYXR0ZW5lZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlbaV0pKSB7XG4gICAgICBmbGF0dGVuZWQgPSBmbGF0dGVuZWQuY29uY2F0KGZsYXR0ZW4oYXJyYXlbaV0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkLnB1c2goYXJyYXlbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmxhdHRlbmVkO1xufVxuXG5mdW5jdGlvbiBzdGF0dXNIYW5kbGVyKGNsYXNzTmFtZSwgZGF0YWJhc2UpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlKG9iamVjdCkge1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZGF0YWJhc2UuY3JlYXRlKGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxhc3RQcm9taXNlO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKHdoZXJlLCBvYmplY3QpIHtcbiAgICBsYXN0UHJvbWlzZSA9IGxhc3RQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIGRhdGFiYXNlLnVwZGF0ZShjbGFzc05hbWUsIHdoZXJlLCBvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBsYXN0UHJvbWlzZTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBjcmVhdGUsXG4gICAgdXBkYXRlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdFN0YXR1c0hhbmRsZXIoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIGNvbnN0IGF1dGggPSBBdXRoLm1hc3Rlcihjb25maWcpO1xuICBmdW5jdGlvbiBjcmVhdGUob2JqZWN0KSB7XG4gICAgbGFzdFByb21pc2UgPSBsYXN0UHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgLy8gbWVyZ2UgdGhlIG9iamVjdHNcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShPYmplY3QuYXNzaWduKHt9LCBvYmplY3QsIHJlc3BvbnNlKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUod2hlcmUsIG9iamVjdCkge1xuICAgIC8vIFRPRE86IHdoZW4gd2UgaGF2ZSB1cGRhdGVXaGVyZSwgdXNlIHRoYXQgZm9yIHByb3BlciBpbnRlcmZhY2luZ1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAudXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB7IG9iamVjdElkOiB3aGVyZS5vYmplY3RJZCB9LCBvYmplY3QpXG4gICAgICAgIC50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgb2JqZWN0c1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoT2JqZWN0LmFzc2lnbih7fSwgb2JqZWN0LCByZXNwb25zZSkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgY3JlYXRlLFxuICAgIHVwZGF0ZSxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBqb2JTdGF0dXNIYW5kbGVyKGNvbmZpZykge1xuICBsZXQgam9iU3RhdHVzO1xuICBjb25zdCBvYmplY3RJZCA9IG5ld09iamVjdElkKGNvbmZpZy5vYmplY3RJZFNpemUpO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHN0YXR1c0hhbmRsZXIoSk9CX1NUQVRVU19DT0xMRUNUSU9OLCBkYXRhYmFzZSk7XG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoam9iTmFtZSwgcGFyYW1zKSB7XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICBqb2JTdGF0dXMgPSB7XG4gICAgICBvYmplY3RJZCxcbiAgICAgIGpvYk5hbWUsXG4gICAgICBwYXJhbXMsXG4gICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgIHNvdXJjZTogJ2FwaScsXG4gICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgIC8vIGxvY2tkb3duIVxuICAgICAgQUNMOiB7fSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKGpvYlN0YXR1cyk7XG4gIH07XG5cbiAgY29uc3Qgc2V0TWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB7IG1lc3NhZ2UgfSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0U3VjY2VlZGVkID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gc2V0RmluYWxTdGF0dXMoJ3N1Y2NlZWRlZCcsIG1lc3NhZ2UpO1xuICB9O1xuXG4gIGNvbnN0IHNldEZhaWxlZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNldEZpbmFsU3RhdHVzKCdmYWlsZWQnLCBtZXNzYWdlKTtcbiAgfTtcblxuICBjb25zdCBzZXRGaW5hbFN0YXR1cyA9IGZ1bmN0aW9uIChzdGF0dXMsIG1lc3NhZ2UgPSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaW5pc2hlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB1cGRhdGUgPSB7IHN0YXR1cywgZmluaXNoZWRBdCB9O1xuICAgIGlmIChtZXNzYWdlICYmIHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgdXBkYXRlLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBtZXNzYWdlLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICB1cGRhdGUubWVzc2FnZSA9IG1lc3NhZ2UubWVzc2FnZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc2V0UnVubmluZyxcbiAgICBzZXRTdWNjZWVkZWQsXG4gICAgc2V0TWVzc2FnZSxcbiAgICBzZXRGYWlsZWQsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnLCBleGlzdGluZ09iamVjdElkKSB7XG4gIGxldCBwdXNoU3RhdHVzO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHJlc3RTdGF0dXNIYW5kbGVyKFBVU0hfU1RBVFVTX0NPTExFQ1RJT04sIGNvbmZpZyk7XG4gIGxldCBvYmplY3RJZCA9IGV4aXN0aW5nT2JqZWN0SWQ7XG4gIGNvbnN0IHNldEluaXRpYWwgPSBmdW5jdGlvbiAoYm9keSA9IHt9LCB3aGVyZSwgb3B0aW9ucyA9IHsgc291cmNlOiAncmVzdCcgfSkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IHB1c2hUaW1lID0gbm93LnRvSVNPU3RyaW5nKCk7XG4gICAgbGV0IHN0YXR1cyA9ICdwZW5kaW5nJztcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKSkge1xuICAgICAgaWYgKGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCkge1xuICAgICAgICBwdXNoVGltZSA9IGJvZHkucHVzaF90aW1lO1xuICAgICAgICBzdGF0dXMgPSAnc2NoZWR1bGVkJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdUcnlpbmcgdG8gc2NoZWR1bGUgYSBwdXNoIHdoaWxlIHNlcnZlciBpcyBub3QgY29uZmlndXJlZC4nKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1B1c2ggd2lsbCBiZSBzZW50IGltbWVkaWF0ZWx5Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YSB8fCB7fTtcbiAgICBjb25zdCBwYXlsb2FkU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgbGV0IHB1c2hIYXNoO1xuICAgIGlmICh0eXBlb2YgZGF0YS5hbGVydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHB1c2hIYXNoID0gbWQ1SGFzaChkYXRhLmFsZXJ0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLmFsZXJ0ID09PSAnb2JqZWN0Jykge1xuICAgICAgcHVzaEhhc2ggPSBtZDVIYXNoKEpTT04uc3RyaW5naWZ5KGRhdGEuYWxlcnQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEhhc2ggPSAnZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2UnO1xuICAgIH1cbiAgICBjb25zdCBvYmplY3QgPSB7XG4gICAgICBwdXNoVGltZSxcbiAgICAgIHF1ZXJ5OiBKU09OLnN0cmluZ2lmeSh3aGVyZSksXG4gICAgICBwYXlsb2FkOiBwYXlsb2FkU3RyaW5nLFxuICAgICAgc291cmNlOiBvcHRpb25zLnNvdXJjZSxcbiAgICAgIHRpdGxlOiBvcHRpb25zLnRpdGxlLFxuICAgICAgZXhwaXJ5OiBib2R5LmV4cGlyYXRpb25fdGltZSxcbiAgICAgIGV4cGlyYXRpb25faW50ZXJ2YWw6IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCxcbiAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgbnVtU2VudDogMCxcbiAgICAgIHB1c2hIYXNoLFxuICAgICAgLy8gbG9ja2Rvd24hXG4gICAgICBBQ0w6IHt9LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKG9iamVjdCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgb2JqZWN0SWQgPSByZXN1bHQub2JqZWN0SWQ7XG4gICAgICBwdXNoU3RhdHVzID0ge1xuICAgICAgICBvYmplY3RJZCxcbiAgICAgIH07XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHB1c2hTdGF0dXMpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoYmF0Y2hlcykge1xuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBzZW5kaW5nIHB1c2ggdG8gaW5zdGFsbGF0aW9ucyB3aXRoICVkIGJhdGNoZXNgLFxuICAgICAgYmF0Y2hlc1xuICAgICk7XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKFxuICAgICAge1xuICAgICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcbiAgICAgICAgb2JqZWN0SWQ6IG9iamVjdElkLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgIGNvdW50OiBiYXRjaGVzLFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgdHJhY2tTZW50ID0gZnVuY3Rpb24gKFxuICAgIHJlc3VsdHMsXG4gICAgVVRDT2Zmc2V0LFxuICAgIGNsZWFudXBJbnN0YWxsYXRpb25zID0gcHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0NMRUFOVVBfSU5WQUxJRF9JTlNUQUxMQVRJT05TXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAgIG51bVNlbnQ6IDAsXG4gICAgICBudW1GYWlsZWQ6IDAsXG4gICAgfTtcbiAgICBjb25zdCBkZXZpY2VzVG9SZW1vdmUgPSBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xuICAgICAgcmVzdWx0cyA9IGZsYXR0ZW4ocmVzdWx0cyk7XG4gICAgICByZXN1bHRzLnJlZHVjZSgobWVtbywgcmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIENhbm5vdCBoYW5kbGUgdGhhdFxuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LmRldmljZSB8fCAhcmVzdWx0LmRldmljZS5kZXZpY2VUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9IHJlc3VsdC5kZXZpY2UuZGV2aWNlVHlwZTtcbiAgICAgICAgY29uc3Qga2V5ID0gcmVzdWx0LnRyYW5zbWl0dGVkXG4gICAgICAgICAgPyBgc2VudFBlclR5cGUuJHtkZXZpY2VUeXBlfWBcbiAgICAgICAgICA6IGBmYWlsZWRQZXJUeXBlLiR7ZGV2aWNlVHlwZX1gO1xuICAgICAgICBtZW1vW2tleV0gPSBpbmNyZW1lbnRPcChtZW1vLCBrZXkpO1xuICAgICAgICBpZiAodHlwZW9mIFVUQ09mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCBvZmZzZXRLZXkgPSByZXN1bHQudHJhbnNtaXR0ZWRcbiAgICAgICAgICAgID8gYHNlbnRQZXJVVENPZmZzZXQuJHtVVENPZmZzZXR9YFxuICAgICAgICAgICAgOiBgZmFpbGVkUGVyVVRDT2Zmc2V0LiR7VVRDT2Zmc2V0fWA7XG4gICAgICAgICAgbWVtb1tvZmZzZXRLZXldID0gaW5jcmVtZW50T3AobWVtbywgb2Zmc2V0S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LnRyYW5zbWl0dGVkKSB7XG4gICAgICAgICAgbWVtby5udW1TZW50Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVzdWx0ICYmXG4gICAgICAgICAgICByZXN1bHQucmVzcG9uc2UgJiZcbiAgICAgICAgICAgIHJlc3VsdC5yZXNwb25zZS5lcnJvciAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZSAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZS5kZXZpY2VUb2tlblxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSByZXN1bHQuZGV2aWNlLmRldmljZVRva2VuO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQucmVzcG9uc2UuZXJyb3I7XG4gICAgICAgICAgICAvLyBHQ00gZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdOb3RSZWdpc3RlcmVkJyB8fCBlcnJvciA9PT0gJ0ludmFsaWRSZWdpc3RyYXRpb24nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFQTlMgZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdVbnJlZ2lzdGVyZWQnIHx8IGVycm9yID09PSAnQmFkRGV2aWNlVG9rZW4nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtby5udW1GYWlsZWQrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIHVwZGF0ZSk7XG4gICAgfVxuXG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IHNlbnQgcHVzaCEgJWQgc3VjY2VzcywgJWQgZmFpbHVyZXNgLFxuICAgICAgdXBkYXRlLm51bVNlbnQsXG4gICAgICB1cGRhdGUubnVtRmFpbGVkXG4gICAgKTtcbiAgICBsb2dnZXIudmVyYm9zZShgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IG5lZWRzIGNsZWFudXBgLCB7XG4gICAgICBkZXZpY2VzVG9SZW1vdmUsXG4gICAgfSk7XG4gICAgWydudW1TZW50JywgJ251bUZhaWxlZCddLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh1cGRhdGVba2V5XSA+IDApIHtcbiAgICAgICAgdXBkYXRlW2tleV0gPSB7XG4gICAgICAgICAgX19vcDogJ0luY3JlbWVudCcsXG4gICAgICAgICAgYW1vdW50OiB1cGRhdGVba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkZXZpY2VzVG9SZW1vdmUubGVuZ3RoID4gMCAmJiBjbGVhbnVwSW5zdGFsbGF0aW9ucykge1xuICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGRldmljZSB0b2tlbnMgb24gJHtkZXZpY2VzVG9SZW1vdmUubGVuZ3RofSBfSW5zdGFsbGF0aW9uc2ApO1xuICAgICAgZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgIHsgZGV2aWNlVG9rZW46IHsgJGluOiBkZXZpY2VzVG9SZW1vdmUgfSB9LFxuICAgICAgICB7IGRldmljZVRva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0gfSxcbiAgICAgICAge1xuICAgICAgICAgIGFjbDogdW5kZWZpbmVkLFxuICAgICAgICAgIG1hbnk6IHRydWUsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gaW5kaWNhdGUgdGhpcyBiYXRjaCBpcyBjb21wbGV0ZVxuICAgIGluY3JlbWVudE9wKHVwZGF0ZSwgJ2NvdW50JywgLTEpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5jb3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHsgb2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAnc3VjY2VlZGVkJyxcbiAgICAgICAgY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGZhaWwgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnIgPSB7IG1lc3NhZ2U6IGVyciB9O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBlcnJvck1lc3NhZ2U6IGVycixcbiAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB1cGRhdGUpO1xuICB9O1xuXG4gIGNvbnN0IHJ2YWwgPSB7XG4gICAgc2V0SW5pdGlhbCxcbiAgICBzZXRSdW5uaW5nLFxuICAgIHRyYWNrU2VudCxcbiAgICBjb21wbGV0ZSxcbiAgICBmYWlsLFxuICB9O1xuXG4gIC8vIGRlZmluZSBvYmplY3RJZCB0byBiZSBkeW5hbWljXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydmFsLCAnb2JqZWN0SWQnLCB7XG4gICAgZ2V0OiAoKSA9PiBvYmplY3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUocnZhbCk7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/TestUtils.js b/lib/TestUtils.js new file mode 100644 index 0000000000..043a6dd202 --- /dev/null +++ b/lib/TestUtils.js @@ -0,0 +1,31 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.destroyAllDataPermanently = destroyAllDataPermanently; + +var _cache = _interopRequireDefault(require("./cache")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Destroys all data in the database + * @param {boolean} fast set to true if it's ok to just drop objects and not indexes. + */ +function destroyAllDataPermanently(fast) { + if (!process.env.TESTING) { + throw 'Only supported in test environment'; + } + + return Promise.all(Object.keys(_cache.default.cache).map(appId => { + const app = _cache.default.get(appId); + + if (app.databaseController) { + return app.databaseController.deleteEverything(fast); + } else { + return Promise.resolve(); + } + })); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXN0VXRpbHMuanMiXSwibmFtZXMiOlsiZGVzdHJveUFsbERhdGFQZXJtYW5lbnRseSIsImZhc3QiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIlByb21pc2UiLCJhbGwiLCJPYmplY3QiLCJrZXlzIiwiQXBwQ2FjaGUiLCJjYWNoZSIsIm1hcCIsImFwcElkIiwiYXBwIiwiZ2V0IiwiZGF0YWJhc2VDb250cm9sbGVyIiwiZGVsZXRlRXZlcnl0aGluZyIsInJlc29sdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBOzs7O0FBSU8sU0FBU0EseUJBQVQsQ0FBbUNDLElBQW5DLEVBQXlDO0FBQzlDLE1BQUksQ0FBQ0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQWpCLEVBQTBCO0FBQ3hCLFVBQU0sb0NBQU47QUFDRDs7QUFDRCxTQUFPQyxPQUFPLENBQUNDLEdBQVIsQ0FDTEMsTUFBTSxDQUFDQyxJQUFQLENBQVlDLGVBQVNDLEtBQXJCLEVBQTRCQyxHQUE1QixDQUFnQ0MsS0FBSyxJQUFJO0FBQ3ZDLFVBQU1DLEdBQUcsR0FBR0osZUFBU0ssR0FBVCxDQUFhRixLQUFiLENBQVo7O0FBQ0EsUUFBSUMsR0FBRyxDQUFDRSxrQkFBUixFQUE0QjtBQUMxQixhQUFPRixHQUFHLENBQUNFLGtCQUFKLENBQXVCQyxnQkFBdkIsQ0FBd0NmLElBQXhDLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPSSxPQUFPLENBQUNZLE9BQVIsRUFBUDtBQUNEO0FBQ0YsR0FQRCxDQURLLENBQVA7QUFVRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcblxuLyoqXG4gKiBEZXN0cm95cyBhbGwgZGF0YSBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZHJvcCBvYmplY3RzIGFuZCBub3QgaW5kZXhlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lBbGxEYXRhUGVybWFuZW50bHkoZmFzdCkge1xuICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICB0aHJvdyAnT25seSBzdXBwb3J0ZWQgaW4gdGVzdCBlbnZpcm9ubWVudCc7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgIE9iamVjdC5rZXlzKEFwcENhY2hlLmNhY2hlKS5tYXAoYXBwSWQgPT4ge1xuICAgICAgY29uc3QgYXBwID0gQXBwQ2FjaGUuZ2V0KGFwcElkKTtcbiAgICAgIGlmIChhcHAuZGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBhcHAuZGF0YWJhc2VDb250cm9sbGVyLmRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSlcbiAgKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/batch.js b/lib/batch.js new file mode 100644 index 0000000000..6572814078 --- /dev/null +++ b/lib/batch.js @@ -0,0 +1,132 @@ +"use strict"; + +const Parse = require('parse/node').Parse; + +const url = require('url'); + +const path = require('path'); // These methods handle batch requests. + + +const batchPath = '/batch'; // Mounts a batch-handler onto a PromiseRouter. + +function mountOnto(router) { + router.route('POST', batchPath, req => { + return handleBatch(router, req); + }); +} + +function parseURL(URL) { + if (typeof URL === 'string') { + return url.parse(URL); + } + + return undefined; +} + +function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { + serverURL = serverURL ? parseURL(serverURL) : undefined; + publicServerURL = publicServerURL ? parseURL(publicServerURL) : undefined; + const apiPrefixLength = originalUrl.length - batchPath.length; + let apiPrefix = originalUrl.slice(0, apiPrefixLength); + + const makeRoutablePath = function (requestPath) { + // The routablePath is the path minus the api prefix + if (requestPath.slice(0, apiPrefix.length) != apiPrefix) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'cannot route batch path ' + requestPath); + } + + return path.posix.join('/', requestPath.slice(apiPrefix.length)); + }; + + if (serverURL && publicServerURL && serverURL.path != publicServerURL.path) { + const localPath = serverURL.path; + const publicPath = publicServerURL.path; // Override the api prefix + + apiPrefix = localPath; + return function (requestPath) { + // Build the new path by removing the public path + // and joining with the local path + const newPath = path.posix.join('/', localPath, '/', requestPath.slice(publicPath.length)); // Use the method for local routing + + return makeRoutablePath(newPath); + }; + } + + return makeRoutablePath; +} // Returns a promise for a {response} object. +// TODO: pass along auth correctly + + +function handleBatch(router, req) { + if (!Array.isArray(req.body.requests)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'requests must be an array'); + } // The batch paths are all from the root of our domain. + // That means they include the API prefix, that the API is mounted + // to. However, our promise router does not route the api prefix. So + // we need to figure out the API prefix, so that we can strip it + // from all the subrequests. + + + if (!req.originalUrl.endsWith(batchPath)) { + throw 'internal routing problem - expected url to end with batch'; + } + + const makeRoutablePath = makeBatchRoutingPathFunction(req.originalUrl, req.config.serverURL, req.config.publicServerURL); + let initialPromise = Promise.resolve(); + + if (req.body.transaction === true) { + initialPromise = req.config.database.createTransactionalSession(); + } + + return initialPromise.then(() => { + const promises = req.body.requests.map(restRequest => { + const routablePath = makeRoutablePath(restRequest.path); // Construct a request that we can send to a handler + + const request = { + body: restRequest.body, + config: req.config, + auth: req.auth, + info: req.info + }; + return router.tryRouteRequest(restRequest.method, routablePath, request).then(response => { + return { + success: response.response + }; + }, error => { + return { + error: { + code: error.code, + error: error.message + } + }; + }); + }); + return Promise.all(promises).then(results => { + if (req.body.transaction === true) { + if (results.find(result => typeof result.error === 'object')) { + return req.config.database.abortTransactionalSession().then(() => { + return Promise.reject({ + response: results + }); + }); + } else { + return req.config.database.commitTransactionalSession().then(() => { + return { + response: results + }; + }); + } + } else { + return { + response: results + }; + } + }); + }); +} + +module.exports = { + mountOnto, + makeBatchRoutingPathFunction +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9iYXRjaC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJwYXRoIiwiYmF0Y2hQYXRoIiwibW91bnRPbnRvIiwicm91dGVyIiwicm91dGUiLCJyZXEiLCJoYW5kbGVCYXRjaCIsInBhcnNlVVJMIiwiVVJMIiwicGFyc2UiLCJ1bmRlZmluZWQiLCJtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uIiwib3JpZ2luYWxVcmwiLCJzZXJ2ZXJVUkwiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJhcGlQcmVmaXhMZW5ndGgiLCJsZW5ndGgiLCJhcGlQcmVmaXgiLCJzbGljZSIsIm1ha2VSb3V0YWJsZVBhdGgiLCJyZXF1ZXN0UGF0aCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicG9zaXgiLCJqb2luIiwibG9jYWxQYXRoIiwicHVibGljUGF0aCIsIm5ld1BhdGgiLCJBcnJheSIsImlzQXJyYXkiLCJib2R5IiwicmVxdWVzdHMiLCJlbmRzV2l0aCIsImNvbmZpZyIsImluaXRpYWxQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0cmFuc2FjdGlvbiIsImRhdGFiYXNlIiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJ0aGVuIiwicHJvbWlzZXMiLCJtYXAiLCJyZXN0UmVxdWVzdCIsInJvdXRhYmxlUGF0aCIsInJlcXVlc3QiLCJhdXRoIiwiaW5mbyIsInRyeVJvdXRlUmVxdWVzdCIsIm1ldGhvZCIsInJlc3BvbnNlIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHRzIiwiZmluZCIsInJlc3VsdCIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFwQzs7QUFDQSxN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LEVBQUVNO0FBQVosU0FBUDtBQUNEO0FBQ0YsS0FkTSxDQUFQO0FBZUQsR0FyQ00sQ0FBUDtBQXNDRDs7QUFFRE0sTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Y3RCxFQUFBQSxTQURlO0FBRWZTLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbi8vIFRoZXNlIG1ldGhvZHMgaGFuZGxlIGJhdGNoIHJlcXVlc3RzLlxuY29uc3QgYmF0Y2hQYXRoID0gJy9iYXRjaCc7XG5cbi8vIE1vdW50cyBhIGJhdGNoLWhhbmRsZXIgb250byBhIFByb21pc2VSb3V0ZXIuXG5mdW5jdGlvbiBtb3VudE9udG8ocm91dGVyKSB7XG4gIHJvdXRlci5yb3V0ZSgnUE9TVCcsIGJhdGNoUGF0aCwgcmVxID0+IHtcbiAgICByZXR1cm4gaGFuZGxlQmF0Y2gocm91dGVyLCByZXEpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VVUkwoVVJMKSB7XG4gIGlmICh0eXBlb2YgVVJMID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB1cmwucGFyc2UoVVJMKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uKG9yaWdpbmFsVXJsLCBzZXJ2ZXJVUkwsIHB1YmxpY1NlcnZlclVSTCkge1xuICBzZXJ2ZXJVUkwgPSBzZXJ2ZXJVUkwgPyBwYXJzZVVSTChzZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuICBwdWJsaWNTZXJ2ZXJVUkwgPSBwdWJsaWNTZXJ2ZXJVUkwgPyBwYXJzZVVSTChwdWJsaWNTZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGFwaVByZWZpeExlbmd0aCA9IG9yaWdpbmFsVXJsLmxlbmd0aCAtIGJhdGNoUGF0aC5sZW5ndGg7XG4gIGxldCBhcGlQcmVmaXggPSBvcmlnaW5hbFVybC5zbGljZSgwLCBhcGlQcmVmaXhMZW5ndGgpO1xuXG4gIGNvbnN0IG1ha2VSb3V0YWJsZVBhdGggPSBmdW5jdGlvbiAocmVxdWVzdFBhdGgpIHtcbiAgICAvLyBUaGUgcm91dGFibGVQYXRoIGlzIHRoZSBwYXRoIG1pbnVzIHRoZSBhcGkgcHJlZml4XG4gICAgaWYgKHJlcXVlc3RQYXRoLnNsaWNlKDAsIGFwaVByZWZpeC5sZW5ndGgpICE9IGFwaVByZWZpeCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2Nhbm5vdCByb3V0ZSBiYXRjaCBwYXRoICcgKyByZXF1ZXN0UGF0aCk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLnBvc2l4LmpvaW4oJy8nLCByZXF1ZXN0UGF0aC5zbGljZShhcGlQcmVmaXgubGVuZ3RoKSk7XG4gIH07XG5cbiAgaWYgKHNlcnZlclVSTCAmJiBwdWJsaWNTZXJ2ZXJVUkwgJiYgc2VydmVyVVJMLnBhdGggIT0gcHVibGljU2VydmVyVVJMLnBhdGgpIHtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBzZXJ2ZXJVUkwucGF0aDtcbiAgICBjb25zdCBwdWJsaWNQYXRoID0gcHVibGljU2VydmVyVVJMLnBhdGg7XG4gICAgLy8gT3ZlcnJpZGUgdGhlIGFwaSBwcmVmaXhcbiAgICBhcGlQcmVmaXggPSBsb2NhbFBhdGg7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChyZXF1ZXN0UGF0aCkge1xuICAgICAgLy8gQnVpbGQgdGhlIG5ldyBwYXRoIGJ5IHJlbW92aW5nIHRoZSBwdWJsaWMgcGF0aFxuICAgICAgLy8gYW5kIGpvaW5pbmcgd2l0aCB0aGUgbG9jYWwgcGF0aFxuICAgICAgY29uc3QgbmV3UGF0aCA9IHBhdGgucG9zaXguam9pbignLycsIGxvY2FsUGF0aCwgJy8nLCByZXF1ZXN0UGF0aC5zbGljZShwdWJsaWNQYXRoLmxlbmd0aCkpO1xuICAgICAgLy8gVXNlIHRoZSBtZXRob2QgZm9yIGxvY2FsIHJvdXRpbmdcbiAgICAgIHJldHVybiBtYWtlUm91dGFibGVQYXRoKG5ld1BhdGgpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gbWFrZVJvdXRhYmxlUGF0aDtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlfSBvYmplY3QuXG4vLyBUT0RPOiBwYXNzIGFsb25nIGF1dGggY29ycmVjdGx5XG5mdW5jdGlvbiBoYW5kbGVCYXRjaChyb3V0ZXIsIHJlcSkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkocmVxLmJvZHkucmVxdWVzdHMpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ3JlcXVlc3RzIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgfVxuXG4gIC8vIFRoZSBiYXRjaCBwYXRocyBhcmUgYWxsIGZyb20gdGhlIHJvb3Qgb2Ygb3VyIGRvbWFpbi5cbiAgLy8gVGhhdCBtZWFucyB0aGV5IGluY2x1ZGUgdGhlIEFQSSBwcmVmaXgsIHRoYXQgdGhlIEFQSSBpcyBtb3VudGVkXG4gIC8vIHRvLiBIb3dldmVyLCBvdXIgcHJvbWlzZSByb3V0ZXIgZG9lcyBub3Qgcm91dGUgdGhlIGFwaSBwcmVmaXguIFNvXG4gIC8vIHdlIG5lZWQgdG8gZmlndXJlIG91dCB0aGUgQVBJIHByZWZpeCwgc28gdGhhdCB3ZSBjYW4gc3RyaXAgaXRcbiAgLy8gZnJvbSBhbGwgdGhlIHN1YnJlcXVlc3RzLlxuICBpZiAoIXJlcS5vcmlnaW5hbFVybC5lbmRzV2l0aChiYXRjaFBhdGgpKSB7XG4gICAgdGhyb3cgJ2ludGVybmFsIHJvdXRpbmcgcHJvYmxlbSAtIGV4cGVjdGVkIHVybCB0byBlbmQgd2l0aCBiYXRjaCc7XG4gIH1cblxuICBjb25zdCBtYWtlUm91dGFibGVQYXRoID0gbWFrZUJhdGNoUm91dGluZ1BhdGhGdW5jdGlvbihcbiAgICByZXEub3JpZ2luYWxVcmwsXG4gICAgcmVxLmNvbmZpZy5zZXJ2ZXJVUkwsXG4gICAgcmVxLmNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkxcbiAgKTtcblxuICBsZXQgaW5pdGlhbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgaWYgKHJlcS5ib2R5LnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgaW5pdGlhbFByb21pc2UgPSByZXEuY29uZmlnLmRhdGFiYXNlLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk7XG4gIH1cblxuICByZXR1cm4gaW5pdGlhbFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSByZXEuYm9keS5yZXF1ZXN0cy5tYXAocmVzdFJlcXVlc3QgPT4ge1xuICAgICAgY29uc3Qgcm91dGFibGVQYXRoID0gbWFrZVJvdXRhYmxlUGF0aChyZXN0UmVxdWVzdC5wYXRoKTtcblxuICAgICAgLy8gQ29uc3RydWN0IGEgcmVxdWVzdCB0aGF0IHdlIGNhbiBzZW5kIHRvIGEgaGFuZGxlclxuICAgICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgICAgYm9keTogcmVzdFJlcXVlc3QuYm9keSxcbiAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICBhdXRoOiByZXEuYXV0aCxcbiAgICAgICAgaW5mbzogcmVxLmluZm8sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gcm91dGVyLnRyeVJvdXRlUmVxdWVzdChyZXN0UmVxdWVzdC5tZXRob2QsIHJvdXRhYmxlUGF0aCwgcmVxdWVzdCkudGhlbihcbiAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHJlc3BvbnNlLnJlc3BvbnNlIH07XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICByZXR1cm4geyBlcnJvcjogeyBjb2RlOiBlcnJvci5jb2RlLCBlcnJvcjogZXJyb3IubWVzc2FnZSB9IH07XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICBpZiAocmVxLmJvZHkudHJhbnNhY3Rpb24gPT09IHRydWUpIHtcbiAgICAgICAgaWYgKHJlc3VsdHMuZmluZChyZXN1bHQgPT4gdHlwZW9mIHJlc3VsdC5lcnJvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2UuYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHsgcmVzcG9uc2U6IHJlc3VsdHMgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2UuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXN1bHRzIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXN1bHRzIH07XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbW91bnRPbnRvLFxuICBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cache.js b/lib/cache.js new file mode 100644 index 0000000000..ddeda818f9 --- /dev/null +++ b/lib/cache.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AppCache = void 0; + +var _InMemoryCache = require("./Adapters/Cache/InMemoryCache"); + +var AppCache = new _InMemoryCache.InMemoryCache({ + ttl: NaN +}); +exports.AppCache = AppCache; +var _default = AppCache; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jYWNoZS5qcyJdLCJuYW1lcyI6WyJBcHBDYWNoZSIsIkluTWVtb3J5Q2FjaGUiLCJ0dGwiLCJOYU4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFFTyxJQUFJQSxRQUFRLEdBQUcsSUFBSUMsNEJBQUosQ0FBa0I7QUFBRUMsRUFBQUEsR0FBRyxFQUFFQztBQUFQLENBQWxCLENBQWY7O2VBQ1FILFEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbk1lbW9yeUNhY2hlIH0gZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlJztcblxuZXhwb3J0IHZhciBBcHBDYWNoZSA9IG5ldyBJbk1lbW9yeUNhY2hlKHsgdHRsOiBOYU4gfSk7XG5leHBvcnQgZGVmYXVsdCBBcHBDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/definitions/parse-live-query-server.js b/lib/cli/definitions/parse-live-query-server.js new file mode 100644 index 0000000000..2aac33fdba --- /dev/null +++ b/lib/cli/definitions/parse-live-query-server.js @@ -0,0 +1,12 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const LiveQueryServerOptions = require('../../Options/Definitions').LiveQueryServerOptions; + +var _default = LiveQueryServerOptions; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsInJlcXVpcmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxNQUFNQSxzQkFBc0IsR0FBR0MsT0FBTyxDQUFDLDJCQUFELENBQVAsQ0FDNUJELHNCQURIOztlQUVlQSxzQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IExpdmVRdWVyeVNlcnZlck9wdGlvbnMgPSByZXF1aXJlKCcuLi8uLi9PcHRpb25zL0RlZmluaXRpb25zJylcbiAgLkxpdmVRdWVyeVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/definitions/parse-server.js b/lib/cli/definitions/parse-server.js new file mode 100644 index 0000000000..c4089a0626 --- /dev/null +++ b/lib/cli/definitions/parse-server.js @@ -0,0 +1,12 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const ParseServerDefinitions = require('../../Options/Definitions').ParseServerOptions; + +var _default = ParseServerDefinitions; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlU2VydmVyRGVmaW5pdGlvbnMiLCJyZXF1aXJlIiwiUGFyc2VTZXJ2ZXJPcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsc0JBQXNCLEdBQUdDLE9BQU8sQ0FBQywyQkFBRCxDQUFQLENBQzVCQyxrQkFESDs7ZUFFZUYsc0IiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBQYXJzZVNlcnZlckRlZmluaXRpb25zID0gcmVxdWlyZSgnLi4vLi4vT3B0aW9ucy9EZWZpbml0aW9ucycpXG4gIC5QYXJzZVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlckRlZmluaXRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/parse-live-query-server.js b/lib/cli/parse-live-query-server.js new file mode 100644 index 0000000000..346727035d --- /dev/null +++ b/lib/cli/parse-live-query-server.js @@ -0,0 +1,19 @@ +"use strict"; + +var _parseLiveQueryServer = _interopRequireDefault(require("./definitions/parse-live-query-server")); + +var _runner = _interopRequireDefault(require("./utils/runner")); + +var _index = require("../index"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(0, _runner.default)({ + definitions: _parseLiveQueryServer.default, + start: function (program, options, logOptions) { + logOptions(); + + _index.ParseServer.createLiveQueryServer(undefined, options); + } +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiZGVmaW5pdGlvbnMiLCJzdGFydCIsInByb2dyYW0iLCJvcHRpb25zIiwibG9nT3B0aW9ucyIsIlBhcnNlU2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOzs7O0FBRUEscUJBQU87QUFDTEEsRUFBQUEsV0FBVyxFQUFYQSw2QkFESztBQUVMQyxFQUFBQSxLQUFLLEVBQUUsVUFBVUMsT0FBVixFQUFtQkMsT0FBbkIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDQSxJQUFBQSxVQUFVOztBQUNWQyx1QkFBWUMscUJBQVosQ0FBa0NDLFNBQWxDLEVBQTZDSixPQUE3QztBQUNEO0FBTEksQ0FBUCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBkZWZpbml0aW9ucyBmcm9tICcuL2RlZmluaXRpb25zL3BhcnNlLWxpdmUtcXVlcnktc2VydmVyJztcbmltcG9ydCBydW5uZXIgZnJvbSAnLi91dGlscy9ydW5uZXInO1xuaW1wb3J0IHsgUGFyc2VTZXJ2ZXIgfSBmcm9tICcuLi9pbmRleCc7XG5cbnJ1bm5lcih7XG4gIGRlZmluaXRpb25zLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBsb2dPcHRpb25zKCk7XG4gICAgUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0sXG59KTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/parse-server.js b/lib/cli/parse-server.js new file mode 100755 index 0000000000..188991e3fe --- /dev/null +++ b/lib/cli/parse-server.js @@ -0,0 +1,111 @@ +"use strict"; + +var _index = _interopRequireDefault(require("../index")); + +var _parseServer = _interopRequireDefault(require("./definitions/parse-server")); + +var _cluster = _interopRequireDefault(require("cluster")); + +var _os = _interopRequireDefault(require("os")); + +var _runner = _interopRequireDefault(require("./utils/runner")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* eslint-disable no-console */ +const help = function () { + console.log(' Get Started guide:'); + console.log(''); + console.log(' Please have a look at the get started guide!'); + console.log(' http://docs.parseplatform.org/parse-server/guide/'); + console.log(''); + console.log(''); + console.log(' Usage with npm start'); + console.log(''); + console.log(' $ npm start -- path/to/config.json'); + console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(''); + console.log(''); + console.log(' Usage:'); + console.log(''); + console.log(' $ parse-server path/to/config.json'); + console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(''); +}; + +(0, _runner.default)({ + definitions: _parseServer.default, + help, + usage: '[options] ', + start: function (program, options, logOptions) { + if (!options.appId || !options.masterKey) { + program.outputHelp(); + console.error(''); + console.error('\u001b[31mERROR: appId and masterKey are required\u001b[0m'); + console.error(''); + process.exit(1); + } + + if (options['liveQuery.classNames']) { + options.liveQuery = options.liveQuery || {}; + options.liveQuery.classNames = options['liveQuery.classNames']; + delete options['liveQuery.classNames']; + } + + if (options['liveQuery.redisURL']) { + options.liveQuery = options.liveQuery || {}; + options.liveQuery.redisURL = options['liveQuery.redisURL']; + delete options['liveQuery.redisURL']; + } + + if (options['liveQuery.redisOptions']) { + options.liveQuery = options.liveQuery || {}; + options.liveQuery.redisOptions = options['liveQuery.redisOptions']; + delete options['liveQuery.redisOptions']; + } + + if (options.cluster) { + const numCPUs = typeof options.cluster === 'number' ? options.cluster : _os.default.cpus().length; + + if (_cluster.default.isMaster) { + logOptions(); + + for (let i = 0; i < numCPUs; i++) { + _cluster.default.fork(); + } + + _cluster.default.on('exit', (worker, code) => { + console.log(`worker ${worker.process.pid} died (${code})... Restarting`); + + _cluster.default.fork(); + }); + } else { + _index.default.start(options, () => { + printSuccessMessage(); + }); + } + } else { + _index.default.start(options, () => { + logOptions(); + console.log(''); + printSuccessMessage(); + }); + } + + function printSuccessMessage() { + console.log('[' + process.pid + '] parse-server running on ' + options.serverURL); + + if (options.mountGraphQL) { + console.log('[' + process.pid + '] GraphQL running on http://localhost:' + options.port + options.graphQLPath); + } + + if (options.mountPlayground) { + console.log('[' + process.pid + '] Playground running on http://localhost:' + options.port + options.playgroundPath); + } + } + } +}); +/* eslint-enable no-console */ +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbImhlbHAiLCJjb25zb2xlIiwibG9nIiwiZGVmaW5pdGlvbnMiLCJ1c2FnZSIsInN0YXJ0IiwicHJvZ3JhbSIsIm9wdGlvbnMiLCJsb2dPcHRpb25zIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJvdXRwdXRIZWxwIiwiZXJyb3IiLCJwcm9jZXNzIiwiZXhpdCIsImxpdmVRdWVyeSIsImNsYXNzTmFtZXMiLCJyZWRpc1VSTCIsInJlZGlzT3B0aW9ucyIsImNsdXN0ZXIiLCJudW1DUFVzIiwib3MiLCJjcHVzIiwibGVuZ3RoIiwiaXNNYXN0ZXIiLCJpIiwiZm9yayIsIm9uIiwid29ya2VyIiwiY29kZSIsInBpZCIsIlBhcnNlU2VydmVyIiwicHJpbnRTdWNjZXNzTWVzc2FnZSIsInNlcnZlclVSTCIsIm1vdW50R3JhcGhRTCIsInBvcnQiLCJncmFwaFFMUGF0aCIsIm1vdW50UGxheWdyb3VuZCIsInBsYXlncm91bmRQYXRoIl0sIm1hcHBpbmdzIjoiOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBTEE7QUFPQSxNQUFNQSxJQUFJLEdBQUcsWUFBWTtBQUN2QkMsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksc0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxrREFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx1REFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxFQUFaO0FBQ0FELEVBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksd0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx3Q0FBWjtBQUNB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QUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLFVBQVMwQixNQUFNLENBQUNmLE9BQVAsQ0FBZWlCLEdBQUksVUFBU0QsSUFBSyxpQkFBdkQ7O0FBQ0FWLDJCQUFRTyxJQUFSO0FBQ0QsU0FIRDtBQUlELE9BVEQsTUFTTztBQUNMSyx1QkFBWTFCLEtBQVosQ0FBa0JFLE9BQWxCLEVBQTJCLE1BQU07QUFDL0J5QixVQUFBQSxtQkFBbUI7QUFDcEIsU0FGRDtBQUdEO0FBQ0YsS0FoQkQsTUFnQk87QUFDTEQscUJBQVkxQixLQUFaLENBQWtCRSxPQUFsQixFQUEyQixNQUFNO0FBQy9CQyxRQUFBQSxVQUFVO0FBQ1ZQLFFBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQThCLFFBQUFBLG1CQUFtQjtBQUNwQixPQUpEO0FBS0Q7O0FBRUQsYUFBU0EsbUJBQVQsR0FBK0I7QUFDN0IvQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxNQUFNVyxPQUFPLENBQUNpQixHQUFkLEdBQW9CLDRCQUFwQixHQUFtRHZCLE9BQU8sQ0FBQzBCLFNBQXZFOztBQUNBLFVBQUkxQixPQUFPLENBQUMyQixZQUFaLEVBQTBCO0FBQ3hCakMsUUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQ0UsTUFDRVcsT0FBTyxDQUFDaUIsR0FEVixHQUVFLHdDQUZGLEdBR0V2QixPQUFPLENBQUM0QixJQUhWLEdBSUU1QixPQUFPLENBQUM2QixXQUxaO0FBT0Q7O0FBQ0QsVUFBSTdCLE9BQU8sQ0FBQzhCLGVBQVosRUFBNkI7QUFDM0JwQyxRQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FDRSxNQUNFVyxPQUFPLENBQUNpQixHQURWLEdBRUUsMkNBRkYsR0FHRXZCLE9BQU8sQ0FBQzRCLElBSFYsR0FJRTVCLE9BQU8sQ0FBQytCLGNBTFo7QUFPRDtBQUNGO0FBQ0Y7QUExRUksQ0FBUDtBQTZFQSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCBQYXJzZVNlcnZlciBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQgZGVmaW5pdGlvbnMgZnJvbSAnLi9kZWZpbml0aW9ucy9wYXJzZS1zZXJ2ZXInO1xuaW1wb3J0IGNsdXN0ZXIgZnJvbSAnY2x1c3Rlcic7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHJ1bm5lciBmcm9tICcuL3V0aWxzL3J1bm5lcic7XG5cbmNvbnN0IGhlbHAgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCcgIEdldCBTdGFydGVkIGd1aWRlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgUGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSBnZXQgc3RhcnRlZCBndWlkZSEnKTtcbiAgY29uc29sZS5sb2coJyAgICBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvJyk7XG4gIGNvbnNvbGUubG9nKCcnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnICBVc2FnZSB3aXRoIG5wbSBzdGFydCcpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgbnBtIHN0YXJ0IC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgIFVzYWdlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgcGFyc2Utc2VydmVyIC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xufTtcblxucnVubmVyKHtcbiAgZGVmaW5pdGlvbnMsXG4gIGhlbHAsXG4gIHVzYWdlOiAnW29wdGlvbnNdIDxwYXRoL3RvL2NvbmZpZ3VyYXRpb24uanNvbj4nLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMuYXBwSWQgfHwgIW9wdGlvbnMubWFzdGVyS2V5KSB7XG4gICAgICBwcm9ncmFtLm91dHB1dEhlbHAoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJycpO1xuICAgICAgY29uc29sZS5lcnJvcignXFx1MDAxYlszMW1FUlJPUjogYXBwSWQgYW5kIG1hc3RlcktleSBhcmUgcmVxdWlyZWRcXHUwMDFiWzBtJyk7XG4gICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9uc1snbGl2ZVF1ZXJ5LmNsYXNzTmFtZXMnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LmNsYXNzTmFtZXMgPSBvcHRpb25zWydsaXZlUXVlcnkuY2xhc3NOYW1lcyddO1xuICAgICAgZGVsZXRlIG9wdGlvbnNbJ2xpdmVRdWVyeS5jbGFzc05hbWVzJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNVUkwnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LnJlZGlzVVJMID0gb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ10pIHtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5ID0gb3B0aW9ucy5saXZlUXVlcnkgfHwge307XG4gICAgICBvcHRpb25zLmxpdmVRdWVyeS5yZWRpc09wdGlvbnMgPSBvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzT3B0aW9ucyddO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmNsdXN0ZXIpIHtcbiAgICAgIGNvbnN0IG51bUNQVXMgPSB0eXBlb2Ygb3B0aW9ucy5jbHVzdGVyID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuY2x1c3RlciA6IG9zLmNwdXMoKS5sZW5ndGg7XG4gICAgICBpZiAoY2x1c3Rlci5pc01hc3Rlcikge1xuICAgICAgICBsb2dPcHRpb25zKCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ1BVczsgaSsrKSB7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2x1c3Rlci5vbignZXhpdCcsICh3b3JrZXIsIGNvZGUpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgd29ya2VyICR7d29ya2VyLnByb2Nlc3MucGlkfSBkaWVkICgke2NvZGV9KS4uLiBSZXN0YXJ0aW5nYCk7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2VTZXJ2ZXIuc3RhcnQob3B0aW9ucywgKCkgPT4ge1xuICAgICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIFBhcnNlU2VydmVyLnN0YXJ0KG9wdGlvbnMsICgpID0+IHtcbiAgICAgICAgbG9nT3B0aW9ucygpO1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByaW50U3VjY2Vzc01lc3NhZ2UoKSB7XG4gICAgICBjb25zb2xlLmxvZygnWycgKyBwcm9jZXNzLnBpZCArICddIHBhcnNlLXNlcnZlciBydW5uaW5nIG9uICcgKyBvcHRpb25zLnNlcnZlclVSTCk7XG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgJ1snICtcbiAgICAgICAgICAgIHByb2Nlc3MucGlkICtcbiAgICAgICAgICAgICddIEdyYXBoUUwgcnVubmluZyBvbiBodHRwOi8vbG9jYWxob3N0OicgK1xuICAgICAgICAgICAgb3B0aW9ucy5wb3J0ICtcbiAgICAgICAgICAgIG9wdGlvbnMuZ3JhcGhRTFBhdGhcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLm1vdW50UGxheWdyb3VuZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAnWycgK1xuICAgICAgICAgICAgcHJvY2Vzcy5waWQgK1xuICAgICAgICAgICAgJ10gUGxheWdyb3VuZCBydW5uaW5nIG9uIGh0dHA6Ly9sb2NhbGhvc3Q6JyArXG4gICAgICAgICAgICBvcHRpb25zLnBvcnQgK1xuICAgICAgICAgICAgb3B0aW9ucy5wbGF5Z3JvdW5kUGF0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbn0pO1xuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cli/utils/commander.js b/lib/cli/utils/commander.js new file mode 100644 index 0000000000..cff789e0ad --- /dev/null +++ b/lib/cli/utils/commander.js @@ -0,0 +1,163 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _commander = require("commander"); + +var _path = _interopRequireDefault(require("path")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* eslint-disable no-console */ +let _definitions; + +let _reverseDefinitions; + +let _defaults; + +_commander.Command.prototype.loadDefinitions = function (definitions) { + _definitions = definitions; + Object.keys(definitions).reduce((program, opt) => { + if (typeof definitions[opt] == 'object') { + const additionalOptions = definitions[opt]; + + if (additionalOptions.required === true) { + return program.option(`--${opt} <${opt}>`, additionalOptions.help, additionalOptions.action); + } else { + return program.option(`--${opt} [${opt}]`, additionalOptions.help, additionalOptions.action); + } + } + + return program.option(`--${opt} [${opt}]`); + }, this); + _reverseDefinitions = Object.keys(definitions).reduce((object, key) => { + let value = definitions[key]; + + if (typeof value == 'object') { + value = value.env; + } + + if (value) { + object[value] = key; + } + + return object; + }, {}); + _defaults = Object.keys(definitions).reduce((defs, opt) => { + if (_definitions[opt].default) { + defs[opt] = _definitions[opt].default; + } + + return defs; + }, {}); + /* istanbul ignore next */ + + this.on('--help', function () { + console.log(' Configure From Environment:'); + console.log(''); + Object.keys(_reverseDefinitions).forEach(key => { + console.log(` $ ${key}='${_reverseDefinitions[key]}'`); + }); + console.log(''); + }); +}; + +function parseEnvironment(env = {}) { + return Object.keys(_reverseDefinitions).reduce((options, key) => { + if (env[key]) { + const originalKey = _reverseDefinitions[key]; + + let action = option => option; + + if (typeof _definitions[originalKey] === 'object') { + action = _definitions[originalKey].action || action; + } + + options[_reverseDefinitions[key]] = action(env[key]); + } + + return options; + }, {}); +} + +function parseConfigFile(program) { + let options = {}; + + if (program.args.length > 0) { + let jsonPath = program.args[0]; + jsonPath = _path.default.resolve(jsonPath); + + const jsonConfig = require(jsonPath); + + if (jsonConfig.apps) { + if (jsonConfig.apps.length > 1) { + throw 'Multiple apps are not supported'; + } + + options = jsonConfig.apps[0]; + } else { + options = jsonConfig; + } + + Object.keys(options).forEach(key => { + const value = options[key]; + + if (!_definitions[key]) { + throw `error: unknown option ${key}`; + } + + const action = _definitions[key].action; + + if (action) { + options[key] = action(value); + } + }); + console.log(`Configuration loaded from ${jsonPath}`); + } + + return options; +} + +_commander.Command.prototype.setValuesIfNeeded = function (options) { + Object.keys(options).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(this, key)) { + this[key] = options[key]; + } + }); +}; + +_commander.Command.prototype._parse = _commander.Command.prototype.parse; + +_commander.Command.prototype.parse = function (args, env) { + this._parse(args); // Parse the environment first + + + const envOptions = parseEnvironment(env); + const fromFile = parseConfigFile(this); // Load the env if not passed from command line + + this.setValuesIfNeeded(envOptions); // Load from file to override + + this.setValuesIfNeeded(fromFile); // Last set the defaults + + this.setValuesIfNeeded(_defaults); +}; + +_commander.Command.prototype.getOptions = function () { + return Object.keys(_definitions).reduce((options, key) => { + if (typeof this[key] !== 'undefined') { + options[key] = this[key]; + } + + return options; + }, {}); +}; + +var _default = new _commander.Command(); +/* eslint-enable no-console */ + + +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvY29tbWFuZGVyLmpzIl0sIm5hbWVzIjpbIl9kZWZpbml0aW9ucyIsIl9yZXZlcnNlRGVmaW5pdGlvbnMiLCJfZGVmYXVsdHMiLCJDb21tYW5kIiwicHJvdG90eXBlIiwibG9hZERlZmluaXRpb25zIiwiZGVmaW5pdGlvbnMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwicHJvZ3JhbSIsIm9wdCIsImFkZGl0aW9uYWxPcHRpb25zIiwicmVxdWlyZWQiLCJvcHRpb24iLCJoZWxwIiwiYWN0aW9uIiwib2JqZWN0Iiwia2V5IiwidmFsdWUiLCJlbnYiLCJkZWZzIiwiZGVmYXVsdCIsIm9uIiwiY29uc29sZSIsImxvZyIsImZvckVhY2giLCJwYXJzZUVudmlyb25tZW50Iiwib3B0aW9ucyIsIm9yaWdpbmFsS2V5IiwicGFyc2VDb25maWdGaWxlIiwiYXJncyIsImxlbmd0aCIsImpzb25QYXRoIiwicGF0aCIsInJlc29sdmUiLCJqc29uQ29uZmlnIiwicmVxdWlyZSIsImFwcHMiLCJzZXRWYWx1ZXNJZk5lZWRlZCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9wYXJzZSIsInBhcnNlIiwiZW52T3B0aW9ucyIsImZyb21GaWxlIiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOzs7O0FBRkE7QUFHQSxJQUFJQSxZQUFKOztBQUNBLElBQUlDLG1CQUFKOztBQUNBLElBQUlDLFNBQUo7O0FBRUFDLG1CQUFRQyxTQUFSLENBQWtCQyxlQUFsQixHQUFvQyxVQUFTQyxXQUFULEVBQXNCO0FBQ3hETixFQUFBQSxZQUFZLEdBQUdNLFdBQWY7QUFFQUMsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVlGLFdBQVosRUFBeUJHLE1BQXpCLENBQWdDLENBQUNDLE9BQUQsRUFBVUMsR0FBVixLQUFrQjtBQUNoRCxRQUFJLE9BQU9MLFdBQVcsQ0FBQ0ssR0FBRCxDQUFsQixJQUEyQixRQUEvQixFQUF5QztB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UixDQUFrQjBDLFVBQWxCLEdBQStCLFlBQVc7QUFDeEMsU0FBT3ZDLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZUixZQUFaLEVBQTBCUyxNQUExQixDQUFpQyxDQUFDbUIsT0FBRCxFQUFVVixHQUFWLEtBQWtCO0FBQ3hELFFBQUksT0FBTyxLQUFLQSxHQUFMLENBQVAsS0FBcUIsV0FBekIsRUFBc0M7QUFDcENVLE1BQUFBLE9BQU8sQ0FBQ1YsR0FBRCxDQUFQLEdBQWUsS0FBS0EsR0FBTCxDQUFmO0FBQ0Q7O0FBQ0QsV0FBT1UsT0FBUDtBQUNELEdBTE0sRUFLSixFQUxJLENBQVA7QUFNRCxDQVBEOztlQVNlLElBQUl6QixrQkFBSixFO0FBQ2YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xubGV0IF9kZWZpbml0aW9ucztcbmxldCBfcmV2ZXJzZURlZmluaXRpb25zO1xubGV0IF9kZWZhdWx0cztcblxuQ29tbWFuZC5wcm90b3R5cGUubG9hZERlZmluaXRpb25zID0gZnVuY3Rpb24oZGVmaW5pdGlvbnMpIHtcbiAgX2RlZmluaXRpb25zID0gZGVmaW5pdGlvbnM7XG5cbiAgT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgocHJvZ3JhbSwgb3B0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBkZWZpbml0aW9uc1tvcHRdID09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IGRlZmluaXRpb25zW29wdF07XG4gICAgICBpZiAoYWRkaXRpb25hbE9wdGlvbnMucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIHByb2dyYW0ub3B0aW9uKFxuICAgICAgICAgIGAtLSR7b3B0fSA8JHtvcHR9PmAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuaGVscCxcbiAgICAgICAgICBhZGRpdGlvbmFsT3B0aW9ucy5hY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihcbiAgICAgICAgICBgLS0ke29wdH0gWyR7b3B0fV1gLFxuICAgICAgICAgIGFkZGl0aW9uYWxPcHRpb25zLmhlbHAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihgLS0ke29wdH0gWyR7b3B0fV1gKTtcbiAgfSwgdGhpcyk7XG5cbiAgX3JldmVyc2VEZWZpbml0aW9ucyA9IE9iamVjdC5rZXlzKGRlZmluaXRpb25zKS5yZWR1Y2UoKG9iamVjdCwga2V5KSA9PiB7XG4gICAgbGV0IHZhbHVlID0gZGVmaW5pdGlvbnNba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLmVudjtcbiAgICB9XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBvYmplY3RbdmFsdWVdID0ga2V5O1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LCB7fSk7XG5cbiAgX2RlZmF1bHRzID0gT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgoZGVmcywgb3B0KSA9PiB7XG4gICAgaWYgKF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQpIHtcbiAgICAgIGRlZnNbb3B0XSA9IF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQ7XG4gICAgfVxuICAgIHJldHVybiBkZWZzO1xuICB9LCB7fSk7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgdGhpcy5vbignLS1oZWxwJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc29sZS5sb2coJyAgQ29uZmlndXJlIEZyb20gRW52aXJvbm1lbnQ6Jyk7XG4gICAgY29uc29sZS5sb2coJycpO1xuICAgIE9iamVjdC5rZXlzKF9yZXZlcnNlRGVmaW5pdGlvbnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGAgICAgJCAke2tleX09JyR7X3JldmVyc2VEZWZpbml0aW9uc1trZXldfSdgKTtcbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZygnJyk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gcGFyc2VFbnZpcm9ubWVudChlbnYgPSB7fSkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoX3JldmVyc2VEZWZpbml0aW9ucykucmVkdWNlKChvcHRpb25zLCBrZXkpID0+IHtcbiAgICBpZiAoZW52W2tleV0pIHtcbiAgICAgIGNvbnN0IG9yaWdpbmFsS2V5ID0gX3JldmVyc2VEZWZpbml0aW9uc1trZXldO1xuICAgICAgbGV0IGFjdGlvbiA9IG9wdGlvbiA9PiBvcHRpb247XG4gICAgICBpZiAodHlwZW9mIF9kZWZpbml0aW9uc1tvcmlnaW5hbEtleV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGFjdGlvbiA9IF9kZWZpbml0aW9uc1tvcmlnaW5hbEtleV0uYWN0aW9uIHx8IGFjdGlvbjtcbiAgICAgIH1cbiAgICAgIG9wdGlvbnNbX3JldmVyc2VEZWZpbml0aW9uc1trZXldXSA9IGFjdGlvbihlbnZba2V5XSk7XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9LCB7fSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlQ29uZmlnRmlsZShwcm9ncmFtKSB7XG4gIGxldCBvcHRpb25zID0ge307XG4gIGlmIChwcm9ncmFtLmFyZ3MubGVuZ3RoID4gMCkge1xuICAgIGxldCBqc29uUGF0aCA9IHByb2dyYW0uYXJnc1swXTtcbiAgICBqc29uUGF0aCA9IHBhdGgucmVzb2x2ZShqc29uUGF0aCk7XG4gICAgY29uc3QganNvbkNvbmZpZyA9IHJlcXVpcmUoanNvblBhdGgpO1xuICAgIGlmIChqc29uQ29uZmlnLmFwcHMpIHtcbiAgICAgIGlmIChqc29uQ29uZmlnLmFwcHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyAnTXVsdGlwbGUgYXBwcyBhcmUgbm90IHN1cHBvcnRlZCc7XG4gICAgICB9XG4gICAgICBvcHRpb25zID0ganNvbkNvbmZpZy5hcHBzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zID0ganNvbkNvbmZpZztcbiAgICB9XG4gICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW2tleV07XG4gICAgICBpZiAoIV9kZWZpbml0aW9uc1trZXldKSB7XG4gICAgICAgIHRocm93IGBlcnJvcjogdW5rbm93biBvcHRpb24gJHtrZXl9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjdGlvbiA9IF9kZWZpbml0aW9uc1trZXldLmFjdGlvbjtcbiAgICAgIGlmIChhY3Rpb24pIHtcbiAgICAgICAgb3B0aW9uc1trZXldID0gYWN0aW9uKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZyhgQ29uZmlndXJhdGlvbiBsb2FkZWQgZnJvbSAke2pzb25QYXRofWApO1xuICB9XG4gIHJldHVybiBvcHRpb25zO1xufVxuXG5Db21tYW5kLnByb3RvdHlwZS5zZXRWYWx1ZXNJZk5lZWRlZCA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsIGtleSkpIHtcbiAgICAgIHRoaXNba2V5XSA9IG9wdGlvbnNba2V5XTtcbiAgICB9XG4gIH0pO1xufTtcblxuQ29tbWFuZC5wcm90b3R5cGUuX3BhcnNlID0gQ29tbWFuZC5wcm90b3R5cGUucGFyc2U7XG5cbkNvbW1hbmQucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oYXJncywgZW52KSB7XG4gIHRoaXMuX3BhcnNlKGFyZ3MpO1xuICAvLyBQYXJzZSB0aGUgZW52aXJvbm1lbnQgZmlyc3RcbiAgY29uc3QgZW52T3B0aW9ucyA9IHBhcnNlRW52aXJvbm1lbnQoZW52KTtcbiAgY29uc3QgZnJvbUZpbGUgPSBwYXJzZUNvbmZpZ0ZpbGUodGhpcyk7XG4gIC8vIExvYWQgdGhlIGVudiBpZiBub3QgcGFzc2VkIGZyb20gY29tbWFuZCBsaW5lXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZW52T3B0aW9ucyk7XG4gIC8vIExvYWQgZnJvbSBmaWxlIHRvIG92ZXJyaWRlXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZnJvbUZpbGUpO1xuICAvLyBMYXN0IHNldCB0aGUgZGVmYXVsdHNcbiAgdGhpcy5zZXRWYWx1ZXNJZk5lZWRlZChfZGVmYXVsdHMpO1xufTtcblxuQ29tbWFuZC5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoX2RlZmluaXRpb25zKS5yZWR1Y2UoKG9wdGlvbnMsIGtleSkgPT4ge1xuICAgIGlmICh0eXBlb2YgdGhpc1trZXldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgb3B0aW9uc1trZXldID0gdGhpc1trZXldO1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfSwge30pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgbmV3IENvbW1hbmQoKTtcbi8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuIl19 \ No newline at end of file diff --git a/lib/cli/utils/runner.js b/lib/cli/utils/runner.js new file mode 100644 index 0000000000..5725eaca43 --- /dev/null +++ b/lib/cli/utils/runner.js @@ -0,0 +1,65 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = _default; + +var _commander = _interopRequireDefault(require("./commander")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function logStartupOptions(options) { + for (const key in options) { + let value = options[key]; + + if (key == 'masterKey') { + value = '***REDACTED***'; + } + + if (key == 'push' && options.verbose != true) { + value = '***REDACTED***'; + } + + if (typeof value === 'object') { + try { + value = JSON.stringify(value); + } catch (e) { + if (value && value.constructor && value.constructor.name) { + value = value.constructor.name; + } + } + } + /* eslint-disable no-console */ + + + console.log(`${key}: ${value}`); + /* eslint-enable no-console */ + } +} + +function _default({ + definitions, + help, + usage, + start +}) { + _commander.default.loadDefinitions(definitions); + + if (usage) { + _commander.default.usage(usage); + } + + if (help) { + _commander.default.on('--help', help); + } + + _commander.default.parse(process.argv, process.env); + + const options = _commander.default.getOptions(); + + start(_commander.default, options, function () { + logStartupOptions(options); + }); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvcnVubmVyLmpzIl0sIm5hbWVzIjpbImxvZ1N0YXJ0dXBPcHRpb25zIiwib3B0aW9ucyIsImtleSIsInZhbHVlIiwidmVyYm9zZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiY29uc29sZSIsImxvZyIsImRlZmluaXRpb25zIiwiaGVscCIsInVzYWdlIiwic3RhcnQiLCJwcm9ncmFtIiwibG9hZERlZmluaXRpb25zIiwib24iLCJwYXJzZSIsInByb2Nlc3MiLCJhcmd2IiwiZW52IiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsU0FBU0EsaUJBQVQsQ0FBMkJDLE9BQTNCLEVBQW9DO0FBQ2xDLE9BQUssTUFBTUMsR0FBWCxJQUFrQkQsT0FBbEIsRUFBMkI7QUFDekIsUUFBSUUsS0FBSyxHQUFHRixPQUFPLENBQUNDLEdBQUQsQ0FBbkI7O0FBQ0EsUUFBSUEsR0FBRyxJQUFJLFdBQVgsRUFBd0I7QUFDdEJDLE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUlELEdBQUcsSUFBSSxNQUFQLElBQWlCRCxPQUFPLENBQUNHLE9BQVIsSUFBbUIsSUFBeEMsRUFBOEM7QUFDNUNELE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUksT0FBT0EsS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUM3QixVQUFJO0FBQ0ZBLFFBQUFBLEtBQUssR0FBR0UsSUFBSSxDQUFDQyxTQUFMLENBQWVILEtBQWYsQ0FBUjtBQUNELE9BRkQsQ0FFRSxPQUFPSSxDQUFQLEVBQVU7QUFDVixZQUFJSixLQUFLLElBQUlBLEtBQUssQ0FBQ0ssV0FBZixJQUE4QkwsS0FBSyxDQUFDSyxXQUFOLENBQWtCQyxJQUFwRCxFQUEwRDtBQUN4RE4sVUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNLLFdBQU4sQ0FBa0JDLElBQTFCO0FBQ0Q7QUFDRjtBQUNGO0FBQ0Q7OztBQUNBQyxJQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxHQUFFVCxHQUFJLEtBQUlDLEtBQU0sRUFBN0I7QUFDQTtBQUNEO0FBQ0Y7O0FBRWMsa0JBQVM7QUFBRVMsRUFBQUEsV0FBRjtBQUFlQyxFQUFBQSxJQUFmO0FBQXFCQyxFQUFBQSxLQUFyQjtBQUE0QkMsRUFBQUE7QUFBNUIsQ0FBVCxFQUE4QztBQUMzREMscUJBQVFDLGVBQVIsQ0FBd0JMLFdBQXhCOztBQUNBLE1BQUlFLEtBQUosRUFBVztBQUNURSx1QkFBUUYsS0FBUixDQUFjQSxLQUFkO0FBQ0Q7O0FBQ0QsTUFBSUQsSUFBSixFQUFVO0FBQ1JHLHVCQUFRRSxFQUFSLENBQVcsUUFBWCxFQUFxQkwsSUFBckI7QUFDRDs7QUFDREcscUJBQVFHLEtBQVIsQ0FBY0MsT0FBTyxDQUFDQyxJQUF0QixFQUE0QkQsT0FBTyxDQUFDRSxHQUFwQzs7QUFFQSxRQUFNckIsT0FBTyxHQUFHZSxtQkFBUU8sVUFBUixFQUFoQjs7QUFDQVIsRUFBQUEsS0FBSyxDQUFDQyxrQkFBRCxFQUFVZixPQUFWLEVBQW1CLFlBQVc7QUFDakNELElBQUFBLGlCQUFpQixDQUFDQyxPQUFELENBQWpCO0FBQ0QsR0FGSSxDQUFMO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHJvZ3JhbSBmcm9tICcuL2NvbW1hbmRlcic7XG5cbmZ1bmN0aW9uIGxvZ1N0YXJ0dXBPcHRpb25zKG9wdGlvbnMpIHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucykge1xuICAgIGxldCB2YWx1ZSA9IG9wdGlvbnNba2V5XTtcbiAgICBpZiAoa2V5ID09ICdtYXN0ZXJLZXknKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmIChrZXkgPT0gJ3B1c2gnICYmIG9wdGlvbnMudmVyYm9zZSAhPSB0cnVlKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgIGNvbnNvbGUubG9nKGAke2tleX06ICR7dmFsdWV9YCk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oeyBkZWZpbml0aW9ucywgaGVscCwgdXNhZ2UsIHN0YXJ0IH0pIHtcbiAgcHJvZ3JhbS5sb2FkRGVmaW5pdGlvbnMoZGVmaW5pdGlvbnMpO1xuICBpZiAodXNhZ2UpIHtcbiAgICBwcm9ncmFtLnVzYWdlKHVzYWdlKTtcbiAgfVxuICBpZiAoaGVscCkge1xuICAgIHByb2dyYW0ub24oJy0taGVscCcsIGhlbHApO1xuICB9XG4gIHByb2dyYW0ucGFyc2UocHJvY2Vzcy5hcmd2LCBwcm9jZXNzLmVudik7XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHByb2dyYW0uZ2V0T3B0aW9ucygpO1xuICBzdGFydChwcm9ncmFtLCBvcHRpb25zLCBmdW5jdGlvbigpIHtcbiAgICBsb2dTdGFydHVwT3B0aW9ucyhvcHRpb25zKTtcbiAgfSk7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/cloud-code/HTTPResponse.js b/lib/cloud-code/HTTPResponse.js new file mode 100644 index 0000000000..88c745095b --- /dev/null +++ b/lib/cloud-code/HTTPResponse.js @@ -0,0 +1,73 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +/** + * @typedef Parse.Cloud.HTTPResponse + * @property {Buffer} buffer The raw byte representation of the response body. Use this to receive binary data. See Buffer for more details. + * @property {Object} cookies The cookies sent by the server. The keys in this object are the names of the cookies. The values are Parse.Cloud.Cookie objects. + * @property {Object} data The parsed response body as a JavaScript object. This is only available when the response Content-Type is application/x-www-form-urlencoded or application/json. + * @property {Object} headers The headers sent by the server. The keys in this object are the names of the headers. We do not support multiple response headers with the same name. In the common case of Set-Cookie headers, please use the cookies field instead. + * @property {Number} status The status code. + * @property {String} text The raw text representation of the response body. + */ +class HTTPResponse { + constructor(response, body) { + let _text, _data; + + this.status = response.statusCode; + this.headers = response.headers || {}; + this.cookies = this.headers['set-cookie']; + + if (typeof body == 'string') { + _text = body; + } else if (Buffer.isBuffer(body)) { + this.buffer = body; + } else if (typeof body == 'object') { + _data = body; + } + + const getText = () => { + if (!_text && this.buffer) { + _text = this.buffer.toString('utf-8'); + } else if (!_text && _data) { + _text = JSON.stringify(_data); + } + + return _text; + }; + + const getData = () => { + if (!_data) { + try { + _data = JSON.parse(getText()); + } catch (e) { + /* */ + } + } + + return _data; + }; + + Object.defineProperty(this, 'body', { + get: () => { + return body; + } + }); + Object.defineProperty(this, 'text', { + enumerable: true, + get: getText + }); + Object.defineProperty(this, 'data', { + enumerable: true, + get: getData + }); + } + +} + +exports.default = HTTPResponse; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL0hUVFBSZXNwb25zZS5qcyJdLCJuYW1lcyI6WyJIVFRQUmVzcG9uc2UiLCJjb25zdHJ1Y3RvciIsInJlc3BvbnNlIiwiYm9keSIsIl90ZXh0IiwiX2RhdGEiLCJzdGF0dXMiLCJzdGF0dXNDb2RlIiwiaGVhZGVycyIsImNvb2tpZXMiLCJCdWZmZXIiLCJpc0J1ZmZlciIsImJ1ZmZlciIsImdldFRleHQiLCJ0b1N0cmluZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJnZXREYXRhIiwicGFyc2UiLCJlIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJlbnVtZXJhYmxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7Ozs7OztBQVNlLE1BQU1BLFlBQU4sQ0FBbUI7QUFDaENDLEVBQUFBLFdBQVcsQ0FBQ0MsUUFBRCxFQUFXQyxJQUFYLEVBQWlCO0FBQzFCLFFBQUlDLEtBQUosRUFBV0MsS0FBWDs7QUFDQSxTQUFLQyxNQUFMLEdBQWNKLFFBQVEsQ0FBQ0ssVUFBdkI7QUFDQSxTQUFLQyxPQUFMLEdBQWVOLFFBQVEsQ0FBQ00sT0FBVCxJQUFvQixFQUFuQztBQUNBLFNBQUtDLE9BQUwsR0FBZSxLQUFLRCxPQUFMLENBQWEsWUFBYixDQUFmOztBQUVBLFFBQUksT0FBT0wsSUFBUCxJQUFlLFFBQW5CLEVBQTZCO0FBQzNCQyxNQUFBQSxLQUFLLEdBQUdELElBQVI7QUFDRCxLQUZELE1BRU8sSUFBSU8sTUFBTSxDQUFDQyxRQUFQLENBQWdCUixJQUFoQixDQUFKLEVBQTJCO0FBQ2hDLFdBQUtTLE1BQUwsR0FBY1QsSUFBZDtBQUNELEtBRk0sTUFFQSxJQUFJLE9BQU9BLElBQVAsSUFBZSxRQUFuQixFQUE2QjtBQUNsQ0UsTUFBQUEsS0FBSyxHQUFHRixJQUFSO0FBQ0Q7O0FBRUQsVUFBTVUsT0FBTyxHQUFHLE1BQU07QUFDcEIsVUFBSSxDQUFDVCxLQUFELElBQVUsS0FBS1EsTUFBbkIsRUFBMkI7QUFDekJSLFFBQUFBLEtBQUssR0FBRyxLQUFLUSxNQUFMLENBQVlFLFFBQVosQ0FBcUIsT0FBckIsQ0FBUjtBQUNELE9BRkQsTUFFTyxJQUFJLENBQUNWLEtBQUQsSUFBVUMsS0FBZCxFQUFxQjtBQUMxQkQsUUFBQUEsS0FBSyxHQUFHVyxJQUFJLENBQUNDLFNBQUwsQ0FBZVgsS0FBZixDQUFSO0FBQ0Q7O0FBQ0QsYUFBT0QsS0FBUDtBQUNELEtBUEQ7O0FBU0EsVUFBTWEsT0FBTyxHQUFHLE1BQU07QUFDcEIsVUFBSSxDQUFDWixLQUFMLEVBQVk7QUFDVixZQUFJO0FBQ0ZBLFVBQUFBLEtBQUssR0FBR1UsSUFBSSxDQUFDRyxLQUFMLENBQVdMLE9BQU8sRUFBbEIsQ0FBUjtBQUNELFNBRkQsQ0FFRSxPQUFPTSxDQUFQLEVBQVU7QUFDVjtBQUNEO0FBQ0Y7O0FBQ0QsYUFBT2QsS0FBUDtBQUNELEtBVEQ7O0FBV0FlLElBQUFBLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixNQUE1QixFQUFvQztBQUNsQ0MsTUFBQUEsR0FBRyxFQUFFLE1BQU07QUFDVCxlQUFPbkIsSUFBUDtBQUNEO0FBSGlDLEtBQXBDO0FBTUFpQixJQUFBQSxNQUFNLENBQUNDLGNBQVAsQ0FBc0IsSUFBdEIsRUFBNEIsTUFBNUIsRUFBb0M7QUFDbENFLE1BQUFBLFVBQVUsRUFBRSxJQURzQjtBQUVsQ0QsTUFBQUEsR0FBRyxFQUFFVDtBQUY2QixLQUFwQztBQUtBTyxJQUFBQSxNQUFNLENBQUNDLGNBQVAsQ0FBc0IsSUFBdEIsRUFBNEIsTUFBNUIsRUFBb0M7QUFDbENFLE1BQUFBLFVBQVUsRUFBRSxJQURzQjtBQUVsQ0QsTUFBQUEsR0FBRyxFQUFFTDtBQUY2QixLQUFwQztBQUlEOztBQWxEK0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEB0eXBlZGVmIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZVxuICogQHByb3BlcnR5IHtCdWZmZXJ9IGJ1ZmZlciBUaGUgcmF3IGJ5dGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHJlc3BvbnNlIGJvZHkuIFVzZSB0aGlzIHRvIHJlY2VpdmUgYmluYXJ5IGRhdGEuIFNlZSBCdWZmZXIgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjb29raWVzIFRoZSBjb29raWVzIHNlbnQgYnkgdGhlIHNlcnZlci4gVGhlIGtleXMgaW4gdGhpcyBvYmplY3QgYXJlIHRoZSBuYW1lcyBvZiB0aGUgY29va2llcy4gVGhlIHZhbHVlcyBhcmUgUGFyc2UuQ2xvdWQuQ29va2llIG9iamVjdHMuXG4gKiBAcHJvcGVydHkge09iamVjdH0gZGF0YSBUaGUgcGFyc2VkIHJlc3BvbnNlIGJvZHkgYXMgYSBKYXZhU2NyaXB0IG9iamVjdC4gVGhpcyBpcyBvbmx5IGF2YWlsYWJsZSB3aGVuIHRoZSByZXNwb25zZSBDb250ZW50LVR5cGUgaXMgYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIG9yIGFwcGxpY2F0aW9uL2pzb24uXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyBzZW50IGJ5IHRoZSBzZXJ2ZXIuIFRoZSBrZXlzIGluIHRoaXMgb2JqZWN0IGFyZSB0aGUgbmFtZXMgb2YgdGhlIGhlYWRlcnMuIFdlIGRvIG5vdCBzdXBwb3J0IG11bHRpcGxlIHJlc3BvbnNlIGhlYWRlcnMgd2l0aCB0aGUgc2FtZSBuYW1lLiBJbiB0aGUgY29tbW9uIGNhc2Ugb2YgU2V0LUNvb2tpZSBoZWFkZXJzLCBwbGVhc2UgdXNlIHRoZSBjb29raWVzIGZpZWxkIGluc3RlYWQuXG4gKiBAcHJvcGVydHkge051bWJlcn0gc3RhdHVzIFRoZSBzdGF0dXMgY29kZS5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB0ZXh0IFRoZSByYXcgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVzcG9uc2UgYm9keS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSFRUUFJlc3BvbnNlIHtcbiAgY29uc3RydWN0b3IocmVzcG9uc2UsIGJvZHkpIHtcbiAgICBsZXQgX3RleHQsIF9kYXRhO1xuICAgIHRoaXMuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzQ29kZTtcbiAgICB0aGlzLmhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzIHx8IHt9O1xuICAgIHRoaXMuY29va2llcyA9IHRoaXMuaGVhZGVyc1snc2V0LWNvb2tpZSddO1xuXG4gICAgaWYgKHR5cGVvZiBib2R5ID09ICdzdHJpbmcnKSB7XG4gICAgICBfdGV4dCA9IGJvZHk7XG4gICAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcbiAgICAgIHRoaXMuYnVmZmVyID0gYm9keTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBib2R5ID09ICdvYmplY3QnKSB7XG4gICAgICBfZGF0YSA9IGJvZHk7XG4gICAgfVxuXG4gICAgY29uc3QgZ2V0VGV4dCA9ICgpID0+IHtcbiAgICAgIGlmICghX3RleHQgJiYgdGhpcy5idWZmZXIpIHtcbiAgICAgICAgX3RleHQgPSB0aGlzLmJ1ZmZlci50b1N0cmluZygndXRmLTgnKTtcbiAgICAgIH0gZWxzZSBpZiAoIV90ZXh0ICYmIF9kYXRhKSB7XG4gICAgICAgIF90ZXh0ID0gSlNPTi5zdHJpbmdpZnkoX2RhdGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIF90ZXh0O1xuICAgIH07XG5cbiAgICBjb25zdCBnZXREYXRhID0gKCkgPT4ge1xuICAgICAgaWYgKCFfZGF0YSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIF9kYXRhID0gSlNPTi5wYXJzZShnZXRUZXh0KCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLyogKi9cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIF9kYXRhO1xuICAgIH07XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2JvZHknLCB7XG4gICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0ZXh0Jywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZ2V0VGV4dCxcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZGF0YScsIHtcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGdldERhdGEsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/cloud-code/Parse.Cloud.js b/lib/cloud-code/Parse.Cloud.js new file mode 100644 index 0000000000..e81a930907 --- /dev/null +++ b/lib/cloud-code/Parse.Cloud.js @@ -0,0 +1,685 @@ +"use strict"; + +var _node = require("parse/node"); + +var triggers = _interopRequireWildcard(require("../triggers")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function isParseObjectConstructor(object) { + return typeof object === 'function' && Object.prototype.hasOwnProperty.call(object, 'className'); +} + +function getClassName(parseClass) { + if (parseClass && parseClass.className) { + return parseClass.className; + } + + return parseClass; +} +/** @namespace + * @name Parse + * @description The Parse SDK. + * see [api docs](https://docs.parseplatform.org/js/api) and [guide](https://docs.parseplatform.org/js/guide) + */ + +/** @namespace + * @name Parse.Cloud + * @memberof Parse + * @description The Parse Cloud Code SDK. + */ + + +var ParseCloud = {}; +/** + * Defines a Cloud Function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.define('functionName', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.define('functionName', (request) => { + * // code here + * }, { ...validationObject }); + * ``` + * + * @static + * @memberof Parse.Cloud + * @param {String} name The name of the Cloud Function + * @param {Function} data The Cloud Function to register. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + +ParseCloud.define = function (functionName, handler, validationHandler) { + triggers.addFunction(functionName, handler, validationHandler, _node.Parse.applicationId); +}; +/** + * Defines a Background Job. + * + * **Available in Cloud Code only.** + * + * @method job + * @name Parse.Cloud.job + * @param {String} name The name of the Background Job + * @param {Function} func The Background Job to register. This function can be async should take a single parameters a {@link Parse.Cloud.JobRequest} + * + */ + + +ParseCloud.job = function (functionName, handler) { + triggers.addJob(functionName, handler, _node.Parse.applicationId); +}; +/** + * + * Registers a before save function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * + * ``` + * Parse.Cloud.beforeSave('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeSave(Parse.User, (request) => { + * // code here + * }, { ...validationObject }) + * ``` + * + * @method beforeSave + * @name Parse.Cloud.beforeSave + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a save. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeSave = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeSave, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before delete function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.beforeDelete('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeDelete(Parse.User, (request) => { + * // code here + * }, { ...validationObject }) + *``` + * + * @method beforeDelete + * @name Parse.Cloud.beforeDelete + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before delete function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a delete. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeDelete = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeDelete, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * + * Registers the before login function. + * + * **Available in Cloud Code only.** + * + * This function provides further control + * in validating a login attempt. Specifically, + * it is triggered after a user enters + * correct credentials (or other valid authData), + * but prior to a session being generated. + * + * ``` + * Parse.Cloud.beforeLogin((request) => { + * // code here + * }) + * + * ``` + * + * @method beforeLogin + * @name Parse.Cloud.beforeLogin + * @param {Function} func The function to run before a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + */ + + +ParseCloud.beforeLogin = function (handler) { + let className = '_User'; + + if (typeof handler === 'string' || isParseObjectConstructor(handler)) { + // validation will occur downstream, this is to maintain internal + // code consistency with the other hook types. + className = getClassName(handler); + handler = arguments[1]; + } + + triggers.addTrigger(triggers.Types.beforeLogin, className, handler, _node.Parse.applicationId); +}; +/** + * + * Registers the after login function. + * + * **Available in Cloud Code only.** + * + * This function is triggered after a user logs in successfully, + * and after a _Session object has been created. + * + * ``` + * Parse.Cloud.afterLogin((request) => { + * // code here + * }); + * ``` + * + * @method afterLogin + * @name Parse.Cloud.afterLogin + * @param {Function} func The function to run after a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + */ + + +ParseCloud.afterLogin = function (handler) { + let className = '_User'; + + if (typeof handler === 'string' || isParseObjectConstructor(handler)) { + // validation will occur downstream, this is to maintain internal + // code consistency with the other hook types. + className = getClassName(handler); + handler = arguments[1]; + } + + triggers.addTrigger(triggers.Types.afterLogin, className, handler, _node.Parse.applicationId); +}; +/** + * + * Registers the after logout function. + * + * **Available in Cloud Code only.** + * + * This function is triggered after a user logs out. + * + * ``` + * Parse.Cloud.afterLogout((request) => { + * // code here + * }); + * ``` + * + * @method afterLogout + * @name Parse.Cloud.afterLogout + * @param {Function} func The function to run after a logout. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + */ + + +ParseCloud.afterLogout = function (handler) { + let className = '_Session'; + + if (typeof handler === 'string' || isParseObjectConstructor(handler)) { + // validation will occur downstream, this is to maintain internal + // code consistency with the other hook types. + className = getClassName(handler); + handler = arguments[1]; + } + + triggers.addTrigger(triggers.Types.afterLogout, className, handler, _node.Parse.applicationId); +}; +/** + * Registers an after save function. + * + * **Available in Cloud Code only.** + * + * If you want to use afterSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * + * ``` + * Parse.Cloud.afterSave('MyCustomClass', async function(request) { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterSave(Parse.User, async function(request) { + * // code here + * }, { ...validationObject }); + * ``` + * + * @method afterSave + * @name Parse.Cloud.afterSave + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run after a save. This function can be an async function and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterSave = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterSave, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after delete function. + * + * **Available in Cloud Code only.** + * + * If you want to use afterDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.afterDelete('MyCustomClass', async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterDelete(Parse.User, async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterDelete + * @name Parse.Cloud.afterDelete + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after delete function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run after a delete. This function can be async and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterDelete = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterDelete, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before find function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.beforeFind('MyCustomClass', async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeFind(Parse.User, async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeFind + * @name Parse.Cloud.beforeFind + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before find function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.BeforeFindRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.BeforeFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeFind = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeFind, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after find function. + * + * **Available in Cloud Code only.** + * + * If you want to use afterFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.afterFind('MyCustomClass', async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterFind(Parse.User, async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterFind + * @name Parse.Cloud.afterFind + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after find function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.AfterFindRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.AfterFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterFind = function (parseClass, handler, validationHandler) { + const className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterFind, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before save file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.beforeSaveFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeSaveFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeSaveFile + * @name Parse.Cloud.beforeSaveFile + * @param {Function} func The function to run before saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeSaveFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.beforeSaveFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after save file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.afterSaveFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterSaveFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterSaveFile + * @name Parse.Cloud.afterSaveFile + * @param {Function} func The function to run after saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterSaveFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.afterSaveFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before delete file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.beforeDeleteFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeDeleteFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeDeleteFile + * @name Parse.Cloud.beforeDeleteFile + * @param {Function} func The function to run before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeDeleteFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.beforeDeleteFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after delete file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.afterDeleteFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterDeleteFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterDeleteFile + * @name Parse.Cloud.afterDeleteFile + * @param {Function} func The function to after before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterDeleteFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.afterDeleteFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before live query server connect function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.beforeConnect(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeConnect(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeConnect + * @name Parse.Cloud.beforeConnect + * @param {Function} func The function to before connection is made. This function can be async and should take just one parameter, {@link Parse.Cloud.ConnectTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.ConnectTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeConnect = function (handler, validationHandler) { + triggers.addConnectTrigger(triggers.Types.beforeConnect, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before live query subscription function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeSubscribe for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.beforeSubscribe('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeSubscribe(Parse.User, (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeSubscribe + * @name Parse.Cloud.beforeSubscribe + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before subscription function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a subscription. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeSubscribe = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeSubscribe, className, handler, _node.Parse.applicationId, validationHandler); +}; + +ParseCloud.onLiveQueryEvent = function (handler) { + triggers.addLiveQueryEventHandler(handler, _node.Parse.applicationId); +}; +/** + * Registers an after live query server event function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterLiveQueryEvent + * @name Parse.Cloud.afterLiveQueryEvent + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after live query event function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run after a live query event. This function can be async and should take one parameter, a {@link Parse.Cloud.LiveQueryEventTrigger}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.LiveQueryEventTrigger}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterLiveQueryEvent = function (parseClass, handler, validationHandler) { + const className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterEvent, className, handler, _node.Parse.applicationId, validationHandler); +}; + +ParseCloud._removeAllHooks = () => { + triggers._unregisterAll(); +}; + +ParseCloud.useMasterKey = () => { + // eslint-disable-next-line + console.warn('Parse.Cloud.useMasterKey is deprecated (and has no effect anymore) on parse-server, please refer to the cloud code migration notes: http://docs.parseplatform.org/parse-server/guide/#master-key-must-be-passed-explicitly'); +}; + +ParseCloud.httpRequest = require('./httpRequest'); +module.exports = ParseCloud; +/** + * @interface Parse.Cloud.TriggerRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.Object} object The object triggering the hook. + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) + * @property {Object} log The current logger inside Parse Server. + * @property {Parse.Object} original If set, the object, as currently stored. + */ + +/** + * @interface Parse.Cloud.FileTriggerRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.File} file The file that triggered the hook. + * @property {Integer} fileSize The size of the file in bytes. + * @property {Integer} contentLength The value from Content-Length header + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSaveFile`, `afterSaveFile`) + * @property {Object} log The current logger inside Parse Server. + */ + +/** + * @interface Parse.Cloud.ConnectTriggerRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} useMasterKey If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Integer} clients The number of clients connected. + * @property {Integer} subscriptions The number of subscriptions connected. + * @property {String} sessionToken If set, the session of the user that made the request. + */ + +/** + * @interface Parse.Cloud.LiveQueryEventTrigger + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} useMasterKey If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {String} sessionToken If set, the session of the user that made the request. + * @property {String} event The live query event that triggered the request. + * @property {Parse.Object} object The object triggering the hook. + * @property {Parse.Object} original If set, the object, as currently stored. + * @property {Integer} clients The number of clients connected. + * @property {Integer} subscriptions The number of subscriptions connected. + * @property {Boolean} sendEvent If the LiveQuery event should be sent to the client. Set to false to prevent LiveQuery from pushing to the client. + */ + +/** + * @interface Parse.Cloud.BeforeFindRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.Query} query The query triggering the hook. + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) + * @property {Object} log The current logger inside Parse Server. + * @property {Boolean} isGet wether the query a `get` or a `find` + */ + +/** + * @interface Parse.Cloud.AfterFindRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.Query} query The query triggering the hook. + * @property {Array} results The results the query yielded. + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) + * @property {Object} log The current logger inside Parse Server. + */ + +/** + * @interface Parse.Cloud.FunctionRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Object} params The params passed to the cloud function. + */ + +/** + * @interface Parse.Cloud.JobRequest + * @property {Object} params The params passed to the background job. + * @property {function} message If message is called with a string argument, will update the current message to be stored in the job status. + */ + +/** + * @interface Parse.Cloud.ValidatorObject + * @property {Boolean} requireUser whether the cloud trigger requires a user. + * @property {Boolean} requireMaster whether the cloud trigger requires a master key. + * @property {Boolean} validateMasterKey whether the validator should run if masterKey is provided. Defaults to false. + * @property {Boolean} skipWithMasterKey whether the cloud code function should be ignored using a masterKey. + * + * @property {Array|Object} requireUserKeys If set, keys required on request.user to make the request. + * @property {String} requireUserKeys.field If requireUserKeys is an object, name of field to validate on request user + * @property {Array|function|Any} requireUserKeys.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. + * @property {String} requireUserKeys.field.error custom error message if field is invalid. + * + * @property {Object|Array} fields if an array of strings, validator will look for keys in request.params, and throw if not provided. If Object, fields to validate. If the trigger is a cloud function, `request.params` will be validated, otherwise `request.object`. + * @property {String} fields.field name of field to validate. + * @property {String} fields.field.type expected type of data for field. + * @property {Boolean} fields.field.constant whether the field can be modified on the object. + * @property {Any} fields.field.default default value if field is `null`, or initial value `constant` is `true`. + * @property {Array|function|Any} fields.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. + * @property {String} fields.field.error custom error message if field is invalid. + */ +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL1BhcnNlLkNsb3VkLmpzIl0sIm5hbWVzIjpbImlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvciIsIm9iamVjdCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImdldENsYXNzTmFtZSIsInBhcnNlQ2xhc3MiLCJjbGFzc05hbWUiLCJQYXJzZUNsb3VkIiwiZGVmaW5lIiwiZnVuY3Rpb25OYW1lIiwiaGFuZGxlciIsInZhbGlkYXRpb25IYW5kbGVyIiwidHJpZ2dlcnMiLCJhZGRGdW5jdGlvbiIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsImpvYiIsImFkZEpvYiIsImJlZm9yZVNhdmUiLCJhZGRUcmlnZ2VyIiwiVHlwZXMiLCJiZWZvcmVEZWxldGUiLCJiZWZvcmVMb2dpbiIsImFyZ3VtZW50cyIsImFmdGVyTG9naW4iLCJhZnRlckxvZ291dCIsImFmdGVyU2F2ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJlZm9yZVNhdmVGaWxlIiwiYWRkRmlsZVRyaWdnZXIiLCJhZnRlclNhdmVGaWxlIiwiYmVmb3JlRGVsZXRlRmlsZSIsImFmdGVyRGVsZXRlRmlsZSIsImJlZm9yZUNvbm5lY3QiLCJhZGRDb25uZWN0VHJpZ2dlciIsImJlZm9yZVN1YnNjcmliZSIsIm9uTGl2ZVF1ZXJ5RXZlbnQiLCJhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIiLCJhZnRlckxpdmVRdWVyeUV2ZW50IiwiYWZ0ZXJFdmVudCIsIl9yZW1vdmVBbGxIb29rcyIsIl91bnJlZ2lzdGVyQWxsIiwidXNlTWFzdGVyS2V5IiwiY29uc29sZSIsIndhcm4iLCJodHRwUmVxdWVzdCIsInJlcXVpcmUiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOzs7Ozs7QUFFQSxTQUFTQSx3QkFBVCxDQUFrQ0MsTUFBbEMsRUFBMEM7QUFDeEMsU0FBTyxPQUFPQSxNQUFQLEtB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QUMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCM0MsVUFBakI7QUFFQTs7Ozs7Ozs7Ozs7OztBQWFBOzs7Ozs7Ozs7Ozs7OztBQWNBOzs7Ozs7Ozs7O0FBVUE7Ozs7Ozs7Ozs7Ozs7O0FBY0E7Ozs7Ozs7Ozs7Ozs7QUFhQTs7Ozs7Ozs7Ozs7OztBQWFBOzs7Ozs7OztBQVFBOzs7Ozs7QUFNQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyB0cmlnZ2VycyBmcm9tICcuLi90cmlnZ2Vycyc7XG5cbmZ1bmN0aW9uIGlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvcihvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ2NsYXNzTmFtZScpO1xufVxuXG5mdW5jdGlvbiBnZXRDbGFzc05hbWUocGFyc2VDbGFzcykge1xuICBpZiAocGFyc2VDbGFzcyAmJiBwYXJzZUNsYXNzLmNsYXNzTmFtZSkge1xuICAgIHJldHVybiBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgfVxuICByZXR1cm4gcGFyc2VDbGFzcztcbn1cblxuLyoqIEBuYW1lc3BhY2VcbiAqIEBuYW1lIFBhcnNlXG4gKiBAZGVzY3JpcHRpb24gVGhlIFBhcnNlIFNESy5cbiAqICBzZWUgW2FwaSBkb2NzXShodHRwczovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvanMvYXBpKSBhbmQgW2d1aWRlXShodHRwczovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvanMvZ3VpZGUpXG4gKi9cblxuLyoqIEBuYW1lc3BhY2VcbiAqIEBuYW1lIFBhcnNlLkNsb3VkXG4gKiBAbWVtYmVyb2YgUGFyc2VcbiAqIEBkZXNjcmlwdGlvbiBUaGUgUGFyc2UgQ2xvdWQgQ29kZSBTREsuXG4gKi9cblxudmFyIFBhcnNlQ2xvdWQgPSB7fTtcbi8qKlxuICogRGVmaW5lcyBhIENsb3VkIEZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuZGVmaW5lKCdmdW5jdGlvbk5hbWUnLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5kZWZpbmUoJ2Z1bmN0aW9uTmFtZScsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICogYGBgXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlcm9mIFBhcnNlLkNsb3VkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgQ2xvdWQgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGRhdGEgVGhlIENsb3VkIEZ1bmN0aW9uIHRvIHJlZ2lzdGVyLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GdW5jdGlvblJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GdW5jdGlvblJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmRlZmluZSA9IGZ1bmN0aW9uIChmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKiBEZWZpbmVzIGEgQmFja2dyb3VuZCBKb2IuXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogQG1ldGhvZCBqb2JcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmpvYlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIEJhY2tncm91bmQgSm9iXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBCYWNrZ3JvdW5kIEpvYiB0byByZWdpc3Rlci4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgc2hvdWxkIHRha2UgYSBzaW5nbGUgcGFyYW1ldGVycyBhIHtAbGluayBQYXJzZS5DbG91ZC5Kb2JSZXF1ZXN0fVxuICpcbiAqL1xuUGFyc2VDbG91ZC5qb2IgPSBmdW5jdGlvbiAoZnVuY3Rpb25OYW1lLCBoYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEpvYihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIHNhdmUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZVNhdmUgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZSgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmUoUGFyc2UuVXNlciwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSlcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlU2F2ZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgc2F2ZSBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBzYXZlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH07XG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVTYXZlID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHZhciBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBkZWxldGUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZURlbGV0ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZSgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZShQYXJzZS5Vc2VyLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KVxuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZURlbGV0ZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBiZWZvcmUgZGVsZXRlIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIGRlbGV0ZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIsIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZURlbGV0ZSA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgdGhlIGJlZm9yZSBsb2dpbiBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHByb3ZpZGVzIGZ1cnRoZXIgY29udHJvbFxuICogaW4gdmFsaWRhdGluZyBhIGxvZ2luIGF0dGVtcHQuIFNwZWNpZmljYWxseSxcbiAqIGl0IGlzIHRyaWdnZXJlZCBhZnRlciBhIHVzZXIgZW50ZXJzXG4gKiBjb3JyZWN0IGNyZWRlbnRpYWxzIChvciBvdGhlciB2YWxpZCBhdXRoRGF0YSksXG4gKiBidXQgcHJpb3IgdG8gYSBzZXNzaW9uIGJlaW5nIGdlbmVyYXRlZC5cbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZUxvZ2luKChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSlcbiAqXG4gKiBgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZUxvZ2luXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVMb2dpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIGxvZ2luLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH07XG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlTG9naW4gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICBsZXQgY2xhc3NOYW1lID0gJ19Vc2VyJztcbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnc3RyaW5nJyB8fCBpc1BhcnNlT2JqZWN0Q29uc3RydWN0b3IoaGFuZGxlcikpIHtcbiAgICAvLyB2YWxpZGF0aW9uIHdpbGwgb2NjdXIgZG93bnN0cmVhbSwgdGhpcyBpcyB0byBtYWludGFpbiBpbnRlcm5hbFxuICAgIC8vIGNvZGUgY29uc2lzdGVuY3kgd2l0aCB0aGUgb3RoZXIgaG9vayB0eXBlcy5cbiAgICBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUoaGFuZGxlcik7XG4gICAgaGFuZGxlciA9IGFyZ3VtZW50c1sxXTtcbiAgfVxuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKHRyaWdnZXJzLlR5cGVzLmJlZm9yZUxvZ2luLCBjbGFzc05hbWUsIGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKlxuICogUmVnaXN0ZXJzIHRoZSBhZnRlciBsb2dpbiBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHRyaWdnZXJlZCBhZnRlciBhIHVzZXIgbG9ncyBpbiBzdWNjZXNzZnVsbHksXG4gKiBhbmQgYWZ0ZXIgYSBfU2Vzc2lvbiBvYmplY3QgaGFzIGJlZW4gY3JlYXRlZC5cbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyTG9naW4oKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJMb2dpblxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGFmdGVyIGEgbG9naW4uIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqL1xuUGFyc2VDbG91ZC5hZnRlckxvZ2luID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgbGV0IGNsYXNzTmFtZSA9ICdfVXNlcic7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycgfHwgaXNQYXJzZU9iamVjdENvbnN0cnVjdG9yKGhhbmRsZXIpKSB7XG4gICAgLy8gdmFsaWRhdGlvbiB3aWxsIG9jY3VyIGRvd25zdHJlYW0sIHRoaXMgaXMgdG8gbWFpbnRhaW4gaW50ZXJuYWxcbiAgICAvLyBjb2RlIGNvbnNpc3RlbmN5IHdpdGggdGhlIG90aGVyIGhvb2sgdHlwZXMuXG4gICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKGhhbmRsZXIpO1xuICAgIGhhbmRsZXIgPSBhcmd1bWVudHNbMV07XG4gIH1cbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcih0cmlnZ2Vycy5UeXBlcy5hZnRlckxvZ2luLCBjbGFzc05hbWUsIGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKlxuICogUmVnaXN0ZXJzIHRoZSBhZnRlciBsb2dvdXQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogVGhpcyBmdW5jdGlvbiBpcyB0cmlnZ2VyZWQgYWZ0ZXIgYSB1c2VyIGxvZ3Mgb3V0LlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dvdXQoKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJMb2dvdXRcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyTG9nb3V0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBsb2dvdXQuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqL1xuUGFyc2VDbG91ZC5hZnRlckxvZ291dCA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gIGxldCBjbGFzc05hbWUgPSAnX1Nlc3Npb24nO1xuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnIHx8IGlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvcihoYW5kbGVyKSkge1xuICAgIC8vIHZhbGlkYXRpb24gd2lsbCBvY2N1ciBkb3duc3RyZWFtLCB0aGlzIGlzIHRvIG1haW50YWluIGludGVybmFsXG4gICAgLy8gY29kZSBjb25zaXN0ZW5jeSB3aXRoIHRoZSBvdGhlciBob29rIHR5cGVzLlxuICAgIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShoYW5kbGVyKTtcbiAgICBoYW5kbGVyID0gYXJndW1lbnRzWzFdO1xuICB9XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIodHJpZ2dlcnMuVHlwZXMuYWZ0ZXJMb2dvdXQsIGNsYXNzTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBhZnRlciBzYXZlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBhZnRlclNhdmUgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgZnVuY3Rpb24ocmVxdWVzdCkge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlclNhdmUoUGFyc2UuVXNlciwgYXN5bmMgZnVuY3Rpb24ocmVxdWVzdCkge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJTYXZlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlclNhdmVcbiAqIEBwYXJhbSB7KFN0cmluZ3xQYXJzZS5PYmplY3QpfSBhcmcxIFRoZSBQYXJzZS5PYmplY3Qgc3ViY2xhc3MgdG8gcmVnaXN0ZXIgdGhlIGFmdGVyIHNhdmUgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBzYXZlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYWZ0ZXJTYXZlID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHZhciBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIGRlbGV0ZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYWZ0ZXJEZWxldGUgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZSgnTXlDdXN0b21DbGFzcycsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlKFBhcnNlLlVzZXIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyRGVsZXRlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgZGVsZXRlIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGFmdGVyIGEgZGVsZXRlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYWZ0ZXJEZWxldGUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckRlbGV0ZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBmaW5kIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBiZWZvcmVGaW5kIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRmluZCgnTXlDdXN0b21DbGFzcycsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZUZpbmQoUGFyc2UuVXNlciwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlRmluZFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlRmluZFxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYmVmb3JlIGZpbmQgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGEgZmluZC4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIGp1c3Qgb25lIHBhcmFtZXRlciwge0BsaW5rIFBhcnNlLkNsb3VkLkJlZm9yZUZpbmRSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuQmVmb3JlRmluZFJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZUZpbmQgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVGaW5kLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIGZpbmQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGFmdGVyRmluZCBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRmluZCgnTXlDdXN0b21DbGFzcycsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRmluZChQYXJzZS5Vc2VyLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlckZpbmRcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyRmluZFxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgZmluZCBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBmaW5kLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuQWZ0ZXJGaW5kUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkFmdGVyRmluZFJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyRmluZCA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBjb25zdCBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIHNhdmUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZVNhdmVGaWxlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVTYXZlRmlsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBzYXZpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVTYXZlRmlsZSA9IGZ1bmN0aW9uIChoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRGaWxlVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTYXZlRmlsZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIHNhdmUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyU2F2ZUZpbGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZUZpbGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBzYXZpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlclNhdmVGaWxlID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZpbGVUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyU2F2ZUZpbGUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBkZWxldGUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVEZWxldGVGaWxlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVEZWxldGVGaWxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGRlbGV0aW5nIGEgZmlsZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIGp1c3Qgb25lIHBhcmFtZXRlciwge0BsaW5rIFBhcnNlLkNsb3VkLkZpbGVUcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkZpbGVUcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlRGVsZXRlRmlsZSA9IGZ1bmN0aW9uIChoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRGaWxlVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVEZWxldGVGaWxlLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgZGVsZXRlIGZpbGUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJEZWxldGVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyRGVsZXRlRmlsZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJEZWxldGVGaWxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhZnRlciBiZWZvcmUgZGVsZXRpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlckRlbGV0ZUZpbGUgPSBmdW5jdGlvbiAoaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkRmlsZVRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJEZWxldGVGaWxlLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgbGl2ZSBxdWVyeSBzZXJ2ZXIgY29ubmVjdCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZUNvbm5lY3QoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlQ29ubmVjdChhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVDb25uZWN0XG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVDb25uZWN0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiZWZvcmUgY29ubmVjdGlvbiBpcyBtYWRlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuQ29ubmVjdFRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuQ29ubmVjdFRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVDb25uZWN0ID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZENvbm5lY3RUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUNvbm5lY3QsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBsaXZlIHF1ZXJ5IHN1YnNjcmlwdGlvbiBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYmVmb3JlU3Vic2NyaWJlIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU3Vic2NyaWJlKCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU3Vic2NyaWJlKFBhcnNlLlVzZXIsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZVN1YnNjcmliZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlU3Vic2NyaWJlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBiZWZvcmUgc3Vic2NyaXB0aW9uIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIHN1YnNjcmlwdGlvbi4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIsIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZVN1YnNjcmliZSA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZVN1YnNjcmliZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG5QYXJzZUNsb3VkLm9uTGl2ZVF1ZXJ5RXZlbnQgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBhZnRlciBsaXZlIHF1ZXJ5IHNlcnZlciBldmVudCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyTGl2ZVF1ZXJ5RXZlbnQoJ015Q3VzdG9tQ2xhc3MnLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlckxpdmVRdWVyeUV2ZW50KCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJMaXZlUXVlcnlFdmVudFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJMaXZlUXVlcnlFdmVudFxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgbGl2ZSBxdWVyeSBldmVudCBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBhIGxpdmUgcXVlcnkgZXZlbnQuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyLCBhIHtAbGluayBQYXJzZS5DbG91ZC5MaXZlUXVlcnlFdmVudFRyaWdnZXJ9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5MaXZlUXVlcnlFdmVudFRyaWdnZXJ9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyTGl2ZVF1ZXJ5RXZlbnQgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgY29uc3QgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRXZlbnQsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuUGFyc2VDbG91ZC5fcmVtb3ZlQWxsSG9va3MgPSAoKSA9PiB7XG4gIHRyaWdnZXJzLl91bnJlZ2lzdGVyQWxsKCk7XG59O1xuXG5QYXJzZUNsb3VkLnVzZU1hc3RlcktleSA9ICgpID0+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIGNvbnNvbGUud2FybihcbiAgICAnUGFyc2UuQ2xvdWQudXNlTWFzdGVyS2V5IGlzIGRlcHJlY2F0ZWQgKGFuZCBoYXMgbm8gZWZmZWN0IGFueW1vcmUpIG9uIHBhcnNlLXNlcnZlciwgcGxlYXNlIHJlZmVyIHRvIHRoZSBjbG91ZCBjb2RlIG1pZ3JhdGlvbiBub3RlczogaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNtYXN0ZXIta2V5LW11c3QtYmUtcGFzc2VkLWV4cGxpY2l0bHknXG4gICk7XG59O1xuXG5QYXJzZUNsb3VkLmh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwUmVxdWVzdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhcnNlQ2xvdWQ7XG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuT2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlYCwgYGFmdGVyU2F2ZWAsIC4uLilcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKiBAcHJvcGVydHkge1BhcnNlLk9iamVjdH0gb3JpZ2luYWwgSWYgc2V0LCB0aGUgb2JqZWN0LCBhcyBjdXJyZW50bHkgc3RvcmVkLlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSBtYXN0ZXIgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1BhcnNlLkZpbGV9IGZpbGUgVGhlIGZpbGUgdGhhdCB0cmlnZ2VyZWQgdGhlIGhvb2suXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IGZpbGVTaXplIFRoZSBzaXplIG9mIHRoZSBmaWxlIGluIGJ5dGVzLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBjb250ZW50TGVuZ3RoIFRoZSB2YWx1ZSBmcm9tIENvbnRlbnQtTGVuZ3RoIGhlYWRlclxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlRmlsZWAsIGBhZnRlclNhdmVGaWxlYClcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLkNvbm5lY3RUcmlnZ2VyUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHVzZU1hc3RlcktleSBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY2xpZW50cyBUaGUgbnVtYmVyIG9mIGNsaWVudHMgY29ubmVjdGVkLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBzdWJzY3JpcHRpb25zIFRoZSBudW1iZXIgb2Ygc3Vic2NyaXB0aW9ucyBjb25uZWN0ZWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gc2Vzc2lvblRva2VuIElmIHNldCwgdGhlIHNlc3Npb24gb2YgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5MaXZlUXVlcnlFdmVudFRyaWdnZXJcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSB1c2VNYXN0ZXJLZXkgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gc2Vzc2lvblRva2VuIElmIHNldCwgdGhlIHNlc3Npb24gb2YgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGV2ZW50IFRoZSBsaXZlIHF1ZXJ5IGV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtQYXJzZS5PYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRyaWdnZXJpbmcgdGhlIGhvb2suXG4gKiBAcHJvcGVydHkge1BhcnNlLk9iamVjdH0gb3JpZ2luYWwgSWYgc2V0LCB0aGUgb2JqZWN0LCBhcyBjdXJyZW50bHkgc3RvcmVkLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBjbGllbnRzIFRoZSBudW1iZXIgb2YgY2xpZW50cyBjb25uZWN0ZWQuXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IHN1YnNjcmlwdGlvbnMgVGhlIG51bWJlciBvZiBzdWJzY3JpcHRpb25zIGNvbm5lY3RlZC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2VuZEV2ZW50IElmIHRoZSBMaXZlUXVlcnkgZXZlbnQgc2hvdWxkIGJlIHNlbnQgdG8gdGhlIGNsaWVudC4gU2V0IHRvIGZhbHNlIHRvIHByZXZlbnQgTGl2ZVF1ZXJ5IGZyb20gcHVzaGluZyB0byB0aGUgY2xpZW50LlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5CZWZvcmVGaW5kUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuUXVlcnl9IHF1ZXJ5IFRoZSBxdWVyeSB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlYCwgYGFmdGVyU2F2ZWAsIC4uLilcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGlzR2V0IHdldGhlciB0aGUgcXVlcnkgYSBgZ2V0YCBvciBhIGBmaW5kYFxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5BZnRlckZpbmRSZXF1ZXN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gbWFzdGVyIElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtQYXJzZS5RdWVyeX0gcXVlcnkgVGhlIHF1ZXJ5IHRyaWdnZXJpbmcgdGhlIGhvb2suXG4gKiBAcHJvcGVydHkge0FycmF5PFBhcnNlLk9iamVjdD59IHJlc3VsdHMgVGhlIHJlc3VsdHMgdGhlIHF1ZXJ5IHlpZWxkZWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaXAgVGhlIElQIGFkZHJlc3Mgb2YgdGhlIGNsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgb3JpZ2luYWwgSFRUUCBoZWFkZXJzIGZvciB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB0cmlnZ2VyTmFtZSBUaGUgbmFtZSBvZiB0aGUgdHJpZ2dlciAoYGJlZm9yZVNhdmVgLCBgYWZ0ZXJTYXZlYCwgLi4uKVxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZyBUaGUgY3VycmVudCBsb2dnZXIgaW5zaWRlIFBhcnNlIFNlcnZlci5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuRnVuY3Rpb25SZXF1ZXN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gbWFzdGVyIElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IHBhcmFtcyBUaGUgcGFyYW1zIHBhc3NlZCB0byB0aGUgY2xvdWQgZnVuY3Rpb24uXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLkpvYlJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhcmFtcyBwYXNzZWQgdG8gdGhlIGJhY2tncm91bmQgam9iLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gbWVzc2FnZSBJZiBtZXNzYWdlIGlzIGNhbGxlZCB3aXRoIGEgc3RyaW5nIGFyZ3VtZW50LCB3aWxsIHVwZGF0ZSB0aGUgY3VycmVudCBtZXNzYWdlIHRvIGJlIHN0b3JlZCBpbiB0aGUgam9iIHN0YXR1cy5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0XG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHJlcXVpcmVVc2VyIHdoZXRoZXIgdGhlIGNsb3VkIHRyaWdnZXIgcmVxdWlyZXMgYSB1c2VyLlxuICogQHByb3BlcnR5IHtCb29sZWFufSByZXF1aXJlTWFzdGVyIHdoZXRoZXIgdGhlIGNsb3VkIHRyaWdnZXIgcmVxdWlyZXMgYSBtYXN0ZXIga2V5LlxuICogQHByb3BlcnR5IHtCb29sZWFufSB2YWxpZGF0ZU1hc3RlcktleSB3aGV0aGVyIHRoZSB2YWxpZGF0b3Igc2hvdWxkIHJ1biBpZiBtYXN0ZXJLZXkgaXMgcHJvdmlkZWQuIERlZmF1bHRzIHRvIGZhbHNlLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBza2lwV2l0aE1hc3RlcktleSB3aGV0aGVyIHRoZSBjbG91ZCBjb2RlIGZ1bmN0aW9uIHNob3VsZCBiZSBpZ25vcmVkIHVzaW5nIGEgbWFzdGVyS2V5LlxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8U3RyaW5nPnxPYmplY3R9IHJlcXVpcmVVc2VyS2V5cyBJZiBzZXQsIGtleXMgcmVxdWlyZWQgb24gcmVxdWVzdC51c2VyIHRvIG1ha2UgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVxdWlyZVVzZXJLZXlzLmZpZWxkIElmIHJlcXVpcmVVc2VyS2V5cyBpcyBhbiBvYmplY3QsIG5hbWUgb2YgZmllbGQgdG8gdmFsaWRhdGUgb24gcmVxdWVzdCB1c2VyXG4gKiBAcHJvcGVydHkge0FycmF5fGZ1bmN0aW9ufEFueX0gcmVxdWlyZVVzZXJLZXlzLmZpZWxkLm9wdGlvbnMgYXJyYXkgb2Ygb3B0aW9ucyB0aGF0IHRoZSBmaWVsZCBjYW4gYmUsIGZ1bmN0aW9uIHRvIHZhbGlkYXRlIGZpZWxkLCBvciBzaW5nbGUgdmFsdWUuIFRocm93IGFuIGVycm9yIGlmIHZhbHVlIGlzIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVxdWlyZVVzZXJLZXlzLmZpZWxkLmVycm9yIGN1c3RvbSBlcnJvciBtZXNzYWdlIGlmIGZpZWxkIGlzIGludmFsaWQuXG4gKlxuICogQHByb3BlcnR5IHtPYmplY3R8QXJyYXk8U3RyaW5nPn0gZmllbGRzIGlmIGFuIGFycmF5IG9mIHN0cmluZ3MsIHZhbGlkYXRvciB3aWxsIGxvb2sgZm9yIGtleXMgaW4gcmVxdWVzdC5wYXJhbXMsIGFuZCB0aHJvdyBpZiBub3QgcHJvdmlkZWQuIElmIE9iamVjdCwgZmllbGRzIHRvIHZhbGlkYXRlLiBJZiB0aGUgdHJpZ2dlciBpcyBhIGNsb3VkIGZ1bmN0aW9uLCBgcmVxdWVzdC5wYXJhbXNgIHdpbGwgYmUgdmFsaWRhdGVkLCBvdGhlcndpc2UgYHJlcXVlc3Qub2JqZWN0YC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWVsZHMuZmllbGQgbmFtZSBvZiBmaWVsZCB0byB2YWxpZGF0ZS5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWVsZHMuZmllbGQudHlwZSBleHBlY3RlZCB0eXBlIG9mIGRhdGEgZm9yIGZpZWxkLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBmaWVsZHMuZmllbGQuY29uc3RhbnQgd2hldGhlciB0aGUgZmllbGQgY2FuIGJlIG1vZGlmaWVkIG9uIHRoZSBvYmplY3QuXG4gKiBAcHJvcGVydHkge0FueX0gZmllbGRzLmZpZWxkLmRlZmF1bHQgZGVmYXVsdCB2YWx1ZSBpZiBmaWVsZCBpcyBgbnVsbGAsIG9yIGluaXRpYWwgdmFsdWUgYGNvbnN0YW50YCBpcyBgdHJ1ZWAuXG4gKiBAcHJvcGVydHkge0FycmF5fGZ1bmN0aW9ufEFueX0gZmllbGRzLmZpZWxkLm9wdGlvbnMgYXJyYXkgb2Ygb3B0aW9ucyB0aGF0IHRoZSBmaWVsZCBjYW4gYmUsIGZ1bmN0aW9uIHRvIHZhbGlkYXRlIGZpZWxkLCBvciBzaW5nbGUgdmFsdWUuIFRocm93IGFuIGVycm9yIGlmIHZhbHVlIGlzIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZmllbGRzLmZpZWxkLmVycm9yIGN1c3RvbSBlcnJvciBtZXNzYWdlIGlmIGZpZWxkIGlzIGludmFsaWQuXG4gKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cloud-code/httpRequest.js b/lib/cloud-code/httpRequest.js new file mode 100644 index 0000000000..32cf06eb38 --- /dev/null +++ b/lib/cloud-code/httpRequest.js @@ -0,0 +1,192 @@ +"use strict"; + +var _HTTPResponse = _interopRequireDefault(require("./HTTPResponse")); + +var _querystring = _interopRequireDefault(require("querystring")); + +var _logger = _interopRequireDefault(require("../logger")); + +var _followRedirects = require("follow-redirects"); + +var _url = require("url"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const clients = { + 'http:': _followRedirects.http, + 'https:': _followRedirects.https +}; + +function makeCallback(resolve, reject) { + return function (response) { + const chunks = []; + response.on('data', chunk => { + chunks.push(chunk); + }); + response.on('end', () => { + const body = Buffer.concat(chunks); + const httpResponse = new _HTTPResponse.default(response, body); // Consider <200 && >= 400 as errors + + if (httpResponse.status < 200 || httpResponse.status >= 400) { + return reject(httpResponse); + } else { + return resolve(httpResponse); + } + }); + response.on('error', reject); + }; +} + +const encodeBody = function ({ + body, + headers = {} +}) { + if (typeof body !== 'object') { + return { + body, + headers + }; + } + + var contentTypeKeys = Object.keys(headers).filter(key => { + return key.match(/content-type/i) != null; + }); + + if (contentTypeKeys.length == 0) { + // no content type + // As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded + body = _querystring.default.stringify(body); + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } else { + /* istanbul ignore next */ + if (contentTypeKeys.length > 1) { + _logger.default.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.'); + } // There maybe many, we'll just take the 1st one + + + var contentType = contentTypeKeys[0]; + + if (headers[contentType].match(/application\/json/i)) { + body = JSON.stringify(body); + } else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) { + body = _querystring.default.stringify(body); + } + } + + return { + body, + headers + }; +}; +/** + * Makes an HTTP Request. + * + * **Available in Cloud Code only.** + * + * By default, Parse.Cloud.httpRequest does not follow redirects caused by HTTP 3xx response codes. You can use the followRedirects option in the {@link Parse.Cloud.HTTPOptions} object to change this behavior. + * + * Sample request: + * ``` + * Parse.Cloud.httpRequest({ + * url: 'http://www.parse.com/' + * }).then(function(httpResponse) { + * // success + * console.log(httpResponse.text); + * },function(httpResponse) { + * // error + * console.error('Request failed with response code ' + httpResponse.status); + * }); + * ``` + * + * @method httpRequest + * @name Parse.Cloud.httpRequest + * @param {Parse.Cloud.HTTPOptions} options The Parse.Cloud.HTTPOptions object that makes the request. + * @return {Promise} A promise that will be resolved with a {@link Parse.Cloud.HTTPResponse} object when the request completes. + */ + + +module.exports = function httpRequest(options) { + let url; + + try { + url = (0, _url.parse)(options.url); + } catch (e) { + return Promise.reject(e); + } + + options = Object.assign(options, encodeBody(options)); // support params options + + if (typeof options.params === 'object') { + options.qs = options.params; + } else if (typeof options.params === 'string') { + options.qs = _querystring.default.parse(options.params); + } + + const client = clients[url.protocol]; + + if (!client) { + return Promise.reject(`Unsupported protocol ${url.protocol}`); + } + + const requestOptions = { + method: options.method, + port: Number(url.port), + path: url.pathname, + hostname: url.hostname, + headers: options.headers, + encoding: null, + followRedirects: options.followRedirects === true + }; + + if (requestOptions.headers) { + Object.keys(requestOptions.headers).forEach(key => { + if (typeof requestOptions.headers[key] === 'undefined') { + delete requestOptions.headers[key]; + } + }); + } + + if (url.search) { + options.qs = Object.assign({}, options.qs, _querystring.default.parse(url.query)); + } + + if (url.auth) { + requestOptions.auth = url.auth; + } + + if (options.qs) { + requestOptions.path += `?${_querystring.default.stringify(options.qs)}`; + } + + if (options.agent) { + requestOptions.agent = options.agent; + } + + return new Promise((resolve, reject) => { + const req = client.request(requestOptions, makeCallback(resolve, reject, options)); + + if (options.body) { + req.write(options.body); + } + + req.on('error', error => { + reject(error); + }); + req.end(); + }); +}; +/** + * @typedef Parse.Cloud.HTTPOptions + * @property {String|Object} body The body of the request. If it is a JSON object, then the Content-Type set in the headers must be application/x-www-form-urlencoded or application/json. You can also set this to a {@link Buffer} object to send raw bytes. If you use a Buffer, you should also set the Content-Type header explicitly to describe what these bytes represent. + * @property {function} error The function that is called when the request fails. It will be passed a Parse.Cloud.HTTPResponse object. + * @property {Boolean} followRedirects Whether to follow redirects caused by HTTP 3xx responses. Defaults to false. + * @property {Object} headers The headers for the request. + * @property {String} method The method of the request. GET, POST, PUT, DELETE, HEAD, and OPTIONS are supported. Will default to GET if not specified. + * @property {String|Object} params The query portion of the url. You can pass a JSON object of key value pairs like params: {q : 'Sean Plott'} or a raw string like params:q=Sean Plott. + * @property {function} success The function that is called when the request successfully completes. It will be passed a Parse.Cloud.HTTPResponse object. + * @property {string} url The url to send the request to. + */ + + +module.exports.encodeBody = encodeBody; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0LmpzIl0sIm5hbWVzIjpbImNsaWVudHMiLCJodHRwIiwiaHR0cHMiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0IiwicmVzcG9uc2UiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsImJvZHkiLCJCdWZmZXIiLCJjb25jYXQiLCJodHRwUmVzcG9uc2UiLCJIVFRQUmVzcG9uc2UiLCJzdGF0dXMiLCJlbmNvZGVCb2R5IiwiaGVhZGVycyIsImNvbnRlbnRUeXBlS2V5cyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJtYXRjaCIsImxlbmd0aCIsInF1ZXJ5c3RyaW5nIiwic3RyaW5naWZ5IiwibG9nIiwiZXJyb3IiLCJjb250ZW50VHlwZSIsIkpTT04iLCJtb2R1bGUiLCJleHBvcnRzIiwiaHR0cFJlcXVlc3QiLCJvcHRpb25zIiwidXJsIiwiZSIsIlByb21pc2UiLCJhc3NpZ24iLCJwYXJhbXMiLCJxcyIsInBhcnNlIiwiY2xpZW50IiwicHJvdG9jb2wiLCJyZXF1ZXN0T3B0aW9ucyIsIm1ldGhvZCIsInBvcnQiLCJOdW1iZXIiLCJwYXRoIiwicGF0aG5hbWUiLCJob3N0bmFtZSIsImVuY29kaW5nIiwiZm9sbG93UmVkaXJlY3RzIiwiZm9yRWFjaCIsInNlYXJjaCIsInF1ZXJ5IiwiYXV0aCIsImFnZW50IiwicmVxIiwicmVxdWVzdCIsIndyaXRlIiwiZW5kIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2QsV0FBU0MscUJBREs7QUFFZCxZQUFVQztBQUZJLENBQWhCOztBQUtBLFNBQVNDLFlBQVQsQ0FBc0JDLE9BQXRCLEVBQStCQyxNQUEvQixFQUF1QztBQUNyQyxTQUFPLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsVUFBTUMsTUFBTSxHQUFHLEVBQWY7QUFDQUQsSUFBQUEsUUFBUSxD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bEI7QUFDRDs7QUFDRGdELElBQUFBLEdBQUcsQ0FBQ25ELEVBQUosQ0FBTyxPQUFQLEVBQWdCcUIsS0FBSyxJQUFJO0FBQ3ZCeEIsTUFBQUEsTUFBTSxDQUFDd0IsS0FBRCxDQUFOO0FBQ0QsS0FGRDtBQUdBOEIsSUFBQUEsR0FBRyxDQUFDRyxHQUFKO0FBQ0QsR0FUTSxDQUFQO0FBVUQsQ0F4REQ7QUEwREE7Ozs7Ozs7Ozs7Ozs7QUFZQTlCLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlaEIsVUFBZixHQUE0QkEsVUFBNUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSFRUUFJlc3BvbnNlIGZyb20gJy4vSFRUUFJlc3BvbnNlJztcbmltcG9ydCBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgbG9nIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBodHRwLCBodHRwcyB9IGZyb20gJ2ZvbGxvdy1yZWRpcmVjdHMnO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICd1cmwnO1xuXG5jb25zdCBjbGllbnRzID0ge1xuICAnaHR0cDonOiBodHRwLFxuICAnaHR0cHM6JzogaHR0cHMsXG59O1xuXG5mdW5jdGlvbiBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICByZXNwb25zZS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICB9KTtcbiAgICByZXNwb25zZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgY29uc3QgYm9keSA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZSA9IG5ldyBIVFRQUmVzcG9uc2UocmVzcG9uc2UsIGJvZHkpO1xuXG4gICAgICAvLyBDb25zaWRlciA8MjAwICYmID49IDQwMCBhcyBlcnJvcnNcbiAgICAgIGlmIChodHRwUmVzcG9uc2Uuc3RhdHVzIDwgMjAwIHx8IGh0dHBSZXNwb25zZS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoaHR0cFJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGh0dHBSZXNwb25zZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzcG9uc2Uub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfTtcbn1cblxuY29uc3QgZW5jb2RlQm9keSA9IGZ1bmN0aW9uICh7IGJvZHksIGhlYWRlcnMgPSB7fSB9KSB7XG4gIGlmICh0eXBlb2YgYm9keSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4geyBib2R5LCBoZWFkZXJzIH07XG4gIH1cbiAgdmFyIGNvbnRlbnRUeXBlS2V5cyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpLmZpbHRlcihrZXkgPT4ge1xuICAgIHJldHVybiBrZXkubWF0Y2goL2NvbnRlbnQtdHlwZS9pKSAhPSBudWxsO1xuICB9KTtcblxuICBpZiAoY29udGVudFR5cGVLZXlzLmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gbm8gY29udGVudCB0eXBlXG4gICAgLy8gIEFzIHBlciBodHRwczovL3BhcnNlLmNvbS9kb2NzL2Nsb3VkY29kZS9ndWlkZSNjbG91ZC1jb2RlLWFkdmFuY2VkLXNlbmRpbmctYS1wb3N0LXJlcXVlc3QgdGhlIGRlZmF1bHQgZW5jb2RpbmcgaXMgc3VwcG9zZWRseSB4LXd3dy1mb3JtLXVybGVuY29kZWRcblxuICAgIGJvZHkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoYm9keSk7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgfSBlbHNlIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmIChjb250ZW50VHlwZUtleXMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nLmVycm9yKCdQYXJzZS5DbG91ZC5odHRwUmVxdWVzdCcsICdtdWx0aXBsZSBjb250ZW50LXR5cGUgaGVhZGVycyBhcmUgc2V0LicpO1xuICAgIH1cbiAgICAvLyBUaGVyZSBtYXliZSBtYW55LCB3ZSdsbCBqdXN0IHRha2UgdGhlIDFzdCBvbmVcbiAgICB2YXIgY29udGVudFR5cGUgPSBjb250ZW50VHlwZUtleXNbMF07XG4gICAgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL2pzb24vaSkpIHtcbiAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShib2R5KTtcbiAgICB9IGVsc2UgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL3gtd3d3LWZvcm0tdXJsZW5jb2RlZC9pKSkge1xuICAgICAgYm9keSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShib2R5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgYm9keSwgaGVhZGVycyB9O1xufTtcblxuLyoqXG4gKiBNYWtlcyBhbiBIVFRQIFJlcXVlc3QuXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogQnkgZGVmYXVsdCwgUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3QgZG9lcyBub3QgZm9sbG93IHJlZGlyZWN0cyBjYXVzZWQgYnkgSFRUUCAzeHggcmVzcG9uc2UgY29kZXMuIFlvdSBjYW4gdXNlIHRoZSBmb2xsb3dSZWRpcmVjdHMgb3B0aW9uIGluIHRoZSB7QGxpbmsgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnN9IG9iamVjdCB0byBjaGFuZ2UgdGhpcyBiZWhhdmlvci5cbiAqXG4gKiBTYW1wbGUgcmVxdWVzdDpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3Qoe1xuICogICB1cmw6ICdodHRwOi8vd3d3LnBhcnNlLmNvbS8nXG4gKiB9KS50aGVuKGZ1bmN0aW9uKGh0dHBSZXNwb25zZSkge1xuICogICAvLyBzdWNjZXNzXG4gKiAgIGNvbnNvbGUubG9nKGh0dHBSZXNwb25zZS50ZXh0KTtcbiAqIH0sZnVuY3Rpb24oaHR0cFJlc3BvbnNlKSB7XG4gKiAgIC8vIGVycm9yXG4gKiAgIGNvbnNvbGUuZXJyb3IoJ1JlcXVlc3QgZmFpbGVkIHdpdGggcmVzcG9uc2UgY29kZSAnICsgaHR0cFJlc3BvbnNlLnN0YXR1cyk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgaHR0cFJlcXVlc3RcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmh0dHBSZXF1ZXN0XG4gKiBAcGFyYW0ge1BhcnNlLkNsb3VkLkhUVFBPcHRpb25zfSBvcHRpb25zIFRoZSBQYXJzZS5DbG91ZC5IVFRQT3B0aW9ucyBvYmplY3QgdGhhdCBtYWtlcyB0aGUgcmVxdWVzdC5cbiAqIEByZXR1cm4ge1Byb21pc2U8UGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlPn0gQSBwcm9taXNlIHRoYXQgd2lsbCBiZSByZXNvbHZlZCB3aXRoIGEge0BsaW5rIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZX0gb2JqZWN0IHdoZW4gdGhlIHJlcXVlc3QgY29tcGxldGVzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGh0dHBSZXF1ZXN0KG9wdGlvbnMpIHtcbiAgbGV0IHVybDtcbiAgdHJ5IHtcbiAgICB1cmwgPSBwYXJzZShvcHRpb25zLnVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XG4gIH1cbiAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgZW5jb2RlQm9keShvcHRpb25zKSk7XG4gIC8vIHN1cHBvcnQgcGFyYW1zIG9wdGlvbnNcbiAgaWYgKHR5cGVvZiBvcHRpb25zLnBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zLnFzID0gb3B0aW9ucy5wYXJhbXM7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMucGFyYW1zID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMucXMgPSBxdWVyeXN0cmluZy5wYXJzZShvcHRpb25zLnBhcmFtcyk7XG4gIH1cbiAgY29uc3QgY2xpZW50ID0gY2xpZW50c1t1cmwucHJvdG9jb2xdO1xuICBpZiAoIWNsaWVudCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJHt1cmwucHJvdG9jb2x9YCk7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgbWV0aG9kOiBvcHRpb25zLm1ldGhvZCxcbiAgICBwb3J0OiBOdW1iZXIodXJsLnBvcnQpLFxuICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICBlbmNvZGluZzogbnVsbCxcbiAgICBmb2xsb3dSZWRpcmVjdHM6IG9wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSB0cnVlLFxuICB9O1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xuICAgIE9iamVjdC5rZXlzKHJlcXVlc3RPcHRpb25zLmhlYWRlcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBkZWxldGUgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGlmICh1cmwuc2VhcmNoKSB7XG4gICAgb3B0aW9ucy5xcyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMucXMsIHF1ZXJ5c3RyaW5nLnBhcnNlKHVybC5xdWVyeSkpO1xuICB9XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIHJlcXVlc3RPcHRpb25zLmF1dGggPSB1cmwuYXV0aDtcbiAgfVxuICBpZiAob3B0aW9ucy5xcykge1xuICAgIHJlcXVlc3RPcHRpb25zLnBhdGggKz0gYD8ke3F1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvcHRpb25zLnFzKX1gO1xuICB9XG4gIGlmIChvcHRpb25zLmFnZW50KSB7XG4gICAgcmVxdWVzdE9wdGlvbnMuYWdlbnQgPSBvcHRpb25zLmFnZW50O1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gY2xpZW50LnJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG9wdGlvbnMpKTtcbiAgICBpZiAob3B0aW9ucy5ib2R5KSB7XG4gICAgICByZXEud3JpdGUob3B0aW9ucy5ib2R5KTtcbiAgICB9XG4gICAgcmVxLm9uKCdlcnJvcicsIGVycm9yID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gICAgcmVxLmVuZCgpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gYm9keSBUaGUgYm9keSBvZiB0aGUgcmVxdWVzdC4gSWYgaXQgaXMgYSBKU09OIG9iamVjdCwgdGhlbiB0aGUgQ29udGVudC1UeXBlIHNldCBpbiB0aGUgaGVhZGVycyBtdXN0IGJlIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCBvciBhcHBsaWNhdGlvbi9qc29uLiBZb3UgY2FuIGFsc28gc2V0IHRoaXMgdG8gYSB7QGxpbmsgQnVmZmVyfSBvYmplY3QgdG8gc2VuZCByYXcgYnl0ZXMuIElmIHlvdSB1c2UgYSBCdWZmZXIsIHlvdSBzaG91bGQgYWxzbyBzZXQgdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgZXhwbGljaXRseSB0byBkZXNjcmliZSB3aGF0IHRoZXNlIGJ5dGVzIHJlcHJlc2VudC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGVycm9yIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IGZhaWxzLiBJdCB3aWxsIGJlIHBhc3NlZCBhIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZSBvYmplY3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGZvbGxvd1JlZGlyZWN0cyBXaGV0aGVyIHRvIGZvbGxvdyByZWRpcmVjdHMgY2F1c2VkIGJ5IEhUVFAgM3h4IHJlc3BvbnNlcy4gRGVmYXVsdHMgdG8gZmFsc2UuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWV0aG9kIFRoZSBtZXRob2Qgb2YgdGhlIHJlcXVlc3QuIEdFVCwgUE9TVCwgUFVULCBERUxFVEUsIEhFQUQsIGFuZCBPUFRJT05TIGFyZSBzdXBwb3J0ZWQuIFdpbGwgZGVmYXVsdCB0byBHRVQgaWYgbm90IHNwZWNpZmllZC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gcGFyYW1zIFRoZSBxdWVyeSBwb3J0aW9uIG9mIHRoZSB1cmwuIFlvdSBjYW4gcGFzcyBhIEpTT04gb2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyBsaWtlIHBhcmFtczoge3EgOiAnU2VhbiBQbG90dCd9IG9yIGEgcmF3IHN0cmluZyBsaWtlIHBhcmFtczpxPVNlYW4gUGxvdHQuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzdWNjZXNzIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXMuIEl0IHdpbGwgYmUgcGFzc2VkIGEgUGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlIG9iamVjdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBzZW5kIHRoZSByZXF1ZXN0IHRvLlxuICovXG5cbm1vZHVsZS5leHBvcnRzLmVuY29kZUJvZHkgPSBlbmNvZGVCb2R5O1xuIl19 \ No newline at end of file diff --git a/lib/cryptoUtils.js b/lib/cryptoUtils.js new file mode 100644 index 0000000000..5267fc1838 --- /dev/null +++ b/lib/cryptoUtils.js @@ -0,0 +1,62 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.randomHexString = randomHexString; +exports.randomString = randomString; +exports.newObjectId = newObjectId; +exports.newToken = newToken; +exports.md5Hash = md5Hash; + +var _crypto = require("crypto"); + +// Returns a new random hex string of the given even size. +function randomHexString(size) { + if (size === 0) { + throw new Error('Zero-length randomHexString is useless.'); + } + + if (size % 2 !== 0) { + throw new Error('randomHexString size must be divisible by 2.'); + } + + return (0, _crypto.randomBytes)(size / 2).toString('hex'); +} // Returns a new random alphanumeric string of the given size. +// +// Note: to simplify implementation, the result has slight modulo bias, +// because chars length of 62 doesn't divide the number of all bytes +// (256) evenly. Such bias is acceptable for most cases when the output +// length is long enough and doesn't need to be uniform. + + +function randomString(size) { + if (size === 0) { + throw new Error('Zero-length randomString is useless.'); + } + + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789'; + let objectId = ''; + const bytes = (0, _crypto.randomBytes)(size); + + for (let i = 0; i < bytes.length; ++i) { + objectId += chars[bytes.readUInt8(i) % chars.length]; + } + + return objectId; +} // Returns a new random alphanumeric string suitable for object ID. + + +function newObjectId(size = 10) { + return randomString(size); +} // Returns a new random hex string suitable for secure tokens. + + +function newToken() { + return randomHexString(32); +} + +function md5Hash(string) { + return (0, _crypto.createHash)('md5').update(string).digest('hex'); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jcnlwdG9VdGlscy5qcyJdLCJuYW1lcyI6WyJyYW5kb21IZXhTdHJpbmciLCJzaXplIiwiRXJyb3IiLCJ0b1N0cmluZyIsInJhbmRvbVN0cmluZyIsImNoYXJzIiwib2JqZWN0SWQiLCJieXRlcyIsImkiLCJsZW5ndGgiLCJyZWFkVUludDgiLCJuZXdPYmplY3RJZCIsIm5ld1Rva2VuIiwibWQ1SGFzaCIsInN0cmluZyIsInVwZGF0ZSIsImRpZ2VzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFFQTs7QUFFQTtBQUNPLFNBQVNBLGVBQVQsQ0FBeUJDLElBQXpCLEVBQStDO0FBQ3BELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUseUNBQVYsQ0FBTjtBQUNEOztBQUNELE1BQUlELElBQUksR0FBRyxDQUFQLEtBQWEsQ0FBakIsRUFBb0I7QUFDbEIsVUFBTSxJQUFJQyxLQUFKLENBQVUsOENBQVYsQ0FBTjtBQUNEOztBQUNELFNBQU8seUJBQVlELElBQUksR0FBRyxDQUFuQixFQUFzQkUsUUFBdEIsQ0FBK0IsS0FBL0IsQ0FBUDtBQUNELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNDLFlBQVQsQ0FBc0JILElBQXRCLEVBQTRDO0FBQ2pELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUsc0NBQVYsQ0FBTjtBQUNEOztBQUNELFFBQU1HLEtBQUssR0FBRywrQkFBK0IsNEJBQS9CLEdBQThELFlBQTVFO0FBQ0EsTUFBSUMsUUFBUSxHQUFHLEVBQWY7QUFDQSxRQUFNQyxLQUFLLEdBQUcseUJBQVlOLElBQVosQ0FBZDs7QUFDQSxPQUFLLElBQUlPLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdELEtBQUssQ0FBQ0UsTUFBMUIsRUFBa0MsRUFBRUQsQ0FBcEMsRUFBdUM7QUFDckNGLElBQUFBLFFBQVEsSUFBSUQsS0FBSyxDQUFDRSxLQUFLLENBQUNHLFNBQU4sQ0FBZ0JGLENBQWhCLElBQXFCSCxLQUFLLENBQUNJLE1BQTVCLENBQWpCO0FBQ0Q7O0FBQ0QsU0FBT0gsUUFBUDtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU0ssV0FBVCxDQUFxQlYsSUFBWSxHQUFHLEVBQXBDLEVBQWdEO0FBQ3JELFNBQU9HLFlBQVksQ0FBQ0gsSUFBRCxDQUFuQjtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU1csUUFBVCxHQUE0QjtBQUNqQyxTQUFPWixlQUFlLENBQUMsRUFBRCxDQUF0QjtBQUNEOztBQUVNLFNBQVNhLE9BQVQsQ0FBaUJDLE1BQWpCLEVBQXlDO0FBQzlDLFNBQU8sd0JBQVcsS0FBWCxFQUFrQkMsTUFBbEIsQ0FBeUJELE1BQXpCLEVBQWlDRSxNQUFqQyxDQUF3QyxLQUF4QyxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBAZmxvdyAqL1xuXG5pbXBvcnQgeyByYW5kb21CeXRlcywgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5cbi8vIFJldHVybnMgYSBuZXcgcmFuZG9tIGhleCBzdHJpbmcgb2YgdGhlIGdpdmVuIGV2ZW4gc2l6ZS5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21IZXhTdHJpbmcoc2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHNpemUgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1plcm8tbGVuZ3RoIHJhbmRvbUhleFN0cmluZyBpcyB1c2VsZXNzLicpO1xuICB9XG4gIGlmIChzaXplICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncmFuZG9tSGV4U3RyaW5nIHNpemUgbXVzdCBiZSBkaXZpc2libGUgYnkgMi4nKTtcbiAgfVxuICByZXR1cm4gcmFuZG9tQnl0ZXMoc2l6ZSAvIDIpLnRvU3RyaW5nKCdoZXgnKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBvZiB0aGUgZ2l2ZW4gc2l6ZS5cbi8vXG4vLyBOb3RlOiB0byBzaW1wbGlmeSBpbXBsZW1lbnRhdGlvbiwgdGhlIHJlc3VsdCBoYXMgc2xpZ2h0IG1vZHVsbyBiaWFzLFxuLy8gYmVjYXVzZSBjaGFycyBsZW5ndGggb2YgNjIgZG9lc24ndCBkaXZpZGUgdGhlIG51bWJlciBvZiBhbGwgYnl0ZXNcbi8vICgyNTYpIGV2ZW5seS4gU3VjaCBiaWFzIGlzIGFjY2VwdGFibGUgZm9yIG1vc3QgY2FzZXMgd2hlbiB0aGUgb3V0cHV0XG4vLyBsZW5ndGggaXMgbG9uZyBlbm91Z2ggYW5kIGRvZXNuJ3QgbmVlZCB0byBiZSB1bmlmb3JtLlxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAoc2l6ZSA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignWmVyby1sZW5ndGggcmFuZG9tU3RyaW5nIGlzIHVzZWxlc3MuJyk7XG4gIH1cbiAgY29uc3QgY2hhcnMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVonICsgJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JyArICcwMTIzNDU2Nzg5JztcbiAgbGV0IG9iamVjdElkID0gJyc7XG4gIGNvbnN0IGJ5dGVzID0gcmFuZG9tQnl0ZXMoc2l6ZSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHtcbiAgICBvYmplY3RJZCArPSBjaGFyc1tieXRlcy5yZWFkVUludDgoaSkgJSBjaGFycy5sZW5ndGhdO1xuICB9XG4gIHJldHVybiBvYmplY3RJZDtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBzdWl0YWJsZSBmb3Igb2JqZWN0IElELlxuZXhwb3J0IGZ1bmN0aW9uIG5ld09iamVjdElkKHNpemU6IG51bWJlciA9IDEwKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJhbmRvbVN0cmluZyhzaXplKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gaGV4IHN0cmluZyBzdWl0YWJsZSBmb3Igc2VjdXJlIHRva2Vucy5cbmV4cG9ydCBmdW5jdGlvbiBuZXdUb2tlbigpOiBzdHJpbmcge1xuICByZXR1cm4gcmFuZG9tSGV4U3RyaW5nKDMyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1kNUhhc2goc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKHN0cmluZykuZGlnZXN0KCdoZXgnKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/defaults.js b/lib/defaults.js new file mode 100644 index 0000000000..d824d3ba1d --- /dev/null +++ b/lib/defaults.js @@ -0,0 +1,60 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefaultMongoURI = exports.default = void 0; + +var _parsers = require("./Options/parsers"); + +const { + ParseServerOptions +} = require('./Options/Definitions'); + +const logsFolder = (() => { + let folder = './logs/'; + + if (typeof process !== 'undefined' && process.env.TESTING === '1') { + folder = './test_logs/'; + } + + if (process.env.PARSE_SERVER_LOGS_FOLDER) { + folder = (0, _parsers.nullParser)(process.env.PARSE_SERVER_LOGS_FOLDER); + } + + return folder; +})(); + +const { + verbose, + level +} = (() => { + const verbose = process.env.VERBOSE ? true : false; + return { + verbose, + level: verbose ? 'verbose' : undefined + }; +})(); + +const DefinitionDefaults = Object.keys(ParseServerOptions).reduce((memo, key) => { + const def = ParseServerOptions[key]; + + if (Object.prototype.hasOwnProperty.call(def, 'default')) { + memo[key] = def.default; + } + + return memo; +}, {}); +const computedDefaults = { + jsonLogs: process.env.JSON_LOGS || false, + logsFolder, + verbose, + level +}; + +var _default = Object.assign({}, DefinitionDefaults, computedDefaults); + +exports.default = _default; +const DefaultMongoURI = DefinitionDefaults.databaseURI; +exports.DefaultMongoURI = DefaultMongoURI; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZWZhdWx0cy5qcyJdLCJuYW1lcyI6WyJQYXJzZVNlcnZlck9wdGlvbnMiLCJyZXF1aXJlIiwibG9nc0ZvbGRlciIsImZvbGRlciIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwiUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSIiwidmVyYm9zZSIsImxldmVsIiwiVkVSQk9TRSIsInVuZGVmaW5lZCIsIkRlZmluaXRpb25EZWZhdWx0cyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJtZW1vIiwia2V5IiwiZGVmIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiZGVmYXVsdCIsImNvbXB1dGVkRGVmYXVsdHMiLCJqc29uTG9ncyIsIkpTT05fTE9HUyIsImFzc2lnbiIsIkRlZmF1bHRNb25nb1VSSSIsImRhdGFiYXNlVVJJIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQXlCQyxPQUFPLENBQUMsdUJBQUQsQ0FBdEM7O0FBQ0EsTUFBTUMsVUFBVSxHQUFHLENBQUMsTUFBTTtBQUN4QixNQUFJQyxNQUFNLEdBQUcsU0FBYjs7QUFDQSxNQUFJLE9BQU9DLE9BQVAsS0FBbUIsV0FBbkIsSUFBa0NBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLEtBQXdCLEdBQTlELEVBQW1FO0FBQ2pFSCxJQUFBQSxNQUFNLEdBQUcsY0FBVDtBQUNEOztBQUNELE1BQUlDLE9BQU8sQ0FBQ0MsR0FBUixDQUFZRSx3QkFBaEIsRUFBMEM7QUFDeENKLElBQUFBLE1BQU0sR0FBRyx5QkFBV0MsT0FBTyxDQUFDQyxHQUFSLENBQVlFLHdCQUF2QixDQUFUO0FBQ0Q7O0FBQ0QsU0FBT0osTUFBUDtBQUNELENBVGtCLEdBQW5COztBQVdBLE1BQU07QUFBRUssRUFBQUEsT0FBRjtBQUFXQyxFQUFBQTtBQUFYLElBQXFCLENBQUMsTUFBTTtBQUNoQyxRQUFNRCxPQUFPLEdBQUdKLE9BQU8sQ0FBQ0MsR0FBUixDQUFZSyxPQUFaLEdBQXNCLElBQXRCLEdBQTZCLEtBQTdDO0FBQ0EsU0FBTztBQUFFRixJQUFBQSxPQUFGO0FBQVdDLElBQUFBLEtBQUssRUFBRUQsT0FBTyxHQUFHLFNBQUgsR0FBZUc7QUFBeEMsR0FBUDtBQUNELENBSDBCLEdBQTNCOztBQUtBLE1BQU1DLGtCQUFrQixHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWWQsa0JBQVosRUFBZ0NlLE1BQWhDLENBQXVDLENBQUNDLElBQUQsRUFBT0MsR0FBUCxLQUFlO0FBQy9FLFFBQU1DLEdBQUcsR0FBR2xCLGtCQUFrQixDQUFDaUIsR0FBRCxDQUE5Qjs7QUFDQSxNQUFJSixNQUFNLENBQUNNLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0gsR0FBckMsRUFBMEMsU0FBMUMsQ0FBSixFQUEwRDtBQUN4REYsSUFBQUEsSUFBSSxDQUFDQyxHQUFELENBQUosR0FBWUMsR0FBRyxDQUFDSSxPQUFoQjtBQUNEOztBQUNELFNBQU9OLElBQVA7QUFDRCxDQU4wQixFQU14QixFQU53QixDQUEzQjtBQVFBLE1BQU1PLGdCQUFnQixHQUFHO0FBQ3ZCQyxFQUFBQSxRQUFRLEVBQUVwQixPQUFPLENBQUNDLEdBQVIsQ0FBWW9CLFNBQVosSUFBeUIsS0FEWjtBQUV2QnZCLEVBQUFBLFVBRnVCO0FBR3ZCTSxFQUFBQSxPQUh1QjtBQUl2QkMsRUFBQUE7QUFKdUIsQ0FBekI7O2VBT2VJLE1BQU0sQ0FBQ2EsTUFBUCxDQUFjLEVBQWQsRUFBa0JkLGtCQUFsQixFQUFzQ1csZ0JBQXRDLEM7OztBQUNSLE1BQU1JLGVBQWUsR0FBR2Ysa0JBQWtCLENBQUNnQixXQUEzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG51bGxQYXJzZXIgfSBmcm9tICcuL09wdGlvbnMvcGFyc2Vycyc7XG5jb25zdCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9ID0gcmVxdWlyZSgnLi9PcHRpb25zL0RlZmluaXRpb25zJyk7XG5jb25zdCBsb2dzRm9sZGVyID0gKCgpID0+IHtcbiAgbGV0IGZvbGRlciA9ICcuL2xvZ3MvJztcbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5URVNUSU5HID09PSAnMScpIHtcbiAgICBmb2xkZXIgPSAnLi90ZXN0X2xvZ3MvJztcbiAgfVxuICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSKSB7XG4gICAgZm9sZGVyID0gbnVsbFBhcnNlcihwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfTE9HU19GT0xERVIpO1xuICB9XG4gIHJldHVybiBmb2xkZXI7XG59KSgpO1xuXG5jb25zdCB7IHZlcmJvc2UsIGxldmVsIH0gPSAoKCkgPT4ge1xuICBjb25zdCB2ZXJib3NlID0gcHJvY2Vzcy5lbnYuVkVSQk9TRSA/IHRydWUgOiBmYWxzZTtcbiAgcmV0dXJuIHsgdmVyYm9zZSwgbGV2ZWw6IHZlcmJvc2UgPyAndmVyYm9zZScgOiB1bmRlZmluZWQgfTtcbn0pKCk7XG5cbmNvbnN0IERlZmluaXRpb25EZWZhdWx0cyA9IE9iamVjdC5rZXlzKFBhcnNlU2VydmVyT3B0aW9ucykucmVkdWNlKChtZW1vLCBrZXkpID0+IHtcbiAgY29uc3QgZGVmID0gUGFyc2VTZXJ2ZXJPcHRpb25zW2tleV07XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZGVmLCAnZGVmYXVsdCcpKSB7XG4gICAgbWVtb1trZXldID0gZGVmLmRlZmF1bHQ7XG4gIH1cbiAgcmV0dXJuIG1lbW87XG59LCB7fSk7XG5cbmNvbnN0IGNvbXB1dGVkRGVmYXVsdHMgPSB7XG4gIGpzb25Mb2dzOiBwcm9jZXNzLmVudi5KU09OX0xPR1MgfHwgZmFsc2UsXG4gIGxvZ3NGb2xkZXIsXG4gIHZlcmJvc2UsXG4gIGxldmVsLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgT2JqZWN0LmFzc2lnbih7fSwgRGVmaW5pdGlvbkRlZmF1bHRzLCBjb21wdXRlZERlZmF1bHRzKTtcbmV4cG9ydCBjb25zdCBEZWZhdWx0TW9uZ29VUkkgPSBEZWZpbml0aW9uRGVmYXVsdHMuZGF0YWJhc2VVUkk7XG4iXX0= \ No newline at end of file diff --git a/lib/deprecated.js b/lib/deprecated.js new file mode 100644 index 0000000000..ea008a18d6 --- /dev/null +++ b/lib/deprecated.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.useExternal = useExternal; + +function useExternal(name, moduleName) { + return function () { + throw `${name} is not provided by parse-server anymore; please install ${moduleName}`; + }; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZXByZWNhdGVkLmpzIl0sIm5hbWVzIjpbInVzZUV4dGVybmFsIiwibmFtZSIsIm1vZHVsZU5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxTQUFTQSxXQUFULENBQXFCQyxJQUFyQixFQUEyQkMsVUFBM0IsRUFBdUM7QUFDNUMsU0FBTyxZQUFZO0FBQ2pCLFVBQU8sR0FBRUQsSUFBSyw0REFBMkRDLFVBQVcsRUFBcEY7QUFDRCxHQUZEO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gdXNlRXh0ZXJuYWwobmFtZSwgbW9kdWxlTmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IGAke25hbWV9IGlzIG5vdCBwcm92aWRlZCBieSBwYXJzZS1zZXJ2ZXIgYW55bW9yZTsgcGxlYXNlIGluc3RhbGwgJHttb2R1bGVOYW1lfWA7XG4gIH07XG59XG4iXX0= \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000000..e34f529164 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,107 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "S3Adapter", { + enumerable: true, + get: function () { + return _s3FilesAdapter.default; + } +}); +Object.defineProperty(exports, "FileSystemAdapter", { + enumerable: true, + get: function () { + return _fsFilesAdapter.default; + } +}); +Object.defineProperty(exports, "InMemoryCacheAdapter", { + enumerable: true, + get: function () { + return _InMemoryCacheAdapter.default; + } +}); +Object.defineProperty(exports, "NullCacheAdapter", { + enumerable: true, + get: function () { + return _NullCacheAdapter.default; + } +}); +Object.defineProperty(exports, "RedisCacheAdapter", { + enumerable: true, + get: function () { + return _RedisCacheAdapter.default; + } +}); +Object.defineProperty(exports, "LRUCacheAdapter", { + enumerable: true, + get: function () { + return _LRUCache.default; + } +}); +Object.defineProperty(exports, "PushWorker", { + enumerable: true, + get: function () { + return _PushWorker.PushWorker; + } +}); +Object.defineProperty(exports, "ParseGraphQLServer", { + enumerable: true, + get: function () { + return _ParseGraphQLServer.ParseGraphQLServer; + } +}); +exports.TestUtils = exports.ParseServer = exports.GCSAdapter = exports.default = void 0; + +var _ParseServer2 = _interopRequireDefault(require("./ParseServer")); + +var _s3FilesAdapter = _interopRequireDefault(require("@parse/s3-files-adapter")); + +var _fsFilesAdapter = _interopRequireDefault(require("@parse/fs-files-adapter")); + +var _InMemoryCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/InMemoryCacheAdapter")); + +var _NullCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/NullCacheAdapter")); + +var _RedisCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/RedisCacheAdapter")); + +var _LRUCache = _interopRequireDefault(require("./Adapters/Cache/LRUCache.js")); + +var TestUtils = _interopRequireWildcard(require("./TestUtils")); + +exports.TestUtils = TestUtils; + +var _deprecated = require("./deprecated"); + +var _logger = require("./logger"); + +var _PushWorker = require("./Push/PushWorker"); + +var _Options = require("./Options"); + +var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Factory function +const _ParseServer = function (options) { + const server = new _ParseServer2.default(options); + return server.app; +}; // Mount the create liveQueryServer + + +exports.ParseServer = _ParseServer; +_ParseServer.createLiveQueryServer = _ParseServer2.default.createLiveQueryServer; +_ParseServer.start = _ParseServer2.default.start; +const GCSAdapter = (0, _deprecated.useExternal)('GCSAdapter', '@parse/gcs-files-adapter'); +exports.GCSAdapter = GCSAdapter; +Object.defineProperty(module.exports, 'logger', { + get: _logger.getLogger +}); +var _default = _ParseServer2.default; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJfUGFyc2VTZXJ2ZXIiLCJvcHRpb25zIiwic2VydmVyIiwiUGFyc2VTZXJ2ZXIiLCJhcHAiLCJjcmVhdGVMaXZlUXVlcnlTZXJ2ZXIiLCJzdGFydCIsIkdDU0FkYXB0ZXIiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsIm1vZHVsZSIsImV4cG9ydHMiLCJnZXQiLCJnZXRMb2dnZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHLFVBQVVDLE9BQVYsRUFBdUM7QUFDMUQsUUFBTUMsTUFBTSxHQUFHLElBQUlDLHFCQUFKLENBQWdCRixPQUFoQixDQUFmO0FBQ0EsU0FBT0MsTUFBTSxDQUFDRSxHQUFkO0FBQ0QsQ0FIRCxDLENBSUE7Ozs7QUFDQUosWUFBWSxDQUFDSyxxQkFBYixHQUFxQ0Ysc0JBQVlFLHFCQUFqRDtBQUNBTCxZQUFZLENBQUNNLEtBQWIsR0FBcUJILHNCQUFZRyxLQUFqQztBQUVBLE1BQU1DLFVBQVUsR0FBRyw2QkFBWSxZQUFaLEVBQTBCLDBCQUExQixDQUFuQjs7QUFFQUMsTUFBTSxDQUFDQyxjQUFQLENBQXNCQyxNQUFNLENBQUNDLE9BQTdCLEVBQXNDLFFBQXRDLEVBQWdEO0FBQzlDQyxFQUFBQSxHQUFHLEVBQUVDO0FBRHlDLENBQWhEO2VBSWVWLHFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlU2VydmVyIGZyb20gJy4vUGFyc2VTZXJ2ZXInO1xuaW1wb3J0IFMzQWRhcHRlciBmcm9tICdAcGFyc2UvczMtZmlsZXMtYWRhcHRlcic7XG5pbXBvcnQgRmlsZVN5c3RlbUFkYXB0ZXIgZnJvbSAnQHBhcnNlL2ZzLWZpbGVzLWFkYXB0ZXInO1xuaW1wb3J0IEluTWVtb3J5Q2FjaGVBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvQ2FjaGUvSW5NZW1vcnlDYWNoZUFkYXB0ZXInO1xuaW1wb3J0IE51bGxDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBSZWRpc0NhY2hlQWRhcHRlciBmcm9tICcuL0FkYXB0ZXJzL0NhY2hlL1JlZGlzQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBMUlVDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyc7XG5pbXBvcnQgKiBhcyBUZXN0VXRpbHMgZnJvbSAnLi9UZXN0VXRpbHMnO1xuaW1wb3J0IHsgdXNlRXh0ZXJuYWwgfSBmcm9tICcuL2RlcHJlY2F0ZWQnO1xuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgUHVzaFdvcmtlciB9IGZyb20gJy4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxTZXJ2ZXIgfSBmcm9tICcuL0dyYXBoUUwvUGFyc2VHcmFwaFFMU2VydmVyJztcblxuLy8gRmFjdG9yeSBmdW5jdGlvblxuY29uc3QgX1BhcnNlU2VydmVyID0gZnVuY3Rpb24gKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCBzZXJ2ZXIgPSBuZXcgUGFyc2VTZXJ2ZXIob3B0aW9ucyk7XG4gIHJldHVybiBzZXJ2ZXIuYXBwO1xufTtcbi8vIE1vdW50IHRoZSBjcmVhdGUgbGl2ZVF1ZXJ5U2VydmVyXG5fUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyID0gUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyO1xuX1BhcnNlU2VydmVyLnN0YXJ0ID0gUGFyc2VTZXJ2ZXIuc3RhcnQ7XG5cbmNvbnN0IEdDU0FkYXB0ZXIgPSB1c2VFeHRlcm5hbCgnR0NTQWRhcHRlcicsICdAcGFyc2UvZ2NzLWZpbGVzLWFkYXB0ZXInKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbmV4cG9ydCB7XG4gIFMzQWRhcHRlcixcbiAgR0NTQWRhcHRlcixcbiAgRmlsZVN5c3RlbUFkYXB0ZXIsXG4gIEluTWVtb3J5Q2FjaGVBZGFwdGVyLFxuICBOdWxsQ2FjaGVBZGFwdGVyLFxuICBSZWRpc0NhY2hlQWRhcHRlcixcbiAgTFJVQ2FjaGVBZGFwdGVyLFxuICBUZXN0VXRpbHMsXG4gIFB1c2hXb3JrZXIsXG4gIFBhcnNlR3JhcGhRTFNlcnZlcixcbiAgX1BhcnNlU2VydmVyIGFzIFBhcnNlU2VydmVyLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/logger.js b/lib/logger.js new file mode 100644 index 0000000000..bd58e6bce9 --- /dev/null +++ b/lib/logger.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setLogger = setLogger; +exports.getLogger = getLogger; + +var _defaults = _interopRequireDefault(require("./defaults")); + +var _WinstonLoggerAdapter = require("./Adapters/Logger/WinstonLoggerAdapter"); + +var _LoggerController = require("./Controllers/LoggerController"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Used for Separate Live Query Server +function defaultLogger() { + const options = { + logsFolder: _defaults.default.logsFolder, + jsonLogs: _defaults.default.jsonLogs, + verbose: _defaults.default.verbose, + silent: _defaults.default.silent + }; + const adapter = new _WinstonLoggerAdapter.WinstonLoggerAdapter(options); + return new _LoggerController.LoggerController(adapter, null, options); +} + +let logger = defaultLogger(); + +function setLogger(aLogger) { + logger = aLogger; +} + +function getLogger() { + return logger; +} // for: `import logger from './logger'` + + +Object.defineProperty(module.exports, 'default', { + get: getLogger +}); // for: `import { logger } from './logger'` + +Object.defineProperty(module.exports, 'logger', { + get: getLogger +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIuanMiXSwibmFtZXMiOlsiZGVmYXVsdExvZ2dlciIsIm9wdGlvbnMiLCJsb2dzRm9sZGVyIiwiZGVmYXVsdHMiLCJqc29uTG9ncyIsInZlcmJvc2UiLCJzaWxlbnQiLCJhZGFwdGVyIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJDb250cm9sbGVyIiwibG9nZ2VyIiwic2V0TG9nZ2VyIiwiYUxvZ2dlciIsImdldExvZ2dlciIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwibW9kdWxlIiwiZXhwb3J0cyIsImdldCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTtBQUNBLFNBQVNBLGFBQVQsR0FBeUI7QUFDdkIsUUFBTUMsT0FBTyxHQUFHO0FBQ2RDLElBQUFBLFVBQVUsRUFBRUMsa0JBQVNELFVBRFA7QUFFZEUsSUFBQUEsUUFBUSxFQUFFRCxrQkFBU0MsUUFGTDtBQUdkQyxJQUFBQSxPQUFPLEVBQUVGLGtCQUFTRSxPQUhKO0FBSWRDLElBQUFBLE1BQU0sRUFBRUgsa0JBQVNHO0FBSkgsR0FBaEI7QUFNQSxRQUFNQyxPQUFPLEdBQUcsSUFBSUMsMENBQUosQ0FBeUJQLE9BQXpCLENBQWhCO0FBQ0EsU0FBTyxJQUFJUSxrQ0FBSixDQUFxQkYsT0FBckIsRUFBOEIsSUFBOUIsRUFBb0NOLE9BQXBDLENBQVA7QUFDRDs7QUFFRCxJQUFJUyxNQUFNLEdBQUdWLGFBQWEsRUFBMUI7O0FBRU8sU0FBU1csU0FBVCxDQUFtQkMsT0FBbkIsRUFBNEI7QUFDakNGLEVBQUFBLE1BQU0sR0FBR0UsT0FBVDtBQUNEOztBQUVNLFNBQVNDLFNBQVQsR0FBcUI7QUFDMUIsU0FBT0gsTUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0FJLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxTQUF0QyxFQUFpRDtBQUMvQ0MsRUFBQUEsR0FBRyxFQUFFTDtBQUQwQyxDQUFqRCxFLENBSUE7O0FBQ0FDLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxRQUF0QyxFQUFnRDtBQUM5Q0MsRUFBQUEsR0FBRyxFQUFFTDtBQUR5QyxDQUFoRCIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCB7IFdpbnN0b25Mb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vQ29udHJvbGxlcnMvTG9nZ2VyQ29udHJvbGxlcic7XG5cbi8vIFVzZWQgZm9yIFNlcGFyYXRlIExpdmUgUXVlcnkgU2VydmVyXG5mdW5jdGlvbiBkZWZhdWx0TG9nZ2VyKCkge1xuICBjb25zdCBvcHRpb25zID0ge1xuICAgIGxvZ3NGb2xkZXI6IGRlZmF1bHRzLmxvZ3NGb2xkZXIsXG4gICAganNvbkxvZ3M6IGRlZmF1bHRzLmpzb25Mb2dzLFxuICAgIHZlcmJvc2U6IGRlZmF1bHRzLnZlcmJvc2UsXG4gICAgc2lsZW50OiBkZWZhdWx0cy5zaWxlbnQsXG4gIH07XG4gIGNvbnN0IGFkYXB0ZXIgPSBuZXcgV2luc3RvbkxvZ2dlckFkYXB0ZXIob3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihhZGFwdGVyLCBudWxsLCBvcHRpb25zKTtcbn1cblxubGV0IGxvZ2dlciA9IGRlZmF1bHRMb2dnZXIoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihhTG9nZ2VyKSB7XG4gIGxvZ2dlciA9IGFMb2dnZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2dnZXIoKSB7XG4gIHJldHVybiBsb2dnZXI7XG59XG5cbi8vIGZvcjogYGltcG9ydCBsb2dnZXIgZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnZGVmYXVsdCcsIHtcbiAgZ2V0OiBnZXRMb2dnZXIsXG59KTtcblxuLy8gZm9yOiBgaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuIl19 \ No newline at end of file diff --git a/lib/middlewares.js b/lib/middlewares.js new file mode 100644 index 0000000000..c7d89304d0 --- /dev/null +++ b/lib/middlewares.js @@ -0,0 +1,492 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.handleParseHeaders = handleParseHeaders; +exports.allowCrossDomain = allowCrossDomain; +exports.allowMethodOverride = allowMethodOverride; +exports.handleParseErrors = handleParseErrors; +exports.enforceMasterKeyAccess = enforceMasterKeyAccess; +exports.promiseEnforceMasterKeyAccess = promiseEnforceMasterKeyAccess; +exports.promiseEnsureIdempotency = promiseEnsureIdempotency; +exports.DEFAULT_ALLOWED_HEADERS = void 0; + +var _cache = _interopRequireDefault(require("./cache")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _Auth = _interopRequireDefault(require("./Auth")); + +var _Config = _interopRequireDefault(require("./Config")); + +var _ClientSDK = _interopRequireDefault(require("./ClientSDK")); + +var _logger = _interopRequireDefault(require("./logger")); + +var _rest = _interopRequireDefault(require("./rest")); + +var _MongoStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Mongo/MongoStorageAdapter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control'; +exports.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS; + +const getMountForRequest = function (req) { + const mountPathLength = req.originalUrl.length - req.url.length; + const mountPath = req.originalUrl.slice(0, mountPathLength); + return req.protocol + '://' + req.get('host') + mountPath; +}; // Checks that the request is authorized for this app and checks user +// auth too. +// The bodyparser should run before this middleware. +// Adds info to the request: +// req.config - the Config for this app +// req.auth - the Auth for this request + + +function handleParseHeaders(req, res, next) { + var mount = getMountForRequest(req); + var info = { + appId: req.get('X-Parse-Application-Id'), + sessionToken: req.get('X-Parse-Session-Token'), + masterKey: req.get('X-Parse-Master-Key'), + installationId: req.get('X-Parse-Installation-Id'), + clientKey: req.get('X-Parse-Client-Key'), + javascriptKey: req.get('X-Parse-Javascript-Key'), + dotNetKey: req.get('X-Parse-Windows-Key'), + restAPIKey: req.get('X-Parse-REST-API-Key'), + clientVersion: req.get('X-Parse-Client-Version'), + context: {} + }; + var basicAuth = httpAuth(req); + + if (basicAuth) { + var basicAuthAppId = basicAuth.appId; + + if (_cache.default.get(basicAuthAppId)) { + info.appId = basicAuthAppId; + info.masterKey = basicAuth.masterKey || info.masterKey; + info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey; + } + } + + if (req.body) { + // Unity SDK sends a _noBody key which needs to be removed. + // Unclear at this point if action needs to be taken. + delete req.body._noBody; + } + + var fileViaJSON = false; + + if (!info.appId || !_cache.default.get(info.appId)) { + // See if we can find the app id on the body. + if (req.body instanceof Buffer) { + // The only chance to find the app id is if this is a file + // upload that actually is a JSON body. So try to parse it. + // https://github.com/parse-community/parse-server/issues/6589 + // It is also possible that the client is trying to upload a file but forgot + // to provide x-parse-app-id in header and parse a binary file will fail + try { + req.body = JSON.parse(req.body); + } catch (e) { + return invalidRequest(req, res); + } + + fileViaJSON = true; + } + + if (req.body) { + delete req.body._RevocableSession; + } + + if (req.body && req.body._ApplicationId && _cache.default.get(req.body._ApplicationId) && (!info.masterKey || _cache.default.get(req.body._ApplicationId).masterKey === info.masterKey)) { + info.appId = req.body._ApplicationId; + info.javascriptKey = req.body._JavaScriptKey || ''; + delete req.body._ApplicationId; + delete req.body._JavaScriptKey; // TODO: test that the REST API formats generated by the other + // SDKs are handled ok + + if (req.body._ClientVersion) { + info.clientVersion = req.body._ClientVersion; + delete req.body._ClientVersion; + } + + if (req.body._InstallationId) { + info.installationId = req.body._InstallationId; + delete req.body._InstallationId; + } + + if (req.body._SessionToken) { + info.sessionToken = req.body._SessionToken; + delete req.body._SessionToken; + } + + if (req.body._MasterKey) { + info.masterKey = req.body._MasterKey; + delete req.body._MasterKey; + } + + if (req.body._context && req.body._context instanceof Object) { + info.context = req.body._context; + delete req.body._context; + } + + if (req.body._ContentType) { + req.headers['content-type'] = req.body._ContentType; + delete req.body._ContentType; + } + } else { + return invalidRequest(req, res); + } + } + + if (info.sessionToken && typeof info.sessionToken !== 'string') { + info.sessionToken = info.sessionToken.toString(); + } + + if (info.clientVersion) { + info.clientSDK = _ClientSDK.default.fromString(info.clientVersion); + } + + if (fileViaJSON) { + req.fileData = req.body.fileData; // We need to repopulate req.body with a buffer + + var base64 = req.body.base64; + req.body = Buffer.from(base64, 'base64'); + } + + const clientIp = getClientIp(req); + info.app = _cache.default.get(info.appId); + req.config = _Config.default.get(info.appId, mount); + req.config.headers = req.headers || {}; + req.config.ip = clientIp; + req.info = info; + + if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(clientIp) === -1) { + return invalidRequest(req, res); + } + + var isMaster = info.masterKey === req.config.masterKey; + + if (isMaster) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: true + }); + next(); + return; + } + + var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey; + + if (typeof req.config.readOnlyMasterKey != 'undefined' && req.config.readOnlyMasterKey && isReadOnlyMaster) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: true, + isReadOnly: true + }); + next(); + return; + } // Client keys are not required in parse-server, but if any have been configured in the server, validate them + // to preserve original behavior. + + + const keys = ['clientKey', 'javascriptKey', 'dotNetKey', 'restAPIKey']; + const oneKeyConfigured = keys.some(function (key) { + return req.config[key] !== undefined; + }); + const oneKeyMatches = keys.some(function (key) { + return req.config[key] !== undefined && info[key] === req.config[key]; + }); + + if (oneKeyConfigured && !oneKeyMatches) { + return invalidRequest(req, res); + } + + if (req.url == '/login') { + delete info.sessionToken; + } + + if (req.userFromJWT) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: false, + user: req.userFromJWT + }); + next(); + return; + } + + if (!info.sessionToken) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: false + }); + next(); + return; + } + + return Promise.resolve().then(() => { + // handle the upgradeToRevocableSession path on it's own + if (info.sessionToken && req.url === '/upgradeToRevocableSession' && info.sessionToken.indexOf('r:') != 0) { + return _Auth.default.getAuthForLegacySessionToken({ + config: req.config, + installationId: info.installationId, + sessionToken: info.sessionToken + }); + } else { + return _Auth.default.getAuthForSessionToken({ + config: req.config, + installationId: info.installationId, + sessionToken: info.sessionToken + }); + } + }).then(auth => { + if (auth) { + req.auth = auth; + next(); + } + }).catch(error => { + if (error instanceof _node.default.Error) { + next(error); + return; + } else { + // TODO: Determine the correct error scenario. + req.config.loggerController.error('error getting auth for sessionToken', error); + throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error); + } + }); +} + +function getClientIp(req) { + if (req.headers['x-forwarded-for']) { + // try to get from x-forwared-for if it set (behind reverse proxy) + return req.headers['x-forwarded-for'].split(',')[0]; + } else if (req.connection && req.connection.remoteAddress) { + // no proxy, try getting from connection.remoteAddress + return req.connection.remoteAddress; + } else if (req.socket) { + // try to get it from req.socket + return req.socket.remoteAddress; + } else if (req.connection && req.connection.socket) { + // try to get it form the connection.socket + return req.connection.socket.remoteAddress; + } else { + // if non above, fallback. + return req.ip; + } +} + +function httpAuth(req) { + if (!(req.req || req).headers.authorization) return; + var header = (req.req || req).headers.authorization; + var appId, masterKey, javascriptKey; // parse header + + var authPrefix = 'basic '; + var match = header.toLowerCase().indexOf(authPrefix); + + if (match == 0) { + var encodedAuth = header.substring(authPrefix.length, header.length); + var credentials = decodeBase64(encodedAuth).split(':'); + + if (credentials.length == 2) { + appId = credentials[0]; + var key = credentials[1]; + var jsKeyPrefix = 'javascript-key='; + var matchKey = key.indexOf(jsKeyPrefix); + + if (matchKey == 0) { + javascriptKey = key.substring(jsKeyPrefix.length, key.length); + } else { + masterKey = key; + } + } + } + + return { + appId: appId, + masterKey: masterKey, + javascriptKey: javascriptKey + }; +} + +function decodeBase64(str) { + return Buffer.from(str, 'base64').toString(); +} + +function allowCrossDomain(appId) { + return (req, res, next) => { + const config = _Config.default.get(appId, getMountForRequest(req)); + + let allowHeaders = DEFAULT_ALLOWED_HEADERS; + + if (config && config.allowHeaders) { + allowHeaders += `, ${config.allowHeaders.join(', ')}`; + } + + const allowOrigin = config && config.allowOrigin || '*'; + res.header('Access-Control-Allow-Origin', allowOrigin); + res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); + res.header('Access-Control-Allow-Headers', allowHeaders); + res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id'); // intercept OPTIONS method + + if ('OPTIONS' == req.method) { + res.sendStatus(200); + } else { + next(); + } + }; +} + +function allowMethodOverride(req, res, next) { + if (req.method === 'POST' && req.body._method) { + req.originalMethod = req.method; + req.method = req.body._method; + delete req.body._method; + } + + next(); +} + +function handleParseErrors(err, req, res, next) { + const log = req.config && req.config.loggerController || _logger.default; + + if (err instanceof _node.default.Error) { + if (req.config && req.config.enableExpressErrorHandler) { + return next(err); + } + + let httpStatus; // TODO: fill out this mapping + + switch (err.code) { + case _node.default.Error.INTERNAL_SERVER_ERROR: + httpStatus = 500; + break; + + case _node.default.Error.OBJECT_NOT_FOUND: + httpStatus = 404; + break; + + default: + httpStatus = 400; + } + + res.status(httpStatus); + res.json({ + code: err.code, + error: err.message + }); + log.error('Parse error: ', err); + } else if (err.status && err.message) { + res.status(err.status); + res.json({ + error: err.message + }); + + if (!(process && process.env.TESTING)) { + next(err); + } + } else { + log.error('Uncaught internal server error.', err, err.stack); + res.status(500); + res.json({ + code: _node.default.Error.INTERNAL_SERVER_ERROR, + message: 'Internal server error.' + }); + + if (!(process && process.env.TESTING)) { + next(err); + } + } +} + +function enforceMasterKeyAccess(req, res, next) { + if (!req.auth.isMaster) { + res.status(403); + res.end('{"error":"unauthorized: master key is required"}'); + return; + } + + next(); +} + +function promiseEnforceMasterKeyAccess(request) { + if (!request.auth.isMaster) { + const error = new Error(); + error.status = 403; + error.message = 'unauthorized: master key is required'; + throw error; + } + + return Promise.resolve(); +} +/** + * Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID + * in the request header. If a request has no request ID, it is executed anyway. + * @param {*} req The request to evaluate. + * @returns Promise<{}> + */ + + +function promiseEnsureIdempotency(req) { + // Enable feature only for MongoDB + if (!(req.config.database.adapter instanceof _MongoStorageAdapter.default)) { + return Promise.resolve(); + } // Get parameters + + + const config = req.config; + const requestId = ((req || {}).headers || {})['x-parse-request-id']; + const { + paths, + ttl + } = config.idempotencyOptions; + + if (!requestId || !config.idempotencyOptions) { + return Promise.resolve(); + } // Request path may contain trailing slashes, depending on the original request, so remove + // leading and trailing slashes to make it easier to specify paths in the configuration + + + const reqPath = req.path.replace(/^\/|\/$/, ''); // Determine whether idempotency is enabled for current request path + + let match = false; + + for (const path of paths) { + // Assume one wants a path to always match from the beginning to prevent any mistakes + const regex = new RegExp(path.charAt(0) === '^' ? path : '^' + path); + + if (reqPath.match(regex)) { + match = true; + break; + } + } + + if (!match) { + return Promise.resolve(); + } // Try to store request + + + const expiryDate = new Date(new Date().setSeconds(new Date().getSeconds() + ttl)); + return _rest.default.create(config, _Auth.default.master(config), '_Idempotency', { + reqId: requestId, + expire: _node.default._encode(expiryDate) + }).catch(e => { + if (e.code == _node.default.Error.DUPLICATE_VALUE) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_REQUEST, 'Duplicate request'); + } + + throw e; + }); +} + +function invalidRequest(req, res) { + res.status(403); + res.end('{"error":"unauthorized"}'); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlcy5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0FMTE9XRURfSEVBREVSUyIsImdldE1vdW50Rm9yUmVxdWVzdCIsInJlcSIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJwcm90b2NvbCIsImdldCIsImhhbmRsZVBhcnNlSGVhZGVycyIsInJlcyIsIm5leHQiLCJtb3VudCIsImluZm8iLCJhcHBJZCIsInNlc3Npb25Ub2tlbiIsIm1hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiY29udGV4dCIsImJhc2ljQXV0aCIsImh0dHBBdXRoIiwiYmFzaWNBdXRoQXBwSWQiLCJBcHBDYWNoZSIsImJvZHkiLCJfbm9Cb2R5IiwiZmlsZVZpYUpTT04iLCJCdWZmZXIiLCJKU09OIiwicGFyc2UiLCJlIiwiaW52YWxpZFJlcXVlc3QiLCJfUmV2b2NhYmxlU2Vzc2lvbiIsIl9BcHBsaWNhdGlvbklkIiwiX0phdmFTY3JpcHRLZXkiLCJfQ2xpZW50VmVyc2lvbiIsIl9JbnN0YWxsYXRpb25JZCIsIl9TZXNzaW9uVG9rZW4iLCJfTWFzdGVyS2V5IiwiX2NvbnRleHQiLCJPYmplY3QiLCJfQ29udGVudFR5cGUiLCJoZWFkZXJzIiwidG9TdHJpbmciLCJjbGllbnRTREsiLCJDbGllbnRTREsiLCJmcm9tU3RyaW5nIiwiZmlsZURhdGEiLCJiYXNlNjQiLCJmcm9tIiwiY2xpZW50SXAiLCJnZXRDbGllbnRJcCIsImFwcCIsImNvbmZpZyIsIkNvbmZpZyIsImlwIiwibWFzdGVyS2V5SXBzIiwiaW5kZXhPZiIsImlzTWFzdGVyIiwiYXV0aCIsIkF1dGgiLCJpc1JlYWRPbmx5TWFzdGVyIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJpc1JlYWRPbmx5Iiwia2V5cyIsIm9uZUtleUNvbmZpZ3VyZWQiLCJzb21lIiwia2V5IiwidW5kZWZpbmVkIiwib25lS2V5TWF0Y2hlcyIsInVzZXJGcm9tSldUIiwidXNlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4iLCJnZXRBdXRoRm9yU2Vzc2lvblRva2VuIiwiY2F0Y2giLCJlcnJvciIsIlBhcnNlIiwiRXJyb3IiLCJsb2dnZXJDb250cm9sbGVyIiwiVU5LTk9XTl9FUlJPUiIsInNwbGl0IiwiY29ubmVjdGlvbiIsInJlbW90ZUFkZHJlc3MiLCJzb2NrZXQiLCJhdXRob3JpemF0aW9uIiwiaGVhZGVyIiwiYXV0aFByZWZpeCIsIm1hdGNoIiwidG9Mb3dlckNhc2UiLCJlbmNvZGVkQXV0aCIsInN1YnN0cmluZyIsImNyZWRlbnRpYWxzIiwiZGVjb2RlQmFzZTY0IiwianNLZXlQcmVmaXgiLCJtYXRjaEtleSIsInN0ciIsImFsbG93Q3Jvc3NEb21haW4iLCJhbGxvd0hlYWRlcnMiLCJqb2luIiwiYWxsb3dPcmlnaW4iLCJtZXRob2QiLCJzZW5kU3RhdHVzIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsIl9tZXRob2QiLCJvcmlnaW5hbE1ldGhvZCIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZXJyIiwibG9nIiwiZGVmYXVsdExvZ2dlciIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJodHRwU3RhdHVzIiwiY29kZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJzdGF0dXMiLCJqc29uIiwibWVzc2FnZSIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwic3RhY2siLCJlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiZW5kIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXF1ZXN0IiwicHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IiwiZGF0YWJhc2UiLCJhZGFwdGVyIiwiTW9uZ29TdG9yYWdlQWRhcHRlciIsInJlcXVlc3RJZCIsInBhdGhzIiwidHRsIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwicmVxUGF0aCIsInBhdGgiLCJyZXBsYWNlIiwicmVnZXgiLCJSZWdFeHAiLCJjaGFyQXQiLCJleHBpcnlEYXRlIiwiRGF0ZSIsInNldFNlY29uZHMiLCJnZXRTZWNvbmRzIiwicmVzdCIsImNyZWF0ZSIsIm1hc3RlciIsInJlcUlkIiwiZXhwaXJlIiwiX2VuY29kZSIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsdUJBQXVCLEdBQ2xDLCtPQURLOzs7QUFHUCxNQUFNQyxrQkFBa0IsR0FBRyxVQUFVQyxHQUFWLEVBQWU7QUFDeEMsUUFBTUMsZUFBZSxHQUFHRCxHQUFHLENBQUNFLFdBQUosQ0FBZ0JDLE1BQWhCLEdBQXlCSCxHQUFHLENBQUNJLEdBQUosQ0FBUUQsTUFBekQ7QUFDQSxRQUFNRSxTQUFTLEdBQUdMLEdBQUcsQ0FBQ0UsV0FBSixDQUFnQkksS0FBaEIsQ0FBc0IsQ0FBdEIsRUFBeUJMLGVBQXpCLENBQWxCO0FBQ0EsU0FBT0QsR0FBRyxDQUFDTyxRQUFKLEdBQWUsS0FBZixHQUF1QlAsR0FBRyxDQUFDUSxHQUFKLENBQVEsTUFBUixDQUF2QixHQUF5Q0gsU0FBaEQ7QUFDRCxDQUpELEMsQ0FNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNJLGtCQUFULENBQTRCVCxHQUE1QixFQUFpQ1UsR0FBakMsRUFBc0NDLElBQXRDLEVBQTRDO0FBQ2pELE1BQUlDLEtBQUssR0FBR2Isa0JBQWtCLENBQUNDLEdBQUQsQ0FBOUI7QUFFQSxNQUFJYSxJQUFJLEdBQUc7QUFDVEMsSUFBQUEsS0FBSyxFQUFFZCxHQUFHLENBQUNRLEdBQUosQ0FBUSx3QkFBUixDQURFO0FBRVRPLElBQUFBLFlBQVksRUFBRWYsR0FBRyxDQUFDUSxH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aGUnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGF1dGggZnJvbSAnLi9BdXRoJztcbmltcG9ydCBDb25maWcgZnJvbSAnLi9Db25maWcnO1xuaW1wb3J0IENsaWVudFNESyBmcm9tICcuL0NsaWVudFNESyc7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuL3Jlc3QnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXInO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9BTExPV0VEX0hFQURFUlMgPVxuICAnWC1QYXJzZS1NYXN0ZXItS2V5LCBYLVBhcnNlLVJFU1QtQVBJLUtleSwgWC1QYXJzZS1KYXZhc2NyaXB0LUtleSwgWC1QYXJzZS1BcHBsaWNhdGlvbi1JZCwgWC1QYXJzZS1DbGllbnQtVmVyc2lvbiwgWC1QYXJzZS1TZXNzaW9uLVRva2VuLCBYLVJlcXVlc3RlZC1XaXRoLCBYLVBhcnNlLVJldm9jYWJsZS1TZXNzaW9uLCBYLVBhcnNlLVJlcXVlc3QtSWQsIENvbnRlbnQtVHlwZSwgUHJhZ21hLCBDYWNoZS1Db250cm9sJztcblxuY29uc3QgZ2V0TW91bnRGb3JSZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcSkge1xuICBjb25zdCBtb3VudFBhdGhMZW5ndGggPSByZXEub3JpZ2luYWxVcmwubGVuZ3RoIC0gcmVxLnVybC5sZW5ndGg7XG4gIGNvbnN0IG1vdW50UGF0aCA9IHJlcS5vcmlnaW5hbFVybC5zbGljZSgwLCBtb3VudFBhdGhMZW5ndGgpO1xuICByZXR1cm4gcmVxLnByb3RvY29sICsgJzovLycgKyByZXEuZ2V0KCdob3N0JykgKyBtb3VudFBhdGg7XG59O1xuXG4vLyBDaGVja3MgdGhhdCB0aGUgcmVxdWVzdCBpcyBhdXRob3JpemVkIGZvciB0aGlzIGFwcCBhbmQgY2hlY2tzIHVzZXJcbi8vIGF1dGggdG9vLlxuLy8gVGhlIGJvZHlwYXJzZXIgc2hvdWxkIHJ1biBiZWZvcmUgdGhpcyBtaWRkbGV3YXJlLlxuLy8gQWRkcyBpbmZvIHRvIHRoZSByZXF1ZXN0OlxuLy8gcmVxLmNvbmZpZyAtIHRoZSBDb25maWcgZm9yIHRoaXMgYXBwXG4vLyByZXEuYXV0aCAtIHRoZSBBdXRoIGZvciB0aGlzIHJlcXVlc3RcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXJzZUhlYWRlcnMocmVxLCByZXMsIG5leHQpIHtcbiAgdmFyIG1vdW50ID0gZ2V0TW91bnRGb3JSZXF1ZXN0KHJlcSk7XG5cbiAgdmFyIGluZm8gPSB7XG4gICAgYXBwSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnKSxcbiAgICBzZXNzaW9uVG9rZW46IHJlcS5nZXQoJ1gtUGFyc2UtU2Vzc2lvbi1Ub2tlbicpLFxuICAgIG1hc3RlcktleTogcmVxLmdldCgnWC1QYXJzZS1NYXN0ZXItS2V5JyksXG4gICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtSW5zdGFsbGF0aW9uLUlkJyksXG4gICAgY2xpZW50S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1LZXknKSxcbiAgICBqYXZhc2NyaXB0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUphdmFzY3JpcHQtS2V5JyksXG4gICAgZG90TmV0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLVdpbmRvd3MtS2V5JyksXG4gICAgcmVzdEFQSUtleTogcmVxLmdldCgnWC1QYXJzZS1SRVNULUFQSS1LZXknKSxcbiAgICBjbGllbnRWZXJzaW9uOiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1WZXJzaW9uJyksXG4gICAgY29udGV4dDoge30sXG4gIH07XG5cbiAgdmFyIGJhc2ljQXV0aCA9IGh0dHBBdXRoKHJlcSk7XG5cbiAgaWYgKGJhc2ljQXV0aCkge1xuICAgIHZhciBiYXNpY0F1dGhBcHBJZCA9IGJhc2ljQXV0aC5hcHBJZDtcbiAgICBpZiAoQXBwQ2FjaGUuZ2V0KGJhc2ljQXV0aEFwcElkKSkge1xuICAgICAgaW5mby5hcHBJZCA9IGJhc2ljQXV0aEFwcElkO1xuICAgICAgaW5mby5tYXN0ZXJLZXkgPSBiYXNpY0F1dGgubWFzdGVyS2V5IHx8IGluZm8ubWFzdGVyS2V5O1xuICAgICAgaW5mby5qYXZhc2NyaXB0S2V5ID0gYmFzaWNBdXRoLmphdmFzY3JpcHRLZXkgfHwgaW5mby5qYXZhc2NyaXB0S2V5O1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXEuYm9keSkge1xuICAgIC8vIFVuaXR5IFNESyBzZW5kcyBhIF9ub0JvZHkga2V5IHdoaWNoIG5lZWRzIHRvIGJlIHJlbW92ZWQuXG4gICAgLy8gVW5jbGVhciBhdCB0aGlzIHBvaW50IGlmIGFjdGlvbiBuZWVkcyB0byBiZSB0YWtlbi5cbiAgICBkZWxldGUgcmVxLmJvZHkuX25vQm9keTtcbiAgfVxuXG4gIHZhciBmaWxlVmlhSlNPTiA9IGZhbHNlO1xuXG4gIGlmICghaW5mby5hcHBJZCB8fCAhQXBwQ2FjaGUuZ2V0KGluZm8uYXBwSWQpKSB7XG4gICAgLy8gU2VlIGlmIHdlIGNhbiBmaW5kIHRoZSBhcHAgaWQgb24gdGhlIGJvZHkuXG4gICAgaWYgKHJlcS5ib2R5IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAvLyBUaGUgb25seSBjaGFuY2UgdG8gZmluZCB0aGUgYXBwIGlkIGlzIGlmIHRoaXMgaXMgYSBmaWxlXG4gICAgICAvLyB1cGxvYWQgdGhhdCBhY3R1YWxseSBpcyBhIEpTT04gYm9keS4gU28gdHJ5IHRvIHBhcnNlIGl0LlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BhcnNlLWNvbW11bml0eS9wYXJzZS1zZXJ2ZXIvaXNzdWVzLzY1ODlcbiAgICAgIC8vIEl0IGlzIGFsc28gcG9zc2libGUgdGhhdCB0aGUgY2xpZW50IGlzIHRyeWluZyB0byB1cGxvYWQgYSBmaWxlIGJ1dCBmb3Jnb3RcbiAgICAgIC8vIHRvIHByb3ZpZGUgeC1wYXJzZS1hcHAtaWQgaW4gaGVhZGVyIGFuZCBwYXJzZSBhIGJpbmFyeSBmaWxlIHdpbGwgZmFpbFxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVxLmJvZHkgPSBKU09OLnBhcnNlKHJlcS5ib2R5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgICAgIH1cbiAgICAgIGZpbGVWaWFKU09OID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocmVxLmJvZHkpIHtcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fUmV2b2NhYmxlU2Vzc2lvbjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICByZXEuYm9keSAmJlxuICAgICAgcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQgJiZcbiAgICAgIEFwcENhY2hlLmdldChyZXEuYm9keS5fQXBwbGljYXRpb25JZCkgJiZcbiAgICAgICghaW5mby5tYXN0ZXJLZXkgfHwgQXBwQ2FjaGUuZ2V0KHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkKS5tYXN0ZXJLZXkgPT09IGluZm8ubWFzdGVyS2V5KVxuICAgICkge1xuICAgICAgaW5mby5hcHBJZCA9IHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkO1xuICAgICAgaW5mby5qYXZhc2NyaXB0S2V5ID0gcmVxLmJvZHkuX0phdmFTY3JpcHRLZXkgfHwgJyc7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQ7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX0phdmFTY3JpcHRLZXk7XG4gICAgICAvLyBUT0RPOiB0ZXN0IHRoYXQgdGhlIFJFU1QgQVBJIGZvcm1hdHMgZ2VuZXJhdGVkIGJ5IHRoZSBvdGhlclxuICAgICAgLy8gU0RLcyBhcmUgaGFuZGxlZCBva1xuICAgICAgaWYgKHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uKSB7XG4gICAgICAgIGluZm8uY2xpZW50VmVyc2lvbiA9IHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0NsaWVudFZlcnNpb247XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX0luc3RhbGxhdGlvbklkKSB7XG4gICAgICAgIGluZm8uaW5zdGFsbGF0aW9uSWQgPSByZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQ7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQ7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX1Nlc3Npb25Ub2tlbikge1xuICAgICAgICBpbmZvLnNlc3Npb25Ub2tlbiA9IHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW47XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fU2Vzc2lvblRva2VuO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9NYXN0ZXJLZXkpIHtcbiAgICAgICAgaW5mby5tYXN0ZXJLZXkgPSByZXEuYm9keS5fTWFzdGVyS2V5O1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX01hc3RlcktleTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fY29udGV4dCAmJiByZXEuYm9keS5fY29udGV4dCBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICBpbmZvLmNvbnRleHQgPSByZXEuYm9keS5fY29udGV4dDtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9jb250ZXh0O1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9Db250ZW50VHlwZSkge1xuICAgICAgICByZXEuaGVhZGVyc1snY29udGVudC10eXBlJ10gPSByZXEuYm9keS5fQ29udGVudFR5cGU7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fQ29udGVudFR5cGU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZm8uc2Vzc2lvblRva2VuICYmIHR5cGVvZiBpbmZvLnNlc3Npb25Ub2tlbiAhPT0gJ3N0cmluZycpIHtcbiAgICBpbmZvLnNlc3Npb25Ub2tlbiA9IGluZm8uc2Vzc2lvblRva2VuLnRvU3RyaW5nKCk7XG4gIH1cblxuICBpZiAoaW5mby5jbGllbnRWZXJzaW9uKSB7XG4gICAgaW5mby5jbGllbnRTREsgPSBDbGllbnRTREsuZnJvbVN0cmluZyhpbmZvLmNsaWVudFZlcnNpb24pO1xuICB9XG5cbiAgaWYgKGZpbGVWaWFKU09OKSB7XG4gICAgcmVxLmZpbGVEYXRhID0gcmVxLmJvZHkuZmlsZURhdGE7XG4gICAgLy8gV2UgbmVlZCB0byByZXBvcHVsYXRlIHJlcS5ib2R5IHdpdGggYSBidWZmZXJcbiAgICB2YXIgYmFzZTY0ID0gcmVxLmJvZHkuYmFzZTY0O1xuICAgIHJlcS5ib2R5ID0gQnVmZmVyLmZyb20oYmFzZTY0LCAnYmFzZTY0Jyk7XG4gIH1cblxuICBjb25zdCBjbGllbnRJcCA9IGdldENsaWVudElwKHJlcSk7XG5cbiAgaW5mby5hcHAgPSBBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCk7XG4gIHJlcS5jb25maWcgPSBDb25maWcuZ2V0KGluZm8uYXBwSWQsIG1vdW50KTtcbiAgcmVxLmNvbmZpZy5oZWFkZXJzID0gcmVxLmhlYWRlcnMgfHwge307XG4gIHJlcS5jb25maWcuaXAgPSBjbGllbnRJcDtcbiAgcmVxLmluZm8gPSBpbmZvO1xuXG4gIGlmIChcbiAgICBpbmZvLm1hc3RlcktleSAmJlxuICAgIHJlcS5jb25maWcubWFzdGVyS2V5SXBzICYmXG4gICAgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMubGVuZ3RoICE9PSAwICYmXG4gICAgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMuaW5kZXhPZihjbGllbnRJcCkgPT09IC0xXG4gICkge1xuICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gIH1cblxuICB2YXIgaXNNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gcmVxLmNvbmZpZy5tYXN0ZXJLZXk7XG5cbiAgaWYgKGlzTWFzdGVyKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IHRydWUsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBpc1JlYWRPbmx5TWFzdGVyID0gaW5mby5tYXN0ZXJLZXkgPT09IHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXk7XG4gIGlmIChcbiAgICB0eXBlb2YgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAhPSAndW5kZWZpbmVkJyAmJlxuICAgIHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXkgJiZcbiAgICBpc1JlYWRPbmx5TWFzdGVyXG4gICkge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiB0cnVlLFxuICAgICAgaXNSZWFkT25seTogdHJ1ZSxcbiAgICB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQ2xpZW50IGtleXMgYXJlIG5vdCByZXF1aXJlZCBpbiBwYXJzZS1zZXJ2ZXIsIGJ1dCBpZiBhbnkgaGF2ZSBiZWVuIGNvbmZpZ3VyZWQgaW4gdGhlIHNlcnZlciwgdmFsaWRhdGUgdGhlbVxuICAvLyAgdG8gcHJlc2VydmUgb3JpZ2luYWwgYmVoYXZpb3IuXG4gIGNvbnN0IGtleXMgPSBbJ2NsaWVudEtleScsICdqYXZhc2NyaXB0S2V5JywgJ2RvdE5ldEtleScsICdyZXN0QVBJS2V5J107XG4gIGNvbnN0IG9uZUtleUNvbmZpZ3VyZWQgPSBrZXlzLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZDtcbiAgfSk7XG4gIGNvbnN0IG9uZUtleU1hdGNoZXMgPSBrZXlzLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZCAmJiBpbmZvW2tleV0gPT09IHJlcS5jb25maWdba2V5XTtcbiAgfSk7XG5cbiAgaWYgKG9uZUtleUNvbmZpZ3VyZWQgJiYgIW9uZUtleU1hdGNoZXMpIHtcbiAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICB9XG5cbiAgaWYgKHJlcS51cmwgPT0gJy9sb2dpbicpIHtcbiAgICBkZWxldGUgaW5mby5zZXNzaW9uVG9rZW47XG4gIH1cblxuICBpZiAocmVxLnVzZXJGcm9tSldUKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgdXNlcjogcmVxLnVzZXJGcm9tSldULFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIWluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyBoYW5kbGUgdGhlIHVwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24gcGF0aCBvbiBpdCdzIG93blxuICAgICAgaWYgKFxuICAgICAgICBpbmZvLnNlc3Npb25Ub2tlbiAmJlxuICAgICAgICByZXEudXJsID09PSAnL3VwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24nICYmXG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuLmluZGV4T2YoJ3I6JykgIT0gMFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBhdXRoLmdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4oe1xuICAgICAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICBzZXNzaW9uVG9rZW46IGluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhdXRoLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICBzZXNzaW9uVG9rZW46IGluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKGF1dGggPT4ge1xuICAgICAgaWYgKGF1dGgpIHtcbiAgICAgICAgcmVxLmF1dGggPSBhdXRoO1xuICAgICAgICBuZXh0KCk7XG4gICAgICB9XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgICAgbmV4dChlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IERldGVybWluZSB0aGUgY29ycmVjdCBlcnJvciBzY2VuYXJpby5cbiAgICAgICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmVycm9yKCdlcnJvciBnZXR0aW5nIGF1dGggZm9yIHNlc3Npb25Ub2tlbicsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVOS05PV05fRVJST1IsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50SXAocmVxKSB7XG4gIGlmIChyZXEuaGVhZGVyc1sneC1mb3J3YXJkZWQtZm9yJ10pIHtcbiAgICAvLyB0cnkgdG8gZ2V0IGZyb20geC1mb3J3YXJlZC1mb3IgaWYgaXQgc2V0IChiZWhpbmQgcmV2ZXJzZSBwcm94eSlcbiAgICByZXR1cm4gcmVxLmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddLnNwbGl0KCcsJylbMF07XG4gIH0gZWxzZSBpZiAocmVxLmNvbm5lY3Rpb24gJiYgcmVxLmNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzcykge1xuICAgIC8vIG5vIHByb3h5LCB0cnkgZ2V0dGluZyBmcm9tIGNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzc1xuICAgIHJldHVybiByZXEuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzO1xuICB9IGVsc2UgaWYgKHJlcS5zb2NrZXQpIHtcbiAgICAvLyB0cnkgdG8gZ2V0IGl0IGZyb20gcmVxLnNvY2tldFxuICAgIHJldHVybiByZXEuc29ja2V0LnJlbW90ZUFkZHJlc3M7XG4gIH0gZWxzZSBpZiAocmVxLmNvbm5lY3Rpb24gJiYgcmVxLmNvbm5lY3Rpb24uc29ja2V0KSB7XG4gICAgLy8gdHJ5IHRvIGdldCBpdCBmb3JtIHRoZSBjb25uZWN0aW9uLnNvY2tldFxuICAgIHJldHVybiByZXEuY29ubmVjdGlvbi5zb2NrZXQucmVtb3RlQWRkcmVzcztcbiAgfSBlbHNlIHtcbiAgICAvLyBpZiBub24gYWJvdmUsIGZhbGxiYWNrLlxuICAgIHJldHVybiByZXEuaXA7XG4gIH1cbn1cblxuZnVuY3Rpb24gaHR0cEF1dGgocmVxKSB7XG4gIGlmICghKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb24pIHJldHVybjtcblxuICB2YXIgaGVhZGVyID0gKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG4gIHZhciBhcHBJZCwgbWFzdGVyS2V5LCBqYXZhc2NyaXB0S2V5O1xuXG4gIC8vIHBhcnNlIGhlYWRlclxuICB2YXIgYXV0aFByZWZpeCA9ICdiYXNpYyAnO1xuXG4gIHZhciBtYXRjaCA9IGhlYWRlci50b0xvd2VyQ2FzZSgpLmluZGV4T2YoYXV0aFByZWZpeCk7XG5cbiAgaWYgKG1hdGNoID09IDApIHtcbiAgICB2YXIgZW5jb2RlZEF1dGggPSBoZWFkZXIuc3Vic3RyaW5nKGF1dGhQcmVmaXgubGVuZ3RoLCBoZWFkZXIubGVuZ3RoKTtcbiAgICB2YXIgY3JlZGVudGlhbHMgPSBkZWNvZGVCYXNlNjQoZW5jb2RlZEF1dGgpLnNwbGl0KCc6Jyk7XG5cbiAgICBpZiAoY3JlZGVudGlhbHMubGVuZ3RoID09IDIpIHtcbiAgICAgIGFwcElkID0gY3JlZGVudGlhbHNbMF07XG4gICAgICB2YXIga2V5ID0gY3JlZGVudGlhbHNbMV07XG5cbiAgICAgIHZhciBqc0tleVByZWZpeCA9ICdqYXZhc2NyaXB0LWtleT0nO1xuXG4gICAgICB2YXIgbWF0Y2hLZXkgPSBrZXkuaW5kZXhPZihqc0tleVByZWZpeCk7XG4gICAgICBpZiAobWF0Y2hLZXkgPT0gMCkge1xuICAgICAgICBqYXZhc2NyaXB0S2V5ID0ga2V5LnN1YnN0cmluZyhqc0tleVByZWZpeC5sZW5ndGgsIGtleS5sZW5ndGgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFzdGVyS2V5ID0ga2V5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFwcElkOiBhcHBJZCwgbWFzdGVyS2V5OiBtYXN0ZXJLZXksIGphdmFzY3JpcHRLZXk6IGphdmFzY3JpcHRLZXkgfTtcbn1cblxuZnVuY3Rpb24gZGVjb2RlQmFzZTY0KHN0cikge1xuICByZXR1cm4gQnVmZmVyLmZyb20oc3RyLCAnYmFzZTY0JykudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93Q3Jvc3NEb21haW4oYXBwSWQpIHtcbiAgcmV0dXJuIChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwSWQsIGdldE1vdW50Rm9yUmVxdWVzdChyZXEpKTtcbiAgICBsZXQgYWxsb3dIZWFkZXJzID0gREVGQVVMVF9BTExPV0VEX0hFQURFUlM7XG4gICAgaWYgKGNvbmZpZyAmJiBjb25maWcuYWxsb3dIZWFkZXJzKSB7XG4gICAgICBhbGxvd0hlYWRlcnMgKz0gYCwgJHtjb25maWcuYWxsb3dIZWFkZXJzLmpvaW4oJywgJyl9YDtcbiAgICB9XG4gICAgY29uc3QgYWxsb3dPcmlnaW4gPSAoY29uZmlnICYmIGNvbmZpZy5hbGxvd09yaWdpbikgfHwgJyonO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsIGFsbG93T3JpZ2luKTtcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCxQVVQsUE9TVCxERUxFVEUsT1BUSU9OUycpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLCBhbGxvd0hlYWRlcnMpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUV4cG9zZS1IZWFkZXJzJywgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCwgWC1QYXJzZS1QdXNoLVN0YXR1cy1JZCcpO1xuICAgIC8vIGludGVyY2VwdCBPUFRJT05TIG1ldGhvZFxuICAgIGlmICgnT1BUSU9OUycgPT0gcmVxLm1ldGhvZCkge1xuICAgICAgcmVzLnNlbmRTdGF0dXMoMjAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93TWV0aG9kT3ZlcnJpZGUocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiByZXEuYm9keS5fbWV0aG9kKSB7XG4gICAgcmVxLm9yaWdpbmFsTWV0aG9kID0gcmVxLm1ldGhvZDtcbiAgICByZXEubWV0aG9kID0gcmVxLmJvZHkuX21ldGhvZDtcbiAgICBkZWxldGUgcmVxLmJvZHkuX21ldGhvZDtcbiAgfVxuICBuZXh0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXJzZUVycm9ycyhlcnIsIHJlcSwgcmVzLCBuZXh0KSB7XG4gIGNvbnN0IGxvZyA9IChyZXEuY29uZmlnICYmIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcikgfHwgZGVmYXVsdExvZ2dlcjtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgaWYgKHJlcS5jb25maWcgJiYgcmVxLmNvbmZpZy5lbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnIpO1xuICAgIH1cbiAgICBsZXQgaHR0cFN0YXR1cztcbiAgICAvLyBUT0RPOiBmaWxsIG91dCB0aGlzIG1hcHBpbmdcbiAgICBzd2l0Y2ggKGVyci5jb2RlKSB7XG4gICAgICBjYXNlIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDUwMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQ6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA0MDQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDQwMDtcbiAgICB9XG4gICAgcmVzLnN0YXR1cyhodHRwU3RhdHVzKTtcbiAgICByZXMuanNvbih7IGNvZGU6IGVyci5jb2RlLCBlcnJvcjogZXJyLm1lc3NhZ2UgfSk7XG4gICAgbG9nLmVycm9yKCdQYXJzZSBlcnJvcjogJywgZXJyKTtcbiAgfSBlbHNlIGlmIChlcnIuc3RhdHVzICYmIGVyci5tZXNzYWdlKSB7XG4gICAgcmVzLnN0YXR1cyhlcnIuc3RhdHVzKTtcbiAgICByZXMuanNvbih7IGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBpZiAoIShwcm9jZXNzICYmIHByb2Nlc3MuZW52LlRFU1RJTkcpKSB7XG4gICAgICBuZXh0KGVycik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxvZy5lcnJvcignVW5jYXVnaHQgaW50ZXJuYWwgc2VydmVyIGVycm9yLicsIGVyciwgZXJyLnN0YWNrKTtcbiAgICByZXMuc3RhdHVzKDUwMCk7XG4gICAgcmVzLmpzb24oe1xuICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgbWVzc2FnZTogJ0ludGVybmFsIHNlcnZlciBlcnJvci4nLFxuICAgIH0pO1xuICAgIGlmICghKHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYuVEVTVElORykpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKCFyZXEuYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcy5zdGF0dXMoNDAzKTtcbiAgICByZXMuZW5kKCd7XCJlcnJvclwiOlwidW5hdXRob3JpemVkOiBtYXN0ZXIga2V5IGlzIHJlcXVpcmVkXCJ9Jyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIG5leHQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzKHJlcXVlc3QpIHtcbiAgaWYgKCFyZXF1ZXN0LmF1dGguaXNNYXN0ZXIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLnN0YXR1cyA9IDQwMztcbiAgICBlcnJvci5tZXNzYWdlID0gJ3VuYXV0aG9yaXplZDogbWFzdGVyIGtleSBpcyByZXF1aXJlZCc7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vKipcbiAqIERlZHVwbGljYXRlcyBhIHJlcXVlc3QgdG8gZW5zdXJlIGlkZW1wb3RlbmN5LiBEdXBsaWNhdGVzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSByZXF1ZXN0IElEXG4gKiBpbiB0aGUgcmVxdWVzdCBoZWFkZXIuIElmIGEgcmVxdWVzdCBoYXMgbm8gcmVxdWVzdCBJRCwgaXQgaXMgZXhlY3V0ZWQgYW55d2F5LlxuICogQHBhcmFtIHsqfSByZXEgVGhlIHJlcXVlc3QgdG8gZXZhbHVhdGUuXG4gKiBAcmV0dXJucyBQcm9taXNlPHt9PlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5KHJlcSkge1xuICAvLyBFbmFibGUgZmVhdHVyZSBvbmx5IGZvciBNb25nb0RCXG4gIGlmICghKHJlcS5jb25maWcuZGF0YWJhc2UuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXIpKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIEdldCBwYXJhbWV0ZXJzXG4gIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gIGNvbnN0IHJlcXVlc3RJZCA9ICgocmVxIHx8IHt9KS5oZWFkZXJzIHx8IHt9KVsneC1wYXJzZS1yZXF1ZXN0LWlkJ107XG4gIGNvbnN0IHsgcGF0aHMsIHR0bCB9ID0gY29uZmlnLmlkZW1wb3RlbmN5T3B0aW9ucztcbiAgaWYgKCFyZXF1ZXN0SWQgfHwgIWNvbmZpZy5pZGVtcG90ZW5jeU9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gUmVxdWVzdCBwYXRoIG1heSBjb250YWluIHRyYWlsaW5nIHNsYXNoZXMsIGRlcGVuZGluZyBvbiB0aGUgb3JpZ2luYWwgcmVxdWVzdCwgc28gcmVtb3ZlXG4gIC8vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgdG8gbWFrZSBpdCBlYXNpZXIgdG8gc3BlY2lmeSBwYXRocyBpbiB0aGUgY29uZmlndXJhdGlvblxuICBjb25zdCByZXFQYXRoID0gcmVxLnBhdGgucmVwbGFjZSgvXlxcL3xcXC8kLywgJycpO1xuICAvLyBEZXRlcm1pbmUgd2hldGhlciBpZGVtcG90ZW5jeSBpcyBlbmFibGVkIGZvciBjdXJyZW50IHJlcXVlc3QgcGF0aFxuICBsZXQgbWF0Y2ggPSBmYWxzZTtcbiAgZm9yIChjb25zdCBwYXRoIG9mIHBhdGhzKSB7XG4gICAgLy8gQXNzdW1lIG9uZSB3YW50cyBhIHBhdGggdG8gYWx3YXlzIG1hdGNoIGZyb20gdGhlIGJlZ2lubmluZyB0byBwcmV2ZW50IGFueSBtaXN0YWtlc1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChwYXRoLmNoYXJBdCgwKSA9PT0gJ14nID8gcGF0aCA6ICdeJyArIHBhdGgpO1xuICAgIGlmIChyZXFQYXRoLm1hdGNoKHJlZ2V4KSkge1xuICAgICAgbWF0Y2ggPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gVHJ5IHRvIHN0b3JlIHJlcXVlc3RcbiAgY29uc3QgZXhwaXJ5RGF0ZSA9IG5ldyBEYXRlKG5ldyBEYXRlKCkuc2V0U2Vjb25kcyhuZXcgRGF0ZSgpLmdldFNlY29uZHMoKSArIHR0bCkpO1xuICByZXR1cm4gcmVzdFxuICAgIC5jcmVhdGUoY29uZmlnLCBhdXRoLm1hc3Rlcihjb25maWcpLCAnX0lkZW1wb3RlbmN5Jywge1xuICAgICAgcmVxSWQ6IHJlcXVlc3RJZCxcbiAgICAgIGV4cGlyZTogUGFyc2UuX2VuY29kZShleHBpcnlEYXRlKSxcbiAgICB9KVxuICAgIC5jYXRjaChlID0+IHtcbiAgICAgIGlmIChlLmNvZGUgPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5EVVBMSUNBVEVfUkVRVUVTVCwgJ0R1cGxpY2F0ZSByZXF1ZXN0Jyk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcykge1xuICByZXMuc3RhdHVzKDQwMyk7XG4gIHJlcy5lbmQoJ3tcImVycm9yXCI6XCJ1bmF1dGhvcml6ZWRcIn0nKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/password.js b/lib/password.js new file mode 100644 index 0000000000..6091ae5d2d --- /dev/null +++ b/lib/password.js @@ -0,0 +1,38 @@ +"use strict"; + +// Tools for encrypting and decrypting passwords. +// Basically promise-friendly wrappers for bcrypt. +var bcrypt = require('bcryptjs'); + +try { + const _bcrypt = require('@node-rs/bcrypt'); + + bcrypt = { + hash: _bcrypt.hash, + compare: _bcrypt.verify + }; +} catch (e) { + /* */ +} // Returns a promise for a hashed password string. + + +function hash(password) { + return bcrypt.hash(password, 10); +} // Returns a promise for whether this password compares to equal this +// hashed password. + + +function compare(password, hashedPassword) { + // Cannot bcrypt compare when one is undefined + if (!password || !hashedPassword) { + return Promise.resolve(false); + } + + return bcrypt.compare(password, hashedPassword); +} + +module.exports = { + hash: hash, + compare: compare +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXNzd29yZC5qcyJdLCJuYW1lcyI6WyJiY3J5cHQiLCJyZXF1aXJlIiwiX2JjcnlwdCIsImhhc2giLCJjb21wYXJlIiwidmVyaWZ5IiwiZSIsInBhc3N3b3JkIiwiaGFzaGVkUGFzc3dvcmQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBLElBQUlBLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBcEI7O0FBRUEsSUFBSTtBQUNGLFFBQU1DLE9BQU8sR0FBR0QsT0FBTyxDQUFDLGlCQUFELENBQXZCOztBQUNBRCxFQUFBQSxNQUFNLEdBQUc7QUFDUEcsSUFBQUEsSUFBSSxFQUFFRCxPQUFPLENBQUNDLElBRFA7QUFFUEMsSUFBQUEsT0FBTyxFQUFFRixPQUFPLENBQUNHO0FBRlYsR0FBVDtBQUlELENBTkQsQ0FNRSxPQUFPQyxDQUFQLEVBQVU7QUFDVjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0gsSUFBVCxDQUFjSSxRQUFkLEVBQXdCO0FBQ3RCLFNBQU9QLE1BQU0sQ0FBQ0csSUFBUCxDQUFZSSxRQUFaLEVBQXNCLEVBQXRCLENBQVA7QUFDRCxDLENBRUQ7QUFDQTs7O0FBQ0EsU0FBU0gsT0FBVCxDQUFpQkcsUUFBakIsRUFBMkJDLGNBQTNCLEVBQTJDO0FBQ3pDO0FBQ0EsTUFBSSxDQUFDRCxRQUFELElBQWEsQ0FBQ0MsY0FBbEIsRUFBa0M7QUFDaEMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEtBQWhCLENBQVA7QUFDRDs7QUFDRCxTQUFPVixNQUFNLENBQUNJLE9BQVAsQ0FBZUcsUUFBZixFQUF5QkMsY0FBekIsQ0FBUDtBQUNEOztBQUVERyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlQsRUFBQUEsSUFBSSxFQUFFQSxJQURTO0FBRWZDLEVBQUFBLE9BQU8sRUFBRUE7QUFGTSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRvb2xzIGZvciBlbmNyeXB0aW5nIGFuZCBkZWNyeXB0aW5nIHBhc3N3b3Jkcy5cbi8vIEJhc2ljYWxseSBwcm9taXNlLWZyaWVuZGx5IHdyYXBwZXJzIGZvciBiY3J5cHQuXG52YXIgYmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0anMnKTtcblxudHJ5IHtcbiAgY29uc3QgX2JjcnlwdCA9IHJlcXVpcmUoJ0Bub2RlLXJzL2JjcnlwdCcpO1xuICBiY3J5cHQgPSB7XG4gICAgaGFzaDogX2JjcnlwdC5oYXNoLFxuICAgIGNvbXBhcmU6IF9iY3J5cHQudmVyaWZ5LFxuICB9O1xufSBjYXRjaCAoZSkge1xuICAvKiAqL1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBoYXNoZWQgcGFzc3dvcmQgc3RyaW5nLlxuZnVuY3Rpb24gaGFzaChwYXNzd29yZCkge1xuICByZXR1cm4gYmNyeXB0Lmhhc2gocGFzc3dvcmQsIDEwKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgdGhpcyBwYXNzd29yZCBjb21wYXJlcyB0byBlcXVhbCB0aGlzXG4vLyBoYXNoZWQgcGFzc3dvcmQuXG5mdW5jdGlvbiBjb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCkge1xuICAvLyBDYW5ub3QgYmNyeXB0IGNvbXBhcmUgd2hlbiBvbmUgaXMgdW5kZWZpbmVkXG4gIGlmICghcGFzc3dvcmQgfHwgIWhhc2hlZFBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYXNoOiBoYXNoLFxuICBjb21wYXJlOiBjb21wYXJlLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/request.js b/lib/request.js new file mode 100644 index 0000000000..47dae80852 --- /dev/null +++ b/lib/request.js @@ -0,0 +1,4 @@ +"use strict"; + +module.exports = require('./cloud-code/httpRequest'); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LmpzIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJyZXF1aXJlIl0sIm1hcHBpbmdzIjoiOztBQUFBQSxNQUFNLENBQUNDLE9BQVAsR0FBaUJDLE9BQU8sQ0FBQywwQkFBRCxDQUF4QiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0Jyk7XG4iXX0= \ No newline at end of file diff --git a/lib/requiredParameter.js b/lib/requiredParameter.js new file mode 100644 index 0000000000..2a657ca91b --- /dev/null +++ b/lib/requiredParameter.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _default = errorMessage => { + throw errorMessage; +}; + +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1aXJlZFBhcmFtZXRlci5qcyJdLCJuYW1lcyI6WyJlcnJvck1lc3NhZ2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7ZUFDZ0JBLFlBQUQsSUFBK0I7QUFDNUMsUUFBTUEsWUFBTjtBQUNELEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQGZsb3cgKi9cbmV4cG9ydCBkZWZhdWx0IChlcnJvck1lc3NhZ2U6IHN0cmluZyk6IGFueSA9PiB7XG4gIHRocm93IGVycm9yTWVzc2FnZTtcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/rest.js b/lib/rest.js new file mode 100644 index 0000000000..f5c9fa9ce5 --- /dev/null +++ b/lib/rest.js @@ -0,0 +1,208 @@ +"use strict"; + +// This file contains helpers for running operations in REST format. +// The goal is that handlers that explicitly handle an express route +// should just be shallow wrappers around things in this file, but +// these functions should not explicitly depend on the request +// object. +// This means that one of these handlers can support multiple +// routes. That's useful for the routes that do really similar +// things. +var Parse = require('parse/node').Parse; + +var RestQuery = require('./RestQuery'); + +var RestWrite = require('./RestWrite'); + +var triggers = require('./triggers'); + +function checkTriggers(className, config, types) { + return types.some(triggerType => { + return triggers.getTrigger(className, triggers.Types[triggerType], config.applicationId); + }); +} + +function checkLiveQuery(className, config) { + return config.liveQueryController && config.liveQueryController.hasLiveQuery(className); +} // Returns a promise for an object with optional keys 'results' and 'count'. + + +function find(config, auth, className, restWhere, restOptions, clientSDK, context) { + enforceRoleSecurity('find', className, auth); + return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context).then(result => { + restWhere = result.restWhere || restWhere; + restOptions = result.restOptions || restOptions; + const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); + return query.execute(); + }); +} // get is just like find but only queries an objectId. + + +const get = (config, auth, className, objectId, restOptions, clientSDK, context) => { + var restWhere = { + objectId + }; + enforceRoleSecurity('get', className, auth); + return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context, true).then(result => { + restWhere = result.restWhere || restWhere; + restOptions = result.restOptions || restOptions; + const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); + return query.execute(); + }); +}; // Returns a promise that doesn't resolve to any useful value. + + +function del(config, auth, className, objectId, context) { + if (typeof objectId !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad objectId'); + } + + if (className === '_User' && auth.isUnauthenticated()) { + throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth to delete user'); + } + + enforceRoleSecurity('delete', className, auth); + let inflatedObject; + let schemaController; + return Promise.resolve().then(() => { + const hasTriggers = checkTriggers(className, config, ['beforeDelete', 'afterDelete']); + const hasLiveQuery = checkLiveQuery(className, config); + + if (hasTriggers || hasLiveQuery || className == '_Session') { + return new RestQuery(config, auth, className, { + objectId + }).execute({ + op: 'delete' + }).then(response => { + if (response && response.results && response.results.length) { + const firstResult = response.results[0]; + firstResult.className = className; + + if (className === '_Session' && !auth.isMaster) { + if (!auth.user || firstResult.user.objectId !== auth.user.id) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + } + + var cacheAdapter = config.cacheController; + cacheAdapter.user.del(firstResult.sessionToken); + inflatedObject = Parse.Object.fromJSON(firstResult); + return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config, context); + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.'); + }); + } + + return Promise.resolve({}); + }).then(() => { + if (!auth.isMaster) { + return auth.getUserRoles(); + } else { + return; + } + }).then(() => config.database.loadSchema()).then(s => { + schemaController = s; + const options = {}; + + if (!auth.isMaster) { + options.acl = ['*']; + + if (auth.user) { + options.acl.push(auth.user.id); + options.acl = options.acl.concat(auth.userRoles); + } + } + + return config.database.destroy(className, { + objectId: objectId + }, options, schemaController); + }).then(() => { + // Notify LiveQuery server if possible + const perms = schemaController.getClassLevelPermissions(className); + config.liveQueryController.onAfterDelete(className, inflatedObject, null, perms); + return triggers.maybeRunTrigger(triggers.Types.afterDelete, auth, inflatedObject, null, config, context); + }).catch(error => { + handleSessionMissingError(error, className, auth); + }); +} // Returns a promise for a {response, status, location} object. + + +function create(config, auth, className, restObject, clientSDK, context) { + enforceRoleSecurity('create', className, auth); + var write = new RestWrite(config, auth, className, null, restObject, null, clientSDK, context); + return write.execute(); +} // Returns a promise that contains the fields of the update that the +// REST API is supposed to return. +// Usually, this is just updatedAt. + + +function update(config, auth, className, restWhere, restObject, clientSDK, context) { + enforceRoleSecurity('update', className, auth); + return Promise.resolve().then(() => { + const hasTriggers = checkTriggers(className, config, ['beforeSave', 'afterSave']); + const hasLiveQuery = checkLiveQuery(className, config); + + if (hasTriggers || hasLiveQuery) { + // Do not use find, as it runs the before finds + return new RestQuery(config, auth, className, restWhere, undefined, undefined, false).execute({ + op: 'update' + }); + } + + return Promise.resolve({}); + }).then(({ + results + }) => { + var originalRestObject; + + if (results && results.length) { + originalRestObject = results[0]; + } + + return new RestWrite(config, auth, className, restWhere, restObject, originalRestObject, clientSDK, context, 'update').execute(); + }).catch(error => { + handleSessionMissingError(error, className, auth); + }); +} + +function handleSessionMissingError(error, className, auth) { + // If we're trying to update a user without / with bad session token + if (className === '_User' && error.code === Parse.Error.OBJECT_NOT_FOUND && !auth.isMaster) { + throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth.'); + } + + throw error; +} + +const classesWithMasterOnlyAccess = ['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_JobSchedule', '_Idempotency']; // Disallowing access to the _Role collection except by master key + +function enforceRoleSecurity(method, className, auth) { + if (className === '_Installation' && !auth.isMaster) { + if (method === 'delete' || method === 'find') { + const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } + } //all volatileClasses are masterKey only + + + if (classesWithMasterOnlyAccess.indexOf(className) >= 0 && !auth.isMaster) { + const error = `Clients aren't allowed to perform the ${method} operation on the ${className} collection.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } // readOnly masterKey is not allowed + + + if (auth.isReadOnly && (method === 'delete' || method === 'create' || method === 'update')) { + const error = `read-only masterKey isn't allowed to perform the ${method} operation.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } +} + +module.exports = { + create, + del, + find, + get, + update +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXN0LmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlJlc3RXcml0ZSIsInRyaWdnZXJzIiwiY2hlY2tUcmlnZ2VycyIsImNsYXNzTmFtZSIsImNvbmZpZyIsInR5cGVzIiwic29tZSIsInRyaWdnZXJUeXBlIiwiZ2V0VHJpZ2dlciIsIlR5cGVzIiwiYXBwbGljYXRpb25JZCIsImNoZWNrTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsImhhc0xpdmVRdWVyeSIsImZpbmQiLCJhdXRoIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiZW5mb3JjZVJvbGVTZWN1cml0eSIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwiYmVmb3JlRmluZCIsInRoZW4iLCJyZXN1bHQiLCJxdWVyeSIsImV4ZWN1dGUiLCJnZXQiLCJvYmplY3RJZCIsImRlbCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJTRVNTSU9OX01JU1NJTkciLCJpbmZsYXRlZE9iamVjdCIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwicmVzb2x2ZSIsImhhc1RyaWdnZXJzIiwib3AiLCJyZXNwb25zZSIsInJlc3VsdHMiLCJsZW5ndGgiLCJmaXJzdFJlc3VsdCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVDb250cm9sbGVyIiwic2Vzc2lvblRva2VuIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJtYXliZVJ1blRyaWdnZXIiLCJiZWZvcmVEZWxldGUiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0VXNlclJvbGVzIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwicyIsIm9wdGlvbnMiLCJhY2wiLCJwdXNoIiwiY29uY2F0IiwidXNlclJvbGVzIiwiZGVzdHJveSIsInBlcm1zIiwiZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwib25BZnRlckRlbGV0ZSIsImFmdGVyRGVsZXRlIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IiLCJjcmVhdGUiLCJyZXN0T2JqZWN0Iiwid3JpdGUiLCJ1cGRhdGUiLCJ1bmRlZmluZWQiLCJvcmlnaW5hbFJlc3RPYmplY3QiLCJjb2RlIiwiY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzIiwibWV0aG9kIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImluZGV4T2YiLCJpc1JlYWRPbmx5IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxJQUFJRSxTQUFTLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBQXZCOztBQUNBLElBQUlFLFNBQVMsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBdkI7O0FBQ0EsSUFBSUcsUUFBUSxHQUFHSCxPQUFPLENBQUMsWUFBRCxDQUF0Qjs7QUFFQSxTQUFTSSxhQUFULENBQXVCQyxTQUF2QixFQUFrQ0MsTUFBbEMsRUFBMENDLEtBQTFDLEVBQWlEO0FBQy9DLFNBQU9BLEtBQUssQ0FBQ0MsSUFBTixDQUFXQyxXQUFXLElBQUk7QUFDL0IsV0FBT04sUUFBUSxDQUFDTyxVQUFULENBQW9CTCxTQUFwQixFQUErQkYsUUFBUSxDQUFDUSxLQUFULENBQWVGLFdBQWYsQ0FBL0IsRUFBNERILE1BQU0sQ0FBQ00sYUFBbkUsQ0FBUDtBQUNELEdBRk0sQ0FBUDtBQUdEOztBQUVELFNBQVNDLGNBQVQsQ0FBd0JSLFNBQXhCLEVBQW1DQyxNQUFuQyxFQUEyQztBQUN6QyxTQUFPQSxNQUFNLENBQUNRLG1CQUFQLElBQThCUixNQUFNLENBQUNRLG1CQUFQLENBQTJCQyxZQUEzQixDQUF3Q1YsU0FBeEMsQ0FBckM7QUFDRCxDLENBRUQ7OztB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SyxRQUFYLElBQXVCQSxNQUFNLEtBQUssTUFBdEMsRUFBOEM7QUFDNUMsWUFBTVYsS0FBSyxHQUFJLHlDQUF3Q1UsTUFBTyw0Q0FBOUQ7QUFDQSxZQUFNLElBQUlwRixLQUFLLENBQUNpQyxLQUFWLENBQWdCakMsS0FBSyxDQUFDaUMsS0FBTixDQUFZb0QsbUJBQTVCLEVBQWlEWCxLQUFqRCxDQUFOO0FBQ0Q7QUFDRixHQU5tRCxDQVFwRDs7O0FBQ0EsTUFBSVMsMkJBQTJCLENBQUNHLE9BQTVCLENBQW9DaEYsU0FBcEMsS0FBa0QsQ0FBbEQsSUFBdUQsQ0FBQ1ksSUFBSSxDQUFDNkIsUUFBakUsRUFBMkU7QUFDekUsVUFBTTJCLEtBQUssR0FBSSx5Q0FBd0NVLE1BQU8scUJBQW9COUUsU0FBVSxjQUE1RjtBQUNBLFVBQU0sSUFBSU4sS0FBSyxDQUFDaUMsS0FBVixDQUFnQmpDLEtBQUssQ0FBQ2lDLEtBQU4sQ0FBWW9ELG1CQUE1QixFQUFpRFgsS0FBakQsQ0FBTjtBQUNELEdBWm1ELENBY3BEOzs7QUFDQSxNQUFJeEQsSUFBSSxDQUFDcUUsVUFBTCxLQUFvQkgsTUFBTSxLQUFLLFFBQVgsSUFBdUJBLE1BQU0sS0FBSyxRQUFsQyxJQUE4Q0EsTUFBTSxLQUFLLFFBQTdFLENBQUosRUFBNEY7QUFDMUYsVUFBTVYsS0FBSyxHQUFJLG9EQUFtRFUsTUFBTyxhQUF6RTtBQUNBLFVBQU0sSUFBSXBGLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlvRCxtQkFBNUIsRUFBaURYLEtBQWpELENBQU47QUFDRDtBQUNGOztBQUVEYyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmIsRUFBQUEsTUFEZTtBQUVmNUMsRUFBQUEsR0FGZTtBQUdmZixFQUFBQSxJQUhlO0FBSWZhLEVBQUFBLEdBSmU7QUFLZmlELEVBQUFBO0FBTGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGlzIGZpbGUgY29udGFpbnMgaGVscGVycyBmb3IgcnVubmluZyBvcGVyYXRpb25zIGluIFJFU1QgZm9ybWF0LlxuLy8gVGhlIGdvYWwgaXMgdGhhdCBoYW5kbGVycyB0aGF0IGV4cGxpY2l0bHkgaGFuZGxlIGFuIGV4cHJlc3Mgcm91dGVcbi8vIHNob3VsZCBqdXN0IGJlIHNoYWxsb3cgd3JhcHBlcnMgYXJvdW5kIHRoaW5ncyBpbiB0aGlzIGZpbGUsIGJ1dFxuLy8gdGhlc2UgZnVuY3Rpb25zIHNob3VsZCBub3QgZXhwbGljaXRseSBkZXBlbmQgb24gdGhlIHJlcXVlc3Rcbi8vIG9iamVjdC5cbi8vIFRoaXMgbWVhbnMgdGhhdCBvbmUgb2YgdGhlc2UgaGFuZGxlcnMgY2FuIHN1cHBvcnQgbXVsdGlwbGVcbi8vIHJvdXRlcy4gVGhhdCdzIHVzZWZ1bCBmb3IgdGhlIHJvdXRlcyB0aGF0IGRvIHJlYWxseSBzaW1pbGFyXG4vLyB0aGluZ3MuXG5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxudmFyIFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG52YXIgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcbnZhciB0cmlnZ2VycyA9IHJlcXVpcmUoJy4vdHJpZ2dlcnMnKTtcblxuZnVuY3Rpb24gY2hlY2tUcmlnZ2VycyhjbGFzc05hbWUsIGNvbmZpZywgdHlwZXMpIHtcbiAgcmV0dXJuIHR5cGVzLnNvbWUodHJpZ2dlclR5cGUgPT4ge1xuICAgIHJldHVybiB0cmlnZ2Vycy5nZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXNbdHJpZ2dlclR5cGVdLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjaGVja0xpdmVRdWVyeShjbGFzc05hbWUsIGNvbmZpZykge1xuICByZXR1cm4gY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIgJiYgY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIuaGFzTGl2ZVF1ZXJ5KGNsYXNzTmFtZSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhbiBvYmplY3Qgd2l0aCBvcHRpb25hbCBrZXlzICdyZXN1bHRzJyBhbmQgJ2NvdW50Jy5cbmZ1bmN0aW9uIGZpbmQoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNsaWVudFNESywgY29udGV4dCkge1xuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCdmaW5kJywgY2xhc3NOYW1lLCBhdXRoKTtcbiAgcmV0dXJuIHRyaWdnZXJzXG4gICAgLm1heWJlUnVuUXVlcnlUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRmluZCxcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgY29uZmlnLFxuICAgICAgYXV0aCxcbiAgICAgIGNvbnRleHRcbiAgICApXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIHJlc3RXaGVyZSA9IHJlc3VsdC5yZXN0V2hlcmUgfHwgcmVzdFdoZXJlO1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN1bHQucmVzdE9wdGlvbnMgfHwgcmVzdE9wdGlvbnM7XG4gICAgICBjb25zdCBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNsaWVudFNESyk7XG4gICAgICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpO1xuICAgIH0pO1xufVxuXG4vLyBnZXQgaXMganVzdCBsaWtlIGZpbmQgYnV0IG9ubHkgcXVlcmllcyBhbiBvYmplY3RJZC5cbmNvbnN0IGdldCA9IChjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0SWQsIHJlc3RPcHRpb25zLCBjbGllbnRTREssIGNvbnRleHQpID0+IHtcbiAgdmFyIHJlc3RXaGVyZSA9IHsgb2JqZWN0SWQgfTtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnZ2V0JywgY2xhc3NOYW1lLCBhdXRoKTtcbiAgcmV0dXJuIHRyaWdnZXJzXG4gICAgLm1heWJlUnVuUXVlcnlUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRmluZCxcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgY29uZmlnLFxuICAgICAgYXV0aCxcbiAgICAgIGNvbnRleHQsXG4gICAgICB0cnVlXG4gICAgKVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICByZXN0V2hlcmUgPSByZXN1bHQucmVzdFdoZXJlIHx8IHJlc3RXaGVyZTtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdWx0LnJlc3RPcHRpb25zIHx8IHJlc3RPcHRpb25zO1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREspO1xuICAgICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICB9KTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZG9lc24ndCByZXNvbHZlIHRvIGFueSB1c2VmdWwgdmFsdWUuXG5mdW5jdGlvbiBkZWwoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2Ygb2JqZWN0SWQgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBvYmplY3RJZCcpO1xuICB9XG5cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiBhdXRoLmlzVW5hdXRoZW50aWNhdGVkKCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0VTU0lPTl9NSVNTSU5HLCAnSW5zdWZmaWNpZW50IGF1dGggdG8gZGVsZXRlIHVzZXInKTtcbiAgfVxuXG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2RlbGV0ZScsIGNsYXNzTmFtZSwgYXV0aCk7XG5cbiAgbGV0IGluZmxhdGVkT2JqZWN0O1xuICBsZXQgc2NoZW1hQ29udHJvbGxlcjtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBoYXNUcmlnZ2VycyA9IGNoZWNrVHJpZ2dlcnMoY2xhc3NOYW1lLCBjb25maWcsIFsnYmVmb3JlRGVsZXRlJywgJ2FmdGVyRGVsZXRlJ10pO1xuICAgICAgY29uc3QgaGFzTGl2ZVF1ZXJ5ID0gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpO1xuICAgICAgaWYgKGhhc1RyaWdnZXJzIHx8IGhhc0xpdmVRdWVyeSB8fCBjbGFzc05hbWUgPT0gJ19TZXNzaW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3RRdWVyeShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgeyBvYmplY3RJZCB9KVxuICAgICAgICAgIC5leGVjdXRlKHsgb3A6ICdkZWxldGUnIH0pXG4gICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnJlc3VsdHMgJiYgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZmlyc3RSZXN1bHQgPSByZXNwb25zZS5yZXN1bHRzWzBdO1xuICAgICAgICAgICAgICBmaXJzdFJlc3VsdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfU2Vzc2lvbicgJiYgIWF1dGguaXNNYXN0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWF1dGgudXNlciB8fCBmaXJzdFJlc3VsdC51c2VyLm9iamVjdElkICE9PSBhdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIGNhY2hlQWRhcHRlciA9IGNvbmZpZy5jYWNoZUNvbnRyb2xsZXI7XG4gICAgICAgICAgICAgIGNhY2hlQWRhcHRlci51c2VyLmRlbChmaXJzdFJlc3VsdC5zZXNzaW9uVG9rZW4pO1xuICAgICAgICAgICAgICBpbmZsYXRlZE9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihmaXJzdFJlc3VsdCk7XG4gICAgICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgICAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRGVsZXRlLFxuICAgICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgICAgaW5mbGF0ZWRPYmplY3QsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kIGZvciBkZWxldGUuJyk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGlmICghYXV0aC5pc01hc3Rlcikge1xuICAgICAgICByZXR1cm4gYXV0aC5nZXRVc2VyUm9sZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKCgpID0+IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKCkpXG4gICAgLnRoZW4ocyA9PiB7XG4gICAgICBzY2hlbWFDb250cm9sbGVyID0gcztcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICAgIGlmICghYXV0aC5pc01hc3Rlcikge1xuICAgICAgICBvcHRpb25zLmFjbCA9IFsnKiddO1xuICAgICAgICBpZiAoYXV0aC51c2VyKSB7XG4gICAgICAgICAgb3B0aW9ucy5hY2wucHVzaChhdXRoLnVzZXIuaWQpO1xuICAgICAgICAgIG9wdGlvbnMuYWNsID0gb3B0aW9ucy5hY2wuY29uY2F0KGF1dGgudXNlclJvbGVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAge1xuICAgICAgICAgIG9iamVjdElkOiBvYmplY3RJZCxcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgc2NoZW1hQ29udHJvbGxlclxuICAgICAgKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIE5vdGlmeSBMaXZlUXVlcnkgc2VydmVyIGlmIHBvc3NpYmxlXG4gICAgICBjb25zdCBwZXJtcyA9IHNjaGVtYUNvbnRyb2xsZXIuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSk7XG4gICAgICBjb25maWcubGl2ZVF1ZXJ5Q29udHJvbGxlci5vbkFmdGVyRGVsZXRlKGNsYXNzTmFtZSwgaW5mbGF0ZWRPYmplY3QsIG51bGwsIHBlcm1zKTtcbiAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlLFxuICAgICAgICBhdXRoLFxuICAgICAgICBpbmZsYXRlZE9iamVjdCxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBjb250ZXh0XG4gICAgICApO1xuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIGhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IoZXJyb3IsIGNsYXNzTmFtZSwgYXV0aCk7XG4gICAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZSwgc3RhdHVzLCBsb2NhdGlvbn0gb2JqZWN0LlxuZnVuY3Rpb24gY3JlYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0T2JqZWN0LCBjbGllbnRTREssIGNvbnRleHQpIHtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnY3JlYXRlJywgY2xhc3NOYW1lLCBhdXRoKTtcbiAgdmFyIHdyaXRlID0gbmV3IFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgbnVsbCwgcmVzdE9iamVjdCwgbnVsbCwgY2xpZW50U0RLLCBjb250ZXh0KTtcbiAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBjb250YWlucyB0aGUgZmllbGRzIG9mIHRoZSB1cGRhdGUgdGhhdCB0aGVcbi8vIFJFU1QgQVBJIGlzIHN1cHBvc2VkIHRvIHJldHVybi5cbi8vIFVzdWFsbHksIHRoaXMgaXMganVzdCB1cGRhdGVkQXQuXG5mdW5jdGlvbiB1cGRhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9iamVjdCwgY2xpZW50U0RLLCBjb250ZXh0KSB7XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ3VwZGF0ZScsIGNsYXNzTmFtZSwgYXV0aCk7XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgaGFzVHJpZ2dlcnMgPSBjaGVja1RyaWdnZXJzKGNsYXNzTmFtZSwgY29uZmlnLCBbJ2JlZm9yZVNhdmUnLCAnYWZ0ZXJTYXZlJ10pO1xuICAgICAgY29uc3QgaGFzTGl2ZVF1ZXJ5ID0gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpO1xuICAgICAgaWYgKGhhc1RyaWdnZXJzIHx8IGhhc0xpdmVRdWVyeSkge1xuICAgICAgICAvLyBEbyBub3QgdXNlIGZpbmQsIGFzIGl0IHJ1bnMgdGhlIGJlZm9yZSBmaW5kc1xuICAgICAgICByZXR1cm4gbmV3IFJlc3RRdWVyeShcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgZmFsc2VcbiAgICAgICAgKS5leGVjdXRlKHtcbiAgICAgICAgICBvcDogJ3VwZGF0ZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoeyByZXN1bHRzIH0pID0+IHtcbiAgICAgIHZhciBvcmlnaW5hbFJlc3RPYmplY3Q7XG4gICAgICBpZiAocmVzdWx0cyAmJiByZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICBvcmlnaW5hbFJlc3RPYmplY3QgPSByZXN1bHRzWzBdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSZXN0V3JpdGUoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgIHJlc3RPYmplY3QsXG4gICAgICAgIG9yaWdpbmFsUmVzdE9iamVjdCxcbiAgICAgICAgY2xpZW50U0RLLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICAndXBkYXRlJ1xuICAgICAgKS5leGVjdXRlKCk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKSB7XG4gIC8vIElmIHdlJ3JlIHRyeWluZyB0byB1cGRhdGUgYSB1c2VyIHdpdGhvdXQgLyB3aXRoIGJhZCBzZXNzaW9uIHRva2VuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCAmJiAhYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5TRVNTSU9OX01JU1NJTkcsICdJbnN1ZmZpY2llbnQgYXV0aC4nKTtcbiAgfVxuICB0aHJvdyBlcnJvcjtcbn1cblxuY29uc3QgY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzID0gW1xuICAnX0pvYlN0YXR1cycsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSG9va3MnLFxuICAnX0dsb2JhbENvbmZpZycsXG4gICdfSm9iU2NoZWR1bGUnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl07XG4vLyBEaXNhbGxvd2luZyBhY2Nlc3MgdG8gdGhlIF9Sb2xlIGNvbGxlY3Rpb24gZXhjZXB0IGJ5IG1hc3RlciBrZXlcbmZ1bmN0aW9uIGVuZm9yY2VSb2xlU2VjdXJpdHkobWV0aG9kLCBjbGFzc05hbWUsIGF1dGgpIHtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19JbnN0YWxsYXRpb24nICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScgfHwgbWV0aG9kID09PSAnZmluZCcpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYENsaWVudHMgYXJlbid0IGFsbG93ZWQgdG8gcGVyZm9ybSB0aGUgJHttZXRob2R9IG9wZXJhdGlvbiBvbiB0aGUgaW5zdGFsbGF0aW9uIGNvbGxlY3Rpb24uYDtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLy9hbGwgdm9sYXRpbGVDbGFzc2VzIGFyZSBtYXN0ZXJLZXkgb25seVxuICBpZiAoY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzLmluZGV4T2YoY2xhc3NOYW1lKSA+PSAwICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgQ2xpZW50cyBhcmVuJ3QgYWxsb3dlZCB0byBwZXJmb3JtIHRoZSAke21ldGhvZH0gb3BlcmF0aW9uIG9uIHRoZSAke2NsYXNzTmFtZX0gY29sbGVjdGlvbi5gO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gIH1cblxuICAvLyByZWFkT25seSBtYXN0ZXJLZXkgaXMgbm90IGFsbG93ZWRcbiAgaWYgKGF1dGguaXNSZWFkT25seSAmJiAobWV0aG9kID09PSAnZGVsZXRlJyB8fCBtZXRob2QgPT09ICdjcmVhdGUnIHx8IG1ldGhvZCA9PT0gJ3VwZGF0ZScpKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgcmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHBlcmZvcm0gdGhlICR7bWV0aG9kfSBvcGVyYXRpb24uYDtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTiwgZXJyb3IpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGUsXG4gIGRlbCxcbiAgZmluZCxcbiAgZ2V0LFxuICB1cGRhdGUsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/triggers.js b/lib/triggers.js new file mode 100644 index 0000000000..7283aae253 --- /dev/null +++ b/lib/triggers.js @@ -0,0 +1,1040 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.addFunction = addFunction; +exports.addJob = addJob; +exports.addTrigger = addTrigger; +exports.addFileTrigger = addFileTrigger; +exports.addConnectTrigger = addConnectTrigger; +exports.addLiveQueryEventHandler = addLiveQueryEventHandler; +exports.removeFunction = removeFunction; +exports.removeTrigger = removeTrigger; +exports._unregisterAll = _unregisterAll; +exports.getTrigger = getTrigger; +exports.getFileTrigger = getFileTrigger; +exports.triggerExists = triggerExists; +exports.getFunction = getFunction; +exports.getFunctionNames = getFunctionNames; +exports.getJob = getJob; +exports.getJobs = getJobs; +exports.getValidator = getValidator; +exports.getRequestObject = getRequestObject; +exports.getRequestQueryObject = getRequestQueryObject; +exports.getResponseObject = getResponseObject; +exports.maybeRunAfterFindTrigger = maybeRunAfterFindTrigger; +exports.maybeRunQueryTrigger = maybeRunQueryTrigger; +exports.resolveError = resolveError; +exports.maybeRunValidator = maybeRunValidator; +exports.maybeRunTrigger = maybeRunTrigger; +exports.inflate = inflate; +exports.runLiveQueryEventHandlers = runLiveQueryEventHandlers; +exports.getRequestFileObject = getRequestFileObject; +exports.maybeRunFileTrigger = maybeRunFileTrigger; +exports.maybeRunConnectTrigger = maybeRunConnectTrigger; +exports.maybeRunSubscribeTrigger = maybeRunSubscribeTrigger; +exports.maybeRunAfterEventTrigger = maybeRunAfterEventTrigger; +exports.Types = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _logger = require("./logger"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const Types = { + beforeLogin: 'beforeLogin', + afterLogin: 'afterLogin', + afterLogout: 'afterLogout', + beforeSave: 'beforeSave', + afterSave: 'afterSave', + beforeDelete: 'beforeDelete', + afterDelete: 'afterDelete', + beforeFind: 'beforeFind', + afterFind: 'afterFind', + beforeSaveFile: 'beforeSaveFile', + afterSaveFile: 'afterSaveFile', + beforeDeleteFile: 'beforeDeleteFile', + afterDeleteFile: 'afterDeleteFile', + beforeConnect: 'beforeConnect', + beforeSubscribe: 'beforeSubscribe', + afterEvent: 'afterEvent' +}; +exports.Types = Types; +const FileClassName = '@File'; +const ConnectClassName = '@Connect'; + +const baseStore = function () { + const Validators = Object.keys(Types).reduce(function (base, key) { + base[key] = {}; + return base; + }, {}); + const Functions = {}; + const Jobs = {}; + const LiveQuery = []; + const Triggers = Object.keys(Types).reduce(function (base, key) { + base[key] = {}; + return base; + }, {}); + return Object.freeze({ + Functions, + Jobs, + Validators, + Triggers, + LiveQuery + }); +}; + +function validateClassNameForTriggers(className, type) { + if (type == Types.beforeSave && className === '_PushStatus') { + // _PushStatus uses undocumented nested key increment ops + // allowing beforeSave would mess up the objects big time + // TODO: Allow proper documented way of using nested increment ops + throw 'Only afterSave is allowed on _PushStatus'; + } + + if ((type === Types.beforeLogin || type === Types.afterLogin) && className !== '_User') { + // TODO: check if upstream code will handle `Error` instance rather + // than this anti-pattern of throwing strings + throw 'Only the _User class is allowed for the beforeLogin and afterLogin triggers'; + } + + if (type === Types.afterLogout && className !== '_Session') { + // TODO: check if upstream code will handle `Error` instance rather + // than this anti-pattern of throwing strings + throw 'Only the _Session class is allowed for the afterLogout trigger.'; + } + + if (className === '_Session' && type !== Types.afterLogout) { + // TODO: check if upstream code will handle `Error` instance rather + // than this anti-pattern of throwing strings + throw 'Only the afterLogout trigger is allowed for the _Session class.'; + } + + return className; +} + +const _triggerStore = {}; +const Category = { + Functions: 'Functions', + Validators: 'Validators', + Jobs: 'Jobs', + Triggers: 'Triggers' +}; + +function getStore(category, name, applicationId) { + const path = name.split('.'); + path.splice(-1); // remove last component + + applicationId = applicationId || _node.default.applicationId; + _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); + let store = _triggerStore[applicationId][category]; + + for (const component of path) { + store = store[component]; + + if (!store) { + return undefined; + } + } + + return store; +} + +function add(category, name, handler, applicationId) { + const lastComponent = name.split('.').splice(-1); + const store = getStore(category, name, applicationId); + + if (store[lastComponent]) { + _logger.logger.warn(`Warning: Duplicate cloud functions exist for ${lastComponent}. Only the last one will be used and the others will be ignored.`); + } + + store[lastComponent] = handler; +} + +function remove(category, name, applicationId) { + const lastComponent = name.split('.').splice(-1); + const store = getStore(category, name, applicationId); + delete store[lastComponent]; +} + +function get(category, name, applicationId) { + const lastComponent = name.split('.').splice(-1); + const store = getStore(category, name, applicationId); + return store[lastComponent]; +} + +function addFunction(functionName, handler, validationHandler, applicationId) { + add(Category.Functions, functionName, handler, applicationId); + add(Category.Validators, functionName, validationHandler, applicationId); +} + +function addJob(jobName, handler, applicationId) { + add(Category.Jobs, jobName, handler, applicationId); +} + +function addTrigger(type, className, handler, applicationId, validationHandler) { + validateClassNameForTriggers(className, type); + add(Category.Triggers, `${type}.${className}`, handler, applicationId); + add(Category.Validators, `${type}.${className}`, validationHandler, applicationId); +} + +function addFileTrigger(type, handler, applicationId, validationHandler) { + add(Category.Triggers, `${type}.${FileClassName}`, handler, applicationId); + add(Category.Validators, `${type}.${FileClassName}`, validationHandler, applicationId); +} + +function addConnectTrigger(type, handler, applicationId, validationHandler) { + add(Category.Triggers, `${type}.${ConnectClassName}`, handler, applicationId); + add(Category.Validators, `${type}.${ConnectClassName}`, validationHandler, applicationId); +} + +function addLiveQueryEventHandler(handler, applicationId) { + applicationId = applicationId || _node.default.applicationId; + _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); + + _triggerStore[applicationId].LiveQuery.push(handler); +} + +function removeFunction(functionName, applicationId) { + remove(Category.Functions, functionName, applicationId); +} + +function removeTrigger(type, className, applicationId) { + remove(Category.Triggers, `${type}.${className}`, applicationId); +} + +function _unregisterAll() { + Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]); +} + +function getTrigger(className, triggerType, applicationId) { + if (!applicationId) { + throw 'Missing ApplicationID'; + } + + return get(Category.Triggers, `${triggerType}.${className}`, applicationId); +} + +function getFileTrigger(type, applicationId) { + return getTrigger(FileClassName, type, applicationId); +} + +function triggerExists(className, type, applicationId) { + return getTrigger(className, type, applicationId) != undefined; +} + +function getFunction(functionName, applicationId) { + return get(Category.Functions, functionName, applicationId); +} + +function getFunctionNames(applicationId) { + const store = _triggerStore[applicationId] && _triggerStore[applicationId][Category.Functions] || {}; + const functionNames = []; + + const extractFunctionNames = (namespace, store) => { + Object.keys(store).forEach(name => { + const value = store[name]; + + if (namespace) { + name = `${namespace}.${name}`; + } + + if (typeof value === 'function') { + functionNames.push(name); + } else { + extractFunctionNames(name, value); + } + }); + }; + + extractFunctionNames(null, store); + return functionNames; +} + +function getJob(jobName, applicationId) { + return get(Category.Jobs, jobName, applicationId); +} + +function getJobs(applicationId) { + var manager = _triggerStore[applicationId]; + + if (manager && manager.Jobs) { + return manager.Jobs; + } + + return undefined; +} + +function getValidator(functionName, applicationId) { + return get(Category.Validators, functionName, applicationId); +} + +function getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context) { + const request = { + triggerName: triggerType, + object: parseObject, + master: false, + log: config.loggerController, + headers: config.headers, + ip: config.ip + }; + + if (originalParseObject) { + request.original = originalParseObject; + } + + if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) { + // Set a copy of the context on the request object. + request.context = Object.assign({}, context); + } + + if (!auth) { + return request; + } + + if (auth.isMaster) { + request['master'] = true; + } + + if (auth.user) { + request['user'] = auth.user; + } + + if (auth.installationId) { + request['installationId'] = auth.installationId; + } + + return request; +} + +function getRequestQueryObject(triggerType, auth, query, count, config, context, isGet) { + isGet = !!isGet; + var request = { + triggerName: triggerType, + query, + master: false, + count, + log: config.loggerController, + isGet, + headers: config.headers, + ip: config.ip, + context: context || {} + }; + + if (!auth) { + return request; + } + + if (auth.isMaster) { + request['master'] = true; + } + + if (auth.user) { + request['user'] = auth.user; + } + + if (auth.installationId) { + request['installationId'] = auth.installationId; + } + + return request; +} // Creates the response object, and uses the request object to pass data +// The API will call this with REST API formatted objects, this will +// transform them to Parse.Object instances expected by Cloud Code. +// Any changes made to the object in a beforeSave will be included. + + +function getResponseObject(request, resolve, reject) { + return { + success: function (response) { + if (request.triggerName === Types.afterFind) { + if (!response) { + response = request.objects; + } + + response = response.map(object => { + return object.toJSON(); + }); + return resolve(response); + } // Use the JSON response + + + if (response && typeof response === 'object' && !request.object.equals(response) && request.triggerName === Types.beforeSave) { + return resolve(response); + } + + if (response && typeof response === 'object' && request.triggerName === Types.afterSave) { + return resolve(response); + } + + if (request.triggerName === Types.afterSave) { + return resolve(); + } + + response = {}; + + if (request.triggerName === Types.beforeSave) { + response['object'] = request.object._getSaveJSON(); + } + + return resolve(response); + }, + error: function (error) { + const e = resolveError(error, { + code: _node.default.Error.SCRIPT_FAILED, + message: 'Script failed. Unknown error.' + }); + reject(e); + } + }; +} + +function userIdForLog(auth) { + return auth && auth.user ? auth.user.id : undefined; +} + +function logTriggerAfterHook(triggerType, className, input, auth) { + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); + + _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, { + className, + triggerType, + user: userIdForLog(auth) + }); +} + +function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) { + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); + + const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result)); + + _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { + className, + triggerType, + user: userIdForLog(auth) + }); +} + +function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) { + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); + + _logger.logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, { + className, + triggerType, + error, + user: userIdForLog(auth) + }); +} + +function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config, query) { + return new Promise((resolve, reject) => { + const trigger = getTrigger(className, triggerType, config.applicationId); + + if (!trigger) { + return resolve(); + } + + const request = getRequestObject(triggerType, auth, null, null, config); + + if (query) { + request.query = query; + } + + const { + success, + error + } = getResponseObject(request, object => { + resolve(object); + }, error => { + reject(error); + }); + logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth); + request.objects = objects.map(object => { + //setting the class name to transform into parse object + object.className = className; + return _node.default.Object.fromJSON(object); + }); + return Promise.resolve().then(() => { + return maybeRunValidator(request, `${triggerType}.${className}`); + }).then(() => { + if (request.skipWithMasterKey) { + return request.objects; + } + + const response = trigger(request); + + if (response && typeof response.then === 'function') { + return response.then(results => { + if (!results) { + throw new _node.default.Error(_node.default.Error.SCRIPT_FAILED, 'AfterFind expect results to be returned in the promise'); + } + + return results; + }); + } + + return response; + }).then(success, error); + }).then(results => { + logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth); + return results; + }); +} + +function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, context, isGet) { + const trigger = getTrigger(className, triggerType, config.applicationId); + + if (!trigger) { + return Promise.resolve({ + restWhere, + restOptions + }); + } + + const json = Object.assign({}, restOptions); + json.where = restWhere; + const parseQuery = new _node.default.Query(className); + parseQuery.withJSON(json); + let count = false; + + if (restOptions) { + count = !!restOptions.count; + } + + const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, context, isGet); + return Promise.resolve().then(() => { + return maybeRunValidator(requestObject, `${triggerType}.${className}`); + }).then(() => { + if (requestObject.skipWithMasterKey) { + return requestObject.query; + } + + return trigger(requestObject); + }).then(result => { + let queryResult = parseQuery; + + if (result && result instanceof _node.default.Query) { + queryResult = result; + } + + const jsonQuery = queryResult.toJSON(); + + if (jsonQuery.where) { + restWhere = jsonQuery.where; + } + + if (jsonQuery.limit) { + restOptions = restOptions || {}; + restOptions.limit = jsonQuery.limit; + } + + if (jsonQuery.skip) { + restOptions = restOptions || {}; + restOptions.skip = jsonQuery.skip; + } + + if (jsonQuery.include) { + restOptions = restOptions || {}; + restOptions.include = jsonQuery.include; + } + + if (jsonQuery.excludeKeys) { + restOptions = restOptions || {}; + restOptions.excludeKeys = jsonQuery.excludeKeys; + } + + if (jsonQuery.explain) { + restOptions = restOptions || {}; + restOptions.explain = jsonQuery.explain; + } + + if (jsonQuery.keys) { + restOptions = restOptions || {}; + restOptions.keys = jsonQuery.keys; + } + + if (jsonQuery.order) { + restOptions = restOptions || {}; + restOptions.order = jsonQuery.order; + } + + if (jsonQuery.hint) { + restOptions = restOptions || {}; + restOptions.hint = jsonQuery.hint; + } + + if (requestObject.readPreference) { + restOptions = restOptions || {}; + restOptions.readPreference = requestObject.readPreference; + } + + if (requestObject.includeReadPreference) { + restOptions = restOptions || {}; + restOptions.includeReadPreference = requestObject.includeReadPreference; + } + + if (requestObject.subqueryReadPreference) { + restOptions = restOptions || {}; + restOptions.subqueryReadPreference = requestObject.subqueryReadPreference; + } + + return { + restWhere, + restOptions + }; + }, err => { + const error = resolveError(err, { + code: _node.default.Error.SCRIPT_FAILED, + message: 'Script failed. Unknown error.' + }); + throw error; + }); +} + +function resolveError(message, defaultOpts) { + if (!defaultOpts) { + defaultOpts = {}; + } + + if (!message) { + return new _node.default.Error(defaultOpts.code || _node.default.Error.SCRIPT_FAILED, defaultOpts.message || 'Script failed.'); + } + + if (message instanceof _node.default.Error) { + return message; + } + + const code = defaultOpts.code || _node.default.Error.SCRIPT_FAILED; // If it's an error, mark it as a script failed + + if (typeof message === 'string') { + return new _node.default.Error(code, message); + } + + const error = new _node.default.Error(code, message.message || message); + + if (message instanceof Error) { + error.stack = message.stack; + } + + return error; +} + +function maybeRunValidator(request, functionName) { + const theValidator = getValidator(functionName, _node.default.applicationId); + + if (!theValidator) { + return; + } + + if (typeof theValidator === 'object' && theValidator.skipWithMasterKey && request.master) { + request.skipWithMasterKey = true; + } + + return new Promise((resolve, reject) => { + return Promise.resolve().then(() => { + return typeof theValidator === 'object' ? builtInTriggerValidator(theValidator, request) : theValidator(request); + }).then(() => { + resolve(); + }).catch(e => { + const error = resolveError(e, { + code: _node.default.Error.VALIDATION_ERROR, + message: 'Validation failed.' + }); + reject(error); + }); + }); +} + +function builtInTriggerValidator(options, request) { + if (request.master && !options.validateMasterKey) { + return; + } + + let reqUser = request.user; + + if (!reqUser && request.object && request.object.className === '_User' && !request.object.existed()) { + reqUser = request.object; + } + + if (options.requireUser && !reqUser) { + throw 'Validation failed. Please login to continue.'; + } + + if (options.requireMaster && !request.master) { + throw 'Validation failed. Master key is required to complete this request.'; + } + + let params = request.params || {}; + + if (request.object) { + params = request.object.toJSON(); + } + + const requiredParam = key => { + const value = params[key]; + + if (value == null) { + throw `Validation failed. Please specify data for ${key}.`; + } + }; + + const validateOptions = (opt, key, val) => { + let opts = opt.options; + + if (typeof opts === 'function') { + try { + const result = opts(val); + + if (!result && result != null) { + throw opt.error || `Validation failed. Invalid value for ${key}.`; + } + } catch (e) { + if (!e) { + throw opt.error || `Validation failed. Invalid value for ${key}.`; + } + + throw opt.error || e.message || e; + } + + return; + } + + if (!Array.isArray(opts)) { + opts = [opt.options]; + } + + if (!opts.includes(val)) { + throw opt.error || `Validation failed. Invalid option for ${key}. Expected: ${opts.join(', ')}`; + } + }; + + const getType = fn => { + const match = fn && fn.toString().match(/^\s*function (\w+)/); + return (match ? match[1] : '').toLowerCase(); + }; + + if (Array.isArray(options.fields)) { + for (const key of options.fields) { + requiredParam(key); + } + } else { + for (const key in options.fields) { + const opt = options.fields[key]; + let val = params[key]; + + if (typeof opt === 'string') { + requiredParam(opt); + } + + if (typeof opt === 'object') { + if (opt.default != null && val == null) { + val = opt.default; + params[key] = val; + + if (request.object) { + request.object.set(key, val); + } + } + + if (opt.constant && request.object) { + if (request.original) { + request.object.set(key, request.original.get(key)); + } else if (opt.default != null) { + request.object.set(key, opt.default); + } + } + + if (opt.required) { + requiredParam(key); + } + + if (opt.type) { + const type = getType(opt.type); + + if (type == 'array' && !Array.isArray(val)) { + throw `Validation failed. Invalid type for ${key}. Expected: array`; + } else if (typeof val !== type) { + throw `Validation failed. Invalid type for ${key}. Expected: ${type}`; + } + } + + if (opt.options) { + validateOptions(opt, key, val); + } + } + } + } + + const userKeys = options.requireUserKeys || []; + + if (Array.isArray(userKeys)) { + for (const key of userKeys) { + if (!reqUser) { + throw 'Please login to make this request.'; + } + + if (reqUser.get(key) == null) { + throw `Validation failed. Please set data for ${key} on your account.`; + } + } + } else if (typeof userKeys === 'object') { + for (const key in options.requireUserKeys) { + const opt = options.requireUserKeys[key]; + + if (opt.options) { + validateOptions(opt, key, reqUser.get(key)); + } + } + } +} // To be used as part of the promise chain when saving/deleting an object +// Will resolve successfully if no trigger is configured +// Resolves to an object, empty or containing an object key. A beforeSave +// trigger will set the object key to the rest format object to save. +// originalParseObject is optional, we only need that for before/afterSave functions + + +function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config, context) { + if (!parseObject) { + return Promise.resolve({}); + } + + return new Promise(function (resolve, reject) { + var trigger = getTrigger(parseObject.className, triggerType, config.applicationId); + if (!trigger) return resolve(); + var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context); + var { + success, + error + } = getResponseObject(request, object => { + logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth); + + if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) { + Object.assign(context, request.context); + } + + resolve(object); + }, error => { + logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error); + reject(error); + }); // AfterSave and afterDelete triggers can return a promise, which if they + // do, needs to be resolved before this promise is resolved, + // so trigger execution is synced with RestWrite.execute() call. + // If triggers do not return a promise, they can run async code parallel + // to the RestWrite.execute() call. + + return Promise.resolve().then(() => { + return maybeRunValidator(request, `${triggerType}.${parseObject.className}`); + }).then(() => { + if (request.skipWithMasterKey) { + return Promise.resolve(); + } + + const promise = trigger(request); + + if (triggerType === Types.afterSave || triggerType === Types.afterDelete || triggerType === Types.afterLogin) { + logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth); + } // beforeSave is expected to return null (nothing) + + + if (triggerType === Types.beforeSave) { + if (promise && typeof promise.then === 'function') { + return promise.then(response => { + // response.object may come from express routing before hook + if (response && response.object) { + return response; + } + + return null; + }); + } + + return null; + } + + return promise; + }).then(success, error); + }); +} // Converts a REST-format object to a Parse.Object +// data is either className or an object + + +function inflate(data, restObject) { + var copy = typeof data == 'object' ? data : { + className: data + }; + + for (var key in restObject) { + copy[key] = restObject[key]; + } + + return _node.default.Object.fromJSON(copy); +} + +function runLiveQueryEventHandlers(data, applicationId = _node.default.applicationId) { + if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) { + return; + } + + _triggerStore[applicationId].LiveQuery.forEach(handler => handler(data)); +} + +function getRequestFileObject(triggerType, auth, fileObject, config) { + const request = _objectSpread(_objectSpread({}, fileObject), {}, { + triggerName: triggerType, + master: false, + log: config.loggerController, + headers: config.headers, + ip: config.ip + }); + + if (!auth) { + return request; + } + + if (auth.isMaster) { + request['master'] = true; + } + + if (auth.user) { + request['user'] = auth.user; + } + + if (auth.installationId) { + request['installationId'] = auth.installationId; + } + + return request; +} + +async function maybeRunFileTrigger(triggerType, fileObject, config, auth) { + const fileTrigger = getFileTrigger(triggerType, config.applicationId); + + if (typeof fileTrigger === 'function') { + try { + const request = getRequestFileObject(triggerType, auth, fileObject, config); + await maybeRunValidator(request, `${triggerType}.${FileClassName}`); + + if (request.skipWithMasterKey) { + return fileObject; + } + + const result = await fileTrigger(request); + logTriggerSuccessBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { + fileSize: fileObject.fileSize + }), result, auth); + return result || fileObject; + } catch (error) { + logTriggerErrorBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { + fileSize: fileObject.fileSize + }), auth, error); + throw error; + } + } + + return fileObject; +} + +async function maybeRunConnectTrigger(triggerType, request) { + const trigger = getTrigger(ConnectClassName, triggerType, _node.default.applicationId); + + if (!trigger) { + return; + } + + request.user = await userForSessionToken(request.sessionToken); + await maybeRunValidator(request, `${triggerType}.${ConnectClassName}`); + + if (request.skipWithMasterKey) { + return; + } + + return trigger(request); +} + +async function maybeRunSubscribeTrigger(triggerType, className, request) { + const trigger = getTrigger(className, triggerType, _node.default.applicationId); + + if (!trigger) { + return; + } + + const parseQuery = new _node.default.Query(className); + parseQuery.withJSON(request.query); + request.query = parseQuery; + request.user = await userForSessionToken(request.sessionToken); + await maybeRunValidator(request, `${triggerType}.${className}`); + + if (request.skipWithMasterKey) { + return; + } + + await trigger(request); + const query = request.query.toJSON(); + + if (query.keys) { + query.fields = query.keys.split(','); + } + + request.query = query; +} + +async function maybeRunAfterEventTrigger(triggerType, className, request) { + const trigger = getTrigger(className, triggerType, _node.default.applicationId); + + if (!trigger) { + return; + } + + if (request.object) { + request.object = _node.default.Object.fromJSON(request.object); + } + + if (request.original) { + request.original = _node.default.Object.fromJSON(request.original); + } + + request.user = await userForSessionToken(request.sessionToken); + await maybeRunValidator(request, `${triggerType}.${className}`); + + if (request.skipWithMasterKey) { + return; + } + + return trigger(request); +} + +async function userForSessionToken(sessionToken) { + if (!sessionToken) { + return; + } + + const q = new _node.default.Query('_Session'); + q.equalTo('sessionToken', sessionToken); + const session = await q.first({ + useMasterKey: true + }); + + if (!session) { + return; + } + + const user = session.get('user'); + + if (!user) { + return; + } + + await user.fetch({ + useMasterKey: true + }); + return user; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJuYW1lcyI6WyJUeXBlcyIsImJlZm9yZUxvZ2luIiwiYWZ0ZXJMb2dpbiIsImFmdGVyTG9nb3V0IiwiYmVmb3JlU2F2ZSIsImFmdGVyU2F2ZSIsImJlZm9yZURlbGV0ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJlZm9yZVNhdmVGaWxlIiwiYWZ0ZXJTYXZlRmlsZSIsImJlZm9yZURlbGV0ZUZpbGUiLCJhZnRlckRlbGV0ZUZpbGUiLCJiZWZvcmVDb25uZWN0IiwiYmVmb3JlU3Vic2NyaWJlIiwiYWZ0ZXJFdmVudCIsIkZpbGVDbGFzc05hbWUiLCJDb25uZWN0Q2xhc3NOYW1lIiwiYmFzZVN0b3JlIiwiVmFsaWRhdG9ycyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJiYXNlIiwia2V5IiwiRnVuY3Rpb25zIiwiSm9icyIsIkxpdmVRdWVyeSIsIlRyaWdnZXJzIiwiZnJlZXplIiwidmFsaWRhdGVDbGFzc05hbWVGb3JUcmlnZ2VycyIsImNsYXNzTmFtZSIsInR5cGUiLCJfdHJpZ2dlclN0b3JlIiwiQ2F0ZWdvcnkiLCJnZXRTdG9yZSIsImNhdGVnb3J5IiwibmFtZSIsImFwcGxpY2F0aW9uSWQiLCJwYXRoIiwic3BsaXQiLCJzcGxpY2UiLCJQYXJzZSIsInN0b3JlIiwiY29tcG9uZW50IiwidW5kZWZpbmVkIiwiYWRkIiwiaGFuZGxlciIsImxhc3RDb21wb25lbnQiLCJsb2dnZXIiLCJ3YXJuIiwicmVtb3ZlIiwiZ2V0IiwiYWRkRnVuY3Rpb24iLCJmdW5jdGlvbk5hbWUiLCJ2YWxpZGF0aW9uSGFuZGxlciIsImFkZEpvYiIsImpvYk5hbWUiLCJhZGRUcmlnZ2VyIiwiYWRkRmlsZVRyaWdnZXIiLCJhZGRDb25uZWN0VHJpZ2dlciIsImFkZExpdmVRdWVyeUV2ZW50SGFuZGxlciIsInB1c2giLCJyZW1vdmVGdW5jdGlvbiIsInJlbW92ZVRyaWdnZXIiLCJfdW5yZWdpc3RlckFsbCIsImZvckVhY2giLCJhcHBJZCIsImdldFRyaWdnZXIiLCJ0cmlnZ2VyVHlwZSIsImdldEZpbGVUcmlnZ2VyIiwidHJpZ2dlckV4aXN0cyIsImdldEZ1bmN0aW9uIiwiZ2V0RnVuY3Rpb25OYW1lcyIsImZ1bmN0aW9uTmFtZXMiLCJleHRyYWN0RnVuY3Rpb25OYW1lcyIsIm5hbWVzcGFjZSIsInZhbHVlIiwiZ2V0Sm9iIiwiZ2V0Sm9icyIsIm1hbmFnZXIiLCJnZXRWYWxpZGF0b3IiLCJnZXRSZXF1ZXN0T2JqZWN0IiwiYXV0aCIsInBhcnNlT2JqZWN0Iiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImNvbmZpZyIsImNvbnRleHQiLCJyZXF1ZXN0IiwidHJpZ2dlck5hbWUiLCJvYmplY3QiLCJtYXN0ZXIiLCJsb2ciLCJsb2dnZXJDb250cm9sbGVyIiwiaGVhZGVycyIsImlwIiwib3JpZ2luYWwiLCJhc3NpZ24iLCJpc01hc3RlciIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsImdldFJlcXVlc3RRdWVyeU9iamVjdCIsInF1ZXJ5IiwiY291bnQiLCJpc0dldCIsImdldFJlc3BvbnNlT2JqZWN0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJ0b0pTT04iLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJlcnJvciIsImUiLCJyZXNvbHZlRXJyb3IiLCJjb2RlIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwibWVzc2FnZSIsInVzZXJJZEZvckxvZyIsImlkIiwibG9nVHJpZ2dlckFmdGVySG9vayIsImlucHV0IiwiY2xlYW5JbnB1dCIsInRydW5jYXRlTG9nTWVzc2FnZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJpbmZvIiwibG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rIiwicmVzdWx0IiwiY2xlYW5SZXN1bHQiLCJsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiUHJvbWlzZSIsInRyaWdnZXIiLCJmcm9tSlNPTiIsInRoZW4iLCJtYXliZVJ1blZhbGlkYXRvciIsInNraXBXaXRoTWFzdGVyS2V5IiwicmVzdWx0cyIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJqc29uIiwid2hlcmUiLCJwYXJzZVF1ZXJ5IiwiUXVlcnkiLCJ3aXRoSlNPTiIsInJlcXVlc3RPYmplY3QiLCJxdWVyeVJlc3VsdCIsImpzb25RdWVyeSIsImxpbWl0Iiwic2tpcCIsImluY2x1ZGUiLCJleGNsdWRlS2V5cyIsImV4cGxhaW4iLCJvcmRlciIsImhpbnQiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJlcnIiLCJkZWZhdWx0T3B0cyIsInN0YWNrIiwidGhlVmFsaWRhdG9yIiwiYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IiLCJjYXRjaCIsIlZBTElEQVRJT05fRVJST1IiLCJvcHRpb25zIiwidmFsaWRhdGVNYXN0ZXJLZXkiLCJyZXFVc2VyIiwiZXhpc3RlZCIsInJlcXVpcmVVc2VyIiwicmVxdWlyZU1hc3RlciIsInBhcmFtcyIsInJlcXVpcmVkUGFyYW0iLCJ2YWxpZGF0ZU9wdGlvbnMiLCJvcHQiLCJ2YWwiLCJvcHRzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZXMiLCJqb2luIiwiZ2V0VHlwZSIsImZuIiwibWF0Y2giLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiZmllbGRzIiwiZGVmYXVsdCIsInNldCIsImNvbnN0YW50IiwicmVxdWlyZWQiLCJ1c2VyS2V5cyIsInJlcXVpcmVVc2VyS2V5cyIsIm1heWJlUnVuVHJpZ2dlciIsInByb21pc2UiLCJpbmZsYXRlIiwiZGF0YSIsInJlc3RPYmplY3QiLCJjb3B5IiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsImdldFJlcXVlc3RGaWxlT2JqZWN0IiwiZmlsZU9iamVjdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJmaWxlVHJpZ2dlciIsImZpbGUiLCJmaWxlU2l6ZSIsIm1heWJlUnVuQ29ubmVjdFRyaWdnZXIiLCJ1c2VyRm9yU2Vzc2lvblRva2VuIiwic2Vzc2lvblRva2VuIiwibWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyIiwibWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlciIsInEiLCJlcXVhbFRvIiwic2Vzc2lvbiIsImZpcnN0IiwidXNlTWFzdGVyS2V5IiwiZmV0Y2giXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBOztBQUNBOzs7Ozs7Ozs7O0FBRU8sTUFBTUEsS0FBSyxHQUFHO0FBQ25CQyxFQUFBQSxXQUFXLEVBQUUsYUFETTtBQUVuQkMsRUFBQUEsVUFBVSxFQUFFLFlBRk87QUFHbkJDLEVBQUFBLFdBQVcsRUFBRSxhQUhNO0FBSW5CQyxFQUFBQSxVQUFVLEVBQUUsWUFKTztBQUtuQkMsRUFBQUEsU0FBUyxFQUFFLFdBTFE7QUFNbkJDLEVBQUFBLFlBQVksRUFBRSxjQU5LO0FBT25CQyxFQUFBQSxXQUFXLEVBQUUsYUFQTTtBQVFuQkMsRUFBQUEsVUFBVSxFQUFFLFlBUk87QUFTbkJDLEVBQUFBLFNBQVMsRUFBRSxXQVRRO0FBVW5CQyxFQUFBQSxjQUFjLEVBQUUsZ0JBVkc7QUFXbkJDLEVBQUFBLGFBQWEsRUFBRSxlQVhJO0FBWW5CQyxFQUFBQSxnQkFBZ0IsRUFBRSxrQkFaQztBQWFuQkMsRUFBQUEsZUFBZSxFQUFFLGlCQWJFO0FBY25CQyxFQUFBQSxhQUFhLEVBQUUsZUFkSTtBQWVuQkMsRUFBQUEsZUFBZSxFQUFFLGlCQWZFO0FBZ0JuQkMsRUFBQUEsVUFBVSxFQUFFO0FBaEJPLENBQWQ7O0FBbUJQLE1BQU1DLGFBQWEsR0FBRyxPQUF0QjtBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFVBQXpCOztBQUVBLE1BQU1DLFNBQVMsR0FBRyxZQUFZO0FBQzVCLFFBQU1DLFVBQVUsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVl0QixLQUFaLEVBQW1CdUIsTUFBbkIsQ0FBMEIsVUFBVUMs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QUFZLEVBQUU7QUFBaEIsR0FBWCxDQUFOO0FBQ0EsU0FBTzFILElBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRyaWdnZXJzLmpzXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBjb25zdCBUeXBlcyA9IHtcbiAgYmVmb3JlTG9naW46ICdiZWZvcmVMb2dpbicsXG4gIGFmdGVyTG9naW46ICdhZnRlckxvZ2luJyxcbiAgYWZ0ZXJMb2dvdXQ6ICdhZnRlckxvZ291dCcsXG4gIGJlZm9yZVNhdmU6ICdiZWZvcmVTYXZlJyxcbiAgYWZ0ZXJTYXZlOiAnYWZ0ZXJTYXZlJyxcbiAgYmVmb3JlRGVsZXRlOiAnYmVmb3JlRGVsZXRlJyxcbiAgYWZ0ZXJEZWxldGU6ICdhZnRlckRlbGV0ZScsXG4gIGJlZm9yZUZpbmQ6ICdiZWZvcmVGaW5kJyxcbiAgYWZ0ZXJGaW5kOiAnYWZ0ZXJGaW5kJyxcbiAgYmVmb3JlU2F2ZUZpbGU6ICdiZWZvcmVTYXZlRmlsZScsXG4gIGFmdGVyU2F2ZUZpbGU6ICdhZnRlclNhdmVGaWxlJyxcbiAgYmVmb3JlRGVsZXRlRmlsZTogJ2JlZm9yZURlbGV0ZUZpbGUnLFxuICBhZnRlckRlbGV0ZUZpbGU6ICdhZnRlckRlbGV0ZUZpbGUnLFxuICBiZWZvcmVDb25uZWN0OiAnYmVmb3JlQ29ubmVjdCcsXG4gIGJlZm9yZVN1YnNjcmliZTogJ2JlZm9yZVN1YnNjcmliZScsXG4gIGFmdGVyRXZlbnQ6ICdhZnRlckV2ZW50Jyxcbn07XG5cbmNvbnN0IEZpbGVDbGFzc05hbWUgPSAnQEZpbGUnO1xuY29uc3QgQ29ubmVjdENsYXNzTmFtZSA9ICdAQ29ubmVjdCc7XG5cbmNvbnN0IGJhc2VTdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgVmFsaWRhdG9ycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG4gIGNvbnN0IEZ1bmN0aW9ucyA9IHt9O1xuICBjb25zdCBKb2JzID0ge307XG4gIGNvbnN0IExpdmVRdWVyeSA9IFtdO1xuICBjb25zdCBUcmlnZ2VycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIEZ1bmN0aW9ucyxcbiAgICBKb2JzLFxuICAgIFZhbGlkYXRvcnMsXG4gICAgVHJpZ2dlcnMsXG4gICAgTGl2ZVF1ZXJ5LFxuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMoY2xhc3NOYW1lLCB0eXBlKSB7XG4gIGlmICh0eXBlID09IFR5cGVzLmJlZm9yZVNhdmUgJiYgY2xhc3NOYW1lID09PSAnX1B1c2hTdGF0dXMnKSB7XG4gICAgLy8gX1B1c2hTdGF0dXMgdXNlcyB1bmRvY3VtZW50ZWQgbmVzdGVkIGtleSBpbmNyZW1lbnQgb3BzXG4gICAgLy8gYWxsb3dpbmcgYmVmb3JlU2F2ZSB3b3VsZCBtZXNzIHVwIHRoZSBvYmplY3RzIGJpZyB0aW1lXG4gICAgLy8gVE9ETzogQWxsb3cgcHJvcGVyIGRvY3VtZW50ZWQgd2F5IG9mIHVzaW5nIG5lc3RlZCBpbmNyZW1lbnQgb3BzXG4gICAgdGhyb3cgJ09ubHkgYWZ0ZXJTYXZlIGlzIGFsbG93ZWQgb24gX1B1c2hTdGF0dXMnO1xuICB9XG4gIGlmICgodHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHwgdHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbikgJiYgY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBfVXNlciBjbGFzcyBpcyBhbGxvd2VkIGZvciB0aGUgYmVmb3JlTG9naW4gYW5kIGFmdGVyTG9naW4gdHJpZ2dlcnMnO1xuICB9XG4gIGlmICh0eXBlID09PSBUeXBlcy5hZnRlckxvZ291dCAmJiBjbGFzc05hbWUgIT09ICdfU2Vzc2lvbicpIHtcbiAgICAvLyBUT0RPOiBjaGVjayBpZiB1cHN0cmVhbSBjb2RlIHdpbGwgaGFuZGxlIGBFcnJvcmAgaW5zdGFuY2UgcmF0aGVyXG4gICAgLy8gdGhhbiB0aGlzIGFudGktcGF0dGVybiBvZiB0aHJvd2luZyBzdHJpbmdzXG4gICAgdGhyb3cgJ09ubHkgdGhlIF9TZXNzaW9uIGNsYXNzIGlzIGFsbG93ZWQgZm9yIHRoZSBhZnRlckxvZ291dCB0cmlnZ2VyLic7XG4gIH1cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19TZXNzaW9uJyAmJiB0eXBlICE9PSBUeXBlcy5hZnRlckxvZ291dCkge1xuICAgIC8vIFRPRE86IGNoZWNrIGlmIHVwc3RyZWFtIGNvZGUgd2lsbCBoYW5kbGUgYEVycm9yYCBpbnN0YW5jZSByYXRoZXJcbiAgICAvLyB0aGFuIHRoaXMgYW50aS1wYXR0ZXJuIG9mIHRocm93aW5nIHN0cmluZ3NcbiAgICB0aHJvdyAnT25seSB0aGUgYWZ0ZXJMb2dvdXQgdHJpZ2dlciBpcyBhbGxvd2VkIGZvciB0aGUgX1Nlc3Npb24gY2xhc3MuJztcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuXG5jb25zdCBfdHJpZ2dlclN0b3JlID0ge307XG5cbmNvbnN0IENhdGVnb3J5ID0ge1xuICBGdW5jdGlvbnM6ICdGdW5jdGlvbnMnLFxuICBWYWxpZGF0b3JzOiAnVmFsaWRhdG9ycycsXG4gIEpvYnM6ICdKb2JzJyxcbiAgVHJpZ2dlcnM6ICdUcmlnZ2VycycsXG59O1xuXG5mdW5jdGlvbiBnZXRTdG9yZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBwYXRoID0gbmFtZS5zcGxpdCgnLicpO1xuICBwYXRoLnNwbGljZSgtMSk7IC8vIHJlbW92ZSBsYXN0IGNvbXBvbmVudFxuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgbGV0IHN0b3JlID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVtjYXRlZ29yeV07XG4gIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgpIHtcbiAgICBzdG9yZSA9IHN0b3JlW2NvbXBvbmVudF07XG4gICAgaWYgKCFzdG9yZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0b3JlO1xufVxuXG5mdW5jdGlvbiBhZGQoY2F0ZWdvcnksIG5hbWUsIGhhbmRsZXIsIGFwcGxpY2F0aW9uSWQpIHtcbiAgY29uc3QgbGFzdENvbXBvbmVudCA9IG5hbWUuc3BsaXQoJy4nKS5zcGxpY2UoLTEpO1xuICBjb25zdCBzdG9yZSA9IGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgaWYgKHN0b3JlW2xhc3RDb21wb25lbnRdKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgV2FybmluZzogRHVwbGljYXRlIGNsb3VkIGZ1bmN0aW9ucyBleGlzdCBmb3IgJHtsYXN0Q29tcG9uZW50fS4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSB1c2VkIGFuZCB0aGUgb3RoZXJzIHdpbGwgYmUgaWdub3JlZC5gXG4gICAgKTtcbiAgfVxuICBzdG9yZVtsYXN0Q29tcG9uZW50XSA9IGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICBkZWxldGUgc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmZ1bmN0aW9uIGdldChjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICByZXR1cm4gc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5GdW5jdGlvbnMsIGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEpvYihqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyaWdnZXIodHlwZSwgY2xhc3NOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFkZChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHlwZX0uJHtjbGFzc05hbWV9YCwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGaWxlVHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb25uZWN0VHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZW1vdmUoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmVtb3ZlKENhdGVnb3J5LlRyaWdnZXJzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF91bnJlZ2lzdGVyQWxsKCkge1xuICBPYmplY3Qua2V5cyhfdHJpZ2dlclN0b3JlKS5mb3JFYWNoKGFwcElkID0+IGRlbGV0ZSBfdHJpZ2dlclN0b3JlW2FwcElkXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFhcHBsaWNhdGlvbklkKSB7XG4gICAgdGhyb3cgJ01pc3NpbmcgQXBwbGljYXRpb25JRCc7XG4gIH1cbiAgcmV0dXJuIGdldChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWAsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZVRyaWdnZXIodHlwZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0VHJpZ2dlcihGaWxlQ2xhc3NOYW1lLCB0eXBlLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXJFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgYXBwbGljYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHlwZSwgYXBwbGljYXRpb25JZCkgIT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb24oZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHJldHVybiBnZXQoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lcyhhcHBsaWNhdGlvbklkKSB7XG4gIGNvbnN0IHN0b3JlID1cbiAgICAoX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSAmJiBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdW0NhdGVnb3J5LkZ1bmN0aW9uc10pIHx8IHt9O1xuICBjb25zdCBmdW5jdGlvbk5hbWVzID0gW107XG4gIGNvbnN0IGV4dHJhY3RGdW5jdGlvbk5hbWVzID0gKG5hbWVzcGFjZSwgc3RvcmUpID0+IHtcbiAgICBPYmplY3Qua2V5cyhzdG9yZSkuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3RvcmVbbmFtZV07XG4gICAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICAgIG5hbWUgPSBgJHtuYW1lc3BhY2V9LiR7bmFtZX1gO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmdW5jdGlvbk5hbWVzLnB1c2gobmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHRyYWN0RnVuY3Rpb25OYW1lcyhuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIGV4dHJhY3RGdW5jdGlvbk5hbWVzKG51bGwsIHN0b3JlKTtcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRKb2Ioam9iTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LkpvYnMsIGpvYk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9icyhhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9icztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LlZhbGlkYXRvcnMsIGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0T2JqZWN0KFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIG9iamVjdDogcGFyc2VPYmplY3QsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gIH07XG5cbiAgaWYgKG9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICByZXF1ZXN0Lm9yaWdpbmFsID0gb3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgfVxuXG4gIGlmIChcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlRGVsZXRlIHx8XG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlXG4gICkge1xuICAgIC8vIFNldCBhIGNvcHkgb2YgdGhlIGNvbnRleHQgb24gdGhlIHJlcXVlc3Qgb2JqZWN0LlxuICAgIHJlcXVlc3QuY29udGV4dCA9IE9iamVjdC5hc3NpZ24oe30sIGNvbnRleHQpO1xuICB9XG5cbiAgaWYgKCFhdXRoKSB7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cbiAgaWYgKGF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXF1ZXN0WydtYXN0ZXInXSA9IHRydWU7XG4gIH1cbiAgaWYgKGF1dGgudXNlcikge1xuICAgIHJlcXVlc3RbJ3VzZXInXSA9IGF1dGgudXNlcjtcbiAgfVxuICBpZiAoYXV0aC5pbnN0YWxsYXRpb25JZCkge1xuICAgIHJlcXVlc3RbJ2luc3RhbGxhdGlvbklkJ10gPSBhdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdFF1ZXJ5T2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBxdWVyeSwgY291bnQsIGNvbmZpZywgY29udGV4dCwgaXNHZXQpIHtcbiAgaXNHZXQgPSAhIWlzR2V0O1xuXG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyVHlwZSxcbiAgICBxdWVyeSxcbiAgICBtYXN0ZXI6IGZhbHNlLFxuICAgIGNvdW50LFxuICAgIGxvZzogY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgaXNHZXQsXG4gICAgaGVhZGVyczogY29uZmlnLmhlYWRlcnMsXG4gICAgaXA6IGNvbmZpZy5pcCxcbiAgICBjb250ZXh0OiBjb250ZXh0IHx8IHt9LFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuLy8gQ3JlYXRlcyB0aGUgcmVzcG9uc2Ugb2JqZWN0LCBhbmQgdXNlcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gcGFzcyBkYXRhXG4vLyBUaGUgQVBJIHdpbGwgY2FsbCB0aGlzIHdpdGggUkVTVCBBUEkgZm9ybWF0dGVkIG9iamVjdHMsIHRoaXMgd2lsbFxuLy8gdHJhbnNmb3JtIHRoZW0gdG8gUGFyc2UuT2JqZWN0IGluc3RhbmNlcyBleHBlY3RlZCBieSBDbG91ZCBDb2RlLlxuLy8gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgb2JqZWN0IGluIGEgYmVmb3JlU2F2ZSB3aWxsIGJlIGluY2x1ZGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyRmluZCkge1xuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgcmVzcG9uc2UgPSByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0LnRvSlNPTigpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHRoZSBKU09OIHJlc3BvbnNlXG4gICAgICBpZiAoXG4gICAgICAgIHJlc3BvbnNlICYmXG4gICAgICAgIHR5cGVvZiByZXNwb25zZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIXJlcXVlc3Qub2JqZWN0LmVxdWFscyhyZXNwb25zZSkgJiZcbiAgICAgICAgcmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXNwb25zZSAmJiB0eXBlb2YgcmVzcG9uc2UgPT09ICdvYmplY3QnICYmIHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyU2F2ZSkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmJlZm9yZVNhdmUpIHtcbiAgICAgICAgcmVzcG9uc2VbJ29iamVjdCddID0gcmVxdWVzdC5vYmplY3QuX2dldFNhdmVKU09OKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgfSxcbiAgICBlcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBjb25zdCBlID0gcmVzb2x2ZUVycm9yKGVycm9yLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgIG1lc3NhZ2U6ICdTY3JpcHQgZmFpbGVkLiBVbmtub3duIGVycm9yLicsXG4gICAgICB9KTtcbiAgICAgIHJlamVjdChlKTtcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiB1c2VySWRGb3JMb2coYXV0aCkge1xuICByZXR1cm4gYXV0aCAmJiBhdXRoLnVzZXIgPyBhdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgpIHtcbiAgY29uc3QgY2xlYW5JbnB1dCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKTtcbiAgbG9nZ2VyLmluZm8oXG4gICAgYCR7dHJpZ2dlclR5cGV9IHRyaWdnZXJlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKFxuICAgICAgYXV0aFxuICAgICl9OlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1gLFxuICAgIHtcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgdXNlcjogdXNlcklkRm9yTG9nKGF1dGgpLFxuICAgIH1cbiAgKTtcbn1cblxuZnVuY3Rpb24gbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIGlucHV0LCByZXN1bHQsIGF1dGgpIHtcbiAgY29uc3QgY2xlYW5JbnB1dCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKTtcbiAgY29uc3QgY2xlYW5SZXN1bHQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICBsb2dnZXIuaW5mbyhcbiAgICBgJHt0cmlnZ2VyVHlwZX0gdHJpZ2dlcmVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIGlucHV0LCBhdXRoLCBlcnJvcikge1xuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXIuZXJyb3IoXG4gICAgYCR7dHJpZ2dlclR5cGV9IGZhaWxlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKFxuICAgICAgYXV0aFxuICAgICl9OlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gLFxuICAgIHtcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgZXJyb3IsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyKHRyaWdnZXJUeXBlLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdHMsIGNvbmZpZywgcXVlcnkpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgbnVsbCwgbnVsbCwgY29uZmlnKTtcbiAgICBpZiAocXVlcnkpIHtcbiAgICAgIHJlcXVlc3QucXVlcnkgPSBxdWVyeTtcbiAgICB9XG4gICAgY29uc3QgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgb2JqZWN0ID0+IHtcbiAgICAgICAgcmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICApO1xuICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCAnQWZ0ZXJGaW5kJywgSlNPTi5zdHJpbmdpZnkob2JqZWN0cyksIGF1dGgpO1xuICAgIHJlcXVlc3Qub2JqZWN0cyA9IG9iamVjdHMubWFwKG9iamVjdCA9PiB7XG4gICAgICAvL3NldHRpbmcgdGhlIGNsYXNzIG5hbWUgdG8gdHJhbnNmb3JtIGludG8gcGFyc2Ugb2JqZWN0XG4gICAgICBvYmplY3QuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgICAgcmV0dXJuIFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgICByZXR1cm4gcmVxdWVzdC5vYmplY3RzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gdHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgICAgaWYgKHJlc3BvbnNlICYmIHR5cGVvZiByZXNwb25zZS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgICAgICAgICAgJ0FmdGVyRmluZCBleHBlY3QgcmVzdWx0cyB0byBiZSByZXR1cm5lZCBpbiB0aGUgcHJvbWlzZSdcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gIH0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgbG9nVHJpZ2dlckFmdGVySG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBKU09OLnN0cmluZ2lmeShyZXN1bHRzKSwgYXV0aCk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5RdWVyeVRyaWdnZXIoXG4gIHRyaWdnZXJUeXBlLFxuICBjbGFzc05hbWUsXG4gIHJlc3RXaGVyZSxcbiAgcmVzdE9wdGlvbnMsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgY29udGV4dCxcbiAgaXNHZXRcbikge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgcmVzdFdoZXJlLFxuICAgICAgcmVzdE9wdGlvbnMsXG4gICAgfSk7XG4gIH1cbiAgY29uc3QganNvbiA9IE9iamVjdC5hc3NpZ24oe30sIHJlc3RPcHRpb25zKTtcbiAganNvbi53aGVyZSA9IHJlc3RXaGVyZTtcblxuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gIHBhcnNlUXVlcnkud2l0aEpTT04oanNvbik7XG5cbiAgbGV0IGNvdW50ID0gZmFsc2U7XG4gIGlmIChyZXN0T3B0aW9ucykge1xuICAgIGNvdW50ID0gISFyZXN0T3B0aW9ucy5jb3VudDtcbiAgfVxuICBjb25zdCByZXF1ZXN0T2JqZWN0ID0gZ2V0UmVxdWVzdFF1ZXJ5T2JqZWN0KFxuICAgIHRyaWdnZXJUeXBlLFxuICAgIGF1dGgsXG4gICAgcGFyc2VRdWVyeSxcbiAgICBjb3VudCxcbiAgICBjb25maWcsXG4gICAgY29udGV4dCxcbiAgICBpc0dldFxuICApO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdE9iamVjdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHJlcXVlc3RPYmplY3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3RPYmplY3QucXVlcnk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJpZ2dlcihyZXF1ZXN0T2JqZWN0KTtcbiAgICB9KVxuICAgIC50aGVuKFxuICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgbGV0IHF1ZXJ5UmVzdWx0ID0gcGFyc2VRdWVyeTtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgICAgICAgIHF1ZXJ5UmVzdWx0ID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGpzb25RdWVyeSA9IHF1ZXJ5UmVzdWx0LnRvSlNPTigpO1xuICAgICAgICBpZiAoanNvblF1ZXJ5LndoZXJlKSB7XG4gICAgICAgICAgcmVzdFdoZXJlID0ganNvblF1ZXJ5LndoZXJlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkubGltaXQpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmxpbWl0ID0ganNvblF1ZXJ5LmxpbWl0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuc2tpcCkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuc2tpcCA9IGpzb25RdWVyeS5za2lwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuaW5jbHVkZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZSA9IGpzb25RdWVyeS5pbmNsdWRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuZXhjbHVkZUtleXMpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmV4Y2x1ZGVLZXlzID0ganNvblF1ZXJ5LmV4Y2x1ZGVLZXlzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuZXhwbGFpbikge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuZXhwbGFpbiA9IGpzb25RdWVyeS5leHBsYWluO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkua2V5cykge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMua2V5cyA9IGpzb25RdWVyeS5rZXlzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkub3JkZXIpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLm9yZGVyID0ganNvblF1ZXJ5Lm9yZGVyO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuaGludCkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuaGludCA9IGpzb25RdWVyeS5oaW50O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LnJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlcXVlc3RPYmplY3QucmVhZFByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3RPYmplY3QuaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSByZXF1ZXN0T2JqZWN0LmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9iamVjdC5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICB9O1xuICAgICAgfSxcbiAgICAgIGVyciA9PiB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGVyciwge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgICAgbWVzc2FnZTogJ1NjcmlwdCBmYWlsZWQuIFVua25vd24gZXJyb3IuJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRXJyb3IobWVzc2FnZSwgZGVmYXVsdE9wdHMpIHtcbiAgaWYgKCFkZWZhdWx0T3B0cykge1xuICAgIGRlZmF1bHRPcHRzID0ge307XG4gIH1cbiAgaWYgKCFtZXNzYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIGRlZmF1bHRPcHRzLmNvZGUgfHwgUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgIGRlZmF1bHRPcHRzLm1lc3NhZ2UgfHwgJ1NjcmlwdCBmYWlsZWQuJ1xuICAgICk7XG4gIH1cbiAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgIHJldHVybiBtZXNzYWdlO1xuICB9XG5cbiAgY29uc3QgY29kZSA9IGRlZmF1bHRPcHRzLmNvZGUgfHwgUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRDtcbiAgLy8gSWYgaXQncyBhbiBlcnJvciwgbWFyayBpdCBhcyBhIHNjcmlwdCBmYWlsZWRcbiAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoY29kZSwgbWVzc2FnZSk7XG4gIH1cbiAgY29uc3QgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoY29kZSwgbWVzc2FnZS5tZXNzYWdlIHx8IG1lc3NhZ2UpO1xuICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgZXJyb3Iuc3RhY2sgPSBtZXNzYWdlLnN0YWNrO1xuICB9XG4gIHJldHVybiBlcnJvcjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBmdW5jdGlvbk5hbWUpIHtcbiAgY29uc3QgdGhlVmFsaWRhdG9yID0gZ2V0VmFsaWRhdG9yKGZ1bmN0aW9uTmFtZSwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdGhlVmFsaWRhdG9yKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICh0eXBlb2YgdGhlVmFsaWRhdG9yID09PSAnb2JqZWN0JyAmJiB0aGVWYWxpZGF0b3Iuc2tpcFdpdGhNYXN0ZXJLZXkgJiYgcmVxdWVzdC5tYXN0ZXIpIHtcbiAgICByZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5ID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHRoZVZhbGlkYXRvciA9PT0gJ29iamVjdCdcbiAgICAgICAgICA/IGJ1aWx0SW5UcmlnZ2VyVmFsaWRhdG9yKHRoZVZhbGlkYXRvciwgcmVxdWVzdClcbiAgICAgICAgICA6IHRoZVZhbGlkYXRvcihyZXF1ZXN0KTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZSA9PiB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGUsIHtcbiAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLFxuICAgICAgICAgIG1lc3NhZ2U6ICdWYWxpZGF0aW9uIGZhaWxlZC4nLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICB9KTtcbn1cbmZ1bmN0aW9uIGJ1aWx0SW5UcmlnZ2VyVmFsaWRhdG9yKG9wdGlvbnMsIHJlcXVlc3QpIHtcbiAgaWYgKHJlcXVlc3QubWFzdGVyICYmICFvcHRpb25zLnZhbGlkYXRlTWFzdGVyS2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCByZXFVc2VyID0gcmVxdWVzdC51c2VyO1xuICBpZiAoXG4gICAgIXJlcVVzZXIgJiZcbiAgICByZXF1ZXN0Lm9iamVjdCAmJlxuICAgIHJlcXVlc3Qub2JqZWN0LmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJlxuICAgICFyZXF1ZXN0Lm9iamVjdC5leGlzdGVkKClcbiAgKSB7XG4gICAgcmVxVXNlciA9IHJlcXVlc3Qub2JqZWN0O1xuICB9XG4gIGlmIChvcHRpb25zLnJlcXVpcmVVc2VyICYmICFyZXFVc2VyKSB7XG4gICAgdGhyb3cgJ1ZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2UgbG9naW4gdG8gY29udGludWUuJztcbiAgfVxuICBpZiAob3B0aW9ucy5yZXF1aXJlTWFzdGVyICYmICFyZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHRocm93ICdWYWxpZGF0aW9uIGZhaWxlZC4gTWFzdGVyIGtleSBpcyByZXF1aXJlZCB0byBjb21wbGV0ZSB0aGlzIHJlcXVlc3QuJztcbiAgfVxuICBsZXQgcGFyYW1zID0gcmVxdWVzdC5wYXJhbXMgfHwge307XG4gIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgIHBhcmFtcyA9IHJlcXVlc3Qub2JqZWN0LnRvSlNPTigpO1xuICB9XG4gIGNvbnN0IHJlcXVpcmVkUGFyYW0gPSBrZXkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyYW1zW2tleV07XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gUGxlYXNlIHNwZWNpZnkgZGF0YSBmb3IgJHtrZXl9LmA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHZhbGlkYXRlT3B0aW9ucyA9IChvcHQsIGtleSwgdmFsKSA9PiB7XG4gICAgbGV0IG9wdHMgPSBvcHQub3B0aW9ucztcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdHModmFsKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgcmVzdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWUpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBlLm1lc3NhZ2UgfHwgZTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICBvcHRzID0gW29wdC5vcHRpb25zXTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdHMuaW5jbHVkZXModmFsKSkge1xuICAgICAgdGhyb3cgKFxuICAgICAgICBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIG9wdGlvbiBmb3IgJHtrZXl9LiBFeHBlY3RlZDogJHtvcHRzLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZ2V0VHlwZSA9IGZuID0+IHtcbiAgICBjb25zdCBtYXRjaCA9IGZuICYmIGZuLnRvU3RyaW5nKCkubWF0Y2goL15cXHMqZnVuY3Rpb24gKFxcdyspLyk7XG4gICAgcmV0dXJuIChtYXRjaCA/IG1hdGNoWzFdIDogJycpLnRvTG93ZXJDYXNlKCk7XG4gIH07XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZmllbGRzKSkge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIG9wdGlvbnMuZmllbGRzKSB7XG4gICAgICByZXF1aXJlZFBhcmFtKGtleSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMuZmllbGRzKSB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zLmZpZWxkc1trZXldO1xuICAgICAgbGV0IHZhbCA9IHBhcmFtc1trZXldO1xuICAgICAgaWYgKHR5cGVvZiBvcHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlcXVpcmVkUGFyYW0ob3B0KTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAob3B0LmRlZmF1bHQgIT0gbnVsbCAmJiB2YWwgPT0gbnVsbCkge1xuICAgICAgICAgIHZhbCA9IG9wdC5kZWZhdWx0O1xuICAgICAgICAgIHBhcmFtc1trZXldID0gdmFsO1xuICAgICAgICAgIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgICAgICAgICAgcmVxdWVzdC5vYmplY3Quc2V0KGtleSwgdmFsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdC5jb25zdGFudCAmJiByZXF1ZXN0Lm9iamVjdCkge1xuICAgICAgICAgIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgICAgICAgICByZXF1ZXN0Lm9iamVjdC5zZXQoa2V5LCByZXF1ZXN0Lm9yaWdpbmFsLmdldChrZXkpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG9wdC5kZWZhdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qub2JqZWN0LnNldChrZXksIG9wdC5kZWZhdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdC5yZXF1aXJlZCkge1xuICAgICAgICAgIHJlcXVpcmVkUGFyYW0oa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LnR5cGUpIHtcbiAgICAgICAgICBjb25zdCB0eXBlID0gZ2V0VHlwZShvcHQudHlwZSk7XG4gICAgICAgICAgaWYgKHR5cGUgPT0gJ2FycmF5JyAmJiAhQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdHlwZSBmb3IgJHtrZXl9LiBFeHBlY3RlZDogYXJyYXlgO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbCAhPT0gdHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHR5cGUgZm9yICR7a2V5fS4gRXhwZWN0ZWQ6ICR7dHlwZX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0Lm9wdGlvbnMpIHtcbiAgICAgICAgICB2YWxpZGF0ZU9wdGlvbnMob3B0LCBrZXksIHZhbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3QgdXNlcktleXMgPSBvcHRpb25zLnJlcXVpcmVVc2VyS2V5cyB8fCBbXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkodXNlcktleXMpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgdXNlcktleXMpIHtcbiAgICAgIGlmICghcmVxVXNlcikge1xuICAgICAgICB0aHJvdyAnUGxlYXNlIGxvZ2luIHRvIG1ha2UgdGhpcyByZXF1ZXN0Lic7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXFVc2VyLmdldChrZXkpID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2Ugc2V0IGRhdGEgZm9yICR7a2V5fSBvbiB5b3VyIGFjY291bnQuYDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHVzZXJLZXlzID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzKSB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zLnJlcXVpcmVVc2VyS2V5c1trZXldO1xuICAgICAgaWYgKG9wdC5vcHRpb25zKSB7XG4gICAgICAgIHZhbGlkYXRlT3B0aW9ucyhvcHQsIGtleSwgcmVxVXNlci5nZXQoa2V5KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIFRvIGJlIHVzZWQgYXMgcGFydCBvZiB0aGUgcHJvbWlzZSBjaGFpbiB3aGVuIHNhdmluZy9kZWxldGluZyBhbiBvYmplY3Rcbi8vIFdpbGwgcmVzb2x2ZSBzdWNjZXNzZnVsbHkgaWYgbm8gdHJpZ2dlciBpcyBjb25maWd1cmVkXG4vLyBSZXNvbHZlcyB0byBhbiBvYmplY3QsIGVtcHR5IG9yIGNvbnRhaW5pbmcgYW4gb2JqZWN0IGtleS4gQSBiZWZvcmVTYXZlXG4vLyB0cmlnZ2VyIHdpbGwgc2V0IHRoZSBvYmplY3Qga2V5IHRvIHRoZSByZXN0IGZvcm1hdCBvYmplY3QgdG8gc2F2ZS5cbi8vIG9yaWdpbmFsUGFyc2VPYmplY3QgaXMgb3B0aW9uYWwsIHdlIG9ubHkgbmVlZCB0aGF0IGZvciBiZWZvcmUvYWZ0ZXJTYXZlIGZ1bmN0aW9uc1xuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVHJpZ2dlcihcbiAgdHJpZ2dlclR5cGUsXG4gIGF1dGgsXG4gIHBhcnNlT2JqZWN0LFxuICBvcmlnaW5hbFBhcnNlT2JqZWN0LFxuICBjb25maWcsXG4gIGNvbnRleHRcbikge1xuICBpZiAoIXBhcnNlT2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgdHJpZ2dlciA9IGdldFRyaWdnZXIocGFyc2VPYmplY3QuY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghdHJpZ2dlcikgcmV0dXJuIHJlc29sdmUoKTtcbiAgICB2YXIgcmVxdWVzdCA9IGdldFJlcXVlc3RPYmplY3QoXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGF1dGgsXG4gICAgICBwYXJzZU9iamVjdCxcbiAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICBjb25maWcsXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgICB2YXIgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgb2JqZWN0ID0+IHtcbiAgICAgICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKFxuICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC50b0pTT04oKSxcbiAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgYXV0aFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZVNhdmUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZURlbGV0ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckRlbGV0ZVxuICAgICAgICApIHtcbiAgICAgICAgICBPYmplY3QuYXNzaWduKGNvbnRleHQsIHJlcXVlc3QuY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgbG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayhcbiAgICAgICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgICAgcGFyc2VPYmplY3QudG9KU09OKCksXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBBZnRlclNhdmUgYW5kIGFmdGVyRGVsZXRlIHRyaWdnZXJzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCBpZiB0aGV5XG4gICAgLy8gZG8sIG5lZWRzIHRvIGJlIHJlc29sdmVkIGJlZm9yZSB0aGlzIHByb21pc2UgaXMgcmVzb2x2ZWQsXG4gICAgLy8gc28gdHJpZ2dlciBleGVjdXRpb24gaXMgc3luY2VkIHdpdGggUmVzdFdyaXRlLmV4ZWN1dGUoKSBjYWxsLlxuICAgIC8vIElmIHRyaWdnZXJzIGRvIG5vdCByZXR1cm4gYSBwcm9taXNlLCB0aGV5IGNhbiBydW4gYXN5bmMgY29kZSBwYXJhbGxlbFxuICAgIC8vIHRvIHRoZSBSZXN0V3JpdGUuZXhlY3V0ZSgpIGNhbGwuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtwYXJzZU9iamVjdC5jbGFzc05hbWV9YCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9taXNlID0gdHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJEZWxldGUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpblxuICAgICAgICApIHtcbiAgICAgICAgICBsb2dUcmlnZ2VyQWZ0ZXJIb29rKHRyaWdnZXJUeXBlLCBwYXJzZU9iamVjdC5jbGFzc05hbWUsIHBhcnNlT2JqZWN0LnRvSlNPTigpLCBhdXRoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBiZWZvcmVTYXZlIGlzIGV4cGVjdGVkIHRvIHJldHVybiBudWxsIChub3RoaW5nKVxuICAgICAgICBpZiAodHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZVNhdmUpIHtcbiAgICAgICAgICBpZiAocHJvbWlzZSAmJiB0eXBlb2YgcHJvbWlzZS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgLy8gcmVzcG9uc2Uub2JqZWN0IG1heSBjb21lIGZyb20gZXhwcmVzcyByb3V0aW5nIGJlZm9yZSBob29rXG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5vYmplY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gIH0pO1xufVxuXG4vLyBDb252ZXJ0cyBhIFJFU1QtZm9ybWF0IG9iamVjdCB0byBhIFBhcnNlLk9iamVjdFxuLy8gZGF0YSBpcyBlaXRoZXIgY2xhc3NOYW1lIG9yIGFuIG9iamVjdFxuZXhwb3J0IGZ1bmN0aW9uIGluZmxhdGUoZGF0YSwgcmVzdE9iamVjdCkge1xuICB2YXIgY29weSA9IHR5cGVvZiBkYXRhID09ICdvYmplY3QnID8gZGF0YSA6IHsgY2xhc3NOYW1lOiBkYXRhIH07XG4gIGZvciAodmFyIGtleSBpbiByZXN0T2JqZWN0KSB7XG4gICAgY29weVtrZXldID0gcmVzdE9iamVjdFtrZXldO1xuICB9XG4gIHJldHVybiBQYXJzZS5PYmplY3QuZnJvbUpTT04oY29weSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKGRhdGEsIGFwcGxpY2F0aW9uSWQgPSBQYXJzZS5hcHBsaWNhdGlvbklkKSB7XG4gIGlmICghX3RyaWdnZXJTdG9yZSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkuZm9yRWFjaChoYW5kbGVyID0+IGhhbmRsZXIoZGF0YSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdEZpbGVPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIGZpbGVPYmplY3QsIGNvbmZpZykge1xuICBjb25zdCByZXF1ZXN0ID0ge1xuICAgIC4uLmZpbGVPYmplY3QsXG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuRmlsZVRyaWdnZXIodHJpZ2dlclR5cGUsIGZpbGVPYmplY3QsIGNvbmZpZywgYXV0aCkge1xuICBjb25zdCBmaWxlVHJpZ2dlciA9IGdldEZpbGVUcmlnZ2VyKHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIGlmICh0eXBlb2YgZmlsZVRyaWdnZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGdldFJlcXVlc3RGaWxlT2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBmaWxlT2JqZWN0LCBjb25maWcpO1xuICAgICAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7RmlsZUNsYXNzTmFtZX1gKTtcbiAgICAgIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgIHJldHVybiBmaWxlT2JqZWN0O1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmlsZVRyaWdnZXIocmVxdWVzdCk7XG4gICAgICBsb2dUcmlnZ2VyU3VjY2Vzc0JlZm9yZUhvb2soXG4gICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAnUGFyc2UuRmlsZScsXG4gICAgICAgIHsgLi4uZmlsZU9iamVjdC5maWxlLnRvSlNPTigpLCBmaWxlU2l6ZTogZmlsZU9iamVjdC5maWxlU2l6ZSB9LFxuICAgICAgICByZXN1bHQsXG4gICAgICAgIGF1dGhcbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzdWx0IHx8IGZpbGVPYmplY3Q7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2soXG4gICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAnUGFyc2UuRmlsZScsXG4gICAgICAgIHsgLi4uZmlsZU9iamVjdC5maWxlLnRvSlNPTigpLCBmaWxlU2l6ZTogZmlsZU9iamVjdC5maWxlU2l6ZSB9LFxuICAgICAgICBhdXRoLFxuICAgICAgICBlcnJvclxuICAgICAgKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmlsZU9iamVjdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuQ29ubmVjdFRyaWdnZXIodHJpZ2dlclR5cGUsIHJlcXVlc3QpIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoQ29ubmVjdENsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmVxdWVzdC51c2VyID0gYXdhaXQgdXNlckZvclNlc3Npb25Ub2tlbihyZXF1ZXN0LnNlc3Npb25Ub2tlbik7XG4gIGF3YWl0IG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke0Nvbm5lY3RDbGFzc05hbWV9YCk7XG4gIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiB0cmlnZ2VyKHJlcXVlc3QpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIHJlcXVlc3QpIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gIHBhcnNlUXVlcnkud2l0aEpTT04ocmVxdWVzdC5xdWVyeSk7XG4gIHJlcXVlc3QucXVlcnkgPSBwYXJzZVF1ZXJ5O1xuICByZXF1ZXN0LnVzZXIgPSBhd2FpdCB1c2VyRm9yU2Vzc2lvblRva2VuKHJlcXVlc3Quc2Vzc2lvblRva2VuKTtcbiAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgIHJldHVybjtcbiAgfVxuICBhd2FpdCB0cmlnZ2VyKHJlcXVlc3QpO1xuICBjb25zdCBxdWVyeSA9IHJlcXVlc3QucXVlcnkudG9KU09OKCk7XG4gIGlmIChxdWVyeS5rZXlzKSB7XG4gICAgcXVlcnkuZmllbGRzID0gcXVlcnkua2V5cy5zcGxpdCgnLCcpO1xuICB9XG4gIHJlcXVlc3QucXVlcnkgPSBxdWVyeTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuQWZ0ZXJFdmVudFRyaWdnZXIodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgcmVxdWVzdCkge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgIHJlcXVlc3Qub2JqZWN0ID0gUGFyc2UuT2JqZWN0LmZyb21KU09OKHJlcXVlc3Qub2JqZWN0KTtcbiAgfVxuICBpZiAocmVxdWVzdC5vcmlnaW5hbCkge1xuICAgIHJlcXVlc3Qub3JpZ2luYWwgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ocmVxdWVzdC5vcmlnaW5hbCk7XG4gIH1cbiAgcmVxdWVzdC51c2VyID0gYXdhaXQgdXNlckZvclNlc3Npb25Ub2tlbihyZXF1ZXN0LnNlc3Npb25Ub2tlbik7XG4gIGF3YWl0IG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke2NsYXNzTmFtZX1gKTtcbiAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRyaWdnZXIocmVxdWVzdCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVzZXJGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuKSB7XG4gIGlmICghc2Vzc2lvblRva2VuKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHEgPSBuZXcgUGFyc2UuUXVlcnkoJ19TZXNzaW9uJyk7XG4gIHEuZXF1YWxUbygnc2Vzc2lvblRva2VuJywgc2Vzc2lvblRva2VuKTtcbiAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHEuZmlyc3QoeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCB1c2VyID0gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbiAgaWYgKCF1c2VyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGF3YWl0IHVzZXIuZmV0Y2goeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIHJldHVybiB1c2VyO1xufVxuIl19 \ No newline at end of file diff --git a/lib/vendor/README.md b/lib/vendor/README.md new file mode 100644 index 0000000000..04e3256f72 --- /dev/null +++ b/lib/vendor/README.md @@ -0,0 +1,8 @@ +# mongoUrl + +A fork of node's `url` module, with the modification that commas and colons are +allowed in hostnames. While this results in a slightly incorrect parsed result, +as the hostname field for a mongodb should be an array of replica sets, it's +good enough to let us pull out and escape the auth portion of the URL. + +https://github.com/parse-community/parse-server/pull/986 diff --git a/lib/vendor/mongodbUrl.js b/lib/vendor/mongodbUrl.js new file mode 100644 index 0000000000..6b95552f05 --- /dev/null +++ b/lib/vendor/mongodbUrl.js @@ -0,0 +1,1064 @@ +// A slightly patched version of node's url module, with support for mongodb:// +// uris. +// +// See https://github.com/nodejs/node/blob/master/LICENSE for licensing +// information +'use strict'; + +const punycode = require('punycode'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} // Reference: RFC 3986, RFC 1808, RFC 2396 +// define these here so at least they only have to be +// compiled once on the first module load. + + +const protocolPattern = /^([a-z0-9.+-]+:)/i; +const portPattern = /:[0-9]*$/; // Special case for a simple path URL + +const simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/; // protocols that can allow "unsafe" and "unwise" chars. + +const unsafeProtocol = { + javascript: true, + 'javascript:': true +}; // protocols that never have a hostname. + +const hostlessProtocol = { + javascript: true, + 'javascript:': true +}; // protocols that always contain a // bit. + +const slashedProtocol = { + http: true, + 'http:': true, + https: true, + 'https:': true, + ftp: true, + 'ftp:': true, + gopher: true, + 'gopher:': true, + file: true, + 'file:': true +}; + +const querystring = require('querystring'); +/* istanbul ignore next: improve coverage */ + + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url instanceof Url) return url; + var u = new Url(); + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) { + if (typeof url !== 'string') { + throw new TypeError('Parameter "url" must be a string, not ' + typeof url); + } // Copy chrome, IE, opera backslash-handling behavior. + // Back slashes before the query string get converted to forward slashes + // See: https://code.google.com/p/chromium/issues/detail?id=25916 + + + var hasHash = false; + var start = -1; + var end = -1; + var rest = ''; + var lastPos = 0; + var i = 0; + + for (var inWs = false, split = false; i < url.length; ++i) { + const code = url.charCodeAt(i); // Find first and last non-whitespace characters for trimming + + const isWs = code === 32 + /* */ + || code === 9 + /*\t*/ + || code === 13 + /*\r*/ + || code === 10 + /*\n*/ + || code === 12 + /*\f*/ + || code === 160 + /*\u00A0*/ + || code === 65279; + /*\uFEFF*/ + + if (start === -1) { + if (isWs) continue; + lastPos = start = i; + } else { + if (inWs) { + if (!isWs) { + end = -1; + inWs = false; + } + } else if (isWs) { + end = i; + inWs = true; + } + } // Only convert backslashes while we haven't seen a split character + + + if (!split) { + switch (code) { + case 35: + // '#' + hasHash = true; + // Fall through + + case 63: + // '?' + split = true; + break; + + case 92: + // '\\' + if (i - lastPos > 0) rest += url.slice(lastPos, i); + rest += '/'; + lastPos = i + 1; + break; + } + } else if (!hasHash && code === 35 + /*#*/ + ) { + hasHash = true; + } + } // Check if string was non-empty (including strings with only whitespace) + + + if (start !== -1) { + if (lastPos === start) { + // We didn't convert any backslashes + if (end === -1) { + if (start === 0) rest = url;else rest = url.slice(start); + } else { + rest = url.slice(start, end); + } + } else if (end === -1 && lastPos < url.length) { + // We converted some backslashes and have only part of the entire string + rest += url.slice(lastPos); + } else if (end !== -1 && lastPos < end) { + // We converted some backslashes and have only part of the entire string + rest += url.slice(lastPos, end); + } + } + + if (!slashesDenoteHost && !hasHash) { + // Try fast path regexp + const simplePath = simplePathPattern.exec(rest); + + if (simplePath) { + this.path = rest; + this.href = rest; + this.pathname = simplePath[1]; + + if (simplePath[2]) { + this.search = simplePath[2]; + + if (parseQueryString) { + this.query = querystring.parse(this.search.slice(1)); + } else { + this.query = this.search.slice(1); + } + } else if (parseQueryString) { + this.search = ''; + this.query = {}; + } + + return this; + } + } + + var proto = protocolPattern.exec(rest); + + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.slice(proto.length); + } // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + + + if (slashesDenoteHost || proto || /^\/\/[^@\/]+@[^@\/]+/.test(rest)) { + var slashes = rest.charCodeAt(0) === 47 + /*/*/ + && rest.charCodeAt(1) === 47; + /*/*/ + + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.slice(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && (slashes || proto && !slashedProtocol[proto])) { + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:b path:/?@c + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + var hostEnd = -1; + var atSign = -1; + var nonHost = -1; + + for (i = 0; i < rest.length; ++i) { + switch (rest.charCodeAt(i)) { + case 9: // '\t' + + case 10: // '\n' + + case 13: // '\r' + + case 32: // ' ' + + case 34: // '"' + + case 37: // '%' + + case 39: // '\'' + + case 59: // ';' + + case 60: // '<' + + case 62: // '>' + + case 92: // '\\' + + case 94: // '^' + + case 96: // '`' + + case 123: // '{' + + case 124: // '|' + + case 125: + // '}' + // Characters that are never ever allowed in a hostname from RFC 2396 + if (nonHost === -1) nonHost = i; + break; + + case 35: // '#' + + case 47: // '/' + + case 63: + // '?' + // Find the first instance of any host-ending characters + if (nonHost === -1) nonHost = i; + hostEnd = i; + break; + + case 64: + // '@' + // At this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + atSign = i; + nonHost = -1; + break; + } + + if (hostEnd !== -1) break; + } + + start = 0; + + if (atSign !== -1) { + this.auth = decodeURIComponent(rest.slice(0, atSign)); + start = atSign + 1; + } + + if (nonHost === -1) { + this.host = rest.slice(start); + rest = ''; + } else { + this.host = rest.slice(start, nonHost); + rest = rest.slice(nonHost); + } // pull out port. + + + this.parseHost(); // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + + if (typeof this.hostname !== 'string') this.hostname = ''; + var hostname = this.hostname; // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + + var ipv6Hostname = hostname.charCodeAt(0) === 91 + /*[*/ + && hostname.charCodeAt(hostname.length - 1) === 93; + /*]*/ + // validate a little. + + if (!ipv6Hostname) { + const result = validateHostname(this, rest, hostname); + if (result !== undefined) rest = result; + } // hostnames are always lower case. + + + this.hostname = this.hostname.toLowerCase(); + + if (!ipv6Hostname) { + // IDNA Support: Returns a punycoded representation of "domain". + // It only converts parts of the domain name that + // have non-ASCII characters, i.e. it doesn't matter if + // you call it with a domain that already is ASCII-only. + this.hostname = punycode.toASCII(this.hostname); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; // strip [ and ] from the hostname + // the host field still retains them, though + + if (ipv6Hostname) { + this.hostname = this.hostname.slice(1, -1); + + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } // now rest is set to the post-host stuff. + // chop off any delim chars. + + + if (!unsafeProtocol[lowerProto]) { + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + const result = autoEscapeStr(rest); + if (result !== undefined) rest = result; + } + + var questionIdx = -1; + var hashIdx = -1; + + for (i = 0; i < rest.length; ++i) { + const code = rest.charCodeAt(i); + + if (code === 35 + /*#*/ + ) { + this.hash = rest.slice(i); + hashIdx = i; + break; + } else if (code === 63 + /*?*/ + && questionIdx === -1) { + questionIdx = i; + } + } + + if (questionIdx !== -1) { + if (hashIdx === -1) { + this.search = rest.slice(questionIdx); + this.query = rest.slice(questionIdx + 1); + } else { + this.search = rest.slice(questionIdx, hashIdx); + this.query = rest.slice(questionIdx + 1, hashIdx); + } + + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + + var firstIdx = questionIdx !== -1 && (hashIdx === -1 || questionIdx < hashIdx) ? questionIdx : hashIdx; + + if (firstIdx === -1) { + if (rest.length > 0) this.pathname = rest; + } else if (firstIdx > 0) { + this.pathname = rest.slice(0, firstIdx); + } + + if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { + this.pathname = '/'; + } // to support http.request + + + if (this.pathname || this.search) { + const p = this.pathname || ''; + const s = this.search || ''; + this.path = p + s; + } // finally, reconstruct the href based on what has been validated. + + + this.href = this.format(); + return this; +}; +/* istanbul ignore next: improve coverage */ + + +function validateHostname(self, rest, hostname) { + for (var i = 0, lastPos; i <= hostname.length; ++i) { + var code; + if (i < hostname.length) code = hostname.charCodeAt(i); + + if (code === 46 + /*.*/ + || i === hostname.length) { + if (i - lastPos > 0) { + if (i - lastPos > 63) { + self.hostname = hostname.slice(0, lastPos + 63); + return '/' + hostname.slice(lastPos + 63) + rest; + } + } + + lastPos = i + 1; + continue; + } else if (code >= 48 + /*0*/ + && code <= 57 || + /*9*/ + code >= 97 + /*a*/ + && code <= 122 + /*z*/ + || code === 45 + /*-*/ + || code >= 65 + /*A*/ + && code <= 90 + /*Z*/ + || code === 43 + /*+*/ + || code === 95 + /*_*/ + || + /* BEGIN MONGO URI PATCH */ + code === 44 + /*,*/ + || code === 58 + /*:*/ + || + /* END MONGO URI PATCH */ + code > 127) { + continue; + } // Invalid host character + + + self.hostname = hostname.slice(0, i); + if (i < hostname.length) return '/' + hostname.slice(i) + rest; + break; + } +} +/* istanbul ignore next: improve coverage */ + + +function autoEscapeStr(rest) { + var newRest = ''; + var lastPos = 0; + + for (var i = 0; i < rest.length; ++i) { + // Automatically escape all delimiters and unwise characters from RFC 2396 + // Also escape single quotes in case of an XSS attack + switch (rest.charCodeAt(i)) { + case 9: + // '\t' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%09'; + lastPos = i + 1; + break; + + case 10: + // '\n' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%0A'; + lastPos = i + 1; + break; + + case 13: + // '\r' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%0D'; + lastPos = i + 1; + break; + + case 32: + // ' ' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%20'; + lastPos = i + 1; + break; + + case 34: + // '"' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%22'; + lastPos = i + 1; + break; + + case 39: + // '\'' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%27'; + lastPos = i + 1; + break; + + case 60: + // '<' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%3C'; + lastPos = i + 1; + break; + + case 62: + // '>' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%3E'; + lastPos = i + 1; + break; + + case 92: + // '\\' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%5C'; + lastPos = i + 1; + break; + + case 94: + // '^' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%5E'; + lastPos = i + 1; + break; + + case 96: + // '`' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%60'; + lastPos = i + 1; + break; + + case 123: + // '{' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%7B'; + lastPos = i + 1; + break; + + case 124: + // '|' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%7C'; + lastPos = i + 1; + break; + + case 125: + // '}' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%7D'; + lastPos = i + 1; + break; + } + } + + if (lastPos === 0) return; + if (lastPos < rest.length) return newRest + rest.slice(lastPos);else return newRest; +} // format a parsed object into a url string + +/* istanbul ignore next: improve coverage */ + + +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (typeof obj === 'string') obj = urlParse(obj);else if (typeof obj !== 'object' || obj === null) throw new TypeError('Parameter "urlObj" must be an object, not ' + obj === null ? 'null' : typeof obj);else if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.format = function () { + var auth = this.auth || ''; + + if (auth) { + auth = encodeAuth(auth); + auth += '@'; + } + + var protocol = this.protocol || ''; + var pathname = this.pathname || ''; + var hash = this.hash || ''; + var host = false; + var query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); + + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query !== null && typeof this.query === 'object') query = querystring.stringify(this.query); + var search = this.search || query && '?' + query || ''; + if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58 + /*:*/ + ) protocol += ':'; + var newPathname = ''; + var lastPos = 0; + + for (var i = 0; i < pathname.length; ++i) { + switch (pathname.charCodeAt(i)) { + case 35: + // '#' + if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); + newPathname += '%23'; + lastPos = i + 1; + break; + + case 63: + // '?' + if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); + newPathname += '%3F'; + lastPos = i + 1; + break; + } + } + + if (lastPos > 0) { + if (lastPos !== pathname.length) pathname = newPathname + pathname.slice(lastPos);else pathname = newPathname; + } // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + + + if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charCodeAt(0) !== 47 + /*/*/ + ) pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + search = search.replace('#', '%23'); + if (hash && hash.charCodeAt(0) !== 35 + /*#*/ + ) hash = '#' + hash; + if (search && search.charCodeAt(0) !== 63 + /*?*/ + ) search = '?' + search; + return protocol + host + pathname + search + hash; +}; +/* istanbul ignore next: improve coverage */ + + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.resolve = function (relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; +/* istanbul ignore next: improve coverage */ + + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.resolveObject = function (relative) { + if (typeof relative === 'string') { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + var tkeys = Object.keys(this); + + for (var tk = 0; tk < tkeys.length; tk++) { + var tkey = tkeys[tk]; + result[tkey] = this[tkey]; + } // hash is always overridden, no matter what. + // even href="" will remove it. + + + result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. + + if (relative.href === '') { + result.href = result.format(); + return result; + } // hrefs like //foo/bar always cut to the protocol. + + + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + var rkeys = Object.keys(relative); + + for (var rk = 0; rk < rkeys.length; rk++) { + var rkey = rkeys[rk]; + if (rkey !== 'protocol') result[rkey] = relative[rkey]; + } //urlParse appends trailing / to urls like http://www.example.com + + + if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + var keys = Object.keys(relative); + + for (var v = 0; v < keys.length; v++) { + var k = keys[v]; + result[k] = relative[k]; + } + + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + + if (!relative.host && !/^file:?$/.test(relative.protocol) && !hostlessProtocol[relative.protocol]) { + const relPath = (relative.pathname || '').split('/'); + + while (relPath.length && !(relative.host = relPath.shift())); + + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; // to support http.request + + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/'; + var isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/'; + var mustEndAbs = isRelAbs || isSourceAbs || result.host && relative.pathname; + var removeAllDots = mustEndAbs; + var srcPath = result.pathname && result.pathname.split('/') || []; + var relPath = relative.pathname && relative.pathname.split('/') || []; + var psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + + if (psychotic) { + result.hostname = ''; + result.port = null; + + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host;else srcPath.unshift(result.host); + } + + result.host = ''; + + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host;else relPath.unshift(relative.host); + } + + relative.host = null; + } + + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = relative.host || relative.host === '' ? relative.host : result.host; + result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (relative.search !== null && relative.search !== undefined) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); //occasionally the auth can get stuck only in host + //this especially happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + + const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; + + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + result.search = relative.search; + result.query = relative.query; //to support http.request + + if (result.pathname !== null || result.search !== null) { + result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); + } + + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; //to support http.request + + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + + result.href = result.format(); + return result; + } // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + + + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + + var up = 0; + + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + + if (last === '.') { + spliceOne(srcPath, i); + } else if (last === '..') { + spliceOne(srcPath, i); + up++; + } else if (up) { + spliceOne(srcPath, i); + up--; + } + } // if the path is allowed to go above the root, restore leading ..s + + + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && srcPath.join('/').substr(-1) !== '/') { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || srcPath[0] && srcPath[0].charAt(0) === '/'; // put the host back + + if (psychotic) { + if (isAbsolute) { + result.hostname = result.host = ''; + } else { + result.hostname = result.host = srcPath.length ? srcPath.shift() : ''; + } //occasionally the auth can get stuck only in host + //this especially happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + + + const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; + + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || result.host && srcPath.length; + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } //to support request.http + + + if (result.pathname !== null || result.search !== null) { + result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); + } + + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; +/* istanbul ignore next: improve coverage */ + + +Url.prototype.parseHost = function () { + var host = this.host; + var port = portPattern.exec(host); + + if (port) { + port = port[0]; + + if (port !== ':') { + this.port = port.slice(1); + } + + host = host.slice(0, host.length - port.length); + } + + if (host) this.hostname = host; +}; // About 1.5x faster than the two-arg version of Array#splice(). + +/* istanbul ignore next: improve coverage */ + + +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) list[i] = list[k]; + + list.pop(); +} + +var hexTable = new Array(256); + +for (var i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); +/* istanbul ignore next: improve coverage */ + + +function encodeAuth(str) { + // faster encodeURIComponent alternative for encoding auth uri components + var out = ''; + var lastPos = 0; + + for (var i = 0; i < str.length; ++i) { + var c = str.charCodeAt(i); // These characters do not need escaping: + // ! - . _ ~ + // ' ( ) * : + // digits + // alpha (uppercase) + // alpha (lowercase) + + if (c === 0x21 || c === 0x2d || c === 0x2e || c === 0x5f || c === 0x7e || c >= 0x27 && c <= 0x2a || c >= 0x30 && c <= 0x3a || c >= 0x41 && c <= 0x5a || c >= 0x61 && c <= 0x7a) { + continue; + } + + if (i - lastPos > 0) out += str.slice(lastPos, i); + lastPos = i + 1; // Other ASCII characters + + if (c < 0x80) { + out += hexTable[c]; + continue; + } // Multi-byte characters ... + + + if (c < 0x800) { + out += hexTable[0xc0 | c >> 6] + hexTable[0x80 | c & 0x3f]; + continue; + } + + if (c < 0xd800 || c >= 0xe000) { + out += hexTable[0xe0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; + continue; + } // Surrogate pair + + + ++i; + var c2; + if (i < str.length) c2 = str.charCodeAt(i) & 0x3ff;else c2 = 0; + c = 0x10000 + ((c & 0x3ff) << 10 | c2); + out += hexTable[0xf0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3f] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; + } + + if (lastPos === 0) return str; + if (lastPos < str.length) return out + str.slice(lastPos); + return out; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZW5kb3IvbW9uZ29kYlVybC5qcyJdLCJuYW1lcyI6WyJwdW55Y29kZSIsInJlcXVpcmUiLCJleHBvcnRzIiwicGFyc2UiLCJ1cmxQYXJzZSIsInJlc29sdmUiLCJ1cmxSZXNvbHZlIiwicmVzb2x2ZU9iamVjdCIsInVybFJlc29sdmVPYmplY3QiLCJmb3JtYXQiLCJ1cmxGb3JtYXQiLCJVcmwiLCJwcm90b2NvbCIsInNsYXNoZXMiLCJhdXRoIiwiaG9zdCIsInBvcnQiLCJob3N0bmFtZSIsImhhc2giLCJzZWFyY2giLCJxdWVyeSIsInBhdGhuYW1lIiwicGF0aCIsImhyZWYiLCJwcm90b2NvbFBhdHRlcm4iLCJwb3J0UGF0dGVybiIsInNpbXBsZVBhdGhQYXR0ZXJuIiwidW5zYWZlUHJvdG9jb2wiLCJqYXZhc2NyaXB0IiwiaG9zdGxlc3NQcm90b2NvbCIsInNsYXNoZWRQcm90b2NvbCIsImh0dHAiLCJodHRwcyIsImZ0cCIsImdvcGhlciIsImZpbGUiLCJxdWVyeXN0cmluZyIsInVybCIsInBhcnNlUXVlcnlTdHJpbmciLCJzbGFzaGVzRGVub3RlSG9zdCIsInUiLCJwcm90b3R5cGUiLCJUeXBlRXJyb3IiLCJoYXNIYXNoIiwic3RhcnQiLCJlbmQiLCJyZXN0IiwibGFzdFBvcyIsImkiLCJpbldzIiwic3BsaXQiLCJsZW5ndGgiLCJjb2RlIiwiY2hhckNvZGVBdCIsImlzV3MiLCJzbGljZSIsInNpbXBsZVBhdGgiLCJleGVjIiwicHJvdG8iLCJsb3dlclByb3RvIiwidG9Mb3dlckNhc2UiLCJ0ZXN0IiwiaG9zdEVuZCIsImF0U2lnbiIsIm5vbkhvc3QiLCJkZWNvZGVVUklDb21wb25lbnQiLCJwYXJzZUhvc3QiLCJpcHY2SG9zdG5hbWUiLCJyZXN1bHQiLCJ2YWxpZGF0ZUhvc3RuYW1lIiwidW5kZWZpbmVkIiwidG9BU0NJSSIsInAiLCJoIiwiYXV0b0VzY2FwZVN0ciIsInF1ZXN0aW9uSWR4IiwiaGFzaElkeCIsImZpcnN0SWR4IiwicyIsInNlbGYiLCJuZXdSZXN0Iiwib2JqIiwiY2FsbCIsImVuY29kZUF1dGgiLCJpbmRleE9mIiwic3RyaW5naWZ5IiwibmV3UGF0aG5hbWUiLCJyZXBsYWNlIiwic291cmNlIiwicmVsYXRpdmUiLCJyZWwiLCJ0a2V5cyIsIk9iamVjdCIsImtleXMiLCJ0ayIsInRrZXkiLCJya2V5cyIsInJrIiwicmtleSIsInYiLCJrIiwicmVsUGF0aCIsInNoaWZ0IiwidW5zaGlmdCIsImpvaW4iLCJpc1NvdXJjZUFicyIsImNoYXJBdCIsImlzUmVsQWJzIiwibXVzdEVuZEFicyIsInJlbW92ZUFsbERvdHMiLCJzcmNQYXRoIiwicHN5Y2hvdGljIiwicG9wIiwiY29uY2F0IiwiYXV0aEluSG9zdCIsImxhc3QiLCJoYXNUcmFpbGluZ1NsYXNoIiwidXAiLCJzcGxpY2VPbmUiLCJzdWJzdHIiLCJwdXNoIiwiaXNBYnNvbHV0ZSIsImxpc3QiLCJpbmRleCIsIm4iLCJoZXhUYWJsZSIsIkFycmF5IiwidG9TdHJpbmciLCJ0b1VwcGVyQ2FzZSIsInN0ciIsIm91dCIsImMiLCJjMiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBLE1BQU1BLFFBQVEsR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBeEI7O0FBRUFDLE9BQU8sQ0FBQ0MsS0FBUixHQUFnQkMsUUFBaEI7QUFDQUYsT0FBTyxDQUFDRyxPQUFSLEdBQWtCQyxVQUFsQjtBQUNBSixPQUFPLENBQUNLLGFBQVIsR0FBd0JDLGdCQUF4QjtBQUNBTixPQUFPLENBQUNPLE1BQVIsR0FBaUJDLFNBQWpCO0FBRUFSLE9BQU8sQ0FBQ1MsR0FBUixHQUFjQSxHQUFkOztBQUVBLFNBQVNBLEdBQVQsR0FBZTtBQUNiLE9BQUtDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQSxPQUFLQyxPQUFMLEdBQWUsSUFBZjtBQUNBLE9BQUtDLElBQUwsR0FBWSxJQUFaO0FBQ0EsT0FBS0MsSUFBTCxHQUFZLElBQVo7QUFDQSxPQUFLQyxJQUFMLEdBQVksSUFB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QUFZLENBQUNBLENBQUMsR0FBRyxLQUFMLEtBQWUsRUFBaEIsR0FBc0JDLEVBQWpDLENBQUo7QUFDQUYsSUFBQUEsR0FBRyxJQUNETCxRQUFRLENBQUMsT0FBUU0sQ0FBQyxJQUFJLEVBQWQsQ0FBUixHQUNBTixRQUFRLENBQUMsT0FBU00sQ0FBQyxJQUFJLEVBQU4sR0FBWSxJQUFyQixDQURSLEdBRUFOLFFBQVEsQ0FBQyxPQUFTTSxDQUFDLElBQUksQ0FBTixHQUFXLElBQXBCLENBRlIsR0FHQU4sUUFBUSxDQUFDLE9BQVFNLENBQUMsR0FBRyxJQUFiLENBSlY7QUFLRDs7QUFDRCxNQUFJcEYsT0FBTyxLQUFLLENBQWhCLEVBQW1CLE9BQU9rRixHQUFQO0FBQ25CLE1BQUlsRixPQUFPLEdBQUdrRixHQUFHLENBQUM5RSxNQUFsQixFQUEwQixPQUFPK0UsR0FBRyxHQUFHRCxHQUFHLENBQUMxRSxLQUFKLENBQVVSLE9BQVYsQ0FBYjtBQUMxQixTQUFPbUYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBzbGlnaHRseSBwYXRjaGVkIHZlcnNpb24gb2Ygbm9kZSdzIHVybCBtb2R1bGUsIHdpdGggc3VwcG9ydCBmb3IgbW9uZ29kYjovL1xuLy8gdXJpcy5cbi8vXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvbWFzdGVyL0xJQ0VOU0UgZm9yIGxpY2Vuc2luZ1xuLy8gaW5mb3JtYXRpb25cblxuJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG5cbmV4cG9ydHMucGFyc2UgPSB1cmxQYXJzZTtcbmV4cG9ydHMucmVzb2x2ZSA9IHVybFJlc29sdmU7XG5leHBvcnRzLnJlc29sdmVPYmplY3QgPSB1cmxSZXNvbHZlT2JqZWN0O1xuZXhwb3J0cy5mb3JtYXQgPSB1cmxGb3JtYXQ7XG5cbmV4cG9ydHMuVXJsID0gVXJsO1xuXG5mdW5jdGlvbiBVcmwoKSB7XG4gIHRoaXMucHJvdG9jb2wgPSBudWxsO1xuICB0aGlzLnNsYXNoZXMgPSBudWxsO1xuICB0aGlzLmF1dGggPSBudWxsO1xuICB0aGlzLmhvc3QgPSBudWxsO1xuICB0aGlzLnBvcnQgPSBudWxsO1xuICB0aGlzLmhvc3RuYW1lID0gbnVsbDtcbiAgdGhpcy5oYXNoID0gbnVsbDtcbiAgdGhpcy5zZWFyY2ggPSBudWxsO1xuICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgdGhpcy5wYXRobmFtZSA9IG51bGw7XG4gIHRoaXMucGF0aCA9IG51bGw7XG4gIHRoaXMuaHJlZiA9IG51bGw7XG59XG5cbi8vIFJlZmVyZW5jZTogUkZDIDM5ODYsIFJGQyAxODA4LCBSRkMgMjM5NlxuXG4vLyBkZWZpbmUgdGhlc2UgaGVyZSBzbyBhdCBsZWFzdCB0aGV5IG9ubHkgaGF2ZSB0byBiZVxuLy8gY29tcGlsZWQgb25jZSBvbiB0aGUgZmlyc3QgbW9kdWxlIGxvYWQuXG5jb25zdCBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pO1xuY29uc3QgcG9ydFBhdHRlcm4gPSAvOlswLTldKiQvO1xuXG4vLyBTcGVjaWFsIGNhc2UgZm9yIGEgc2ltcGxlIHBhdGggVVJMXG5jb25zdCBzaW1wbGVQYXRoUGF0dGVybiA9IC9eKFxcL1xcLz8oPyFcXC8pW15cXD9cXHNdKikoXFw/W15cXHNdKik/JC87XG5cbi8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuY29uc3QgdW5zYWZlUHJvdG9jb2wgPSB7XG4gIGphdmFzY3JpcHQ6IHRydWUsXG4gICdqYXZhc2NyaXB0Oic6IHRydWUsXG59O1xuLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuY29uc3QgaG9zdGxlc3NQcm90b2NvbCA9IHtcbiAgamF2YXNjcmlwdDogdHJ1ZSxcbiAgJ2phdmFzY3JpcHQ6JzogdHJ1ZSxcbn07XG4vLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbmNvbnN0IHNsYXNoZWRQcm90b2NvbCA9IHtcbiAgaHR0cDogdHJ1ZSxcbiAgJ2h0dHA6JzogdHJ1ZSxcbiAgaHR0cHM6IHRydWUsXG4gICdodHRwczonOiB0cnVlLFxuICBmdHA6IHRydWUsXG4gICdmdHA6JzogdHJ1ZSxcbiAgZ29waGVyOiB0cnVlLFxuICAnZ29waGVyOic6IHRydWUsXG4gIGZpbGU6IHRydWUsXG4gICdmaWxlOic6IHRydWUsXG59O1xuY29uc3QgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsIGluc3RhbmNlb2YgVXJsKSByZXR1cm4gdXJsO1xuXG4gIHZhciB1ID0gbmV3IFVybCgpO1xuICB1LnBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpO1xuICByZXR1cm4gdTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQYXJhbWV0ZXIgXCJ1cmxcIiBtdXN0IGJlIGEgc3RyaW5nLCBub3QgJyArIHR5cGVvZiB1cmwpO1xuICB9XG5cbiAgLy8gQ29weSBjaHJvbWUsIElFLCBvcGVyYSBiYWNrc2xhc2gtaGFuZGxpbmcgYmVoYXZpb3IuXG4gIC8vIEJhY2sgc2xhc2hlcyBiZWZvcmUgdGhlIHF1ZXJ5IHN0cmluZyBnZXQgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlc1xuICAvLyBTZWU6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0yNTkxNlxuICB2YXIgaGFzSGFzaCA9IGZhbHNlO1xuICB2YXIgc3RhcnQgPSAtMTtcbiAgdmFyIGVuZCA9IC0xO1xuICB2YXIgcmVzdCA9ICcnO1xuICB2YXIgbGFzdFBvcyA9IDA7XG4gIHZhciBpID0gMDtcbiAgZm9yICh2YXIgaW5XcyA9IGZhbHNlLCBzcGxpdCA9IGZhbHNlOyBpIDwgdXJsLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHVybC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gRmluZCBmaXJzdCBhbmQgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGZvciB0cmltbWluZ1xuICAgIGNvbnN0IGlzV3MgPVxuICAgICAgY29kZSA9PT0gMzIgLyogKi8gfHxcbiAgICAgIGNvZGUgPT09IDkgLypcXHQqLyB8fFxuICAgICAgY29kZSA9PT0gMTMgLypcXHIqLyB8fFxuICAgICAgY29kZSA9PT0gMTAgLypcXG4qLyB8fFxuICAgICAgY29kZSA9PT0gMTIgLypcXGYqLyB8fFxuICAgICAgY29kZSA9PT0gMTYwIC8qXFx1MDBBMCovIHx8XG4gICAgICBjb2RlID09PSA2NTI3OTsgLypcXHVGRUZGKi9cbiAgICBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICBpZiAoaXNXcykgY29udGludWU7XG4gICAgICBsYXN0UG9zID0gc3RhcnQgPSBpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5Xcykge1xuICAgICAgICBpZiAoIWlzV3MpIHtcbiAgICAgICAgICBlbmQgPSAtMTtcbiAgICAgICAgICBpbldzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNXcykge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBpbldzID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBPbmx5IGNvbnZlcnQgYmFja3NsYXNoZXMgd2hpbGUgd2UgaGF2ZW4ndCBzZWVuIGEgc3BsaXQgY2hhcmFjdGVyXG4gICAgaWYgKCFzcGxpdCkge1xuICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgIGNhc2UgMzU6IC8vICcjJ1xuICAgICAgICAgIGhhc0hhc2ggPSB0cnVlO1xuICAgICAgICAvLyBGYWxsIHRocm91Z2hcbiAgICAgICAgY2FzZSA2MzogLy8gJz8nXG4gICAgICAgICAgc3BsaXQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSByZXN0ICs9IHVybC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgICByZXN0ICs9ICcvJztcbiAgICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaGFzSGFzaCAmJiBjb2RlID09PSAzNSAvKiMqLykge1xuICAgICAgaGFzSGFzaCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgaWYgc3RyaW5nIHdhcyBub24tZW1wdHkgKGluY2x1ZGluZyBzdHJpbmdzIHdpdGggb25seSB3aGl0ZXNwYWNlKVxuICBpZiAoc3RhcnQgIT09IC0xKSB7XG4gICAgaWYgKGxhc3RQb3MgPT09IHN0YXJ0KSB7XG4gICAgICAvLyBXZSBkaWRuJ3QgY29udmVydCBhbnkgYmFja3NsYXNoZXNcblxuICAgICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgICAgaWYgKHN0YXJ0ID09PSAwKSByZXN0ID0gdXJsO1xuICAgICAgICBlbHNlIHJlc3QgPSB1cmwuc2xpY2Uoc3RhcnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdCA9IHVybC5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVuZCA9PT0gLTEgJiYgbGFzdFBvcyA8IHVybC5sZW5ndGgpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcyk7XG4gICAgfSBlbHNlIGlmIChlbmQgIT09IC0xICYmIGxhc3RQb3MgPCBlbmQpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcywgZW5kKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXNsYXNoZXNEZW5vdGVIb3N0ICYmICFoYXNIYXNoKSB7XG4gICAgLy8gVHJ5IGZhc3QgcGF0aCByZWdleHBcbiAgICBjb25zdCBzaW1wbGVQYXRoID0gc2ltcGxlUGF0aFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgICBpZiAoc2ltcGxlUGF0aCkge1xuICAgICAgdGhpcy5wYXRoID0gcmVzdDtcbiAgICAgIHRoaXMuaHJlZiA9IHJlc3Q7XG4gICAgICB0aGlzLnBhdGhuYW1lID0gc2ltcGxlUGF0aFsxXTtcbiAgICAgIGlmIChzaW1wbGVQYXRoWzJdKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gc2ltcGxlUGF0aFsyXTtcbiAgICAgICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5zZWFyY2guc2xpY2UoMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucXVlcnkgPSB0aGlzLnNlYXJjaC5zbGljZSgxKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gJyc7XG4gICAgICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHZhciBwcm90byA9IHByb3RvY29sUGF0dGVybi5leGVjKHJlc3QpO1xuICBpZiAocHJvdG8pIHtcbiAgICBwcm90byA9IHByb3RvWzBdO1xuICAgIHZhciBsb3dlclByb3RvID0gcHJvdG8udG9Mb3dlckNhc2UoKTtcbiAgICB0aGlzLnByb3RvY29sID0gbG93ZXJQcm90bztcbiAgICByZXN0ID0gcmVzdC5zbGljZShwcm90by5sZW5ndGgpO1xuICB9XG5cbiAgLy8gZmlndXJlIG91dCBpZiBpdCdzIGdvdCBhIGhvc3RcbiAgLy8gdXNlckBzZXJ2ZXIgaXMgKmFsd2F5cyogaW50ZXJwcmV0ZWQgYXMgYSBob3N0bmFtZSwgYW5kIHVybFxuICAvLyByZXNvbHV0aW9uIHdpbGwgdHJlYXQgLy9mb28vYmFyIGFzIGhvc3Q9Zm9vLHBhdGg9YmFyIGJlY2F1c2UgdGhhdCdzXG4gIC8vIGhvdyB0aGUgYnJvd3NlciByZXNvbHZlcyByZWxhdGl2ZSBVUkxzLlxuICBpZiAoc2xhc2hlc0Rlbm90ZUhvc3QgfHwgcHJvdG8gfHwgL15cXC9cXC9bXkBcXC9dK0BbXkBcXC9dKy8udGVzdChyZXN0KSkge1xuICAgIHZhciBzbGFzaGVzID0gcmVzdC5jaGFyQ29kZUF0KDApID09PSA0NyAvKi8qLyAmJiByZXN0LmNoYXJDb2RlQXQoMSkgPT09IDQ3OyAvKi8qL1xuICAgIGlmIChzbGFzaGVzICYmICEocHJvdG8gJiYgaG9zdGxlc3NQcm90b2NvbFtwcm90b10pKSB7XG4gICAgICByZXN0ID0gcmVzdC5zbGljZSgyKTtcbiAgICAgIHRoaXMuc2xhc2hlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFob3N0bGVzc1Byb3RvY29sW3Byb3RvXSAmJiAoc2xhc2hlcyB8fCAocHJvdG8gJiYgIXNsYXNoZWRQcm90b2NvbFtwcm90b10pKSkge1xuICAgIC8vIHRoZXJlJ3MgYSBob3N0bmFtZS5cbiAgICAvLyB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgLywgPywgOywgb3IgIyBlbmRzIHRoZSBob3N0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gQCBpbiB0aGUgaG9zdG5hbWUsIHRoZW4gbm9uLWhvc3QgY2hhcnMgKmFyZSogYWxsb3dlZFxuICAgIC8vIHRvIHRoZSBsZWZ0IG9mIHRoZSBsYXN0IEAgc2lnbiwgdW5sZXNzIHNvbWUgaG9zdC1lbmRpbmcgY2hhcmFjdGVyXG4gICAgLy8gY29tZXMgKmJlZm9yZSogdGhlIEAtc2lnbi5cbiAgICAvLyBVUkxzIGFyZSBvYm5veGlvdXMuXG4gICAgLy9cbiAgICAvLyBleDpcbiAgICAvLyBodHRwOi8vYUBiQGMvID0+IHVzZXI6YUBiIGhvc3Q6Y1xuICAgIC8vIGh0dHA6Ly9hQGI/QGMgPT4gdXNlcjphIGhvc3Q6YiBwYXRoOi8/QGNcblxuICAgIC8vIHYwLjEyIFRPRE8oaXNhYWNzKTogVGhpcyBpcyBub3QgcXVpdGUgaG93IENocm9tZSBkb2VzIHRoaW5ncy5cbiAgICAvLyBSZXZpZXcgb3VyIHRlc3QgY2FzZSBhZ2FpbnN0IGJyb3dzZXJzIG1vcmUgY29tcHJlaGVuc2l2ZWx5LlxuXG4gICAgdmFyIGhvc3RFbmQgPSAtMTtcbiAgICB2YXIgYXRTaWduID0gLTE7XG4gICAgdmFyIG5vbkhvc3QgPSAtMTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7ICsraSkge1xuICAgICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgICAgY2FzZSA5OiAvLyAnXFx0J1xuICAgICAgICBjYXNlIDEwOiAvLyAnXFxuJ1xuICAgICAgICBjYXNlIDEzOiAvLyAnXFxyJ1xuICAgICAgICBjYXNlIDMyOiAvLyAnICdcbiAgICAgICAgY2FzZSAzNDogLy8gJ1wiJ1xuICAgICAgICBjYXNlIDM3OiAvLyAnJSdcbiAgICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgY2FzZSA1OTogLy8gJzsnXG4gICAgICAgIGNhc2UgNjA6IC8vICc8J1xuICAgICAgICBjYXNlIDYyOiAvLyAnPidcbiAgICAgICAgY2FzZSA5MjogLy8gJ1xcXFwnXG4gICAgICAgIGNhc2UgOTQ6IC8vICdeJ1xuICAgICAgICBjYXNlIDk2OiAvLyAnYCdcbiAgICAgICAgY2FzZSAxMjM6IC8vICd7J1xuICAgICAgICBjYXNlIDEyNDogLy8gJ3wnXG4gICAgICAgIGNhc2UgMTI1OiAvLyAnfSdcbiAgICAgICAgICAvLyBDaGFyYWN0ZXJzIHRoYXQgYXJlIG5ldmVyIGV2ZXIgYWxsb3dlZCBpbiBhIGhvc3RuYW1lIGZyb20gUkZDIDIzOTZcbiAgICAgICAgICBpZiAobm9uSG9zdCA9PT0gLTEpIG5vbkhvc3QgPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM1OiAvLyAnIydcbiAgICAgICAgY2FzZSA0NzogLy8gJy8nXG4gICAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSBob3N0LWVuZGluZyBjaGFyYWN0ZXJzXG4gICAgICAgICAgaWYgKG5vbkhvc3QgPT09IC0xKSBub25Ib3N0ID0gaTtcbiAgICAgICAgICBob3N0RW5kID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA2NDogLy8gJ0AnXG4gICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgZWl0aGVyIHdlIGhhdmUgYW4gZXhwbGljaXQgcG9pbnQgd2hlcmUgdGhlXG4gICAgICAgICAgLy8gYXV0aCBwb3J0aW9uIGNhbm5vdCBnbyBwYXN0LCBvciB0aGUgbGFzdCBAIGNoYXIgaXMgdGhlIGRlY2lkZXIuXG4gICAgICAgICAgYXRTaWduID0gaTtcbiAgICAgICAgICBub25Ib3N0ID0gLTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoaG9zdEVuZCAhPT0gLTEpIGJyZWFrO1xuICAgIH1cbiAgICBzdGFydCA9IDA7XG4gICAgaWYgKGF0U2lnbiAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYXV0aCA9IGRlY29kZVVSSUNvbXBvbmVudChyZXN0LnNsaWNlKDAsIGF0U2lnbikpO1xuICAgICAgc3RhcnQgPSBhdFNpZ24gKyAxO1xuICAgIH1cbiAgICBpZiAobm9uSG9zdCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuaG9zdCA9IHJlc3Quc2xpY2Uoc3RhcnQpO1xuICAgICAgcmVzdCA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhvc3QgPSByZXN0LnNsaWNlKHN0YXJ0LCBub25Ib3N0KTtcbiAgICAgIHJlc3QgPSByZXN0LnNsaWNlKG5vbkhvc3QpO1xuICAgIH1cblxuICAgIC8vIHB1bGwgb3V0IHBvcnQuXG4gICAgdGhpcy5wYXJzZUhvc3QoKTtcblxuICAgIC8vIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgLy8gc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICBpZiAodHlwZW9mIHRoaXMuaG9zdG5hbWUgIT09ICdzdHJpbmcnKSB0aGlzLmhvc3RuYW1lID0gJyc7XG5cbiAgICB2YXIgaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lO1xuXG4gICAgLy8gaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAvLyBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID1cbiAgICAgIGhvc3RuYW1lLmNoYXJDb2RlQXQoMCkgPT09IDkxIC8qWyovICYmIGhvc3RuYW1lLmNoYXJDb2RlQXQoaG9zdG5hbWUubGVuZ3RoIC0gMSkgPT09IDkzOyAvKl0qL1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlSG9zdG5hbWUodGhpcywgcmVzdCwgaG9zdG5hbWUpO1xuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIGhvc3RuYW1lcyBhcmUgYWx3YXlzIGxvd2VyIGNhc2UuXG4gICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICAvLyBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55Y29kZWQgcmVwcmVzZW50YXRpb24gb2YgXCJkb21haW5cIi5cbiAgICAgIC8vIEl0IG9ubHkgY29udmVydHMgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHRoYXRcbiAgICAgIC8vIGhhdmUgbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIGkuZS4gaXQgZG9lc24ndCBtYXR0ZXIgaWZcbiAgICAgIC8vIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIEFTQ0lJLW9ubHkuXG4gICAgICB0aGlzLmhvc3RuYW1lID0gcHVueWNvZGUudG9BU0NJSSh0aGlzLmhvc3RuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMucG9ydCA/ICc6JyArIHRoaXMucG9ydCA6ICcnO1xuICAgIHZhciBoID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcbiAgICB0aGlzLmhvc3QgPSBoICsgcDtcblxuICAgIC8vIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAvLyB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnNsaWNlKDEsIC0xKTtcbiAgICAgIGlmIChyZXN0WzBdICE9PSAnLycpIHtcbiAgICAgICAgcmVzdCA9ICcvJyArIHJlc3Q7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gbm93IHJlc3QgaXMgc2V0IHRvIHRoZSBwb3N0LWhvc3Qgc3R1ZmYuXG4gIC8vIGNob3Agb2ZmIGFueSBkZWxpbSBjaGFycy5cbiAgaWYgKCF1bnNhZmVQcm90b2NvbFtsb3dlclByb3RvXSkge1xuICAgIC8vIEZpcnN0LCBtYWtlIDEwMCUgc3VyZSB0aGF0IGFueSBcImF1dG9Fc2NhcGVcIiBjaGFycyBnZXRcbiAgICAvLyBlc2NhcGVkLCBldmVuIGlmIGVuY29kZVVSSUNvbXBvbmVudCBkb2Vzbid0IHRoaW5rIHRoZXlcbiAgICAvLyBuZWVkIHRvIGJlLlxuICAgIGNvbnN0IHJlc3VsdCA9IGF1dG9Fc2NhcGVTdHIocmVzdCk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICB9XG5cbiAgdmFyIHF1ZXN0aW9uSWR4ID0gLTE7XG4gIHZhciBoYXNoSWR4ID0gLTE7XG4gIGZvciAoaSA9IDA7IGkgPCByZXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHJlc3QuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gMzUgLyojKi8pIHtcbiAgICAgIHRoaXMuaGFzaCA9IHJlc3Quc2xpY2UoaSk7XG4gICAgICBoYXNoSWR4ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoY29kZSA9PT0gNjMgLyo/Ki8gJiYgcXVlc3Rpb25JZHggPT09IC0xKSB7XG4gICAgICBxdWVzdGlvbklkeCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXN0aW9uSWR4ICE9PSAtMSkge1xuICAgIGlmIChoYXNoSWR4ID09PSAtMSkge1xuICAgICAgdGhpcy5zZWFyY2ggPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4KTtcbiAgICAgIHRoaXMucXVlcnkgPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCwgaGFzaElkeCk7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCArIDEsIGhhc2hJZHgpO1xuICAgIH1cbiAgICBpZiAocGFyc2VRdWVyeVN0cmluZykge1xuICAgICAgdGhpcy5xdWVyeSA9IHF1ZXJ5c3RyaW5nLnBhcnNlKHRoaXMucXVlcnkpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuXG4gIHZhciBmaXJzdElkeCA9XG4gICAgcXVlc3Rpb25JZHggIT09IC0xICYmIChoYXNoSWR4ID09PSAtMSB8fCBxdWVzdGlvbklkeCA8IGhhc2hJZHgpID8gcXVlc3Rpb25JZHggOiBoYXNoSWR4O1xuICBpZiAoZmlyc3RJZHggPT09IC0xKSB7XG4gICAgaWYgKHJlc3QubGVuZ3RoID4gMCkgdGhpcy5wYXRobmFtZSA9IHJlc3Q7XG4gIH0gZWxzZSBpZiAoZmlyc3RJZHggPiAwKSB7XG4gICAgdGhpcy5wYXRobmFtZSA9IHJlc3Quc2xpY2UoMCwgZmlyc3RJZHgpO1xuICB9XG4gIGlmIChzbGFzaGVkUHJvdG9jb2xbbG93ZXJQcm90b10gJiYgdGhpcy5ob3N0bmFtZSAmJiAhdGhpcy5wYXRobmFtZSkge1xuICAgIHRoaXMucGF0aG5hbWUgPSAnLyc7XG4gIH1cblxuICAvLyB0byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICBpZiAodGhpcy5wYXRobmFtZSB8fCB0aGlzLnNlYXJjaCkge1xuICAgIGNvbnN0IHAgPSB0aGlzLnBhdGhuYW1lIHx8ICcnO1xuICAgIGNvbnN0IHMgPSB0aGlzLnNlYXJjaCB8fCAnJztcbiAgICB0aGlzLnBhdGggPSBwICsgcztcbiAgfVxuXG4gIC8vIGZpbmFsbHksIHJlY29uc3RydWN0IHRoZSBocmVmIGJhc2VkIG9uIHdoYXQgaGFzIGJlZW4gdmFsaWRhdGVkLlxuICB0aGlzLmhyZWYgPSB0aGlzLmZvcm1hdCgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB2YWxpZGF0ZUhvc3RuYW1lKHNlbGYsIHJlc3QsIGhvc3RuYW1lKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsYXN0UG9zOyBpIDw9IGhvc3RuYW1lLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvZGU7XG4gICAgaWYgKGkgPCBob3N0bmFtZS5sZW5ndGgpIGNvZGUgPSBob3N0bmFtZS5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChjb2RlID09PSA0NiAvKi4qLyB8fCBpID09PSBob3N0bmFtZS5sZW5ndGgpIHtcbiAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIHtcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gNjMpIHtcbiAgICAgICAgICBzZWxmLmhvc3RuYW1lID0gaG9zdG5hbWUuc2xpY2UoMCwgbGFzdFBvcyArIDYzKTtcbiAgICAgICAgICByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UobGFzdFBvcyArIDYzKSArIHJlc3Q7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAoY29kZSA+PSA0OCAvKjAqLyAmJiBjb2RlIDw9IDU3KSAvKjkqLyB8fFxuICAgICAgKGNvZGUgPj0gOTcgLyphKi8gJiYgY29kZSA8PSAxMjIpIC8qeiovIHx8XG4gICAgICBjb2RlID09PSA0NSAvKi0qLyB8fFxuICAgICAgKGNvZGUgPj0gNjUgLypBKi8gJiYgY29kZSA8PSA5MCkgLypaKi8gfHxcbiAgICAgIGNvZGUgPT09IDQzIC8qKyovIHx8XG4gICAgICBjb2RlID09PSA5NSAvKl8qLyB8fFxuICAgICAgLyogQkVHSU4gTU9OR08gVVJJIFBBVENIICovXG4gICAgICBjb2RlID09PSA0NCAvKiwqLyB8fFxuICAgICAgY29kZSA9PT0gNTggLyo6Ki8gfHxcbiAgICAgIC8qIEVORCBNT05HTyBVUkkgUEFUQ0ggKi9cbiAgICAgIGNvZGUgPiAxMjdcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICAvLyBJbnZhbGlkIGhvc3QgY2hhcmFjdGVyXG4gICAgc2VsZi5ob3N0bmFtZSA9IGhvc3RuYW1lLnNsaWNlKDAsIGkpO1xuICAgIGlmIChpIDwgaG9zdG5hbWUubGVuZ3RoKSByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UoaSkgKyByZXN0O1xuICAgIGJyZWFrO1xuICB9XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBhdXRvRXNjYXBlU3RyKHJlc3QpIHtcbiAgdmFyIG5ld1Jlc3QgPSAnJztcbiAgdmFyIGxhc3RQb3MgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJlc3QubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBBdXRvbWF0aWNhbGx5IGVzY2FwZSBhbGwgZGVsaW1pdGVycyBhbmQgdW53aXNlIGNoYXJhY3RlcnMgZnJvbSBSRkMgMjM5NlxuICAgIC8vIEFsc28gZXNjYXBlIHNpbmdsZSBxdW90ZXMgaW4gY2FzZSBvZiBhbiBYU1MgYXR0YWNrXG4gICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgIGNhc2UgOTogLy8gJ1xcdCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMDknO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMDogLy8gJ1xcbidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEEnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMzogLy8gJ1xccidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEQnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMjogLy8gJyAnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTIwJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzQ6IC8vICdcIidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjInO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjcnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2MDogLy8gJzwnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTNDJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjI6IC8vICc+J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyUzRSc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclNUMnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5NDogLy8gJ14nXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTVFJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgOTY6IC8vICdgJ1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU2MCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyMzogLy8gJ3snXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTdCJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI0OiAvLyAnfCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclN0MnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjU6IC8vICd9J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU3RCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID09PSAwKSByZXR1cm47XG4gIGlmIChsYXN0UG9zIDwgcmVzdC5sZW5ndGgpIHJldHVybiBuZXdSZXN0ICsgcmVzdC5zbGljZShsYXN0UG9zKTtcbiAgZWxzZSByZXR1cm4gbmV3UmVzdDtcbn1cblxuLy8gZm9ybWF0IGEgcGFyc2VkIG9iamVjdCBpbnRvIGEgdXJsIHN0cmluZ1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybEZvcm1hdChvYmopIHtcbiAgLy8gZW5zdXJlIGl0J3MgYW4gb2JqZWN0LCBhbmQgbm90IGEgc3RyaW5nIHVybC5cbiAgLy8gSWYgaXQncyBhbiBvYmosIHRoaXMgaXMgYSBuby1vcC5cbiAgLy8gdGhpcyB3YXksIHlvdSBjYW4gY2FsbCB1cmxfZm9ybWF0KCkgb24gc3RyaW5nc1xuICAvLyB0byBjbGVhbiB1cCBwb3RlbnRpYWxseSB3b25reSB1cmxzLlxuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIG9iaiA9IHVybFBhcnNlKG9iaik7XG4gIGVsc2UgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1BhcmFtZXRlciBcInVybE9ialwiIG11c3QgYmUgYW4gb2JqZWN0LCBub3QgJyArIG9iaiA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiBvYmpcbiAgICApO1xuICBlbHNlIGlmICghKG9iaiBpbnN0YW5jZW9mIFVybCkpIHJldHVybiBVcmwucHJvdG90eXBlLmZvcm1hdC5jYWxsKG9iaik7XG5cbiAgcmV0dXJuIG9iai5mb3JtYXQoKTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXV0aCA9IHRoaXMuYXV0aCB8fCAnJztcbiAgaWYgKGF1dGgpIHtcbiAgICBhdXRoID0gZW5jb2RlQXV0aChhdXRoKTtcbiAgICBhdXRoICs9ICdAJztcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHRoaXMucHJvdG9jb2wgfHwgJyc7XG4gIHZhciBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJyc7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoIHx8ICcnO1xuICB2YXIgaG9zdCA9IGZhbHNlO1xuICB2YXIgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/IHRoaXMuaG9zdG5hbWUgOiAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5xdWVyeSA9PT0gJ29iamVjdCcpXG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSk7XG5cbiAgdmFyIHNlYXJjaCA9IHRoaXMuc2VhcmNoIHx8IChxdWVyeSAmJiAnPycgKyBxdWVyeSkgfHwgJyc7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLmNoYXJDb2RlQXQocHJvdG9jb2wubGVuZ3RoIC0gMSkgIT09IDU4IC8qOiovKSBwcm90b2NvbCArPSAnOic7XG5cbiAgdmFyIG5ld1BhdGhuYW1lID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRobmFtZS5sZW5ndGg7ICsraSkge1xuICAgIHN3aXRjaCAocGF0aG5hbWUuY2hhckNvZGVBdChpKSkge1xuICAgICAgY2FzZSAzNTogLy8gJyMnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1BhdGhuYW1lICs9IHBhdGhuYW1lLnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdQYXRobmFtZSArPSAnJTIzJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdQYXRobmFtZSArPSBwYXRobmFtZS5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UGF0aG5hbWUgKz0gJyUzRic7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID4gMCkge1xuICAgIGlmIChsYXN0UG9zICE9PSBwYXRobmFtZS5sZW5ndGgpIHBhdGhuYW1lID0gbmV3UGF0aG5hbWUgKyBwYXRobmFtZS5zbGljZShsYXN0UG9zKTtcbiAgICBlbHNlIHBhdGhuYW1lID0gbmV3UGF0aG5hbWU7XG4gIH1cblxuICAvLyBvbmx5IHRoZSBzbGFzaGVkUHJvdG9jb2xzIGdldCB0aGUgLy8uICBOb3QgbWFpbHRvOiwgeG1wcDosIGV0Yy5cbiAgLy8gdW5sZXNzIHRoZXkgaGFkIHRoZW0gdG8gYmVnaW4gd2l0aC5cbiAgaWYgKHRoaXMuc2xhc2hlcyB8fCAoKCFwcm90b2NvbCB8fCBzbGFzaGVkUHJvdG9jb2xbcHJvdG9jb2xdKSAmJiBob3N0ICE9PSBmYWxzZSkpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckNvZGVBdCgwKSAhPT0gNDcgLyovKi8pIHBhdGhuYW1lID0gJy8nICsgcGF0aG5hbWU7XG4gIH0gZWxzZSBpZiAoIWhvc3QpIHtcbiAgICBob3N0ID0gJyc7XG4gIH1cblxuICBzZWFyY2ggPSBzZWFyY2gucmVwbGFjZSgnIycsICclMjMnKTtcblxuICBpZiAoaGFzaCAmJiBoYXNoLmNoYXJDb2RlQXQoMCkgIT09IDM1IC8qIyovKSBoYXNoID0gJyMnICsgaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2guY2hhckNvZGVBdCgwKSAhPT0gNjMgLyo/Ki8pIHNlYXJjaCA9ICc/JyArIHNlYXJjaDtcblxuICByZXR1cm4gcHJvdG9jb2wgKyBob3N0ICsgcGF0aG5hbWUgKyBzZWFyY2ggKyBoYXNoO1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybFJlc29sdmUoc291cmNlLCByZWxhdGl2ZSkge1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZShyZWxhdGl2ZSk7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5VcmwucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAocmVsYXRpdmUpIHtcbiAgcmV0dXJuIHRoaXMucmVzb2x2ZU9iamVjdCh1cmxQYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpKS5mb3JtYXQoKTtcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiByZWxhdGl2ZTtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmVPYmplY3QocmVsYXRpdmUpO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24gKHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgcmVsYXRpdmUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIHZhciB0a2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICBmb3IgKHZhciB0ayA9IDA7IHRrIDwgdGtleXMubGVuZ3RoOyB0aysrKSB7XG4gICAgdmFyIHRrZXkgPSB0a2V5c1t0a107XG4gICAgcmVzdWx0W3RrZXldID0gdGhpc1t0a2V5XTtcbiAgfVxuXG4gIC8vIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAvLyBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgcmVzdWx0Lmhhc2ggPSByZWxhdGl2ZS5oYXNoO1xuXG4gIC8vIGlmIHRoZSByZWxhdGl2ZSB1cmwgaXMgZW1wdHksIHRoZW4gdGhlcmUncyBub3RoaW5nIGxlZnQgdG8gZG8gaGVyZS5cbiAgaWYgKHJlbGF0aXZlLmhyZWYgPT09ICcnKSB7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGhyZWZzIGxpa2UgLy9mb28vYmFyIGFsd2F5cyBjdXQgdG8gdGhlIHByb3RvY29sLlxuICBpZiAocmVsYXRpdmUuc2xhc2hlcyAmJiAhcmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAvLyB0YWtlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBwcm90b2NvbCBmcm9tIHJlbGF0aXZlXG4gICAgdmFyIHJrZXlzID0gT2JqZWN0LmtleXMocmVsYXRpdmUpO1xuICAgIGZvciAodmFyIHJrID0gMDsgcmsgPCBya2V5cy5sZW5ndGg7IHJrKyspIHtcbiAgICAgIHZhciBya2V5ID0gcmtleXNbcmtdO1xuICAgICAgaWYgKHJrZXkgIT09ICdwcm90b2NvbCcpIHJlc3VsdFtya2V5XSA9IHJlbGF0aXZlW3JrZXldO1xuICAgIH1cblxuICAgIC8vdXJsUGFyc2UgYXBwZW5kcyB0cmFpbGluZyAvIHRvIHVybHMgbGlrZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tXG4gICAgaWYgKHNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdICYmIHJlc3VsdC5ob3N0bmFtZSAmJiAhcmVzdWx0LnBhdGhuYW1lKSB7XG4gICAgICByZXN1bHQucGF0aCA9IHJlc3VsdC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKHJlbGF0aXZlLnByb3RvY29sICYmIHJlbGF0aXZlLnByb3RvY29sICE9PSByZXN1bHQucHJvdG9jb2wpIHtcbiAgICAvLyBpZiBpdCdzIGEga25vd24gdXJsIHByb3RvY29sLCB0aGVuIGNoYW5naW5nXG4gICAgLy8gdGhlIHByb3RvY29sIGRvZXMgd2VpcmQgdGhpbmdzXG4gICAgLy8gZmlyc3QsIGlmIGl0J3Mgbm90IGZpbGU6LCB0aGVuIHdlIE1VU1QgaGF2ZSBhIGhvc3QsXG4gICAgLy8gYW5kIGlmIHRoZXJlIHdhcyBhIHBhdGhcbiAgICAvLyB0byBiZWdpbiB3aXRoLCB0aGVuIHdlIE1VU1QgaGF2ZSBhIHBhdGguXG4gICAgLy8gaWYgaXQgaXMgZmlsZTosIHRoZW4gdGhlIGhvc3QgaXMgZHJvcHBlZCxcbiAgICAvLyBiZWNhdXNlIHRoYXQncyBrbm93biB0byBiZSBob3N0bGVzcy5cbiAgICAvLyBhbnl0aGluZyBlbHNlIGlzIGFzc3VtZWQgdG8gYmUgYWJzb2x1dGUuXG4gICAgaWYgKCFzbGFzaGVkUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHJlbGF0aXZlKTtcbiAgICAgIGZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICAgICAgICB2YXIgayA9IGtleXNbdl07XG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgICAgfVxuICAgICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJlc3VsdC5wcm90b2NvbCA9IHJlbGF0aXZlLnByb3RvY29sO1xuICAgIGlmIChcbiAgICAgICFyZWxhdGl2ZS5ob3N0ICYmXG4gICAgICAhL15maWxlOj8kLy50ZXN0KHJlbGF0aXZlLnByb3RvY29sKSAmJlxuICAgICAgIWhvc3RsZXNzUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdXG4gICAgKSB7XG4gICAgICBjb25zdCByZWxQYXRoID0gKHJlbGF0aXZlLnBhdGhuYW1lIHx8ICcnKS5zcGxpdCgnLycpO1xuICAgICAgd2hpbGUgKHJlbFBhdGgubGVuZ3RoICYmICEocmVsYXRpdmUuaG9zdCA9IHJlbFBhdGguc2hpZnQoKSkpO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0KSByZWxhdGl2ZS5ob3N0ID0gJyc7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSByZWxhdGl2ZS5ob3N0bmFtZSA9ICcnO1xuICAgICAgaWYgKHJlbFBhdGhbMF0gIT09ICcnKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgaWYgKHJlbFBhdGgubGVuZ3RoIDwgMikgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gcmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJztcbiAgdmFyIGlzUmVsQWJzID0gcmVsYXRpdmUuaG9zdCB8fCAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpO1xuICB2YXIgbXVzdEVuZEFicyA9IGlzUmVsQWJzIHx8IGlzU291cmNlQWJzIHx8IChyZXN1bHQuaG9zdCAmJiByZWxhdGl2ZS5wYXRobmFtZSk7XG4gIHZhciByZW1vdmVBbGxEb3RzID0gbXVzdEVuZEFicztcbiAgdmFyIHNyY1BhdGggPSAocmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5zcGxpdCgnLycpKSB8fCBbXTtcbiAgdmFyIHJlbFBhdGggPSAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSkgfHwgW107XG4gIHZhciBwc3ljaG90aWMgPSByZXN1bHQucHJvdG9jb2wgJiYgIXNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdO1xuXG4gIC8vIGlmIHRoZSB1cmwgaXMgYSBub24tc2xhc2hlZCB1cmwsIHRoZW4gcmVsYXRpdmVcbiAgLy8gbGlua3MgbGlrZSAuLi8uLiBzaG91bGQgYmUgYWJsZVxuICAvLyB0byBjcmF3bCB1cCB0byB0aGUgaG9zdG5hbWUsIGFzIHdlbGwuICBUaGlzIGlzIHN0cmFuZ2UuXG4gIC8vIHJlc3VsdC5wcm90b2NvbCBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSBub3cuXG4gIC8vIExhdGVyIG9uLCBwdXQgdGhlIGZpcnN0IHBhdGggcGFydCBpbnRvIHRoZSBob3N0IGZpZWxkLlxuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gJyc7XG4gICAgcmVzdWx0LnBvcnQgPSBudWxsO1xuICAgIGlmIChyZXN1bHQuaG9zdCkge1xuICAgICAgaWYgKHNyY1BhdGhbMF0gPT09ICcnKSBzcmNQYXRoWzBdID0gcmVzdWx0Lmhvc3Q7XG4gICAgICBlbHNlIHNyY1BhdGgudW5zaGlmdChyZXN1bHQuaG9zdCk7XG4gICAgfVxuICAgIHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgaWYgKHJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgICByZWxhdGl2ZS5ob3N0bmFtZSA9IG51bGw7XG4gICAgICByZWxhdGl2ZS5wb3J0ID0gbnVsbDtcbiAgICAgIGlmIChyZWxhdGl2ZS5ob3N0KSB7XG4gICAgICAgIGlmIChyZWxQYXRoWzBdID09PSAnJykgcmVsUGF0aFswXSA9IHJlbGF0aXZlLmhvc3Q7XG4gICAgICAgIGVsc2UgcmVsUGF0aC51bnNoaWZ0KHJlbGF0aXZlLmhvc3QpO1xuICAgICAgfVxuICAgICAgcmVsYXRpdmUuaG9zdCA9IG51bGw7XG4gICAgfVxuICAgIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzICYmIChyZWxQYXRoWzBdID09PSAnJyB8fCBzcmNQYXRoWzBdID09PSAnJyk7XG4gIH1cblxuICBpZiAoaXNSZWxBYnMpIHtcbiAgICAvLyBpdCdzIGFic29sdXRlLlxuICAgIHJlc3VsdC5ob3N0ID0gcmVsYXRpdmUuaG9zdCB8fCByZWxhdGl2ZS5ob3N0ID09PSAnJyA/IHJlbGF0aXZlLmhvc3QgOiByZXN1bHQuaG9zdDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPVxuICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdG5hbWUgPT09ICcnID8gcmVsYXRpdmUuaG9zdG5hbWUgOiByZXN1bHQuaG9zdG5hbWU7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICBzcmNQYXRoID0gcmVsUGF0aDtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gdGhlIGRvdC1oYW5kbGluZyBiZWxvdy5cbiAgfSBlbHNlIGlmIChyZWxQYXRoLmxlbmd0aCkge1xuICAgIC8vIGl0J3MgcmVsYXRpdmVcbiAgICAvLyB0aHJvdyBhd2F5IHRoZSBleGlzdGluZyBmaWxlLCBhbmQgdGFrZSB0aGUgbmV3IHBhdGggaW5zdGVhZC5cbiAgICBpZiAoIXNyY1BhdGgpIHNyY1BhdGggPSBbXTtcbiAgICBzcmNQYXRoLnBvcCgpO1xuICAgIHNyY1BhdGggPSBzcmNQYXRoLmNvbmNhdChyZWxQYXRoKTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKHJlbGF0aXZlLnNlYXJjaCAhPT0gbnVsbCAmJiByZWxhdGl2ZS5zZWFyY2ggIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGp1c3QgcHVsbCBvdXQgdGhlIHNlYXJjaC5cbiAgICAvLyBsaWtlIGhyZWY9Jz9mb28nLlxuICAgIC8vIFB1dCB0aGlzIGFmdGVyIHRoZSBvdGhlciB0d28gY2FzZXMgYmVjYXVzZSBpdCBzaW1wbGlmaWVzIHRoZSBib29sZWFuc1xuICAgIGlmIChwc3ljaG90aWMpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5zaGlmdCgpO1xuICAgICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAgIC8vdGhpcyBlc3BlY2lhbGx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgIGNvbnN0IGF1dGhJbkhvc3QgPVxuICAgICAgICByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBubyBwYXRoIGF0IGFsbC4gIGVhc3kuXG4gICAgLy8gd2UndmUgYWxyZWFkeSBoYW5kbGVkIHRoZSBvdGhlciBzdHVmZiBhYm92ZS5cbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgLy8gaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gIC8vIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIHZhciBsYXN0ID0gc3JjUGF0aC5zbGljZSgtMSlbMF07XG4gIHZhciBoYXNUcmFpbGluZ1NsYXNoID1cbiAgICAoKHJlc3VsdC5ob3N0IHx8IHJlbGF0aXZlLmhvc3QgfHwgc3JjUGF0aC5sZW5ndGggPiAxKSAmJiAobGFzdCA9PT0gJy4nIHx8IGxhc3QgPT09ICcuLicpKSB8fFxuICAgIGxhc3QgPT09ICcnO1xuXG4gIC8vIHN0cmlwIHNpbmdsZSBkb3RzLCByZXNvbHZlIGRvdWJsZSBkb3RzIHRvIHBhcmVudCBkaXJcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHNyY1BhdGgubGVuZ3RoOyBpID49IDA7IGktLSkge1xuICAgIGxhc3QgPSBzcmNQYXRoW2ldO1xuICAgIGlmIChsYXN0ID09PSAnLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09ICcuLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3BsaWNlT25lKHNyY1BhdGgsIGkpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGF0aCBpcyBhbGxvd2VkIHRvIGdvIGFib3ZlIHRoZSByb290LCByZXN0b3JlIGxlYWRpbmcgLi5zXG4gIGlmICghbXVzdEVuZEFicyAmJiAhcmVtb3ZlQWxsRG90cykge1xuICAgIGZvciAoOyB1cC0tOyB1cCkge1xuICAgICAgc3JjUGF0aC51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtdXN0RW5kQWJzICYmIHNyY1BhdGhbMF0gIT09ICcnICYmICghc3JjUGF0aFswXSB8fCBzcmNQYXRoWzBdLmNoYXJBdCgwKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoaGFzVHJhaWxpbmdTbGFzaCAmJiBzcmNQYXRoLmpvaW4oJy8nKS5zdWJzdHIoLTEpICE9PSAnLycpIHtcbiAgICBzcmNQYXRoLnB1c2goJycpO1xuICB9XG5cbiAgdmFyIGlzQWJzb2x1dGUgPSBzcmNQYXRoWzBdID09PSAnJyB8fCAoc3JjUGF0aFswXSAmJiBzcmNQYXRoWzBdLmNoYXJBdCgwKSA9PT0gJy8nKTtcblxuICAvLyBwdXQgdGhlIGhvc3QgYmFja1xuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5sZW5ndGggPyBzcmNQYXRoLnNoaWZ0KCkgOiAnJztcbiAgICB9XG4gICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAvL3RoaXMgZXNwZWNpYWxseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAvL3VybC5yZXNvbHZlT2JqZWN0KCdtYWlsdG86bG9jYWwxQGRvbWFpbjEnLCAnbG9jYWwyQGRvbWFpbjInKVxuICAgIGNvbnN0IGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgIH1cbiAgfVxuXG4gIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzIHx8IChyZXN1bHQuaG9zdCAmJiBzcmNQYXRoLmxlbmd0aCk7XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgIWlzQWJzb2x1dGUpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IHNyY1BhdGguam9pbignLycpO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgKyAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2VIb3N0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaG9zdCA9IHRoaXMuaG9zdDtcbiAgdmFyIHBvcnQgPSBwb3J0UGF0dGVybi5leGVjKGhvc3QpO1xuICBpZiAocG9ydCkge1xuICAgIHBvcnQgPSBwb3J0WzBdO1xuICAgIGlmIChwb3J0ICE9PSAnOicpIHtcbiAgICAgIHRoaXMucG9ydCA9IHBvcnQuc2xpY2UoMSk7XG4gICAgfVxuICAgIGhvc3QgPSBob3N0LnNsaWNlKDAsIGhvc3QubGVuZ3RoIC0gcG9ydC5sZW5ndGgpO1xuICB9XG4gIGlmIChob3N0KSB0aGlzLmhvc3RuYW1lID0gaG9zdDtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICh2YXIgaSA9IGluZGV4LCBrID0gaSArIDEsIG4gPSBsaXN0Lmxlbmd0aDsgayA8IG47IGkgKz0gMSwgayArPSAxKSBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxudmFyIGhleFRhYmxlID0gbmV3IEFycmF5KDI1Nik7XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKVxuICBoZXhUYWJsZVtpXSA9ICclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCk7XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gZW5jb2RlQXV0aChzdHIpIHtcbiAgLy8gZmFzdGVyIGVuY29kZVVSSUNvbXBvbmVudCBhbHRlcm5hdGl2ZSBmb3IgZW5jb2RpbmcgYXV0aCB1cmkgY29tcG9uZW50c1xuICB2YXIgb3V0ID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gVGhlc2UgY2hhcmFjdGVycyBkbyBub3QgbmVlZCBlc2NhcGluZzpcbiAgICAvLyAhIC0gLiBfIH5cbiAgICAvLyAnICggKSAqIDpcbiAgICAvLyBkaWdpdHNcbiAgICAvLyBhbHBoYSAodXBwZXJjYXNlKVxuICAgIC8vIGFscGhhIChsb3dlcmNhc2UpXG4gICAgaWYgKFxuICAgICAgYyA9PT0gMHgyMSB8fFxuICAgICAgYyA9PT0gMHgyZCB8fFxuICAgICAgYyA9PT0gMHgyZSB8fFxuICAgICAgYyA9PT0gMHg1ZiB8fFxuICAgICAgYyA9PT0gMHg3ZSB8fFxuICAgICAgKGMgPj0gMHgyNyAmJiBjIDw9IDB4MmEpIHx8XG4gICAgICAoYyA+PSAweDMwICYmIGMgPD0gMHgzYSkgfHxcbiAgICAgIChjID49IDB4NDEgJiYgYyA8PSAweDVhKSB8fFxuICAgICAgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N2EpXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBvdXQgKz0gc3RyLnNsaWNlKGxhc3RQb3MsIGkpO1xuXG4gICAgbGFzdFBvcyA9IGkgKyAxO1xuXG4gICAgLy8gT3RoZXIgQVNDSUkgY2hhcmFjdGVyc1xuICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgb3V0ICs9IGhleFRhYmxlW2NdO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gTXVsdGktYnl0ZSBjaGFyYWN0ZXJzIC4uLlxuICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgIG91dCArPSBoZXhUYWJsZVsweGMwIHwgKGMgPj4gNildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChjIDwgMHhkODAwIHx8IGMgPj0gMHhlMDAwKSB7XG4gICAgICBvdXQgKz1cbiAgICAgICAgaGV4VGFibGVbMHhlMCB8IChjID4+IDEyKV0gK1xuICAgICAgICBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzZildICtcbiAgICAgICAgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIC8vIFN1cnJvZ2F0ZSBwYWlyXG4gICAgKytpO1xuICAgIHZhciBjMjtcbiAgICBpZiAoaSA8IHN0ci5sZW5ndGgpIGMyID0gc3RyLmNoYXJDb2RlQXQoaSkgJiAweDNmZjtcbiAgICBlbHNlIGMyID0gMDtcbiAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNmZikgPDwgMTApIHwgYzIpO1xuICAgIG91dCArPVxuICAgICAgaGV4VGFibGVbMHhmMCB8IChjID4+IDE4KV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNmKV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M2YpXSArXG4gICAgICBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNmKV07XG4gIH1cbiAgaWYgKGxhc3RQb3MgPT09IDApIHJldHVybiBzdHI7XG4gIGlmIChsYXN0UG9zIDwgc3RyLmxlbmd0aCkgcmV0dXJuIG91dCArIHN0ci5zbGljZShsYXN0UG9zKTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ== \ No newline at end of file From e84958da268d1ab1fd3eef8eed127d8885efcfcb Mon Sep 17 00:00:00 2001 From: Snyk bot Date: Thu, 29 Oct 2020 23:48:41 +0200 Subject: [PATCH 02/17] fix: upgrade pg-promise from 10.6.2 to 10.7.0 (#6979) Snyk has created this PR to upgrade pg-promise from 10.6.2 to 10.7.0. See this package in npm: https://www.npmjs.com/package/pg-promise See this project in Snyk: https://app.snyk.io/org/acinader/project/8c1a9edb-c8f5-4dc1-b221-4d6030a323eb?utm_source=github&utm_medium=upgrade-pr --- package-lock.json | 73 +++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 268921f28a..1474c21d7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10448,25 +10448,17 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pg": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.3.3.tgz", - "integrity": "sha512-wmUyoQM/Xzmo62wgOdQAn5tl7u+IA1ZYK7qbuppi+3E+Gj4hlUxVHjInulieWrd0SfHi/ADriTb5ILJ/lsJrSg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.4.0.tgz", + "integrity": "sha512-01LcNrAf+mBI46c78mE86I5o5KkOM942lLiSBdiCfgHTR+oUNIjh1fKClWeoPNHJz2oXe/VUSqtk1vwAQYwWEg==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.3.0", + "pg-connection-string": "^2.4.0", "pg-pool": "^3.2.1", - "pg-protocol": "^1.2.5", + "pg-protocol": "^1.3.0", "pg-types": "^2.1.0", - "pgpass": "1.x", - "semver": "4.3.2" - }, - "dependencies": { - "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" - } + "pgpass": "1.x" } }, "pg-connection-string": { @@ -10485,17 +10477,17 @@ "integrity": "sha512-ujanxJJB9CSDUvlAOshtjdKAywOPR2vY0a7D+vvgk5rbrYcthZA7TjpN+Z+UwZsz/G/bUexYDT6huE33vYVN0g==" }, "pg-pool": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", - "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", + "integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==" }, "pg-promise": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.6.2.tgz", - "integrity": "sha512-MrS7JatbX3cBsL5hjojkdcUggV+514Owkx+LJfrKS2STAt1MAQAGmBLDQVglrKmFA5Yus8ZKPKsQaXEJcU5MdA==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.7.0.tgz", + "integrity": "sha512-jQui6HvPUpvnFGDo8hxJ1/4KamqRGjYan7+QApp+dA7hOv5GIJP+IRZayYqsX6+ktHqUFqxvn3se+Bd4WW/vmw==", "requires": { "assert-options": "0.6.2", - "pg": "8.3.3", + "pg": "8.4.0", "pg-minify": "1.6.1", "spex": "3.0.2" } @@ -10518,11 +10510,11 @@ } }, "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", "requires": { - "split": "^1.0.0" + "split2": "^3.1.1" } }, "picomatch": { @@ -11626,14 +11618,6 @@ "resolved": "https://registry.npmjs.org/spex/-/spex-3.0.2.tgz", "integrity": "sha512-ZNCrOso+oNv5P01HCO4wuxV9Og5rS6ms7gGAqugfBPjx1QwfNXJI3T02ldfaap1O0dlT1sB0Rk+mhDqxt3Z27w==" }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -11644,6 +11628,26 @@ "extend-shallow": "^3.0.0" } }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -12037,7 +12041,8 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true }, "through2": { "version": "0.6.5", diff --git a/package.json b/package.json index f5a9b4b6fa..36a4e57ff0 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "mime": "2.4.6", "mongodb": "3.6.2", "parse": "2.17.0", - "pg-promise": "10.6.2", + "pg-promise": "10.7.0", "pluralize": "8.0.0", "redis": "3.0.2", "semver": "7.3.2", From 7ecf264a3e4fed7914bd4003d6564e768f0a76a8 Mon Sep 17 00:00:00 2001 From: Vitaly Tomilov Date: Fri, 30 Oct 2020 15:58:53 +0000 Subject: [PATCH 03/17] Update PostgresStorageAdapter.js (#6981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update PostgresStorageAdapter.js Start moving toward better, ES7 syntax. * Update PostgresStorageAdapter.js Fixing spaces 🤦‍♂️ --- .../Postgres/PostgresStorageAdapter.js | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 3ca9cd43f9..ada6c51ace 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -2463,20 +2463,19 @@ export class PostgresStorageAdapter implements StorageAdapter { }); return Promise.all(promises) .then(() => { - return this._client.tx('perform-initialization', t => { - return t.batch([ - t.none(sql.misc.jsonObjectSetKeys), - t.none(sql.array.add), - t.none(sql.array.addUnique), - t.none(sql.array.remove), - t.none(sql.array.containsAll), - t.none(sql.array.containsAllRegex), - t.none(sql.array.contains), - ]); + return this._client.tx('perform-initialization', async t => { + await t.none(sql.misc.jsonObjectSetKeys); + await t.none(sql.array.add); + await t.none(sql.array.addUnique); + await t.none(sql.array.remove); + await t.none(sql.array.containsAll); + await t.none(sql.array.containsAllRegex); + await t.none(sql.array.contains); + return t.ctx; }); }) - .then(data => { - debug(`initializationDone in ${data.duration}`); + .then(ctx => { + debug(`initializationDone in ${ctx.duration}`); }) .catch(error => { /* eslint-disable no-console */ From 27d82dcdf8ca32f9b3981dfa9cdc8801699aa436 Mon Sep 17 00:00:00 2001 From: Antonio Davi Macedo Coelho de Castro Date: Mon, 2 Nov 2020 08:01:26 -0800 Subject: [PATCH 04/17] Release 4.4.0 (#6985) --- CHANGELOG.md | 36 +++++++++++++++++++++++++++++++++++- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4abc5f613..9882230ba1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,42 @@ ## Parse Server Changelog ### master -[Full Changelog](https://github.com/parse-community/parse-server/compare/4.3.0...master) +[Full Changelog](https://github.com/parse-community/parse-server/compare/4.4.0...master) + +### 4.4.0 +[Full Changelog](https://github.com/parse-community/parse-server/compare/4.3.0...4.4.0) +- IMPROVE: Update PostgresStorageAdapter.js. [#6981](https://github.com/parse-community/parse-server/pull/6981). Thanks to [Vitaly Tomilov](https://github.com/vitaly-t) +- NEW: skipWithMasterKey on Built-In Validator. [#6972](https://github.com/parse-community/parse-server/issues/6972). Thanks to [dblythy](https://github.com/dblythy). +- NEW: Add fileKey rotation to GridFSBucketAdapter. [#6768](https://github.com/parse-community/parse-server/pull/6768). Thanks to [Corey Baker](https://github.com/cbaker6). +- IMPROVE: Remove unused parameter in Cloud Function. [#6969](https://github.com/parse-community/parse-server/issues/6969). Thanks to [Diamond Lewis](https://github.com/dplewis). +- IMPROVE: Validation Handler Update. [#6968](https://github.com/parse-community/parse-server/issues/6968). Thanks to [dblythy](https://github.com/dblythy). +- FIX: (directAccess): Properly handle response status. [#6966](https://github.com/parse-community/parse-server/issues/6966). Thanks to [Diamond Lewis](https://github.com/dplewis). +- FIX: Remove hostnameMaxLen for Mongo URL. [#6693](https://github.com/parse-community/parse-server/issues/6693). Thanks to [markhoward02](https://github.com/markhoward02). +- IMPROVE: Show a message if cloud functions are duplicated. [#6963](https://github.com/parse-community/parse-server/issues/6963). Thanks to [dblythy](https://github.com/dblythy). +- FIX: Pass request.query to afterFind. [#6960](https://github.com/parse-community/parse-server/issues/6960). Thanks to [dblythy](https://github.com/dblythy). +- SECURITY FIX: Patch session vulnerability over Live Query. See [GHSA-2xm2-xj2q-qgpj](https://github.com/parse-community/parse-server/security/advisories/GHSA-2xm2-xj2q-qgpj) for more details about the vulnerability and [78b59fb](https://github.com/parse-community/parse-server/commit/78b59fb26b1c36e3cdbd42ba9fec025003267f58) for the fix. Thanks to [Antonio Davi Macedo Coelho de Castro](https://github.com/davimacedo). +- IMPROVE: LiveQueryEvent Error Logging Improvements. [#6951](https://github.com/parse-community/parse-server/issues/6951). Thanks to [dblythy](https://github.com/dblythy). +- IMPROVE: Include stack in Cloud Code. [#6958](https://github.com/parse-community/parse-server/issues/6958). Thanks to [dblythy](https://github.com/dblythy). +- FIX: (jobs): Add Error Message to JobStatus Failure. [#6954](https://github.com/parse-community/parse-server/issues/6954). Thanks to [Diamond Lewis](https://github.com/dplewis). +- NEW: Create Cloud function afterLiveQueryEvent. [#6859](https://github.com/parse-community/parse-server/issues/6859). Thanks to [dblythy](https://github.com/dblythy). +- FIX: Update vkontakte API to the latest version. [#6944](https://github.com/parse-community/parse-server/issues/6944). Thanks to [Antonio Davi Macedo Coelho de Castro](https://github.com/davimacedo). +- FIX: Use an empty object as default value of options for Google Sign in. [#6844](https://github.com/parse-community/parse-server/issues/6844). Thanks to [Kevin Kuang](https://github.com/kvnkuang). +- FIX: Postgres: prepend className to unique indexes. [#6741](https://github.com/parse-community/parse-server/pull/6741). Thanks to [Corey Baker](https://github.com/cbaker6). +- FIX: GraphQL: Transform input types also on user mutations. [#6934](https://github.com/parse-community/parse-server/pull/6934). Thanks to [Antoine Cormouls](https://github.com/Moumouls). +- FIX: Set objectId into query for Email Validation. [#6930](https://github.com/parse-community/parse-server/pull/6930). Thanks to [Danaru](https://github.com/Danaru87). +- FIX: GraphQL: Optimize queries, fixes some null returns (on object), fix stitched GraphQLUpload. [#6709](https://github.com/parse-community/parse-server/pull/6709). Thanks to [Antoine Cormouls](https://github.com/Moumouls). +- FIX: Do not throw error if user provide a pointer like index onMongo. [#6923](https://github.com/parse-community/parse-server/pull/6923). Thanks to [Antoine Cormouls](https://github.com/Moumouls). +- FIX: Hotfix instagram api. [#6922](https://github.com/parse-community/parse-server/issues/6922). Thanks to [Tim](https://github.com/timination). +- FIX: (directAccess/cloud-code): Pass installationId with LogIn. [#6903](https://github.com/parse-community/parse-server/issues/6903). Thanks to [Diamond Lewis](https://github.com/dplewis). +- FIX: Fix bcrypt binary incompatibility. [#6891](https://github.com/parse-community/parse-server/issues/6891). Thanks to [Manuel Trezza](https://github.com/mtrezza). +- NEW: Keycloak auth adapter. [#6376](https://github.com/parse-community/parse-server/issues/6376). Thanks to [Rhuan](https://github.com/rhuanbarreto). +- IMPROVE: Changed incorrect key name in apple auth adapter tests. [#6861](https://github.com/parse-community/parse-server/issues/6861). Thanks to [Manuel Trezza](https://github.com/mtrezza). +- FIX: Fix mutating beforeSubscribe Query. [#6868](https://github.com/parse-community/parse-server/issues/6868). Thanks to [dblythy](https://github.com/dblythy). +- FIX: Fix beforeLogin for users logging in with AuthData. [#6872](https://github.com/parse-community/parse-server/issues/6872). Thanks to [Kevin Kuang](https://github.com/kvnkuang). +- FIX: Remove Facebook AccountKit auth. [#6870](https://github.com/parse-community/parse-server/issues/6870). Thanks to [Diamond Lewis](https://github.com/dplewis). +- FIX: Updated TOKEN_ISSUER to 'accounts.google.com'. [#6836](https://github.com/parse-community/parse-server/issues/6836). Thanks to [Arjun Vedak](https://github.com/arjun3396). - IMPROVE: Optimized deletion of class field from schema by using an index if available to do an index scan instead of a collection scan. [#6815](https://github.com/parse-community/parse-server/issues/6815). Thanks to [Manuel Trezza](https://github.com/mtrezza). +- IMPROVE: Enable MongoDB transaction test for MongoDB >= 4.0.4 [#6827](https://github.com/parse-community/parse-server/pull/6827). Thanks to [Manuel](https://github.com/mtrezza). ### 4.3.0 [Full Changelog](https://github.com/parse-community/parse-server/compare/4.2.0...4.3.0) diff --git a/package-lock.json b/package-lock.json index 1474c21d7e..ef031dace3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "4.3.0", + "version": "4.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 36a4e57ff0..f41d8c4ac7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "4.3.0", + "version": "4.4.0", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From b8b8c054dd86ec6f921760bbf217001f3b71a267 Mon Sep 17 00:00:00 2001 From: Vitaly Tomilov Date: Tue, 3 Nov 2020 16:01:04 +0000 Subject: [PATCH 05/17] Update PostgresStorageAdapter.js (#6989) * Update PostgresStorageAdapter.js Improve `createClass` transaction: * `await` makes it a more consistent sequence of queries * `batch` is not needed there * No need for an extra `.then` section * Update PostgresStorageAdapter.js Remove batch-dependent error code check, as it should happen automatically without batch result. * Update PostgresStorageAdapter.js Removing unused variable. --- .../Storage/Postgres/PostgresStorageAdapter.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index ada6c51ace..aa2ddf3f40 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -12,7 +12,6 @@ const PostgresDuplicateColumnError = '42701'; const PostgresMissingColumnError = '42703'; const PostgresDuplicateObjectError = '42710'; const PostgresUniqueIndexViolationError = '23505'; -const PostgresTransactionAbortedError = '25P02'; const logger = require('../../../logger'); const debug = function (...args: any) { @@ -986,29 +985,21 @@ export class PostgresStorageAdapter implements StorageAdapter { conn = conn || this._client; return conn .tx('create-class', async t => { - const q1 = this.createTable(className, schema, t); - const q2 = t.none( + await this.createTable(className, schema, t); + await t.none( 'INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($, $, true)', { className, schema } ); - const q3 = this.setIndexesWithSchemaFormat( + await this.setIndexesWithSchemaFormat( className, schema.indexes, {}, schema.fields, t ); - // TODO: The test should not verify the returned value, and then - // the method can be simplified, to avoid returning useless stuff. - return t.batch([q1, q2, q3]); - }) - .then(() => { return toParseSchema(schema); }) .catch(err => { - if (err.data[0].result.code === PostgresTransactionAbortedError) { - err = err.data[1].result; - } if ( err.code === PostgresUniqueIndexViolationError && err.detail.includes(className) From ee32837595fe32b6a92cc9e1bad3934023d79805 Mon Sep 17 00:00:00 2001 From: Laode Muhammad Al Fatih Date: Wed, 4 Nov 2020 06:57:58 +0700 Subject: [PATCH 06/17] Add `cloud` parameter to Docker command (#6988) (#6990) * Add `cloud` parameter to Docker command (#6988) * Add note to run Image with Cloud Code feature. --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99181820bf..bf701ad41a 100644 --- a/README.md +++ b/README.md @@ -92,14 +92,22 @@ $ parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongo ### Inside a Docker container + ```bash $ git clone https://github.com/parse-community/parse-server $ cd parse-server $ docker build --tag parse-server . $ docker run --name my-mongo -d mongo -$ docker run --name my-parse-server -v cloud-code-vol:/parse-server/cloud -v config-vol:/parse-server/config -p 1337:1337 --link my-mongo:mongo -d parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://mongo/test ``` +#### Running the Parse Server Image + +```bash +$ docker run --name my-parse-server -v config-vol:/parse-server/config -p 1337:1337 --link my-mongo:mongo -d parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://mongo/test +``` + +***Note:*** *If you want to use [Cloud Code](https://docs.parseplatform.org/cloudcode/guide/) feature, please add `-v cloud-code-vol:/parse-server/cloud --cloud /parse-server/cloud/main.js` to command above. Make sure the `main.js` file is available in the `cloud-code-vol` directory before run this command. Otherwise, an error will occur.* + You can use any arbitrary string as your application id and master key. These will be used by your clients to authenticate with the Parse Server. That's it! You are now running a standalone version of Parse Server on your machine. @@ -472,9 +480,16 @@ $ git clone https://github.com/parse-community/parse-server $ cd parse-server $ docker build --tag parse-server . $ docker run --name my-mongo -d mongo -$ docker run --name my-parse-server --link my-mongo:mongo -v cloud-code-vol:/parse-server/cloud -v config-vol:/parse-server/config -p 1337:1337 -d parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://mongo/test --publicServerURL http://localhost:1337/parse --mountGraphQL --mountPlayground ``` +#### Running the Parse Server Image + +```bash +$ docker run --name my-parse-server --link my-mongo:mongo -v config-vol:/parse-server/config -p 1337:1337 -d parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://mongo/test --publicServerURL http://localhost:1337/parse --mountGraphQL --mountPlayground +``` + +***Note:*** *If you want to use [Cloud Code](https://docs.parseplatform.org/cloudcode/guide/) feature, please add `-v cloud-code-vol:/parse-server/cloud --cloud /parse-server/cloud/main.js` to command above. Make sure the `main.js` file is available in the `cloud-code-vol` directory before run this command. Otherwise, an error will occur.* + After starting the server, you can visit http://localhost:1337/playground in your browser to start playing with your GraphQL API. ***Note:*** Do ***NOT*** use --mountPlayground option in production. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and it is the recommended option for production apps. From 84c64d05f5cdde53fe5efc6eb307d248830b9fba Mon Sep 17 00:00:00 2001 From: Gunnar Oledal Date: Thu, 5 Nov 2020 17:55:42 +0100 Subject: [PATCH 07/17] Absolute path is no longer required for cloud code (#6993) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf701ad41a..b500230c13 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ var app = express(); var api = new ParseServer({ databaseURI: 'mongodb://localhost:27017/dev', // Connection string for your MongoDB database - cloud: '/home/myApp/cloud/main.js', // Absolute path to your Cloud Code + cloud: './cloud/main.js', // Path to your Cloud Code appId: 'myAppId', masterKey: 'myMasterKey', // Keep this key secret! fileKey: 'optionalFileKey', From 8b0c5de12e8fcc9c8d302c8da3f1fb6f2b0ef206 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 8 Nov 2020 23:41:58 +1100 Subject: [PATCH 08/17] Initial --- README.md | 14 ++++-- spec/ParseFile.spec.js | 99 ++++++++++++++++++++++++++++++++++++++ spec/helper.js | 3 ++ src/Options/Definitions.js | 5 ++ src/Routers/FilesRouter.js | 21 ++++++++ 5 files changed, 138 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b500230c13..85660e9416 100644 --- a/README.md +++ b/README.md @@ -208,16 +208,20 @@ We have provided a basic [Node.js application](https://github.com/parse-communit You can also create an instance of Parse Server, and mount it on a new or existing Express website: ```js -var express = require('express'); -var ParseServer = require('parse-server').ParseServer; -var app = express(); +const express = require('express'); +const ParseServer = require('parse-server').ParseServer; +const app = express(); -var api = new ParseServer({ +const api = new ParseServer({ databaseURI: 'mongodb://localhost:27017/dev', // Connection string for your MongoDB database cloud: './cloud/main.js', // Path to your Cloud Code appId: 'myAppId', masterKey: 'myMasterKey', // Keep this key secret! fileKey: 'optionalFileKey', + fileUpload: { + enabled:true, + enabledForPublic: false + }, serverURL: 'http://localhost:1337/parse' // Don't forget to change to https if needed }); @@ -396,6 +400,8 @@ Parse Server allows developers to choose from several options when hosting files `GridFSBucketAdapter` is used by default and requires no setup, but if you're interested in using S3 or Google Cloud Storage, additional configuration information is available in the [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/#configuring-file-adapters). +Make sure you enable file upload in your server configuration if you'd like to save files. + ### Idempodency Enforcement **Caution, this is an experimental feature that may not be appropriate for production.** diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js index 410d15c81b..68198150fb 100644 --- a/spec/ParseFile.spec.js +++ b/spec/ParseFile.spec.js @@ -860,4 +860,103 @@ describe('Parse.File testing', () => { }); }); }); + + describe('reject no file uploads', () => { + it('can reject file upload with unspecified', async () => { + await reconfigureServer({ + fileUpload: {}, + }); + try { + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save(); + fail('should not have been able to save file.'); + } catch (e) { + expect(e.code).toBe(130); + expect(e.message).toBe('File upload is not enabled.'); + } + }); + it('disable file upload', async () => { + await reconfigureServer({ + fileUpload: { + enabled: false, + }, + }); + try { + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save(); + fail('should not have been able to save file.'); + } catch (e) { + expect(e.code).toBe(130); + expect(e.message).toBe('File upload is not enabled.'); + } + }); + it('disable for public', async () => { + await reconfigureServer({ + fileUpload: { + enabled: true, + enabledForPublic: false, + }, + }); + try { + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save(); + fail('should not have been able to save file.'); + } catch (e) { + expect(e.code).toBe(130); + expect(e.message).toBe('Public file upload is not enabled.'); + } + }); + + it('disable for public allow user', async () => { + await reconfigureServer({ + fileUpload: { + enabled: true, + enabledForPublic: false, + }, + }); + try { + const user = await Parse.User.signUp('myUser', 'password'); + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save({ sessionToken: user.getSessionToken() }); + } catch (e) { + fail('should have allowed file to save.'); + } + }); + + it('disable for anonymous', async () => { + await reconfigureServer({ + fileUpload: { + enabled: true, + enabledForPublic: false, + enabledForAnonymousUser: false, + }, + }); + try { + const user = await Parse.AnonymousUtils.logIn(); + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save({ sessionToken: user.getSessionToken() }); + fail('should not have been able to save file.'); + } catch (e) { + expect(e.code).toBe(130); + expect(e.message).toBe('Anonymous file upload is not enabled.'); + } + }); + + it('enable for anonymous', async () => { + await reconfigureServer({ + fileUpload: { + enabled: true, + enabledForPublic: false, + enabledForAnonymousUser: true, + }, + }); + try { + const user = await Parse.AnonymousUtils.logIn(); + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save({ sessionToken: user.getSessionToken() }); + } catch (e) { + fail('should have allowed file to save.'); + } + }); + }); }); diff --git a/spec/helper.js b/spec/helper.js index a7f6cf2280..a608dae8a3 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -88,6 +88,9 @@ const defaultConfiguration = { fileKey: 'test', silent, logLevel, + fileUpload: { + enabled: true, + }, push: { android: { senderId: 'yolo', diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index c3c1271786..24982a6ac3 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -168,6 +168,11 @@ module.exports.ParseServerOptions = { help: 'Adapter module for the files sub-system', action: parsers.moduleOrObjectParser, }, + fileUpload: { + env: 'PARSE_SERVER_FILE_UPLOAD', + help: 'Configuration for file uploads', + default: {}, + }, graphQLPath: { env: 'PARSE_SERVER_GRAPHQL_PATH', help: 'Mount path for the GraphQL endpoint, defaults to /graphql', diff --git a/src/Routers/FilesRouter.js b/src/Routers/FilesRouter.js index 2b0140fe7d..13779a7875 100644 --- a/src/Routers/FilesRouter.js +++ b/src/Routers/FilesRouter.js @@ -94,6 +94,27 @@ export class FilesRouter { async createHandler(req, res, next) { const config = req.config; + if (!req.config.fileUpload.enabled) { + next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'File upload is not enabled.')); + return; + } + if ( + !req.config.fileUpload.enabledForAnonymousUser && + req.config.fileUpload.enabledForAnonymousUser != null && + req.auth.user && + Parse.AnonymousUtils.isLinked(req.auth.user) + ) { + next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Anonymous file upload is not enabled.')); + return; + } + if ( + !req.config.fileUpload.enabledForPublic && + req.config.fileUpload.enabledForPublic != null && + !req.auth.user + ) { + next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Public file upload is not enabled.')); + return; + } const filesController = config.filesController; const { filename } = req.params; const contentType = req.get('Content-type'); From cb8c268c83b79054fa87d3ceb7c125a8b0a72448 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 8 Nov 2020 23:48:18 +1100 Subject: [PATCH 09/17] Default to reject public --- spec/helper.js | 1 + src/Routers/FilesRouter.js | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index a608dae8a3..715fe5f9d2 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -90,6 +90,7 @@ const defaultConfiguration = { logLevel, fileUpload: { enabled: true, + enabledForPublic: true, }, push: { android: { diff --git a/src/Routers/FilesRouter.js b/src/Routers/FilesRouter.js index 13779a7875..f01898dcdd 100644 --- a/src/Routers/FilesRouter.js +++ b/src/Routers/FilesRouter.js @@ -107,11 +107,7 @@ export class FilesRouter { next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Anonymous file upload is not enabled.')); return; } - if ( - !req.config.fileUpload.enabledForPublic && - req.config.fileUpload.enabledForPublic != null && - !req.auth.user - ) { + if (!req.config.fileUpload.enabledForPublic && !req.auth.user) { next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Public file upload is not enabled.')); return; } From 3608790b56ae0a77c870f022dda3a297d4245cf9 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 8 Nov 2020 23:53:11 +1100 Subject: [PATCH 10/17] Allow by default --- spec/ParseFile.spec.js | 2 +- spec/helper.js | 1 - src/Routers/FilesRouter.js | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js index 68198150fb..69dcae55ab 100644 --- a/spec/ParseFile.spec.js +++ b/spec/ParseFile.spec.js @@ -872,7 +872,7 @@ describe('Parse.File testing', () => { fail('should not have been able to save file.'); } catch (e) { expect(e.code).toBe(130); - expect(e.message).toBe('File upload is not enabled.'); + expect(e.message).toBe('Public file upload is not enabled.'); } }); it('disable file upload', async () => { diff --git a/spec/helper.js b/spec/helper.js index 715fe5f9d2..385b0aa51b 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -89,7 +89,6 @@ const defaultConfiguration = { silent, logLevel, fileUpload: { - enabled: true, enabledForPublic: true, }, push: { diff --git a/src/Routers/FilesRouter.js b/src/Routers/FilesRouter.js index f01898dcdd..b2f25f8cd5 100644 --- a/src/Routers/FilesRouter.js +++ b/src/Routers/FilesRouter.js @@ -94,13 +94,12 @@ export class FilesRouter { async createHandler(req, res, next) { const config = req.config; - if (!req.config.fileUpload.enabled) { + if (!req.config.fileUpload.enabled && req.config.fileUpload.enabled != null) { next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'File upload is not enabled.')); return; } if ( !req.config.fileUpload.enabledForAnonymousUser && - req.config.fileUpload.enabledForAnonymousUser != null && req.auth.user && Parse.AnonymousUtils.isLinked(req.auth.user) ) { From fa0cede0d9861be1d375f8b0325a5f4cb452a0e4 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 8 Nov 2020 23:55:23 +1100 Subject: [PATCH 11/17] Undo --- README.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 85660e9416..b500230c13 100644 --- a/README.md +++ b/README.md @@ -208,20 +208,16 @@ We have provided a basic [Node.js application](https://github.com/parse-communit You can also create an instance of Parse Server, and mount it on a new or existing Express website: ```js -const express = require('express'); -const ParseServer = require('parse-server').ParseServer; -const app = express(); +var express = require('express'); +var ParseServer = require('parse-server').ParseServer; +var app = express(); -const api = new ParseServer({ +var api = new ParseServer({ databaseURI: 'mongodb://localhost:27017/dev', // Connection string for your MongoDB database cloud: './cloud/main.js', // Path to your Cloud Code appId: 'myAppId', masterKey: 'myMasterKey', // Keep this key secret! fileKey: 'optionalFileKey', - fileUpload: { - enabled:true, - enabledForPublic: false - }, serverURL: 'http://localhost:1337/parse' // Don't forget to change to https if needed }); @@ -400,8 +396,6 @@ Parse Server allows developers to choose from several options when hosting files `GridFSBucketAdapter` is used by default and requires no setup, but if you're interested in using S3 or Google Cloud Storage, additional configuration information is available in the [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/#configuring-file-adapters). -Make sure you enable file upload in your server configuration if you'd like to save files. - ### Idempodency Enforcement **Caution, this is an experimental feature that may not be appropriate for production.** From 888db3b8d6f8796b301655da7b415cd1f69adb96 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 9 Nov 2020 10:39:17 +1100 Subject: [PATCH 12/17] Update Definitions --- resources/buildConfigDefinitions.js | 5 ++++- spec/ParseFile.spec.js | 2 +- src/Options/Definitions.js | 30 +++++++++++++++++++++++------ src/Options/docs.js | 8 ++++++++ src/Options/index.js | 15 +++++++++++++++ 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index a640e1c3c7..59ac161516 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -55,6 +55,9 @@ function getENVPrefix(iface) { if (iface.id.name === 'IdempotencyOptions') { return 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_'; } + if (iface.id.name === 'FileUploadOptions') { + return 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_'; + } } function processProperty(property, iface) { @@ -173,7 +176,7 @@ function parseDefaultValue(elt, value, t) { }); literalValue = t.objectExpression(props); } - if (type == 'IdempotencyOptions') { + if (type == 'IdempotencyOptions' || type == 'FileUploadOptions') { const object = parsers.objectParser(value); const props = Object.keys(object).map((key) => { return t.objectProperty(key, object[value]); diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js index 69dcae55ab..19903bddf9 100644 --- a/spec/ParseFile.spec.js +++ b/spec/ParseFile.spec.js @@ -861,7 +861,7 @@ describe('Parse.File testing', () => { }); }); - describe('reject no file uploads', () => { + describe('file upload restrictions', () => { it('can reject file upload with unspecified', async () => { await reconfigureServer({ fileUpload: {}, diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 24982a6ac3..f8480ae70f 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -149,10 +149,6 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: false, }, - encryptionKey: { - env: 'PARSE_SERVER_ENCRYPTION_KEY', - help: 'Key for encrypting your files', - }, expireInactiveSessions: { env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', help: 'Sets wether we should expire the inactive sessions, defaults to true', @@ -169,8 +165,9 @@ module.exports.ParseServerOptions = { action: parsers.moduleOrObjectParser, }, fileUpload: { - env: 'PARSE_SERVER_FILE_UPLOAD', - help: 'Configuration for file uploads', + env: 'PARSE_SERVER_FILE_UPLOAD_OPTIONS', + help: 'Options for file uploads', + action: parsers.objectParser, default: {}, }, graphQLPath: { @@ -550,3 +547,24 @@ module.exports.IdempotencyOptions = { default: 300, }, }; +module.exports.FileUploadOptions = { + enabled: { + env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED', + help: 'Files can be uploaded with Parse Server.', + action: parsers.booleanParser, + default: true, + }, + enabledForAnonymousUser: { + env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_ANONYMOUS_USER', + help: 'File upload is enabled for Anonymous Users.', + action: parsers.booleanParser, + default: false, + }, + enabledForPublic: { + env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_PUBLIC', + help: + 'File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication.', + action: parsers.booleanParser, + default: false, + }, +}; diff --git a/src/Options/docs.js b/src/Options/docs.js index febe3d77cc..a020b64965 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -30,6 +30,7 @@ * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true * @property {String} fileKey Key for your files * @property {Adapter} filesAdapter Adapter module for the files sub-system + * @property {FileUploadOptions} fileUpload Options for file uploads * @property {String} graphQLPath Mount path for the GraphQL endpoint, defaults to /graphql * @property {String} graphQLSchema Full path to your GraphQL custom schema.graphql file * @property {String} host The host to serve ParseServer on, defaults to 0.0.0.0 @@ -118,3 +119,10 @@ * @property {String[]} paths An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths. * @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s. */ + +/** + * @interface FileUploadOptions + * @property {Boolean} enabled Files can be uploaded with Parse Server. + * @property {Boolean} enabledForAnonymousUser File upload is enabled for Anonymous Users. + * @property {Boolean} enabledForPublic File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication. + */ diff --git a/src/Options/index.js b/src/Options/index.js index 1283f849a7..e8970d24bf 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -192,6 +192,10 @@ export interface ParseServerOptions { :ENV: PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_OPTIONS :DEFAULT: false */ idempotencyOptions: ?IdempotencyOptions; + /* Options for file uploads + :ENV: PARSE_SERVER_FILE_UPLOAD_OPTIONS + :DEFAULT: false */ + fileUpload: ?FileUploadOptions; /* Full path to your GraphQL custom schema.graphql file */ graphQLSchema: ?string; /* Mounts the GraphQL endpoint @@ -285,3 +289,14 @@ export interface IdempotencyOptions { :DEFAULT: 300 */ ttl: ?number; } +export interface FileUploadOptions { + /* Files can be uploaded with Parse Server. + :DEFAULT: true */ + enabled: ?boolean; + /* File upload is enabled for Anonymous Users. + :DEFAULT: false */ + enabledForAnonymousUser: ?boolean; + /* File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication. + :DEFAULT: false */ + enabledForPublic: ?boolean; +} From 4c19cd80936a16ad7127f05a06e230cd4382a122 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 9 Nov 2020 10:44:58 +1100 Subject: [PATCH 13/17] Restore encryptionKey --- src/Options/Definitions.js | 4 ++++ src/Options/docs.js | 1 + src/Options/index.js | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index f8480ae70f..f621c51f92 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -149,6 +149,10 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: false, }, + encryptionKey: { + env: 'PARSE_SERVER_ENCRYPTION_KEY', + help: 'Key for encrypting your files', + }, expireInactiveSessions: { env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', help: 'Sets wether we should expire the inactive sessions, defaults to true', diff --git a/src/Options/docs.js b/src/Options/docs.js index a020b64965..3b0a4a0c8a 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -27,6 +27,7 @@ * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors * @property {Boolean} enableSingleSchemaCache Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request. + * @property {String} encryptionKey Key for encrypting your files * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true * @property {String} fileKey Key for your files * @property {Adapter} filesAdapter Adapter module for the files sub-system diff --git a/src/Options/index.js b/src/Options/index.js index e8970d24bf..7b4202b128 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -77,6 +77,9 @@ export interface ParseServerOptions { javascriptKey: ?string; /* Key for Unity and .Net SDK */ dotNetKey: ?string; + /* Key for encrypting your files + :ENV: PARSE_SERVER_ENCRYPTION_KEY */ + encryptionKey: ?string; /* Key for REST calls :ENV: PARSE_SERVER_REST_API_KEY */ restAPIKey: ?string; From 77cecb86845600699df5b3896914ecc54ba159db Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 9 Nov 2020 11:36:21 +1100 Subject: [PATCH 14/17] enabledForAuthenticatedUser --- spec/ParseFile.spec.js | 27 +++++++++++++++++++++++++++ src/Options/Definitions.js | 6 ++++++ src/Options/docs.js | 1 + src/Options/index.js | 3 +++ src/Routers/FilesRouter.js | 11 +++++++++++ 5 files changed, 48 insertions(+) diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js index 19903bddf9..6b1260ba49 100644 --- a/spec/ParseFile.spec.js +++ b/spec/ParseFile.spec.js @@ -958,5 +958,32 @@ describe('Parse.File testing', () => { fail('should have allowed file to save.'); } }); + + it('enable for anonymous but not authenticated', async () => { + await reconfigureServer({ + fileUpload: { + enabled: true, + enabledForPublic: false, + enabledForAnonymousUser: true, + enabledForAuthenticatedUser: false, + }, + }); + try { + const user = await Parse.AnonymousUtils.logIn(); + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save({ sessionToken: user.getSessionToken() }); + } catch (e) { + fail('should have allowed file to save.'); + } + try { + const user = await Parse.User.signUp('myUser', 'password'); + const file = new Parse.File('hello.txt', data, 'text/plain'); + await file.save({ sessionToken: user.getSessionToken() }); + fail('should have not allowed file to save.'); + } catch (e) { + expect(e.code).toBe(130); + expect(e.message).toBe('Authenticated file upload is not enabled.'); + } + }); }); }); diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index f621c51f92..ef4373c3d3 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -564,6 +564,12 @@ module.exports.FileUploadOptions = { action: parsers.booleanParser, default: false, }, + enabledForAuthenticatedUser: { + env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_AUTHENTICATED_USER', + help: 'File upload is enabled for authenticated users.', + action: parsers.booleanParser, + default: true, + }, enabledForPublic: { env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_PUBLIC', help: diff --git a/src/Options/docs.js b/src/Options/docs.js index 3b0a4a0c8a..56120b1ebb 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -125,5 +125,6 @@ * @interface FileUploadOptions * @property {Boolean} enabled Files can be uploaded with Parse Server. * @property {Boolean} enabledForAnonymousUser File upload is enabled for Anonymous Users. + * @property {Boolean} enabledForAuthenticatedUser File upload is enabled for authenticated users. * @property {Boolean} enabledForPublic File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication. */ diff --git a/src/Options/index.js b/src/Options/index.js index 7b4202b128..2e8ac614ac 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -302,4 +302,7 @@ export interface FileUploadOptions { /* File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication. :DEFAULT: false */ enabledForPublic: ?boolean; + /* File upload is enabled for authenticated users. + :DEFAULT: true */ + enabledForAuthenticatedUser: ?boolean; } diff --git a/src/Routers/FilesRouter.js b/src/Routers/FilesRouter.js index b2f25f8cd5..1b7b207fb1 100644 --- a/src/Routers/FilesRouter.js +++ b/src/Routers/FilesRouter.js @@ -106,6 +106,17 @@ export class FilesRouter { next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Anonymous file upload is not enabled.')); return; } + if ( + !req.config.fileUpload.enabledForAuthenticatedUser && + req.config.fileUpload.enabledForAuthenticatedUser != null && + req.auth.user && + !Parse.AnonymousUtils.isLinked(req.auth.user) + ) { + next( + new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Authenticated file upload is not enabled.') + ); + return; + } if (!req.config.fileUpload.enabledForPublic && !req.auth.user) { next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Public file upload is not enabled.')); return; From a62ba27678dffb736ccc29a0cf7c649425cf1735 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 9 Nov 2020 17:09:23 +1100 Subject: [PATCH 15/17] Remove double --- resources/buildConfigDefinitions.js | 2 +- src/Options/Definitions.js | 12 ++++-------- src/Options/docs.js | 1 - src/Options/index.js | 3 --- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index 59ac161516..e73070c7db 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -56,7 +56,7 @@ function getENVPrefix(iface) { return 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_'; } if (iface.id.name === 'FileUploadOptions') { - return 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_'; + return 'PARSE_SERVER_FILE_UPLOAD_'; } } diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index ef4373c3d3..2cc773eebd 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -149,10 +149,6 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: false, }, - encryptionKey: { - env: 'PARSE_SERVER_ENCRYPTION_KEY', - help: 'Key for encrypting your files', - }, expireInactiveSessions: { env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', help: 'Sets wether we should expire the inactive sessions, defaults to true', @@ -553,25 +549,25 @@ module.exports.IdempotencyOptions = { }; module.exports.FileUploadOptions = { enabled: { - env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED', + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLED', help: 'Files can be uploaded with Parse Server.', action: parsers.booleanParser, default: true, }, enabledForAnonymousUser: { - env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_ANONYMOUS_USER', + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_ANONYMOUS_USER', help: 'File upload is enabled for Anonymous Users.', action: parsers.booleanParser, default: false, }, enabledForAuthenticatedUser: { - env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_AUTHENTICATED_USER', + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_AUTHENTICATED_USER', help: 'File upload is enabled for authenticated users.', action: parsers.booleanParser, default: true, }, enabledForPublic: { - env: 'PARSE_SERVER_PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_PUBLIC', + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_PUBLIC', help: 'File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication.', action: parsers.booleanParser, diff --git a/src/Options/docs.js b/src/Options/docs.js index 56120b1ebb..cc33b25764 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -27,7 +27,6 @@ * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors * @property {Boolean} enableSingleSchemaCache Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request. - * @property {String} encryptionKey Key for encrypting your files * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true * @property {String} fileKey Key for your files * @property {Adapter} filesAdapter Adapter module for the files sub-system diff --git a/src/Options/index.js b/src/Options/index.js index 2e8ac614ac..3fe305117e 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -77,9 +77,6 @@ export interface ParseServerOptions { javascriptKey: ?string; /* Key for Unity and .Net SDK */ dotNetKey: ?string; - /* Key for encrypting your files - :ENV: PARSE_SERVER_ENCRYPTION_KEY */ - encryptionKey: ?string; /* Key for REST calls :ENV: PARSE_SERVER_REST_API_KEY */ restAPIKey: ?string; From 652d874b70b72894a7a177e7875fb60884afa8bd Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 9 Nov 2020 17:56:01 +1100 Subject: [PATCH 16/17] Remove enabled --- spec/ParseFile.spec.js | 12 ++++-------- src/Options/Definitions.js | 6 ------ src/Options/docs.js | 1 - src/Options/index.js | 3 --- src/Routers/FilesRouter.js | 4 ---- 5 files changed, 4 insertions(+), 22 deletions(-) diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js index 6b1260ba49..bdd84bb36c 100644 --- a/spec/ParseFile.spec.js +++ b/spec/ParseFile.spec.js @@ -878,7 +878,9 @@ describe('Parse.File testing', () => { it('disable file upload', async () => { await reconfigureServer({ fileUpload: { - enabled: false, + enabledForPublic: false, + enabledForAnonymousUser: false, + enabledForAuthenticatedUser: false, }, }); try { @@ -887,13 +889,12 @@ describe('Parse.File testing', () => { fail('should not have been able to save file.'); } catch (e) { expect(e.code).toBe(130); - expect(e.message).toBe('File upload is not enabled.'); + expect(e.message).toBe('Public file upload is not enabled.'); } }); it('disable for public', async () => { await reconfigureServer({ fileUpload: { - enabled: true, enabledForPublic: false, }, }); @@ -910,7 +911,6 @@ describe('Parse.File testing', () => { it('disable for public allow user', async () => { await reconfigureServer({ fileUpload: { - enabled: true, enabledForPublic: false, }, }); @@ -926,8 +926,6 @@ describe('Parse.File testing', () => { it('disable for anonymous', async () => { await reconfigureServer({ fileUpload: { - enabled: true, - enabledForPublic: false, enabledForAnonymousUser: false, }, }); @@ -945,7 +943,6 @@ describe('Parse.File testing', () => { it('enable for anonymous', async () => { await reconfigureServer({ fileUpload: { - enabled: true, enabledForPublic: false, enabledForAnonymousUser: true, }, @@ -962,7 +959,6 @@ describe('Parse.File testing', () => { it('enable for anonymous but not authenticated', async () => { await reconfigureServer({ fileUpload: { - enabled: true, enabledForPublic: false, enabledForAnonymousUser: true, enabledForAuthenticatedUser: false, diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 2cc773eebd..c0011bf194 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -548,12 +548,6 @@ module.exports.IdempotencyOptions = { }, }; module.exports.FileUploadOptions = { - enabled: { - env: 'PARSE_SERVER_FILE_UPLOAD_ENABLED', - help: 'Files can be uploaded with Parse Server.', - action: parsers.booleanParser, - default: true, - }, enabledForAnonymousUser: { env: 'PARSE_SERVER_FILE_UPLOAD_ENABLED_FOR_ANONYMOUS_USER', help: 'File upload is enabled for Anonymous Users.', diff --git a/src/Options/docs.js b/src/Options/docs.js index cc33b25764..c036059232 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -122,7 +122,6 @@ /** * @interface FileUploadOptions - * @property {Boolean} enabled Files can be uploaded with Parse Server. * @property {Boolean} enabledForAnonymousUser File upload is enabled for Anonymous Users. * @property {Boolean} enabledForAuthenticatedUser File upload is enabled for authenticated users. * @property {Boolean} enabledForPublic File upload is enabled for anyone with access to the Parse Server file upload endpoint, regardless of user authentication. diff --git a/src/Options/index.js b/src/Options/index.js index 3fe305117e..f06ce6eba0 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -290,9 +290,6 @@ export interface IdempotencyOptions { ttl: ?number; } export interface FileUploadOptions { - /* Files can be uploaded with Parse Server. - :DEFAULT: true */ - enabled: ?boolean; /* File upload is enabled for Anonymous Users. :DEFAULT: false */ enabledForAnonymousUser: ?boolean; diff --git a/src/Routers/FilesRouter.js b/src/Routers/FilesRouter.js index 1b7b207fb1..bb333a8c4f 100644 --- a/src/Routers/FilesRouter.js +++ b/src/Routers/FilesRouter.js @@ -94,10 +94,6 @@ export class FilesRouter { async createHandler(req, res, next) { const config = req.config; - if (!req.config.fileUpload.enabled && req.config.fileUpload.enabled != null) { - next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'File upload is not enabled.')); - return; - } if ( !req.config.fileUpload.enabledForAnonymousUser && req.auth.user && From b27395fdfd1d54fc1266e90d72f89d74408c22d3 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 14 Dec 2020 22:00:35 +1100 Subject: [PATCH 17/17] Revert "Include lib for AWS" This reverts commit 076ef26929413189ae5987b7cf41b2c3275f45fe. --- .gitignore | 2 +- lib/AccountLockout.js | 172 -- lib/Adapters/AdapterLoader.js | 63 - lib/Adapters/Analytics/AnalyticsAdapter.js | 41 - lib/Adapters/Auth/AuthAdapter.js | 34 - lib/Adapters/Auth/OAuth1Client.js | 227 -- lib/Adapters/Auth/apple.js | 105 - lib/Adapters/Auth/facebook.js | 62 - lib/Adapters/Auth/gcenter.js | 126 - lib/Adapters/Auth/github.js | 40 - lib/Adapters/Auth/google.js | 167 -- lib/Adapters/Auth/gpgames.js | 35 - lib/Adapters/Auth/httpsRequest.js | 47 - lib/Adapters/Auth/index.js | 173 -- lib/Adapters/Auth/instagram.js | 31 - lib/Adapters/Auth/janraincapture.js | 46 - lib/Adapters/Auth/janrainengage.js | 52 - lib/Adapters/Auth/keycloak.js | 125 - lib/Adapters/Auth/ldap.js | 83 - lib/Adapters/Auth/line.js | 41 - lib/Adapters/Auth/linkedin.js | 46 - lib/Adapters/Auth/meetup.js | 39 - lib/Adapters/Auth/microsoft.js | 39 - lib/Adapters/Auth/oauth2.js | 142 - lib/Adapters/Auth/phantauth.js | 47 - lib/Adapters/Auth/qq.js | 48 - lib/Adapters/Auth/spotify.js | 51 - lib/Adapters/Auth/twitter.js | 60 - lib/Adapters/Auth/vkontakte.js | 54 - lib/Adapters/Auth/wechat.js | 33 - lib/Adapters/Auth/weibo.js | 47 - lib/Adapters/Cache/CacheAdapter.js | 50 - lib/Adapters/Cache/InMemoryCache.js | 76 - lib/Adapters/Cache/InMemoryCacheAdapter.js | 45 - lib/Adapters/Cache/LRUCache.js | 46 - lib/Adapters/Cache/NullCacheAdapter.js | 34 - .../RedisCacheAdapter/KeyPromiseQueue.js | 59 - lib/Adapters/Cache/RedisCacheAdapter/index.js | 130 - lib/Adapters/Email/MailAdapter.js | 40 - lib/Adapters/Files/FilesAdapter.js | 136 - lib/Adapters/Files/GridFSBucketAdapter.js | 273 -- lib/Adapters/Files/GridStoreAdapter.js | 182 -- lib/Adapters/Logger/LoggerAdapter.js | 39 - lib/Adapters/Logger/WinstonLogger.js | 137 - lib/Adapters/Logger/WinstonLoggerAdapter.js | 75 - lib/Adapters/MessageQueue/EventEmitterMQ.js | 73 - lib/Adapters/PubSub/EventEmitterPubSub.js | 65 - lib/Adapters/PubSub/PubSubAdapter.js | 39 - lib/Adapters/PubSub/RedisPubSub.js | 33 - lib/Adapters/Push/PushAdapter.js | 50 - lib/Adapters/Storage/Mongo/MongoCollection.js | 229 -- .../Storage/Mongo/MongoSchemaCollection.js | 365 --- .../Storage/Mongo/MongoStorageAdapter.js | 957 ------- lib/Adapters/Storage/Mongo/MongoTransform.js | 1795 ------------ .../Storage/Postgres/PostgresClient.js | 40 - .../Storage/Postgres/PostgresConfigParser.js | 95 - .../Postgres/PostgresStorageAdapter.js | 2496 ----------------- .../Storage/Postgres/sql/array/add-unique.sql | 11 - .../Storage/Postgres/sql/array/add.sql | 11 - .../Postgres/sql/array/contains-all-regex.sql | 14 - .../Postgres/sql/array/contains-all.sql | 14 - .../Storage/Postgres/sql/array/contains.sql | 11 - .../Storage/Postgres/sql/array/remove.sql | 11 - lib/Adapters/Storage/Postgres/sql/index.js | 35 - .../sql/misc/json-object-set-keys.sql | 19 - lib/Adapters/Storage/StorageAdapter.js | 2 - lib/Adapters/WebSocketServer/WSAdapter.js | 45 - lib/Adapters/WebSocketServer/WSSAdapter.js | 74 - lib/Auth.js | 373 --- lib/ClientSDK.js | 47 - lib/Config.js | 348 --- lib/Controllers/AdaptableController.js | 88 - lib/Controllers/AnalyticsController.js | 52 - lib/Controllers/CacheController.js | 92 - lib/Controllers/DatabaseController.js | 1485 ---------- lib/Controllers/FilesController.js | 136 - lib/Controllers/HooksController.js | 301 -- lib/Controllers/LiveQueryController.js | 71 - lib/Controllers/LoggerController.js | 265 -- lib/Controllers/ParseGraphQLController.js | 358 --- lib/Controllers/PushController.js | 257 -- lib/Controllers/SchemaCache.js | 75 - lib/Controllers/SchemaController.js | 1662 ----------- lib/Controllers/UserController.js | 318 --- lib/Controllers/index.js | 312 --- lib/Controllers/types.js | 2 - lib/GraphQL/ParseGraphQLSchema.js | 446 --- lib/GraphQL/ParseGraphQLServer.js | 140 - lib/GraphQL/helpers/objectsMutations.js | 40 - lib/GraphQL/helpers/objectsQueries.js | 307 -- .../loaders/defaultGraphQLMutations.js | 28 - lib/GraphQL/loaders/defaultGraphQLQueries.js | 29 - lib/GraphQL/loaders/defaultGraphQLTypes.js | 1271 --------- lib/GraphQL/loaders/defaultRelaySchema.js | 71 - lib/GraphQL/loaders/filesMutations.js | 103 - lib/GraphQL/loaders/functionsMutations.js | 90 - lib/GraphQL/loaders/parseClassMutations.js | 288 -- lib/GraphQL/loaders/parseClassQueries.js | 150 - lib/GraphQL/loaders/parseClassTypes.js | 531 ---- lib/GraphQL/loaders/schemaDirectives.js | 72 - lib/GraphQL/loaders/schemaMutations.js | 179 -- lib/GraphQL/loaders/schemaQueries.js | 93 - lib/GraphQL/loaders/schemaTypes.js | 376 --- lib/GraphQL/loaders/usersMutations.js | 333 --- lib/GraphQL/loaders/usersQueries.js | 111 - lib/GraphQL/parseGraphQLUtils.js | 69 - lib/GraphQL/transformers/className.js | 17 - lib/GraphQL/transformers/constraintType.js | 73 - lib/GraphQL/transformers/inputType.js | 71 - lib/GraphQL/transformers/mutation.js | 275 -- lib/GraphQL/transformers/outputType.js | 71 - lib/GraphQL/transformers/query.js | 273 -- lib/GraphQL/transformers/schemaFields.js | 128 - lib/LiveQuery/Client.js | 114 - lib/LiveQuery/Id.js | 26 - lib/LiveQuery/ParseCloudCodePublisher.js | 50 - lib/LiveQuery/ParseLiveQueryServer.js | 847 ------ lib/LiveQuery/ParsePubSub.js | 49 - lib/LiveQuery/ParseWebSocketServer.js | 80 - lib/LiveQuery/QueryTools.js | 407 --- lib/LiveQuery/RequestSchema.js | 146 - lib/LiveQuery/SessionTokenCache.js | 67 - lib/LiveQuery/Subscription.js | 61 - lib/LiveQuery/equalObjects.js | 62 - lib/Options/Definitions.js | 531 ---- lib/Options/docs.js | 122 - lib/Options/index.js | 18 - lib/Options/parsers.js | 90 - lib/ParseMessageQueue.js | 34 - lib/ParseServer.js | 495 ---- lib/ParseServerRESTController.js | 184 -- lib/PromiseRouter.js | 255 -- lib/Push/PushQueue.js | 79 - lib/Push/PushWorker.js | 130 - lib/Push/utils.js | 159 -- lib/RestQuery.js | 978 ------- lib/RestWrite.js | 1480 ---------- lib/Routers/AggregateRouter.js | 153 - lib/Routers/AnalyticsRouter.js | 32 - lib/Routers/AudiencesRouter.js | 70 - lib/Routers/ClassesRouter.js | 231 -- lib/Routers/CloudCodeRouter.js | 105 - lib/Routers/FeaturesRouter.js | 79 - lib/Routers/FilesRouter.js | 260 -- lib/Routers/FunctionsRouter.js | 181 -- lib/Routers/GlobalConfigRouter.js | 95 - lib/Routers/GraphQLRouter.js | 55 - lib/Routers/HooksRouter.js | 144 - lib/Routers/IAPValidationRouter.js | 136 - lib/Routers/InstallationsRouter.js | 57 - lib/Routers/LogsRouter.js | 71 - lib/Routers/PublicAPIRouter.js | 322 --- lib/Routers/PurgeRouter.js | 60 - lib/Routers/PushRouter.js | 92 - lib/Routers/RolesRouter.js | 40 - lib/Routers/SchemasRouter.js | 120 - lib/Routers/SessionsRouter.js | 107 - lib/Routers/UsersRouter.js | 436 --- lib/StatusHandler.js | 386 --- lib/TestUtils.js | 31 - lib/batch.js | 132 - lib/cache.js | 16 - .../definitions/parse-live-query-server.js | 12 - lib/cli/definitions/parse-server.js | 12 - lib/cli/parse-live-query-server.js | 19 - lib/cli/parse-server.js | 111 - lib/cli/utils/commander.js | 163 -- lib/cli/utils/runner.js | 65 - lib/cloud-code/HTTPResponse.js | 73 - lib/cloud-code/Parse.Cloud.js | 685 ----- lib/cloud-code/httpRequest.js | 192 -- lib/cryptoUtils.js | 62 - lib/defaults.js | 60 - lib/deprecated.js | 13 - lib/index.js | 107 - lib/logger.js | 47 - lib/middlewares.js | 492 ---- lib/password.js | 38 - lib/request.js | 4 - lib/requiredParameter.js | 13 - lib/rest.js | 208 -- lib/triggers.js | 1040 ------- lib/vendor/README.md | 8 - lib/vendor/mongodbUrl.js | 1064 ------- 184 files changed, 1 insertion(+), 36323 deletions(-) delete mode 100644 lib/AccountLockout.js delete mode 100644 lib/Adapters/AdapterLoader.js delete mode 100644 lib/Adapters/Analytics/AnalyticsAdapter.js delete mode 100644 lib/Adapters/Auth/AuthAdapter.js delete mode 100644 lib/Adapters/Auth/OAuth1Client.js delete mode 100644 lib/Adapters/Auth/apple.js delete mode 100644 lib/Adapters/Auth/facebook.js delete mode 100644 lib/Adapters/Auth/gcenter.js delete mode 100644 lib/Adapters/Auth/github.js delete mode 100644 lib/Adapters/Auth/google.js delete mode 100644 lib/Adapters/Auth/gpgames.js delete mode 100644 lib/Adapters/Auth/httpsRequest.js delete mode 100755 lib/Adapters/Auth/index.js delete mode 100644 lib/Adapters/Auth/instagram.js delete mode 100644 lib/Adapters/Auth/janraincapture.js delete mode 100644 lib/Adapters/Auth/janrainengage.js delete mode 100644 lib/Adapters/Auth/keycloak.js delete mode 100644 lib/Adapters/Auth/ldap.js delete mode 100644 lib/Adapters/Auth/line.js delete mode 100644 lib/Adapters/Auth/linkedin.js delete mode 100644 lib/Adapters/Auth/meetup.js delete mode 100644 lib/Adapters/Auth/microsoft.js delete mode 100644 lib/Adapters/Auth/oauth2.js delete mode 100644 lib/Adapters/Auth/phantauth.js delete mode 100644 lib/Adapters/Auth/qq.js delete mode 100644 lib/Adapters/Auth/spotify.js delete mode 100644 lib/Adapters/Auth/twitter.js delete mode 100644 lib/Adapters/Auth/vkontakte.js delete mode 100644 lib/Adapters/Auth/wechat.js delete mode 100644 lib/Adapters/Auth/weibo.js delete mode 100644 lib/Adapters/Cache/CacheAdapter.js delete mode 100644 lib/Adapters/Cache/InMemoryCache.js delete mode 100644 lib/Adapters/Cache/InMemoryCacheAdapter.js delete mode 100644 lib/Adapters/Cache/LRUCache.js delete mode 100644 lib/Adapters/Cache/NullCacheAdapter.js delete mode 100644 lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js delete mode 100644 lib/Adapters/Cache/RedisCacheAdapter/index.js delete mode 100644 lib/Adapters/Email/MailAdapter.js delete mode 100644 lib/Adapters/Files/FilesAdapter.js delete mode 100644 lib/Adapters/Files/GridFSBucketAdapter.js delete mode 100644 lib/Adapters/Files/GridStoreAdapter.js delete mode 100644 lib/Adapters/Logger/LoggerAdapter.js delete mode 100644 lib/Adapters/Logger/WinstonLogger.js delete mode 100644 lib/Adapters/Logger/WinstonLoggerAdapter.js delete mode 100644 lib/Adapters/MessageQueue/EventEmitterMQ.js delete mode 100644 lib/Adapters/PubSub/EventEmitterPubSub.js delete mode 100644 lib/Adapters/PubSub/PubSubAdapter.js delete mode 100644 lib/Adapters/PubSub/RedisPubSub.js delete mode 100644 lib/Adapters/Push/PushAdapter.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoCollection.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoSchemaCollection.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoStorageAdapter.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoTransform.js delete mode 100644 lib/Adapters/Storage/Postgres/PostgresClient.js delete mode 100644 lib/Adapters/Storage/Postgres/PostgresConfigParser.js delete mode 100644 lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/add-unique.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/add.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/remove.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/index.js delete mode 100644 lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql delete mode 100644 lib/Adapters/Storage/StorageAdapter.js delete mode 100644 lib/Adapters/WebSocketServer/WSAdapter.js delete mode 100644 lib/Adapters/WebSocketServer/WSSAdapter.js delete mode 100644 lib/Auth.js delete mode 100644 lib/ClientSDK.js delete mode 100644 lib/Config.js delete mode 100644 lib/Controllers/AdaptableController.js delete mode 100644 lib/Controllers/AnalyticsController.js delete mode 100644 lib/Controllers/CacheController.js delete mode 100644 lib/Controllers/DatabaseController.js delete mode 100644 lib/Controllers/FilesController.js delete mode 100644 lib/Controllers/HooksController.js delete mode 100644 lib/Controllers/LiveQueryController.js delete mode 100644 lib/Controllers/LoggerController.js delete mode 100644 lib/Controllers/ParseGraphQLController.js delete mode 100644 lib/Controllers/PushController.js delete mode 100644 lib/Controllers/SchemaCache.js delete mode 100644 lib/Controllers/SchemaController.js delete mode 100644 lib/Controllers/UserController.js delete mode 100644 lib/Controllers/index.js delete mode 100644 lib/Controllers/types.js delete mode 100644 lib/GraphQL/ParseGraphQLSchema.js delete mode 100644 lib/GraphQL/ParseGraphQLServer.js delete mode 100644 lib/GraphQL/helpers/objectsMutations.js delete mode 100644 lib/GraphQL/helpers/objectsQueries.js delete mode 100644 lib/GraphQL/loaders/defaultGraphQLMutations.js delete mode 100644 lib/GraphQL/loaders/defaultGraphQLQueries.js delete mode 100644 lib/GraphQL/loaders/defaultGraphQLTypes.js delete mode 100644 lib/GraphQL/loaders/defaultRelaySchema.js delete mode 100644 lib/GraphQL/loaders/filesMutations.js delete mode 100644 lib/GraphQL/loaders/functionsMutations.js delete mode 100644 lib/GraphQL/loaders/parseClassMutations.js delete mode 100644 lib/GraphQL/loaders/parseClassQueries.js delete mode 100644 lib/GraphQL/loaders/parseClassTypes.js delete mode 100644 lib/GraphQL/loaders/schemaDirectives.js delete mode 100644 lib/GraphQL/loaders/schemaMutations.js delete mode 100644 lib/GraphQL/loaders/schemaQueries.js delete mode 100644 lib/GraphQL/loaders/schemaTypes.js delete mode 100644 lib/GraphQL/loaders/usersMutations.js delete mode 100644 lib/GraphQL/loaders/usersQueries.js delete mode 100644 lib/GraphQL/parseGraphQLUtils.js delete mode 100644 lib/GraphQL/transformers/className.js delete mode 100644 lib/GraphQL/transformers/constraintType.js delete mode 100644 lib/GraphQL/transformers/inputType.js delete mode 100644 lib/GraphQL/transformers/mutation.js delete mode 100644 lib/GraphQL/transformers/outputType.js delete mode 100644 lib/GraphQL/transformers/query.js delete mode 100644 lib/GraphQL/transformers/schemaFields.js delete mode 100644 lib/LiveQuery/Client.js delete mode 100644 lib/LiveQuery/Id.js delete mode 100644 lib/LiveQuery/ParseCloudCodePublisher.js delete mode 100644 lib/LiveQuery/ParseLiveQueryServer.js delete mode 100644 lib/LiveQuery/ParsePubSub.js delete mode 100644 lib/LiveQuery/ParseWebSocketServer.js delete mode 100644 lib/LiveQuery/QueryTools.js delete mode 100644 lib/LiveQuery/RequestSchema.js delete mode 100644 lib/LiveQuery/SessionTokenCache.js delete mode 100644 lib/LiveQuery/Subscription.js delete mode 100644 lib/LiveQuery/equalObjects.js delete mode 100644 lib/Options/Definitions.js delete mode 100644 lib/Options/docs.js delete mode 100644 lib/Options/index.js delete mode 100644 lib/Options/parsers.js delete mode 100644 lib/ParseMessageQueue.js delete mode 100644 lib/ParseServer.js delete mode 100644 lib/ParseServerRESTController.js delete mode 100644 lib/PromiseRouter.js delete mode 100644 lib/Push/PushQueue.js delete mode 100644 lib/Push/PushWorker.js delete mode 100644 lib/Push/utils.js delete mode 100644 lib/RestQuery.js delete mode 100644 lib/RestWrite.js delete mode 100644 lib/Routers/AggregateRouter.js delete mode 100644 lib/Routers/AnalyticsRouter.js delete mode 100644 lib/Routers/AudiencesRouter.js delete mode 100644 lib/Routers/ClassesRouter.js delete mode 100644 lib/Routers/CloudCodeRouter.js delete mode 100644 lib/Routers/FeaturesRouter.js delete mode 100644 lib/Routers/FilesRouter.js delete mode 100644 lib/Routers/FunctionsRouter.js delete mode 100644 lib/Routers/GlobalConfigRouter.js delete mode 100644 lib/Routers/GraphQLRouter.js delete mode 100644 lib/Routers/HooksRouter.js delete mode 100644 lib/Routers/IAPValidationRouter.js delete mode 100644 lib/Routers/InstallationsRouter.js delete mode 100644 lib/Routers/LogsRouter.js delete mode 100644 lib/Routers/PublicAPIRouter.js delete mode 100644 lib/Routers/PurgeRouter.js delete mode 100644 lib/Routers/PushRouter.js delete mode 100644 lib/Routers/RolesRouter.js delete mode 100644 lib/Routers/SchemasRouter.js delete mode 100644 lib/Routers/SessionsRouter.js delete mode 100644 lib/Routers/UsersRouter.js delete mode 100644 lib/StatusHandler.js delete mode 100644 lib/TestUtils.js delete mode 100644 lib/batch.js delete mode 100644 lib/cache.js delete mode 100644 lib/cli/definitions/parse-live-query-server.js delete mode 100644 lib/cli/definitions/parse-server.js delete mode 100644 lib/cli/parse-live-query-server.js delete mode 100755 lib/cli/parse-server.js delete mode 100644 lib/cli/utils/commander.js delete mode 100644 lib/cli/utils/runner.js delete mode 100644 lib/cloud-code/HTTPResponse.js delete mode 100644 lib/cloud-code/Parse.Cloud.js delete mode 100644 lib/cloud-code/httpRequest.js delete mode 100644 lib/cryptoUtils.js delete mode 100644 lib/defaults.js delete mode 100644 lib/deprecated.js delete mode 100644 lib/index.js delete mode 100644 lib/logger.js delete mode 100644 lib/middlewares.js delete mode 100644 lib/password.js delete mode 100644 lib/request.js delete mode 100644 lib/requiredParameter.js delete mode 100644 lib/rest.js delete mode 100644 lib/triggers.js delete mode 100644 lib/vendor/README.md delete mode 100644 lib/vendor/mongodbUrl.js diff --git a/.gitignore b/.gitignore index 751741e08a..e4e19156c2 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,7 @@ node_modules .vscode # Babel.js - +lib/ # cache folder .cache diff --git a/lib/AccountLockout.js b/lib/AccountLockout.js deleted file mode 100644 index 45fe53ef56..0000000000 --- a/lib/AccountLockout.js +++ /dev/null @@ -1,172 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AccountLockout = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// This class handles the Account Lockout Policy settings. -class AccountLockout { - constructor(user, config) { - this._user = user; - this._config = config; - } - /** - * set _failed_login_count to value - */ - - - _setFailedLoginCount(value) { - const query = { - username: this._user.username - }; - const updateFields = { - _failed_login_count: value - }; - return this._config.database.update('_User', query, updateFields); - } - /** - * check if the _failed_login_count field has been set - */ - - - _isFailedLoginCountSet() { - const query = { - username: this._user.username, - _failed_login_count: { - $exists: true - } - }; - return this._config.database.find('_User', query).then(users => { - if (Array.isArray(users) && users.length > 0) { - return true; - } else { - return false; - } - }); - } - /** - * if _failed_login_count is NOT set then set it to 0 - * else do nothing - */ - - - _initFailedLoginCount() { - return this._isFailedLoginCountSet().then(failedLoginCountIsSet => { - if (!failedLoginCountIsSet) { - return this._setFailedLoginCount(0); - } - }); - } - /** - * increment _failed_login_count by 1 - */ - - - _incrementFailedLoginCount() { - const query = { - username: this._user.username - }; - const updateFields = { - _failed_login_count: { - __op: 'Increment', - amount: 1 - } - }; - return this._config.database.update('_User', query, updateFields); - } - /** - * if the failed login count is greater than the threshold - * then sets lockout expiration to 'currenttime + accountPolicy.duration', i.e., account is locked out for the next 'accountPolicy.duration' minutes - * else do nothing - */ - - - _setLockoutExpiration() { - const query = { - username: this._user.username, - _failed_login_count: { - $gte: this._config.accountLockout.threshold - } - }; - const now = new Date(); - const updateFields = { - _account_lockout_expires_at: _node.default._encode(new Date(now.getTime() + this._config.accountLockout.duration * 60 * 1000)) - }; - return this._config.database.update('_User', query, updateFields).catch(err => { - if (err && err.code && err.message && err.code === 101 && err.message === 'Object not found.') { - return; // nothing to update so we are good - } else { - throw err; // unknown error - } - }); - } - /** - * if _account_lockout_expires_at > current_time and _failed_login_count > threshold - * reject with account locked error - * else - * resolve - */ - - - _notLocked() { - const query = { - username: this._user.username, - _account_lockout_expires_at: { - $gt: _node.default._encode(new Date()) - }, - _failed_login_count: { - $gte: this._config.accountLockout.threshold - } - }; - return this._config.database.find('_User', query).then(users => { - if (Array.isArray(users) && users.length > 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your account is locked due to multiple failed login attempts. Please try again after ' + this._config.accountLockout.duration + ' minute(s)'); - } - }); - } - /** - * set and/or increment _failed_login_count - * if _failed_login_count > threshold - * set the _account_lockout_expires_at to current_time + accountPolicy.duration - * else - * do nothing - */ - - - _handleFailedLoginAttempt() { - return this._initFailedLoginCount().then(() => { - return this._incrementFailedLoginCount(); - }).then(() => { - return this._setLockoutExpiration(); - }); - } - /** - * handle login attempt if the Account Lockout Policy is enabled - */ - - - handleLoginAttempt(loginSuccessful) { - if (!this._config.accountLockout) { - return Promise.resolve(); - } - - return this._notLocked().then(() => { - if (loginSuccessful) { - return this._setFailedLoginCount(0); - } else { - return this._handleFailedLoginAttempt(); - } - }); - } - -} - -exports.AccountLockout = AccountLockout; -var _default = AccountLockout; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BY2NvdW50TG9ja291dC5qcyJdLCJuYW1lcyI6WyJBY2NvdW50TG9ja291dCIsImNvbnN0cnVjdG9yIiwidXNlciIsImNvbmZpZyIsIl91c2VyIiwiX2NvbmZpZyIsIl9zZXRGYWlsZWRMb2dpbkNvdW50IiwidmFsdWUiLCJxdWVyeSIsInVzZXJuYW1lIiwidXBkYXRlRmllbGRzIiwiX2ZhaWxlZF9sb2dpbl9jb3VudCIsImRhdGFiYXNlIiwidXBkYXRlIiwiX2lzRmFpbGVkTG9naW5Db3VudFNldCIsIiRleGlzdHMiLCJmaW5kIiwidGhlbiIsInVzZXJzIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiX2luaXRGYWlsZWRMb2dpbkNvdW50IiwiZmFpbGVkTG9naW5Db3VudElzU2V0IiwiX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQiLCJfX29wIiwiYW1vdW50IiwiX3NldExvY2tvdXRFeHBpcmF0aW9uIiwiJGd0ZSIsImFjY291bnRMb2Nrb3V0IiwidGhyZXNob2xkIiwibm93IiwiRGF0ZSIsIl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCIsIlBhcnNlIiwiX2VuY29kZSIsImdldFRpbWUiLCJkdXJhdGlvbiIsImNhdGNoIiwiZXJyIiwiY29kZSIsIm1lc3NhZ2UiLCJfbm90TG9ja2VkIiwiJGd0IiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiX2hhbmRsZUZhaWxlZExvZ2luQXR0ZW1wdCIsImhhbmRsZUxvZ2luQXR0ZW1wdCIsImxvZ2luU3VjY2Vzc2Z1bCIsIlByb21pc2UiLCJyZXNvbHZlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFEQTtBQUdPLE1BQU1BLGNBQU4sQ0FBcUI7QUFDMUJDLEVBQUFBLFdBQVcsQ0FBQ0MsSUFBRCxFQUFPQyxNQUFQLEVBQWU7QUFDeEIsU0FBS0MsS0FBTCxHQUFhRixJQUFiO0FBQ0EsU0FBS0csT0FBTCxHQUFlRixNQUFmO0FBQ0Q7QUFFRDs7Ozs7QUFHQUcsRUFBQUEsb0JB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OztBQUdBb0IsRUFBQUEsa0JBQWtCLENBQUNDLGVBQUQsRUFBa0I7QUFDbEMsUUFBSSxDQUFDLEtBQUszQyxPQUFMLENBQWF3QixjQUFsQixFQUFrQztBQUNoQyxhQUFPb0IsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtSLFVBQUwsR0FBa0J6QixJQUFsQixDQUF1QixNQUFNO0FBQ2xDLFVBQUkrQixlQUFKLEVBQXFCO0FBQ25CLGVBQU8sS0FBSzFDLG9CQUFMLENBQTBCLENBQTFCLENBQVA7QUFDRCxPQUZELE1BRU87QUFDTCxlQUFPLEtBQUt3Qyx5QkFBTCxFQUFQO0FBQ0Q7QUFDRixLQU5NLENBQVA7QUFPRDs7QUE1SnlCOzs7ZUErSmI5QyxjIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBjbGFzcyBoYW5kbGVzIHRoZSBBY2NvdW50IExvY2tvdXQgUG9saWN5IHNldHRpbmdzLlxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5leHBvcnQgY2xhc3MgQWNjb3VudExvY2tvdXQge1xuICBjb25zdHJ1Y3Rvcih1c2VyLCBjb25maWcpIHtcbiAgICB0aGlzLl91c2VyID0gdXNlcjtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cblxuICAvKipcbiAgICogc2V0IF9mYWlsZWRfbG9naW5fY291bnQgdG8gdmFsdWVcbiAgICovXG4gIF9zZXRGYWlsZWRMb2dpbkNvdW50KHZhbHVlKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogdmFsdWUsXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNoZWNrIGlmIHRoZSBfZmFpbGVkX2xvZ2luX2NvdW50IGZpZWxkIGhhcyBiZWVuIHNldFxuICAgKi9cbiAgX2lzRmFpbGVkTG9naW5Db3VudFNldCgpIHtcbiAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgIHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lLFxuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyAkZXhpc3RzOiB0cnVlIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCBxdWVyeSkudGhlbih1c2VycyA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh1c2VycykgJiYgdXNlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpZiBfZmFpbGVkX2xvZ2luX2NvdW50IGlzIE5PVCBzZXQgdGhlbiBzZXQgaXQgdG8gMFxuICAgKiBlbHNlIGRvIG5vdGhpbmdcbiAgICovXG4gIF9pbml0RmFpbGVkTG9naW5Db3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNGYWlsZWRMb2dpbkNvdW50U2V0KCkudGhlbihmYWlsZWRMb2dpbkNvdW50SXNTZXQgPT4ge1xuICAgICAgaWYgKCFmYWlsZWRMb2dpbkNvdW50SXNTZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldEZhaWxlZExvZ2luQ291bnQoMCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaW5jcmVtZW50IF9mYWlsZWRfbG9naW5fY291bnQgYnkgMVxuICAgKi9cbiAgX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyBfX29wOiAnSW5jcmVtZW50JywgYW1vdW50OiAxIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIGlmIHRoZSBmYWlsZWQgbG9naW4gY291bnQgaXMgZ3JlYXRlciB0aGFuIHRoZSB0aHJlc2hvbGRcbiAgICogdGhlbiBzZXRzIGxvY2tvdXQgZXhwaXJhdGlvbiB0byAnY3VycmVudHRpbWUgKyBhY2NvdW50UG9saWN5LmR1cmF0aW9uJywgaS5lLiwgYWNjb3VudCBpcyBsb2NrZWQgb3V0IGZvciB0aGUgbmV4dCAnYWNjb3VudFBvbGljeS5kdXJhdGlvbicgbWludXRlc1xuICAgKiBlbHNlIGRvIG5vdGhpbmdcbiAgICovXG4gIF9zZXRMb2Nrb3V0RXhwaXJhdGlvbigpIHtcbiAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgIHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lLFxuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyAkZ3RlOiB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQudGhyZXNob2xkIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cbiAgICBjb25zdCB1cGRhdGVGaWVsZHMgPSB7XG4gICAgICBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ6IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQuZHVyYXRpb24gKiA2MCAqIDEwMDApXG4gICAgICApLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKS5jYXRjaChlcnIgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBlcnIgJiZcbiAgICAgICAgZXJyLmNvZGUgJiZcbiAgICAgICAgZXJyLm1lc3NhZ2UgJiZcbiAgICAgICAgZXJyLmNvZGUgPT09IDEwMSAmJlxuICAgICAgICBlcnIubWVzc2FnZSA9PT0gJ09iamVjdCBub3QgZm91bmQuJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybjsgLy8gbm90aGluZyB0byB1cGRhdGUgc28gd2UgYXJlIGdvb2RcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjsgLy8gdW5rbm93biBlcnJvclxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGlmIF9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCA+IGN1cnJlbnRfdGltZSBhbmQgX2ZhaWxlZF9sb2dpbl9jb3VudCA+IHRocmVzaG9sZFxuICAgKiAgIHJlamVjdCB3aXRoIGFjY291bnQgbG9ja2VkIGVycm9yXG4gICAqIGVsc2VcbiAgICogICByZXNvbHZlXG4gICAqL1xuICBfbm90TG9ja2VkKCkge1xuICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgdXNlcm5hbWU6IHRoaXMuX3VzZXIudXNlcm5hbWUsXG4gICAgICBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ6IHsgJGd0OiBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpIH0sXG4gICAgICBfZmFpbGVkX2xvZ2luX2NvdW50OiB7ICRndGU6IHRoaXMuX2NvbmZpZy5hY2NvdW50TG9ja291dC50aHJlc2hvbGQgfSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5kYXRhYmFzZS5maW5kKCdfVXNlcicsIHF1ZXJ5KS50aGVuKHVzZXJzID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHVzZXJzKSAmJiB1c2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdZb3VyIGFjY291bnQgaXMgbG9ja2VkIGR1ZSB0byBtdWx0aXBsZSBmYWlsZWQgbG9naW4gYXR0ZW1wdHMuIFBsZWFzZSB0cnkgYWdhaW4gYWZ0ZXIgJyArXG4gICAgICAgICAgICB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQuZHVyYXRpb24gK1xuICAgICAgICAgICAgJyBtaW51dGUocyknXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogc2V0IGFuZC9vciBpbmNyZW1lbnQgX2ZhaWxlZF9sb2dpbl9jb3VudFxuICAgKiBpZiBfZmFpbGVkX2xvZ2luX2NvdW50ID4gdGhyZXNob2xkXG4gICAqICAgc2V0IHRoZSBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQgdG8gY3VycmVudF90aW1lICsgYWNjb3VudFBvbGljeS5kdXJhdGlvblxuICAgKiBlbHNlXG4gICAqICAgZG8gbm90aGluZ1xuICAgKi9cbiAgX2hhbmRsZUZhaWxlZExvZ2luQXR0ZW1wdCgpIHtcbiAgICByZXR1cm4gdGhpcy5faW5pdEZhaWxlZExvZ2luQ291bnQoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faW5jcmVtZW50RmFpbGVkTG9naW5Db3VudCgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldExvY2tvdXRFeHBpcmF0aW9uKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBoYW5kbGUgbG9naW4gYXR0ZW1wdCBpZiB0aGUgQWNjb3VudCBMb2Nrb3V0IFBvbGljeSBpcyBlbmFibGVkXG4gICAqL1xuICBoYW5kbGVMb2dpbkF0dGVtcHQobG9naW5TdWNjZXNzZnVsKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX25vdExvY2tlZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKGxvZ2luU3VjY2Vzc2Z1bCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2V0RmFpbGVkTG9naW5Db3VudCgwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVGYWlsZWRMb2dpbkF0dGVtcHQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBY2NvdW50TG9ja291dDtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/AdapterLoader.js b/lib/Adapters/AdapterLoader.js deleted file mode 100644 index 51cbe9e2a1..0000000000 --- a/lib/Adapters/AdapterLoader.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.loadAdapter = loadAdapter; -exports.default = void 0; - -/** - * @module AdapterLoader - */ - -/** - * @static - * Attempt to load an adapter or fallback to the default. - * @param {Adapter} adapter an adapter - * @param {Adapter} defaultAdapter the default adapter to load - * @param {any} options options to pass to the contstructor - * @returns {Object} the loaded adapter - */ -function loadAdapter(adapter, defaultAdapter, options) { - if (!adapter) { - if (!defaultAdapter) { - return options; - } // Load from the default adapter when no adapter is set - - - return loadAdapter(defaultAdapter, undefined, options); - } else if (typeof adapter === 'function') { - try { - return adapter(options); - } catch (e) { - if (e.name === 'TypeError') { - var Adapter = adapter; - return new Adapter(options); - } else { - throw e; - } - } - } else if (typeof adapter === 'string') { - /* eslint-disable */ - adapter = require(adapter); // If it's define as a module, get the default - - if (adapter.default) { - adapter = adapter.default; - } - - return loadAdapter(adapter, undefined, options); - } else if (adapter.module) { - return loadAdapter(adapter.module, undefined, adapter.options); - } else if (adapter.class) { - return loadAdapter(adapter.class, undefined, adapter.options); - } else if (adapter.adapter) { - return loadAdapter(adapter.adapter, undefined, adapter.options); - } // return the adapter as provided - - - return adapter; -} - -var _default = loadAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9BZGFwdGVycy9BZGFwdGVyTG9hZGVyLmpzIl0sIm5hbWVzIjpbImxvYWRBZGFwdGVyIiwiYWRhcHRlciIsImRlZmF1bHRBZGFwdGVyIiwib3B0aW9ucyIsInVuZGVmaW5lZCIsImUiLCJuYW1lIiwiQWRhcHRlciIsInJlcXVpcmUiLCJkZWZhdWx0IiwibW9kdWxlIiwiY2xhc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7QUFHQTs7Ozs7Ozs7QUFRTyxTQUFTQSxXQUFULENBQXdCQyxPQUF4QixFQUFpQ0MsY0FBakMsRUFBaURDLE9BQWpELEVBQTZEO0FBQ2xFLE1BQUksQ0FBQ0YsT0FBTCxFQUFjO0FBQ1osUUFBSSxDQUFDQyxjQUFMLEVBQXFCO0FBQ25CLGFBQU9DLE9BQVA7QUFDRCxLQUhXLENBSVo7OztBQUNBLFdBQU9ILFdBQVcsQ0FBQ0UsY0FBRCxFQUFpQkUsU0FBakIsRUFBNEJELE9BQTVCLENBQWxCO0FBQ0QsR0FORCxNQU1PLElBQUksT0FBT0YsT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUN4QyxRQUFJO0FBQ0YsYUFBT0EsT0FBTyxDQUFDRSxPQUFELENBQWQ7QUFDRCxLQUZELENBRUUsT0FBT0UsQ0FBUCxFQUFVO0FBQ1YsVUFBSUEsQ0FBQyxDQUFDQyxJQUFGLEtBQVcsV0FBZixFQUE0QjtBQUMxQixZQUFJQyxPQUFPLEdBQUdOLE9BQWQ7QUFDQSxlQUFPLElBQUlNLE9BQUosQ0FBWUosT0FBWixDQUFQO0FBQ0QsT0FIRCxNQUdPO0FBQ0wsY0FBTUUsQ0FBTjtBQUNEO0FBQ0Y7QUFDRixHQVhNLE1BV0EsSUFBSSxPQUFPSixPQUFQLEtBQW1CLFFBQXZCLEVBQWlDO0FBQ3RDO0FBQ0FBLElBQUFBLE9BQU8sR0FBR08sT0FBTyxDQUFDUCxPQUFELENBQWpCLENBRnNDLENBR3RDOztBQUNBLFFBQUlBLE9BQU8sQ0FBQ1EsT0FBWixFQUFxQjtBQUNuQlIsTUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNRLE9BQWxCO0FBQ0Q7O0FBQ0QsV0FBT1QsV0FBVyxDQUFDQyxPQUFELEVBQVVHLFNBQVYsRUFBcUJELE9BQXJCLENBQWxCO0FBQ0QsR0FSTSxNQVFBLElBQUlGLE9BQU8sQ0FBQ1MsTUFBWixFQUFvQjtBQUN6QixXQUFPVixXQUFXLENBQUNDLE9BQU8sQ0FBQ1MsTUFBVCxFQUFpQk4sU0FBakIsRUFBNEJILE9BQU8sQ0FBQ0UsT0FBcEMsQ0FBbEI7QUFDRCxHQUZNLE1BRUEsSUFBSUYsT0FBTyxDQUFDVSxLQUFaLEVBQW1CO0FBQ3hCLFdBQU9YLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDVSxLQUFULEVBQWdCUCxTQUFoQixFQUEyQkgsT0FBTyxDQUFDRSxPQUFuQyxDQUFsQjtBQUNELEdBRk0sTUFFQSxJQUFJRixPQUFPLENBQUNBLE9BQVosRUFBcUI7QUFDMUIsV0FBT0QsV0FBVyxDQUFDQyxPQUFPLENBQUNBLE9BQVQsRUFBa0JHLFNBQWxCLEVBQTZCSCxPQUFPLENBQUNFLE9BQXJDLENBQWxCO0FBQ0QsR0FoQ2lFLENBaUNsRTs7O0FBQ0EsU0FBT0YsT0FBUDtBQUNEOztlQUVjRCxXIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJMb2FkZXJcbiAqL1xuLyoqXG4gKiBAc3RhdGljXG4gKiBBdHRlbXB0IHRvIGxvYWQgYW4gYWRhcHRlciBvciBmYWxsYmFjayB0byB0aGUgZGVmYXVsdC5cbiAqIEBwYXJhbSB7QWRhcHRlcn0gYWRhcHRlciBhbiBhZGFwdGVyXG4gKiBAcGFyYW0ge0FkYXB0ZXJ9IGRlZmF1bHRBZGFwdGVyIHRoZSBkZWZhdWx0IGFkYXB0ZXIgdG8gbG9hZFxuICogQHBhcmFtIHthbnl9IG9wdGlvbnMgb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb250c3RydWN0b3JcbiAqIEByZXR1cm5zIHtPYmplY3R9IHRoZSBsb2FkZWQgYWRhcHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFkYXB0ZXI8VD4oYWRhcHRlciwgZGVmYXVsdEFkYXB0ZXIsIG9wdGlvbnMpOiBUIHtcbiAgaWYgKCFhZGFwdGVyKSB7XG4gICAgaWYgKCFkZWZhdWx0QWRhcHRlcikge1xuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8vIExvYWQgZnJvbSB0aGUgZGVmYXVsdCBhZGFwdGVyIHdoZW4gbm8gYWRhcHRlciBpcyBzZXRcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoZGVmYXVsdEFkYXB0ZXIsIHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFkYXB0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGFkYXB0ZXIob3B0aW9ucyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUubmFtZSA9PT0gJ1R5cGVFcnJvcicpIHtcbiAgICAgICAgdmFyIEFkYXB0ZXIgPSBhZGFwdGVyO1xuICAgICAgICByZXR1cm4gbmV3IEFkYXB0ZXIob3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgYWRhcHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAgIGFkYXB0ZXIgPSByZXF1aXJlKGFkYXB0ZXIpO1xuICAgIC8vIElmIGl0J3MgZGVmaW5lIGFzIGEgbW9kdWxlLCBnZXQgdGhlIGRlZmF1bHRcbiAgICBpZiAoYWRhcHRlci5kZWZhdWx0KSB7XG4gICAgICBhZGFwdGVyID0gYWRhcHRlci5kZWZhdWx0O1xuICAgIH1cbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlciwgdW5kZWZpbmVkLCBvcHRpb25zKTtcbiAgfSBlbHNlIGlmIChhZGFwdGVyLm1vZHVsZSkge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLm1vZHVsZSwgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuY2xhc3MpIHtcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlci5jbGFzcywgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuYWRhcHRlcikge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLmFkYXB0ZXIsIHVuZGVmaW5lZCwgYWRhcHRlci5vcHRpb25zKTtcbiAgfVxuICAvLyByZXR1cm4gdGhlIGFkYXB0ZXIgYXMgcHJvdmlkZWRcbiAgcmV0dXJuIGFkYXB0ZXI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGxvYWRBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Analytics/AnalyticsAdapter.js b/lib/Adapters/Analytics/AnalyticsAdapter.js deleted file mode 100644 index 109ac4b3f6..0000000000 --- a/lib/Adapters/Analytics/AnalyticsAdapter.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AnalyticsAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface AnalyticsAdapter - */ -class AnalyticsAdapter { - /** - @param {any} parameters: the analytics request body, analytics info will be in the dimensions property - @param {Request} req: the original http request - */ - appOpened(parameters, req) { - return Promise.resolve({}); - } - /** - @param {String} eventName: the name of the custom eventName - @param {any} parameters: the analytics request body, analytics info will be in the dimensions property - @param {Request} req: the original http request - */ - - - trackEvent(eventName, parameters, req) { - return Promise.resolve({}); - } - -} - -exports.AnalyticsAdapter = AnalyticsAdapter; -var _default = AnalyticsAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJBbmFseXRpY3NBZGFwdGVyIiwiYXBwT3BlbmVkIiwicGFyYW1ldGVycyIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwidHJhY2tFdmVudCIsImV2ZW50TmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7OztBQUdPLE1BQU1BLGdCQUFOLENBQXVCO0FBQzVCOzs7O0FBSUFDLEVBQUFBLFNBQVMsQ0FBQ0MsVUFBRCxFQUFhQyxHQUFiLEVBQWtCO0FBQ3pCLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0Q7QUFFRDs7Ozs7OztBQUtBQyxFQUFBQSxVQUFVLENBQUNDLFNBQUQsRUFBWUwsVUFBWixFQUF3QkMsR0FBeEIsRUFBNkI7QUFDckMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEVBQWhCLENBQVA7QUFDRDs7QUFoQjJCOzs7ZUFtQmZMLGdCIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJzXG4gKi9cbi8qKlxuICogQGludGVyZmFjZSBBbmFseXRpY3NBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NBZGFwdGVyIHtcbiAgLyoqXG4gIEBwYXJhbSB7YW55fSBwYXJhbWV0ZXJzOiB0aGUgYW5hbHl0aWNzIHJlcXVlc3QgYm9keSwgYW5hbHl0aWNzIGluZm8gd2lsbCBiZSBpbiB0aGUgZGltZW5zaW9ucyBwcm9wZXJ0eVxuICBAcGFyYW0ge1JlcXVlc3R9IHJlcTogdGhlIG9yaWdpbmFsIGh0dHAgcmVxdWVzdFxuICAgKi9cbiAgYXBwT3BlbmVkKHBhcmFtZXRlcnMsIHJlcSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG5cbiAgLyoqXG4gIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWU6IHRoZSBuYW1lIG9mIHRoZSBjdXN0b20gZXZlbnROYW1lXG4gIEBwYXJhbSB7YW55fSBwYXJhbWV0ZXJzOiB0aGUgYW5hbHl0aWNzIHJlcXVlc3QgYm9keSwgYW5hbHl0aWNzIGluZm8gd2lsbCBiZSBpbiB0aGUgZGltZW5zaW9ucyBwcm9wZXJ0eVxuICBAcGFyYW0ge1JlcXVlc3R9IHJlcTogdGhlIG9yaWdpbmFsIGh0dHAgcmVxdWVzdFxuICAgKi9cbiAgdHJhY2tFdmVudChldmVudE5hbWUsIHBhcmFtZXRlcnMsIHJlcSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuYWx5dGljc0FkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/AuthAdapter.js b/lib/Adapters/Auth/AuthAdapter.js deleted file mode 100644 index 2b1f9ba12b..0000000000 --- a/lib/Adapters/Auth/AuthAdapter.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AuthAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ -class AuthAdapter { - /* - @param appIds: the specified app ids in the configuration - @param authData: the client provided authData - @param options: additional options - @returns a promise that resolves if the applicationId is valid - */ - validateAppId(appIds, authData, options) { - return Promise.resolve({}); - } - /* - @param authData: the client provided authData - @param options: additional options - */ - - - validateAuthData(authData, options) { - return Promise.resolve({}); - } - -} - -exports.AuthAdapter = AuthAdapter; -var _default = AuthAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL0F1dGhBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkF1dGhBZGFwdGVyIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImF1dGhEYXRhIiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwidmFsaWRhdGVBdXRoRGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2Qjs7Ozs7O0FBTUFDLEVBQUFBLGFBQWEsQ0FBQ0MsTUFBRCxFQUFTQyxRQUFULEVBQW1CQyxPQUFuQixFQUE0QjtBQUN2QyxXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEO0FBRUQ7Ozs7OztBQUlBQyxFQUFBQSxnQkFBZ0IsQ0FBQ0osUUFBRCxFQUFXQyxPQUFYLEVBQW9CO0FBQ2xDLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0Q7O0FBakJzQjs7O2VBb0JWTixXIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuZXhwb3J0IGNsYXNzIEF1dGhBZGFwdGVyIHtcbiAgLypcbiAgQHBhcmFtIGFwcElkczogdGhlIHNwZWNpZmllZCBhcHAgaWRzIGluIHRoZSBjb25maWd1cmF0aW9uXG4gIEBwYXJhbSBhdXRoRGF0YTogdGhlIGNsaWVudCBwcm92aWRlZCBhdXRoRGF0YVxuICBAcGFyYW0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gIEByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGlmIHRoZSBhcHBsaWNhdGlvbklkIGlzIHZhbGlkXG4gICAqL1xuICB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuXG4gIC8qXG4gIEBwYXJhbSBhdXRoRGF0YTogdGhlIGNsaWVudCBwcm92aWRlZCBhdXRoRGF0YVxuICBAcGFyYW0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gICAqL1xuICB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXV0aEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/OAuth1Client.js b/lib/Adapters/Auth/OAuth1Client.js deleted file mode 100644 index f9689a6e32..0000000000 --- a/lib/Adapters/Auth/OAuth1Client.js +++ /dev/null @@ -1,227 +0,0 @@ -"use strict"; - -var https = require('https'), - crypto = require('crypto'); - -var Parse = require('parse/node').Parse; - -var OAuth = function (options) { - if (!options) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth'); - } - - this.consumer_key = options.consumer_key; - this.consumer_secret = options.consumer_secret; - this.auth_token = options.auth_token; - this.auth_token_secret = options.auth_token_secret; - this.host = options.host; - this.oauth_params = options.oauth_params || {}; -}; - -OAuth.prototype.send = function (method, path, params, body) { - var request = this.buildRequest(method, path, params, body); // Encode the body properly, the current Parse Implementation don't do it properly - - return new Promise(function (resolve, reject) { - var httpRequest = https.request(request, function (res) { - var data = ''; - res.on('data', function (chunk) { - data += chunk; - }); - res.on('end', function () { - data = JSON.parse(data); - resolve(data); - }); - }).on('error', function () { - reject('Failed to make an OAuth request'); - }); - - if (request.body) { - httpRequest.write(request.body); - } - - httpRequest.end(); - }); -}; - -OAuth.prototype.buildRequest = function (method, path, params, body) { - if (path.indexOf('/') != 0) { - path = '/' + path; - } - - if (params && Object.keys(params).length > 0) { - path += '?' + OAuth.buildParameterString(params); - } - - var request = { - host: this.host, - path: path, - method: method.toUpperCase() - }; - var oauth_params = this.oauth_params || {}; - oauth_params.oauth_consumer_key = this.consumer_key; - - if (this.auth_token) { - oauth_params['oauth_token'] = this.auth_token; - } - - request = OAuth.signRequest(request, oauth_params, this.consumer_secret, this.auth_token_secret); - - if (body && Object.keys(body).length > 0) { - request.body = OAuth.buildParameterString(body); - } - - return request; -}; - -OAuth.prototype.get = function (path, params) { - return this.send('GET', path, params); -}; - -OAuth.prototype.post = function (path, params, body) { - return this.send('POST', path, params, body); -}; -/* - Proper string %escape encoding -*/ - - -OAuth.encode = function (str) { - // discuss at: http://phpjs.org/functions/rawurlencode/ - // original by: Brett Zamir (http://brett-zamir.me) - // input by: travc - // input by: Brett Zamir (http://brett-zamir.me) - // input by: Michael Grier - // input by: Ratheous - // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // bugfixed by: Brett Zamir (http://brett-zamir.me) - // bugfixed by: Joris - // reimplemented by: Brett Zamir (http://brett-zamir.me) - // reimplemented by: Brett Zamir (http://brett-zamir.me) - // note: This reflects PHP 5.3/6.0+ behavior - // note: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on - // note: pages served as UTF-8 - // example 1: rawurlencode('Kevin van Zonneveld!'); - // returns 1: 'Kevin%20van%20Zonneveld%21' - // example 2: rawurlencode('http://kevin.vanzonneveld.net/'); - // returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F' - // example 3: rawurlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'); - // returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a' - str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current - // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. - - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); -}; - -OAuth.signatureMethod = 'HMAC-SHA1'; -OAuth.version = '1.0'; -/* - Generate a nonce -*/ - -OAuth.nonce = function () { - var text = ''; - var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - for (var i = 0; i < 30; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); - - return text; -}; - -OAuth.buildParameterString = function (obj) { - // Sort keys and encode values - if (obj) { - var keys = Object.keys(obj).sort(); // Map key=value, join them by & - - return keys.map(function (key) { - return key + '=' + OAuth.encode(obj[key]); - }).join('&'); - } - - return ''; -}; -/* - Build the signature string from the object -*/ - - -OAuth.buildSignatureString = function (method, url, parameters) { - return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join('&'); -}; -/* - Retuns encoded HMAC-SHA1 from key and text -*/ - - -OAuth.signature = function (text, key) { - crypto = require('crypto'); - return OAuth.encode(crypto.createHmac('sha1', key).update(text).digest('base64')); -}; - -OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_token_secret) { - oauth_parameters = oauth_parameters || {}; // Set default values - - if (!oauth_parameters.oauth_nonce) { - oauth_parameters.oauth_nonce = OAuth.nonce(); - } - - if (!oauth_parameters.oauth_timestamp) { - oauth_parameters.oauth_timestamp = Math.floor(new Date().getTime() / 1000); - } - - if (!oauth_parameters.oauth_signature_method) { - oauth_parameters.oauth_signature_method = OAuth.signatureMethod; - } - - if (!oauth_parameters.oauth_version) { - oauth_parameters.oauth_version = OAuth.version; - } - - if (!auth_token_secret) { - auth_token_secret = ''; - } // Force GET method if unset - - - if (!request.method) { - request.method = 'GET'; - } // Collect all the parameters in one signatureParameters object - - - var signatureParams = {}; - var parametersToMerge = [request.params, request.body, oauth_parameters]; - - for (var i in parametersToMerge) { - var parameters = parametersToMerge[i]; - - for (var k in parameters) { - signatureParams[k] = parameters[k]; - } - } // Create a string based on the parameters - - - var parameterString = OAuth.buildParameterString(signatureParams); // Build the signature string - - var url = 'https://' + request.host + '' + request.path; - var signatureString = OAuth.buildSignatureString(request.method, url, parameterString); // Hash the signature string - - var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join('&'); - var signature = OAuth.signature(signatureString, signatureKey); // Set the signature in the params - - oauth_parameters.oauth_signature = signature; - - if (!request.headers) { - request.headers = {}; - } // Set the authorization header - - - var authHeader = Object.keys(oauth_parameters).sort().map(function (key) { - var value = oauth_parameters[key]; - return key + '="' + value + '"'; - }).join(', '); - request.headers.Authorization = 'OAuth ' + authHeader; // Set the content type header - - request.headers['Content-Type'] = 'application/x-www-form-urlencoded'; - return request; -}; - -module.exports = OAuth; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL09BdXRoMUNsaWVudC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBbkI7QUFBQSxJQUNFQyxNQUFNLEdBQUdELE9BQU8sQ0FBQyxRQUFELENBRGxCOztBQUVBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkUsS0FBbEM7O0FBRUEsSUFBSUMsS0FBSyxHQUFHLFVBQVNDLE9BQVQsRUFBa0I7QUFDNUIsTUFBSSxDQUFDQSxPQUFMLEVBQWM7QUFDWixVQUFNLElBQUlGLEtBQUssQ0FBQ0csS0FBVixDQUNKSCxLQUFLLENBQUNHLEtBQU4sQ0FBWUMscUJBRFIsRUFFSiw0QkFGSSxDQUFOO0FBSUQ7O0FBQ0QsT0FBS0MsWUFBTCxHQUFvQkgsT0FBTyxDQUFDRyxZQUE1QjtBQUNBLE9BQUtDLGVBQUwsR0FBdUJKLE9BQU8sQ0FBQ0ksZUFBL0I7QUFDQSxPQUFLQyxVQUFMLEdBQWtCTCxPQUFPLENBQUNLLFVBQTFCO0FBQ0EsT0FBS0MsaUJBQUwsR0FBeUJOLE9BQU8sQ0FBQ00saUJBQWpDO0FBQ0EsT0FBS0MsSUFBTCxHQUFZUCxPQUFPLENBQUNPLElBQXBCO0FBQ0EsT0FBS0MsWUFBTCxHQUFvQlIsT0FBTyxDQUFDUSxZQUFSLElBQXdCLEVBQTVDO0FBQ0QsQ0FiRDs7QUFlQVQsS0FBSyxDQUFDVSxTQUFOLENBQWdCQyxJQUFoQixHQUF1QixVQUFTQyxNQUFULEVBQWlCQyxJQUFqQixFQUF1QkMsTUFBdkIsRUFBK0JDLElBQS9CLEVBQXFDO0FBQzFELE1BQUlDLE9BQU8sR0FBRyxLQUFLQyxZQUFM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Q2lFLE9BQVIsR0FBa0IsRUFBbEI7QUFDRCxHQTFERCxDQTREQTs7O0FBQ0EsTUFBSUMsVUFBVSxHQUFHbkQsTUFBTSxDQUFDQyxJQUFQLENBQVltQyxnQkFBWixFQUNkWCxJQURjLEdBRWRDLEdBRmMsQ0FFVixVQUFTQyxHQUFULEVBQWM7QUFDakIsUUFBSXlCLEtBQUssR0FBR2hCLGdCQUFnQixDQUFDVCxHQUFELENBQTVCO0FBQ0EsV0FBT0EsR0FBRyxHQUFHLElBQU4sR0FBYXlCLEtBQWIsR0FBcUIsR0FBNUI7QUFDRCxHQUxjLEVBTWR4QixJQU5jLENBTVQsSUFOUyxDQUFqQjtBQVFBM0MsRUFBQUEsT0FBTyxDQUFDaUUsT0FBUixDQUFnQkcsYUFBaEIsR0FBZ0MsV0FBV0YsVUFBM0MsQ0FyRUEsQ0F1RUE7O0FBQ0FsRSxFQUFBQSxPQUFPLENBQUNpRSxPQUFSLENBQWdCLGNBQWhCLElBQWtDLG1DQUFsQztBQUNBLFNBQU9qRSxPQUFQO0FBQ0QsQ0EvRUQ7O0FBaUZBcUUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCdEYsS0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxudmFyIE9BdXRoID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAnTm8gb3B0aW9ucyBwYXNzZWQgdG8gT0F1dGgnXG4gICAgKTtcbiAgfVxuICB0aGlzLmNvbnN1bWVyX2tleSA9IG9wdGlvbnMuY29uc3VtZXJfa2V5O1xuICB0aGlzLmNvbnN1bWVyX3NlY3JldCA9IG9wdGlvbnMuY29uc3VtZXJfc2VjcmV0O1xuICB0aGlzLmF1dGhfdG9rZW4gPSBvcHRpb25zLmF1dGhfdG9rZW47XG4gIHRoaXMuYXV0aF90b2tlbl9zZWNyZXQgPSBvcHRpb25zLmF1dGhfdG9rZW5fc2VjcmV0O1xuICB0aGlzLmhvc3QgPSBvcHRpb25zLmhvc3Q7XG4gIHRoaXMub2F1dGhfcGFyYW1zID0gb3B0aW9ucy5vYXV0aF9wYXJhbXMgfHwge307XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uKG1ldGhvZCwgcGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHZhciByZXF1ZXN0ID0gdGhpcy5idWlsZFJlcXVlc3QobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xuICAvLyBFbmNvZGUgdGhlIGJvZHkgcHJvcGVybHksIHRoZSBjdXJyZW50IFBhcnNlIEltcGxlbWVudGF0aW9uIGRvbid0IGRvIGl0IHByb3Blcmx5XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgaHR0cFJlcXVlc3QgPSBodHRwc1xuICAgICAgLnJlcXVlc3QocmVxdWVzdCwgZnVuY3Rpb24ocmVzKSB7XG4gICAgICAgIHZhciBkYXRhID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QoJ0ZhaWxlZCB0byBtYWtlIGFuIE9BdXRoIHJlcXVlc3QnKTtcbiAgICAgIH0pO1xuICAgIGlmIChyZXF1ZXN0LmJvZHkpIHtcbiAgICAgIGh0dHBSZXF1ZXN0LndyaXRlKHJlcXVlc3QuYm9keSk7XG4gICAgfVxuICAgIGh0dHBSZXF1ZXN0LmVuZCgpO1xuICB9KTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5idWlsZFJlcXVlc3QgPSBmdW5jdGlvbihtZXRob2QsIHBhdGgsIHBhcmFtcywgYm9keSkge1xuICBpZiAocGF0aC5pbmRleE9mKCcvJykgIT0gMCkge1xuICAgIHBhdGggPSAnLycgKyBwYXRoO1xuICB9XG4gIGlmIChwYXJhbXMgJiYgT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPiAwKSB7XG4gICAgcGF0aCArPSAnPycgKyBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhwYXJhbXMpO1xuICB9XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgaG9zdDogdGhpcy5ob3N0LFxuICAgIHBhdGg6IHBhdGgsXG4gICAgbWV0aG9kOiBtZXRob2QudG9VcHBlckNhc2UoKSxcbiAgfTtcblxuICB2YXIgb2F1dGhfcGFyYW1zID0gdGhpcy5vYXV0aF9wYXJhbXMgfHwge307XG4gIG9hdXRoX3BhcmFtcy5vYXV0aF9jb25zdW1lcl9rZXkgPSB0aGlzLmNvbnN1bWVyX2tleTtcbiAgaWYgKHRoaXMuYXV0aF90b2tlbikge1xuICAgIG9hdXRoX3BhcmFtc1snb2F1dGhfdG9rZW4nXSA9IHRoaXMuYXV0aF90b2tlbjtcbiAgfVxuXG4gIHJlcXVlc3QgPSBPQXV0aC5zaWduUmVxdWVzdChcbiAgICByZXF1ZXN0LFxuICAgIG9hdXRoX3BhcmFtcyxcbiAgICB0aGlzLmNvbnN1bWVyX3NlY3JldCxcbiAgICB0aGlzLmF1dGhfdG9rZW5fc2VjcmV0XG4gICk7XG5cbiAgaWYgKGJvZHkgJiYgT2JqZWN0LmtleXMoYm9keSkubGVuZ3RoID4gMCkge1xuICAgIHJlcXVlc3QuYm9keSA9IE9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nKGJvZHkpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuT0F1dGgucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHBhdGgsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5zZW5kKCdHRVQnLCBwYXRoLCBwYXJhbXMpO1xufTtcblxuT0F1dGgucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbihwYXRoLCBwYXJhbXMsIGJvZHkpIHtcbiAgcmV0dXJuIHRoaXMuc2VuZCgnUE9TVCcsIHBhdGgsIHBhcmFtcywgYm9keSk7XG59O1xuXG4vKlxuXHRQcm9wZXIgc3RyaW5nICVlc2NhcGUgZW5jb2RpbmdcbiovXG5PQXV0aC5lbmNvZGUgPSBmdW5jdGlvbihzdHIpIHtcbiAgLy8gICAgICAgZGlzY3VzcyBhdDogaHR0cDovL3BocGpzLm9yZy9mdW5jdGlvbnMvcmF3dXJsZW5jb2RlL1xuICAvLyAgICAgIG9yaWdpbmFsIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiB0cmF2Y1xuICAvLyAgICAgICAgIGlucHV0IGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiBNaWNoYWVsIEdyaWVyXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IFJhdGhlb3VzXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEtldmluIHZhbiBab25uZXZlbGQgKGh0dHA6Ly9rZXZpbi52YW56b25uZXZlbGQubmV0KVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBKb3Jpc1xuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgICAgICBub3RlOiBUaGlzIHJlZmxlY3RzIFBIUCA1LjMvNi4wKyBiZWhhdmlvclxuICAvLyAgICAgICAgICAgICBub3RlOiBQbGVhc2UgYmUgYXdhcmUgdGhhdCB0aGlzIGZ1bmN0aW9uIGV4cGVjdHMgdG8gZW5jb2RlIGludG8gVVRGLTggZW5jb2RlZCBzdHJpbmdzLCBhcyBmb3VuZCBvblxuICAvLyAgICAgICAgICAgICBub3RlOiBwYWdlcyBzZXJ2ZWQgYXMgVVRGLThcbiAgLy8gICAgICAgIGV4YW1wbGUgMTogcmF3dXJsZW5jb2RlKCdLZXZpbiB2YW4gWm9ubmV2ZWxkIScpO1xuICAvLyAgICAgICAgcmV0dXJucyAxOiAnS2V2aW4lMjB2YW4lMjBab25uZXZlbGQlMjEnXG4gIC8vICAgICAgICBleGFtcGxlIDI6IHJhd3VybGVuY29kZSgnaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQvJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDI6ICdodHRwJTNBJTJGJTJGa2V2aW4udmFuem9ubmV2ZWxkLm5ldCUyRidcbiAgLy8gICAgICAgIGV4YW1wbGUgMzogcmF3dXJsZW5jb2RlKCdodHRwOi8vd3d3Lmdvb2dsZS5ubC9zZWFyY2g/cT1waHAuanMmaWU9dXRmLTgmb2U9dXRmLTgmYXE9dCZybHM9Y29tLnVidW50dTplbi1VUzp1bm9mZmljaWFsJmNsaWVudD1maXJlZm94LWEnKTtcbiAgLy8gICAgICAgIHJldHVybnMgMzogJ2h0dHAlM0ElMkYlMkZ3d3cuZ29vZ2xlLm5sJTJGc2VhcmNoJTNGcSUzRHBocC5qcyUyNmllJTNEdXRmLTglMjZvZSUzRHV0Zi04JTI2YXElM0R0JTI2cmxzJTNEY29tLnVidW50dSUzQWVuLVVTJTNBdW5vZmZpY2lhbCUyNmNsaWVudCUzRGZpcmVmb3gtYSdcblxuICBzdHIgPSAoc3RyICsgJycpLnRvU3RyaW5nKCk7XG5cbiAgLy8gVGlsZGUgc2hvdWxkIGJlIGFsbG93ZWQgdW5lc2NhcGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiBQSFAgKGFzIHJlZmxlY3RlZCBiZWxvdyksIGJ1dCBpZiB5b3Ugd2FudCB0byByZWZsZWN0IGN1cnJlbnRcbiAgLy8gUEhQIGJlaGF2aW9yLCB5b3Ugd291bGQgbmVlZCB0byBhZGQgXCIucmVwbGFjZSgvfi9nLCAnJTdFJyk7XCIgdG8gdGhlIGZvbGxvd2luZy5cbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpXG4gICAgLnJlcGxhY2UoLyEvZywgJyUyMScpXG4gICAgLnJlcGxhY2UoLycvZywgJyUyNycpXG4gICAgLnJlcGxhY2UoL1xcKC9nLCAnJTI4JylcbiAgICAucmVwbGFjZSgvXFwpL2csICclMjknKVxuICAgIC5yZXBsYWNlKC9cXCovZywgJyUyQScpO1xufTtcblxuT0F1dGguc2lnbmF0dXJlTWV0aG9kID0gJ0hNQUMtU0hBMSc7XG5PQXV0aC52ZXJzaW9uID0gJzEuMCc7XG5cbi8qXG5cdEdlbmVyYXRlIGEgbm9uY2VcbiovXG5PQXV0aC5ub25jZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdGV4dCA9ICcnO1xuICB2YXIgcG9zc2libGUgPVxuICAgICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAzMDsgaSsrKVxuICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpO1xuXG4gIHJldHVybiB0ZXh0O1xufTtcblxuT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcgPSBmdW5jdGlvbihvYmopIHtcbiAgLy8gU29ydCBrZXlzIGFuZCBlbmNvZGUgdmFsdWVzXG4gIGlmIChvYmopIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaikuc29ydCgpO1xuXG4gICAgLy8gTWFwIGtleT12YWx1ZSwgam9pbiB0aGVtIGJ5ICZcbiAgICByZXR1cm4ga2V5c1xuICAgICAgLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSArICc9JyArIE9BdXRoLmVuY29kZShvYmpba2V5XSk7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJyYnKTtcbiAgfVxuXG4gIHJldHVybiAnJztcbn07XG5cbi8qXG5cdEJ1aWxkIHRoZSBzaWduYXR1cmUgc3RyaW5nIGZyb20gdGhlIG9iamVjdFxuKi9cblxuT0F1dGguYnVpbGRTaWduYXR1cmVTdHJpbmcgPSBmdW5jdGlvbihtZXRob2QsIHVybCwgcGFyYW1ldGVycykge1xuICByZXR1cm4gW1xuICAgIG1ldGhvZC50b1VwcGVyQ2FzZSgpLFxuICAgIE9BdXRoLmVuY29kZSh1cmwpLFxuICAgIE9BdXRoLmVuY29kZShwYXJhbWV0ZXJzKSxcbiAgXS5qb2luKCcmJyk7XG59O1xuXG4vKlxuXHRSZXR1bnMgZW5jb2RlZCBITUFDLVNIQTEgZnJvbSBrZXkgYW5kIHRleHRcbiovXG5PQXV0aC5zaWduYXR1cmUgPSBmdW5jdGlvbih0ZXh0LCBrZXkpIHtcbiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG4gIHJldHVybiBPQXV0aC5lbmNvZGUoXG4gICAgY3J5cHRvXG4gICAgICAuY3JlYXRlSG1hYygnc2hhMScsIGtleSlcbiAgICAgIC51cGRhdGUodGV4dClcbiAgICAgIC5kaWdlc3QoJ2Jhc2U2NCcpXG4gICk7XG59O1xuXG5PQXV0aC5zaWduUmVxdWVzdCA9IGZ1bmN0aW9uKFxuICByZXF1ZXN0LFxuICBvYXV0aF9wYXJhbWV0ZXJzLFxuICBjb25zdW1lcl9zZWNyZXQsXG4gIGF1dGhfdG9rZW5fc2VjcmV0XG4pIHtcbiAgb2F1dGhfcGFyYW1ldGVycyA9IG9hdXRoX3BhcmFtZXRlcnMgfHwge307XG5cbiAgLy8gU2V0IGRlZmF1bHQgdmFsdWVzXG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9ub25jZSkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfbm9uY2UgPSBPQXV0aC5ub25jZSgpO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF90aW1lc3RhbXApIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3RpbWVzdGFtcCA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCA9IE9BdXRoLnNpZ25hdHVyZU1ldGhvZDtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbikge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbiA9IE9BdXRoLnZlcnNpb247XG4gIH1cblxuICBpZiAoIWF1dGhfdG9rZW5fc2VjcmV0KSB7XG4gICAgYXV0aF90b2tlbl9zZWNyZXQgPSAnJztcbiAgfVxuICAvLyBGb3JjZSBHRVQgbWV0aG9kIGlmIHVuc2V0XG4gIGlmICghcmVxdWVzdC5tZXRob2QpIHtcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdHRVQnO1xuICB9XG5cbiAgLy8gQ29sbGVjdCAgYWxsIHRoZSBwYXJhbWV0ZXJzIGluIG9uZSBzaWduYXR1cmVQYXJhbWV0ZXJzIG9iamVjdFxuICB2YXIgc2lnbmF0dXJlUGFyYW1zID0ge307XG4gIHZhciBwYXJhbWV0ZXJzVG9NZXJnZSA9IFtyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdC5ib2R5LCBvYXV0aF9wYXJhbWV0ZXJzXTtcbiAgZm9yICh2YXIgaSBpbiBwYXJhbWV0ZXJzVG9NZXJnZSkge1xuICAgIHZhciBwYXJhbWV0ZXJzID0gcGFyYW1ldGVyc1RvTWVyZ2VbaV07XG4gICAgZm9yICh2YXIgayBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICBzaWduYXR1cmVQYXJhbXNba10gPSBwYXJhbWV0ZXJzW2tdO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHN0cmluZyBiYXNlZCBvbiB0aGUgcGFyYW1ldGVyc1xuICB2YXIgcGFyYW1ldGVyU3RyaW5nID0gT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcoc2lnbmF0dXJlUGFyYW1zKTtcblxuICAvLyBCdWlsZCB0aGUgc2lnbmF0dXJlIHN0cmluZ1xuICB2YXIgdXJsID0gJ2h0dHBzOi8vJyArIHJlcXVlc3QuaG9zdCArICcnICsgcmVxdWVzdC5wYXRoO1xuXG4gIHZhciBzaWduYXR1cmVTdHJpbmcgPSBPQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyhcbiAgICByZXF1ZXN0Lm1ldGhvZCxcbiAgICB1cmwsXG4gICAgcGFyYW1ldGVyU3RyaW5nXG4gICk7XG4gIC8vIEhhc2ggdGhlIHNpZ25hdHVyZSBzdHJpbmdcbiAgdmFyIHNpZ25hdHVyZUtleSA9IFtcbiAgICBPQXV0aC5lbmNvZGUoY29uc3VtZXJfc2VjcmV0KSxcbiAgICBPQXV0aC5lbmNvZGUoYXV0aF90b2tlbl9zZWNyZXQpLFxuICBdLmpvaW4oJyYnKTtcblxuICB2YXIgc2lnbmF0dXJlID0gT0F1dGguc2lnbmF0dXJlKHNpZ25hdHVyZVN0cmluZywgc2lnbmF0dXJlS2V5KTtcblxuICAvLyBTZXQgdGhlIHNpZ25hdHVyZSBpbiB0aGUgcGFyYW1zXG4gIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICBpZiAoIXJlcXVlc3QuaGVhZGVycykge1xuICAgIHJlcXVlc3QuaGVhZGVycyA9IHt9O1xuICB9XG5cbiAgLy8gU2V0IHRoZSBhdXRob3JpemF0aW9uIGhlYWRlclxuICB2YXIgYXV0aEhlYWRlciA9IE9iamVjdC5rZXlzKG9hdXRoX3BhcmFtZXRlcnMpXG4gICAgLnNvcnQoKVxuICAgIC5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICB2YXIgdmFsdWUgPSBvYXV0aF9wYXJhbWV0ZXJzW2tleV07XG4gICAgICByZXR1cm4ga2V5ICsgJz1cIicgKyB2YWx1ZSArICdcIic7XG4gICAgfSlcbiAgICAuam9pbignLCAnKTtcblxuICByZXF1ZXN0LmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdPQXV0aCAnICsgYXV0aEhlYWRlcjtcblxuICAvLyBTZXQgdGhlIGNvbnRlbnQgdHlwZSBoZWFkZXJcbiAgcmVxdWVzdC5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnO1xuICByZXR1cm4gcmVxdWVzdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT0F1dGg7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/apple.js b/lib/Adapters/Auth/apple.js deleted file mode 100644 index b73bffde57..0000000000 --- a/lib/Adapters/Auth/apple.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -// Apple SignIn Auth -// https://developer.apple.com/documentation/signinwithapplerestapi -const Parse = require('parse/node').Parse; - -const jwksClient = require('jwks-rsa'); - -const util = require('util'); - -const jwt = require('jsonwebtoken'); - -const TOKEN_ISSUER = 'https://appleid.apple.com'; - -const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { - const client = jwksClient({ - jwksUri: `${TOKEN_ISSUER}/auth/keys`, - cache: true, - cacheMaxEntries, - cacheMaxAge - }); - const asyncGetSigningKeyFunction = util.promisify(client.getSigningKey); - let key; - - try { - key = await asyncGetSigningKeyFunction(keyId); - } catch (error) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`); - } - - return key; -}; - -const getHeaderFromToken = token => { - const decodedToken = jwt.decode(token, { - complete: true - }); - - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -}; - -const verifyIdToken = async ({ - token, - id -}, { - clientId, - cacheMaxEntries, - cacheMaxAge -}) => { - if (!token) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); - } - - const { - kid: keyId, - alg: algorithm - } = getHeaderFromToken(token); - const ONE_HOUR_IN_MS = 3600000; - let jwtClaims; - cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS; - cacheMaxEntries = cacheMaxEntries || 5; - const appleKey = await getAppleKeyByKeyId(keyId, cacheMaxEntries, cacheMaxAge); - const signingKey = appleKey.publicKey || appleKey.rsaPublicKey; - - try { - jwtClaims = jwt.verify(token, signingKey, { - algorithms: algorithm, - // the audience can be checked against a string, a regular expression or a list of strings and/or regular expressions. - audience: clientId - }); - } catch (exception) { - const message = exception.message; - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); - } - - if (jwtClaims.iss !== TOKEN_ISSUER) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`); - } - - if (jwtClaims.sub !== id) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); - } - - return jwtClaims; -}; // Returns a promise that fulfills if this id token is valid - - -function validateAuthData(authData, options = {}) { - return verifyIdToken(authData, options); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2FwcGxlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImp3a3NDbGllbnQiLCJ1dGlsIiwiand0IiwiVE9LRU5fSVNTVUVSIiwiZ2V0QXBwbGVLZXlCeUtleUlkIiwia2V5SWQiLCJjYWNoZU1heEVudHJpZXMiLCJjYWNoZU1heEFnZSIsImNsaWVudCIsImp3a3NVcmkiLCJjYWNoZSIsImFzeW5jR2V0U2lnbmluZ0tleUZ1bmN0aW9uIiwicHJvbWlzaWZ5IiwiZ2V0U2lnbmluZ0tleSIsImtleSIsImVycm9yIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0SGVhZGVyRnJvbVRva2VuIiwidG9rZW4iLCJkZWNvZGVkVG9rZW4iLCJkZWNvZGUiLCJjb21wbGV0ZSIsImhlYWRlciIsInZlcmlmeUlkVG9rZW4iLCJpZCIsImNsaWVudElkIiwia2lkIiwiYWxnIiwiYWxnb3JpdGhtIiwiT05FX0hPVVJfSU5fTVMiLCJqd3RDbGFpbXMiLCJhcHBsZUtleSIsInNpZ25pbmdLZXkiLCJwdWJsaWNLZXkiLCJyc2FQdWJsaWNLZXkiLCJ2ZXJpZnkiLCJhbGdvcml0aG1zIiwiYXVkaWVuY2UiLCJleGNlcHRpb24iLCJtZXNzYWdlIiwiaXNzIiwic3ViIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUVBLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBcEM7O0FBQ0EsTUFBTUUsVUFBVSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUExQjs7QUFDQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLE1BQU1HLEdBQUcsR0FBR0gsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7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LENBQU47QUFDRDs7QUFFRCxNQUFJVCxTQUFTLENBQUNVLEdBQVYsS0FBa0J0QyxZQUF0QixFQUFvQztBQUNsQyxVQUFNLElBQUlMLEtBQUssQ0FBQ2tCLEtBQVYsQ0FDSmxCLEtBQUssQ0FBQ2tCLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSCw4REFBNkRkLFlBQWEsWUFBVzRCLFNBQVMsQ0FBQ1UsR0FBSSxFQUZoRyxDQUFOO0FBSUQ7O0FBRUQsTUFBSVYsU0FBUyxDQUFDVyxHQUFWLEtBQWtCakIsRUFBdEIsRUFBMEI7QUFDeEIsVUFBTSxJQUFJM0IsS0FBSyxDQUFDa0IsS0FBVixDQUNKbEIsS0FBSyxDQUFDa0IsS0FBTixDQUFZQyxnQkFEUixFQUVILHFDQUZHLENBQU47QUFJRDs7QUFDRCxTQUFPYyxTQUFQO0FBQ0QsQ0FuREQsQyxDQXFEQTs7O0FBQ0EsU0FBU1ksZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DQyxPQUFPLEdBQUcsRUFBOUMsRUFBa0Q7QUFDaEQsU0FBT3JCLGFBQWEsQ0FBQ29CLFFBQUQsRUFBV0MsT0FBWCxDQUFwQjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmSCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQXBwbGUgU2lnbkluIEF1dGhcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9kb2N1bWVudGF0aW9uL3NpZ25pbndpdGhhcHBsZXJlc3RhcGlcblxuY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBqd2tzQ2xpZW50ID0gcmVxdWlyZSgnandrcy1yc2EnKTtcbmNvbnN0IHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5jb25zdCBqd3QgPSByZXF1aXJlKCdqc29ud2VidG9rZW4nKTtcblxuY29uc3QgVE9LRU5fSVNTVUVSID0gJ2h0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20nO1xuXG5jb25zdCBnZXRBcHBsZUtleUJ5S2V5SWQgPSBhc3luYyAoa2V5SWQsIGNhY2hlTWF4RW50cmllcywgY2FjaGVNYXhBZ2UpID0+IHtcbiAgY29uc3QgY2xpZW50ID0gandrc0NsaWVudCh7XG4gICAgandrc1VyaTogYCR7VE9LRU5fSVNTVUVSfS9hdXRoL2tleXNgLFxuICAgIGNhY2hlOiB0cnVlLFxuICAgIGNhY2hlTWF4RW50cmllcyxcbiAgICBjYWNoZU1heEFnZSxcbiAgfSk7XG5cbiAgY29uc3QgYXN5bmNHZXRTaWduaW5nS2V5RnVuY3Rpb24gPSB1dGlsLnByb21pc2lmeShjbGllbnQuZ2V0U2lnbmluZ0tleSk7XG5cbiAgbGV0IGtleTtcbiAgdHJ5IHtcbiAgICBrZXkgPSBhd2FpdCBhc3luY0dldFNpZ25pbmdLZXlGdW5jdGlvbihrZXlJZCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBVbmFibGUgdG8gZmluZCBtYXRjaGluZyBrZXkgZm9yIEtleSBJRDogJHtrZXlJZH1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4ga2V5O1xufTtcblxuY29uc3QgZ2V0SGVhZGVyRnJvbVRva2VuID0gdG9rZW4gPT4ge1xuICBjb25zdCBkZWNvZGVkVG9rZW4gPSBqd3QuZGVjb2RlKHRva2VuLCB7IGNvbXBsZXRlOiB0cnVlIH0pO1xuICBpZiAoIWRlY29kZWRUb2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgcHJvdmlkZWQgdG9rZW4gZG9lcyBub3QgZGVjb2RlIGFzIEpXVGBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGRlY29kZWRUb2tlbi5oZWFkZXI7XG59O1xuXG5jb25zdCB2ZXJpZnlJZFRva2VuID0gYXN5bmMgKFxuICB7IHRva2VuLCBpZCB9LFxuICB7IGNsaWVudElkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlIH1cbikgPT4ge1xuICBpZiAoIXRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuYFxuICAgICk7XG4gIH1cblxuICBjb25zdCB7IGtpZDoga2V5SWQsIGFsZzogYWxnb3JpdGhtIH0gPSBnZXRIZWFkZXJGcm9tVG9rZW4odG9rZW4pO1xuICBjb25zdCBPTkVfSE9VUl9JTl9NUyA9IDM2MDAwMDA7XG4gIGxldCBqd3RDbGFpbXM7XG5cbiAgY2FjaGVNYXhBZ2UgPSBjYWNoZU1heEFnZSB8fCBPTkVfSE9VUl9JTl9NUztcbiAgY2FjaGVNYXhFbnRyaWVzID0gY2FjaGVNYXhFbnRyaWVzIHx8IDU7XG5cbiAgY29uc3QgYXBwbGVLZXkgPSBhd2FpdCBnZXRBcHBsZUtleUJ5S2V5SWQoXG4gICAga2V5SWQsXG4gICAgY2FjaGVNYXhFbnRyaWVzLFxuICAgIGNhY2hlTWF4QWdlXG4gICk7XG4gIGNvbnN0IHNpZ25pbmdLZXkgPSBhcHBsZUtleS5wdWJsaWNLZXkgfHwgYXBwbGVLZXkucnNhUHVibGljS2V5O1xuXG4gIHRyeSB7XG4gICAgand0Q2xhaW1zID0gand0LnZlcmlmeSh0b2tlbiwgc2lnbmluZ0tleSwge1xuICAgICAgYWxnb3JpdGhtczogYWxnb3JpdGhtLFxuICAgICAgLy8gdGhlIGF1ZGllbmNlIGNhbiBiZSBjaGVja2VkIGFnYWluc3QgYSBzdHJpbmcsIGEgcmVndWxhciBleHByZXNzaW9uIG9yIGEgbGlzdCBvZiBzdHJpbmdzIGFuZC9vciByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgICAgYXVkaWVuY2U6IGNsaWVudElkLFxuICAgIH0pO1xuICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXhjZXB0aW9uLm1lc3NhZ2U7XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYCR7bWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuaXNzICE9PSBUT0tFTl9JU1NVRVIpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYGlkIHRva2VuIG5vdCBpc3N1ZWQgYnkgY29ycmVjdCBPcGVuSUQgcHJvdmlkZXIgLSBleHBlY3RlZDogJHtUT0tFTl9JU1NVRVJ9IHwgZnJvbTogJHtqd3RDbGFpbXMuaXNzfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5zdWIgIT09IGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBhdXRoIGRhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmBcbiAgICApO1xuICB9XG4gIHJldHVybiBqd3RDbGFpbXM7XG59O1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgaWQgdG9rZW4gaXMgdmFsaWRcbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gdmVyaWZ5SWRUb2tlbihhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/facebook.js b/lib/Adapters/Auth/facebook.js deleted file mode 100644 index 61bd1b0d5b..0000000000 --- a/lib/Adapters/Auth/facebook.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Facebook Graph API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; - -const crypto = require('crypto'); - -function getAppSecretPath(authData, options = {}) { - const appSecret = options.appSecret; - - if (!appSecret) { - return ''; - } - - const appsecret_proof = crypto.createHmac('sha256', appSecret).update(authData.access_token).digest('hex'); - return `&appsecret_proof=${appsecret_proof}`; -} // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - return graphRequest('me?fields=id&access_token=' + authData.access_token + getAppSecretPath(authData, options)).then(data => { - if (data && data.id == authData.id || process.env.TESTING && authData.id === 'test') { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId(appIds, authData, options) { - var access_token = authData.access_token; - - if (process.env.TESTING && access_token === 'test') { - return Promise.resolve(); - } - - if (!appIds.length) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.'); - } - - return graphRequest('app?access_token=' + access_token + getAppSecretPath(authData, options)).then(data => { - if (data && appIds.indexOf(data.id) != -1) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); - }); -} // A promisey wrapper for FB graph requests. - - -function graphRequest(path) { - return httpsRequest.get('https://graph.facebook.com/' + path); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2ZhY2Vib29rLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsImNyeXB0byIsImdldEFwcFNlY3JldFBhdGgiLCJhdXRoRGF0YSIsIm9wdGlvbnMiLCJhcHBTZWNyZXQiLCJhcHBzZWNyZXRfcHJvb2YiLCJjcmVhdGVIbWFjIiwidXBkYXRlIiwiYWNjZXNzX3Rva2VuIiwiZGlnZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsInRoZW4iLCJkYXRhIiwiaWQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJhcHBJZHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsImluZGV4T2YiLCJwYXRoIiwiZ2V0IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLE1BQU1BLFlBQVksR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEM7O0FBQ0EsTUFBTUMsTUFBTSxHQUFHRixPQUFPLENBQUMsUUFBRCxDQUF0Qjs7QUFFQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQU8sR0FBRyxFQUE5QyxFQUFrRDtBQUNoRCxRQUFNQyxTQUFTLEdBQUdELE9BQU8sQ0FBQ0MsU0FBMUI7O0FBQ0EsTUFBSSxDQUFDQSxTQUFMLEVBQWdCO0FBQ2QsV0FBTyxFQUFQO0FBQ0Q7O0FBQ0QsUUFBTUMsZUFBZSxHQUFHTCxNQUFNLENBQzNCTSxVQURxQixDQUNWLFFBRFUsRUFDQUYsU0FEQSxFQUVyQkcsTUFGcUIsQ0FFZEwsUUFBUSxDQUFDTSxZQUZLLEVBR3JCQyxNQUhxQixDQUdkLEtBSGMsQ0FBeEI7QUFLQSxTQUFRLG9CQUFtQkosZUFBZ0IsRUFBM0M7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNLLGdCQUFULENBQTBCUixRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT1EsWUFBWSxDQUNqQiwrQkFDRVQsUUFBUSxDQUFDTSxZQURYLEdBRUVQLGdCQUFnQixDQUFDQyxRQUFELEVBQVdDLE9BQVgsQ0FIRCxDQUFaLENBSUxTLElBSkssQ0FJQUMsSUFBSSxJQUFJO0FBQ2IsUUFDR0EsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV1osUUFBUSxDQUFDWSxFQUE3QixJQUNDQyxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBWixJQUF1QmYsUUFBUSxDQUFDWSxFQUFULEtBQWdCLE1BRjFDLEVBR0U7QUFDQTtBQUNEOztBQUNELFVBQU0sSUFBSWYsS0FBSyxDQUFDbUIsS0FBVixDQUNKbkIsS0FBSyxDQUFDbUIsS0FBTixDQUFZQyxnQkFEUixFQUVKLHlDQUZJLENBQU47QUFJRCxHQWZNLENBQVA7QUFnQkQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQm5CLFFBQS9CLEVBQXlDQyxPQUF6QyxFQUFrRDtBQUNoRCxNQUFJSyxZQUFZLEdBQUdOLFFBQVEsQ0FBQ00sWUFBNUI7O0FBQ0EsTUFBSU8sT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQVosSUFBdUJULFlBQVksS0FBSyxNQUE1QyxFQUFvRDtBQUNsRCxXQUFPYyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELE1BQUksQ0FBQ0YsTUFBTSxDQUFDRyxNQUFaLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSXpCLEtBQUssQ0FBQ21CLEtBQVYsQ0FDSm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixrQ0FGSSxDQUFOO0FBSUQ7O0FBQ0QsU0FBT1IsWUFBWSxDQUNqQixzQkFBc0JILFlBQXRCLEdBQXFDUCxnQkFBZ0IsQ0FBQ0MsUUFBRCxFQUFXQyxPQUFYLENBRHBDLENBQVosQ0FFTFMsSUFGSyxDQUVBQyxJQUFJLElBQUk7QUFDYixRQUFJQSxJQUFJLElBQUlRLE1BQU0sQ0FBQ0ksT0FBUCxDQUFlWixJQUFJLENBQUNDLEVBQXBCLEtBQTJCLENBQUMsQ0FBeEMsRUFBMkM7QUFDekM7QUFDRDs7QUFDRCxVQUFNLElBQUlmLEtBQUssQ0FBQ21CLEtBQVYsQ0FDSm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5Q0FGSSxDQUFOO0FBSUQsR0FWTSxDQUFQO0FBV0QsQyxDQUVEOzs7QUFDQSxTQUFTUixZQUFULENBQXNCZSxJQUF0QixFQUE0QjtBQUMxQixTQUFPN0IsWUFBWSxDQUFDOEIsR0FBYixDQUFpQixnQ0FBZ0NELElBQWpELENBQVA7QUFDRDs7QUFFREUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVixFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgRmFjZWJvb2sgR3JhcGggQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG5mdW5jdGlvbiBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgYXBwU2VjcmV0ID0gb3B0aW9ucy5hcHBTZWNyZXQ7XG4gIGlmICghYXBwU2VjcmV0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IGFwcHNlY3JldF9wcm9vZiA9IGNyeXB0b1xuICAgIC5jcmVhdGVIbWFjKCdzaGEyNTYnLCBhcHBTZWNyZXQpXG4gICAgLnVwZGF0ZShhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pXG4gICAgLmRpZ2VzdCgnaGV4Jyk7XG5cbiAgcmV0dXJuIGAmYXBwc2VjcmV0X3Byb29mPSR7YXBwc2VjcmV0X3Byb29mfWA7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChcbiAgICAnbWU/ZmllbGRzPWlkJmFjY2Vzc190b2tlbj0nICtcbiAgICAgIGF1dGhEYXRhLmFjY2Vzc190b2tlbiArXG4gICAgICBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zKVxuICApLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKFxuICAgICAgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkgfHxcbiAgICAgIChwcm9jZXNzLmVudi5URVNUSU5HICYmIGF1dGhEYXRhLmlkID09PSAndGVzdCcpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnRmFjZWJvb2sgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoYXBwSWRzLCBhdXRoRGF0YSwgb3B0aW9ucykge1xuICB2YXIgYWNjZXNzX3Rva2VuID0gYXV0aERhdGEuYWNjZXNzX3Rva2VuO1xuICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyAmJiBhY2Nlc3NfdG9rZW4gPT09ICd0ZXN0Jykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICBpZiAoIWFwcElkcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0ZhY2Vib29rIGF1dGggaXMgbm90IGNvbmZpZ3VyZWQuJ1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChcbiAgICAnYXBwP2FjY2Vzc190b2tlbj0nICsgYWNjZXNzX3Rva2VuICsgZ2V0QXBwU2VjcmV0UGF0aChhdXRoRGF0YSwgb3B0aW9ucylcbiAgKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGFwcElkcy5pbmRleE9mKGRhdGEuaWQpICE9IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnRmFjZWJvb2sgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIEZCIGdyYXBoIHJlcXVlc3RzLlxuZnVuY3Rpb24gZ3JhcGhSZXF1ZXN0KHBhdGgpIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoJ2h0dHBzOi8vZ3JhcGguZmFjZWJvb2suY29tLycgKyBwYXRoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/gcenter.js b/lib/Adapters/Auth/gcenter.js deleted file mode 100644 index 1145b1e4eb..0000000000 --- a/lib/Adapters/Auth/gcenter.js +++ /dev/null @@ -1,126 +0,0 @@ -"use strict"; - -/* Apple Game Center Auth -https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign#discussion - -const authData = { - publicKeyUrl: 'https://valid.apple.com/public/timeout.cer', - timestamp: 1460981421303, - signature: 'PoDwf39DCN464B49jJCU0d9Y0J', - salt: 'saltST==', - bundleId: 'com.valid.app' - id: 'playerId', -}; -*/ -const { - Parse -} = require('parse/node'); - -const crypto = require('crypto'); - -const https = require('https'); - -const url = require('url'); - -const cache = {}; // (publicKey -> cert) cache - -function verifyPublicKeyUrl(publicKeyUrl) { - const parsedUrl = url.parse(publicKeyUrl); - - if (parsedUrl.protocol !== 'https:') { - return false; - } - - const hostnameParts = parsedUrl.hostname.split('.'); - const length = hostnameParts.length; - const domainParts = hostnameParts.slice(length - 2, length); - const domain = domainParts.join('.'); - return domain === 'apple.com'; -} - -function convertX509CertToPEM(X509Cert) { - const pemPreFix = '-----BEGIN CERTIFICATE-----\n'; - const pemPostFix = '-----END CERTIFICATE-----'; - const base64 = X509Cert; - const certBody = base64.match(new RegExp('.{0,64}', 'g')).join('\n'); - return pemPreFix + certBody + pemPostFix; -} - -function getAppleCertificate(publicKeyUrl) { - if (!verifyPublicKeyUrl(publicKeyUrl)) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`); - } - - if (cache[publicKeyUrl]) { - return cache[publicKeyUrl]; - } - - return new Promise((resolve, reject) => { - https.get(publicKeyUrl, res => { - let data = ''; - res.on('data', chunk => { - data += chunk.toString('base64'); - }); - res.on('end', () => { - const cert = convertX509CertToPEM(data); - - if (res.headers['cache-control']) { - var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); - - if (expire) { - cache[publicKeyUrl] = cert; // we'll expire the cache entry later, as per max-age - - setTimeout(() => { - delete cache[publicKeyUrl]; - }, parseInt(expire[1], 10) * 1000); - } - } - - resolve(cert); - }); - }).on('error', reject); - }); -} - -function convertTimestampToBigEndian(timestamp) { - const buffer = Buffer.alloc(8); - const high = ~~(timestamp / 0xffffffff); - const low = timestamp % (0xffffffff + 0x1); - buffer.writeUInt32BE(parseInt(high, 10), 0); - buffer.writeUInt32BE(parseInt(low, 10), 4); - return buffer; -} - -function verifySignature(publicKey, authData) { - const verifier = crypto.createVerify('sha256'); - verifier.update(authData.playerId, 'utf8'); - verifier.update(authData.bundleId, 'utf8'); - verifier.update(convertTimestampToBigEndian(authData.timestamp)); - verifier.update(authData.salt, 'base64'); - - if (!verifier.verify(publicKey, authData.signature, 'base64')) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - invalid signature'); - } -} // Returns a promise that fulfills if this user id is valid. - - -async function validateAuthData(authData) { - if (!authData.id) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - authData id missing'); - } - - authData.playerId = authData.id; - const publicKey = await getAppleCertificate(authData.publicKeyUrl); - return verifySignature(publicKey, authData); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2djZW50ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiY3J5cHRvIiwiaHR0cHMiLCJ1cmwiLCJjYWNoZSIsInZlcmlmeVB1YmxpY0tleVVybCIsInB1YmxpY0tleVVybCIsInBhcnNlZFVybCIsInBhcnNlIiwicHJvdG9jb2wiLCJob3N0bmFtZVBhcnRzIiwiaG9zdG5hbWUiLCJzcGxpdCIsImxlbmd0aCIsImRvbWFpblBhcnRzIiwic2xpY2UiLCJkb21haW4iLCJqb2luIiwiY29udmVydFg1MDlDZXJ0VG9QRU0iLCJYNTA5Q2VydCIsInBlbVByZUZpeCIsInBlbVBvc3RGaXgiLCJiYXNlNjQiLCJjZXJ0Qm9keSIsIm1hdGNoIiwiUmVnRXhwIiwiZ2V0QXBwbGVDZXJ0aWZpY2F0ZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImNlcnQiLCJoZWFkZXJzIiwiZXhwaXJlIiwic2V0VGltZW91dCIsInBhcnNlSW50IiwiY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuIiwidGltZXN0YW1wIiwiYnVmZmVyIiwiQnVmZmVyIiwiYWxsb2MiLCJoaWdoIiwibG93Iiwid3JpdGVVSW50MzJCRSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJwbGF5ZXJJZCIsImJ1bmRsZUlkIiwic2FsdCIsInZlcmlmeSIsInNpZ25hdHVyZSIsInZhbGlkYXRlQXV0aERhdGEiLCJpZCIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7Ozs7Ozs7QUFhQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQs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QWdCSCxRQUFRLENBQUNNLElBQXpCLEVBQStCLFFBQS9COztBQUVBLE1BQUksQ0FBQ0wsUUFBUSxDQUFDTSxNQUFULENBQWdCUixTQUFoQixFQUEyQkMsUUFBUSxDQUFDUSxTQUFwQyxFQUErQyxRQUEvQyxDQUFMLEVBQStEO0FBQzdELFVBQU0sSUFBSTlELEtBQUssQ0FBQzRCLEtBQVYsQ0FDSjVCLEtBQUssQ0FBQzRCLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix1Q0FGSSxDQUFOO0FBSUQ7QUFDRixDLENBRUQ7OztBQUNBLGVBQWVrQyxnQkFBZixDQUFnQ1QsUUFBaEMsRUFBMEM7QUFDeEMsTUFBSSxDQUFDQSxRQUFRLENBQUNVLEVBQWQsRUFBa0I7QUFDaEIsVUFBTSxJQUFJaEUsS0FBSyxDQUFDNEIsS0FBVixDQUNKNUIsS0FBSyxDQUFDNEIsS0FBTixDQUFZQyxnQkFEUixFQUVKLHlDQUZJLENBQU47QUFJRDs7QUFDRHlCLEVBQUFBLFFBQVEsQ0FBQ0ksUUFBVCxHQUFvQkosUUFBUSxDQUFDVSxFQUE3QjtBQUNBLFFBQU1YLFNBQVMsR0FBRyxNQUFNMUIsbUJBQW1CLENBQUMyQixRQUFRLENBQUMvQyxZQUFWLENBQTNDO0FBQ0EsU0FBTzZDLGVBQWUsQ0FBQ0MsU0FBRCxFQUFZQyxRQUFaLENBQXRCO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9uQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEbUMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZGLEVBQUFBLGFBRGU7QUFFZkYsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIEFwcGxlIEdhbWUgQ2VudGVyIEF1dGhcbmh0dHBzOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9kb2N1bWVudGF0aW9uL2dhbWVraXQvZ2tsb2NhbHBsYXllci8xNTE1NDA3LWdlbmVyYXRlaWRlbnRpdHl2ZXJpZmljYXRpb25zaWduI2Rpc2N1c3Npb25cblxuY29uc3QgYXV0aERhdGEgPSB7XG4gIHB1YmxpY0tleVVybDogJ2h0dHBzOi8vdmFsaWQuYXBwbGUuY29tL3B1YmxpYy90aW1lb3V0LmNlcicsXG4gIHRpbWVzdGFtcDogMTQ2MDk4MTQyMTMwMyxcbiAgc2lnbmF0dXJlOiAnUG9Ed2YzOURDTjQ2NEI0OWpKQ1UwZDlZMEonLFxuICBzYWx0OiAnc2FsdFNUPT0nLFxuICBidW5kbGVJZDogJ2NvbS52YWxpZC5hcHAnXG4gIGlkOiAncGxheWVySWQnLFxufTtcbiovXG5cbmNvbnN0IHsgUGFyc2UgfSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuY29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5cbmNvbnN0IGNhY2hlID0ge307IC8vIChwdWJsaWNLZXkgLT4gY2VydCkgY2FjaGVcblxuZnVuY3Rpb24gdmVyaWZ5UHVibGljS2V5VXJsKHB1YmxpY0tleVVybCkge1xuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocHVibGljS2V5VXJsKTtcbiAgaWYgKHBhcnNlZFVybC5wcm90b2NvbCAhPT0gJ2h0dHBzOicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgaG9zdG5hbWVQYXJ0cyA9IHBhcnNlZFVybC5ob3N0bmFtZS5zcGxpdCgnLicpO1xuICBjb25zdCBsZW5ndGggPSBob3N0bmFtZVBhcnRzLmxlbmd0aDtcbiAgY29uc3QgZG9tYWluUGFydHMgPSBob3N0bmFtZVBhcnRzLnNsaWNlKGxlbmd0aCAtIDIsIGxlbmd0aCk7XG4gIGNvbnN0IGRvbWFpbiA9IGRvbWFpblBhcnRzLmpvaW4oJy4nKTtcbiAgcmV0dXJuIGRvbWFpbiA9PT0gJ2FwcGxlLmNvbSc7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRYNTA5Q2VydFRvUEVNKFg1MDlDZXJ0KSB7XG4gIGNvbnN0IHBlbVByZUZpeCA9ICctLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cXG4nO1xuICBjb25zdCBwZW1Qb3N0Rml4ID0gJy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0nO1xuXG4gIGNvbnN0IGJhc2U2NCA9IFg1MDlDZXJ0O1xuICBjb25zdCBjZXJ0Qm9keSA9IGJhc2U2NC5tYXRjaChuZXcgUmVnRXhwKCcuezAsNjR9JywgJ2cnKSkuam9pbignXFxuJyk7XG5cbiAgcmV0dXJuIHBlbVByZUZpeCArIGNlcnRCb2R5ICsgcGVtUG9zdEZpeDtcbn1cblxuZnVuY3Rpb24gZ2V0QXBwbGVDZXJ0aWZpY2F0ZShwdWJsaWNLZXlVcmwpIHtcbiAgaWYgKCF2ZXJpZnlQdWJsaWNLZXlVcmwocHVibGljS2V5VXJsKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgQXBwbGUgR2FtZSBDZW50ZXIgLSBpbnZhbGlkIHB1YmxpY0tleVVybDogJHtwdWJsaWNLZXlVcmx9YFxuICAgICk7XG4gIH1cbiAgaWYgKGNhY2hlW3B1YmxpY0tleVVybF0pIHtcbiAgICByZXR1cm4gY2FjaGVbcHVibGljS2V5VXJsXTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGh0dHBzXG4gICAgICAuZ2V0KHB1YmxpY0tleVVybCwgcmVzID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bmsudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2VydCA9IGNvbnZlcnRYNTA5Q2VydFRvUEVNKGRhdGEpO1xuICAgICAgICAgIGlmIChyZXMuaGVhZGVyc1snY2FjaGUtY29udHJvbCddKSB7XG4gICAgICAgICAgICB2YXIgZXhwaXJlID0gcmVzLmhlYWRlcnNbJ2NhY2hlLWNvbnRyb2wnXS5tYXRjaCgvbWF4LWFnZT0oWzAtOV0rKS8pO1xuICAgICAgICAgICAgaWYgKGV4cGlyZSkge1xuICAgICAgICAgICAgICBjYWNoZVtwdWJsaWNLZXlVcmxdID0gY2VydDtcbiAgICAgICAgICAgICAgLy8gd2UnbGwgZXhwaXJlIHRoZSBjYWNoZSBlbnRyeSBsYXRlciwgYXMgcGVyIG1heC1hZ2VcbiAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNhY2hlW3B1YmxpY0tleVVybF07XG4gICAgICAgICAgICAgIH0sIHBhcnNlSW50KGV4cGlyZVsxXSwgMTApICogMTAwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUoY2VydCk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCByZWplY3QpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKHRpbWVzdGFtcCkge1xuICBjb25zdCBidWZmZXIgPSBCdWZmZXIuYWxsb2MoOCk7XG5cbiAgY29uc3QgaGlnaCA9IH5+KHRpbWVzdGFtcCAvIDB4ZmZmZmZmZmYpO1xuICBjb25zdCBsb3cgPSB0aW1lc3RhbXAgJSAoMHhmZmZmZmZmZiArIDB4MSk7XG5cbiAgYnVmZmVyLndyaXRlVUludDMyQkUocGFyc2VJbnQoaGlnaCwgMTApLCAwKTtcbiAgYnVmZmVyLndyaXRlVUludDMyQkUocGFyc2VJbnQobG93LCAxMCksIDQpO1xuXG4gIHJldHVybiBidWZmZXI7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeVNpZ25hdHVyZShwdWJsaWNLZXksIGF1dGhEYXRhKSB7XG4gIGNvbnN0IHZlcmlmaWVyID0gY3J5cHRvLmNyZWF0ZVZlcmlmeSgnc2hhMjU2Jyk7XG4gIHZlcmlmaWVyLnVwZGF0ZShhdXRoRGF0YS5wbGF5ZXJJZCwgJ3V0ZjgnKTtcbiAgdmVyaWZpZXIudXBkYXRlKGF1dGhEYXRhLmJ1bmRsZUlkLCAndXRmOCcpO1xuICB2ZXJpZmllci51cGRhdGUoY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKGF1dGhEYXRhLnRpbWVzdGFtcCkpO1xuICB2ZXJpZmllci51cGRhdGUoYXV0aERhdGEuc2FsdCwgJ2Jhc2U2NCcpO1xuXG4gIGlmICghdmVyaWZpZXIudmVyaWZ5KHB1YmxpY0tleSwgYXV0aERhdGEuc2lnbmF0dXJlLCAnYmFzZTY0JykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0FwcGxlIEdhbWUgQ2VudGVyIC0gaW52YWxpZCBzaWduYXR1cmUnXG4gICAgKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgaWYgKCFhdXRoRGF0YS5pZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnQXBwbGUgR2FtZSBDZW50ZXIgLSBhdXRoRGF0YSBpZCBtaXNzaW5nJ1xuICAgICk7XG4gIH1cbiAgYXV0aERhdGEucGxheWVySWQgPSBhdXRoRGF0YS5pZDtcbiAgY29uc3QgcHVibGljS2V5ID0gYXdhaXQgZ2V0QXBwbGVDZXJ0aWZpY2F0ZShhdXRoRGF0YS5wdWJsaWNLZXlVcmwpO1xuICByZXR1cm4gdmVyaWZ5U2lnbmF0dXJlKHB1YmxpY0tleSwgYXV0aERhdGEpO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/github.js b/lib/Adapters/Auth/github.js deleted file mode 100644 index 686d718a9c..0000000000 --- a/lib/Adapters/Auth/github.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -// Helper functions for accessing the github API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('user', authData.access_token).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Github auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'api.github.com', - path: '/' + path, - headers: { - Authorization: 'bearer ' + access_token, - 'User-Agent': 'parse-server' - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dpdGh1Yi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsTUFBRCxFQUFTRCxRQUFRLENBQUNFLFlBQWxCLENBQVAsQ0FBdUNDLElBQXZDLENBQTRDQyxJQUFJLElBQUk7QUFDekQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVQsS0FBSyxDQUFDVSxLQUFWLENBQ0pWLEtBQUssQ0FBQ1UsS0FBTixDQUFZQyxnQkFEUixFQUVKLHVDQUZJLENBQU47QUFJRCxHQVJNLENBQVA7QUFTRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNULE9BQVQsQ0FBaUJVLElBQWpCLEVBQXVCVCxZQUF2QixFQUFxQztBQUNuQyxTQUFPSixZQUFZLENBQUNjLEdBQWIsQ0FBaUI7QUFDdEJDLElBQUFBLElBQUksRUFBRSxnQkFEZ0I7QUFFdEJGLElBQUFBLElBQUksRUFBRSxNQUFNQSxJQUZVO0FBR3RCRyxJQUFBQSxPQUFPLEVBQUU7QUFDUEMsTUFBQUEsYUFBYSxFQUFFLFlBQVliLFlBRHBCO0FBRVAsb0JBQWM7QUFGUDtBQUhhLEdBQWpCLENBQVA7QUFRRDs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgZ2l0aHViIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ3VzZXInLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0dpdGh1YiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuZ2l0aHViLmNvbScsXG4gICAgcGF0aDogJy8nICsgcGF0aCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiAnYmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICAnVXNlci1BZ2VudCc6ICdwYXJzZS1zZXJ2ZXInLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/google.js b/lib/Adapters/Auth/google.js deleted file mode 100644 index 91f9c720f5..0000000000 --- a/lib/Adapters/Auth/google.js +++ /dev/null @@ -1,167 +0,0 @@ -'use strict'; // Helper functions for accessing the google API. - -var Parse = require('parse/node').Parse; - -const https = require('https'); - -const jwt = require('jsonwebtoken'); - -const TOKEN_ISSUER = 'accounts.google.com'; -const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com'; -let cache = {}; // Retrieve Google Signin Keys (with cache control) - -function getGoogleKeyByKeyId(keyId) { - if (cache[keyId] && cache.expiresAt > new Date()) { - return cache[keyId]; - } - - return new Promise((resolve, reject) => { - https.get(`https://www.googleapis.com/oauth2/v3/certs`, res => { - let data = ''; - res.on('data', chunk => { - data += chunk.toString('utf8'); - }); - res.on('end', () => { - const { - keys - } = JSON.parse(data); - const pems = keys.reduce((pems, { - n: modulus, - e: exposant, - kid - }) => Object.assign(pems, { - [kid]: rsaPublicKeyToPEM(modulus, exposant) - }), {}); - - if (res.headers['cache-control']) { - var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); - - if (expire) { - cache = Object.assign({}, pems, { - expiresAt: new Date(new Date().getTime() + Number(expire[1]) * 1000) - }); - } - } - - resolve(pems[keyId]); - }); - }).on('error', reject); - }); -} - -function getHeaderFromToken(token) { - const decodedToken = jwt.decode(token, { - complete: true - }); - - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -} - -async function verifyIdToken({ - id_token: token, - id -}, { - clientId -}) { - if (!token) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); - } - - const { - kid: keyId, - alg: algorithm - } = getHeaderFromToken(token); - let jwtClaims; - const googleKey = await getGoogleKeyByKeyId(keyId); - - try { - jwtClaims = jwt.verify(token, googleKey, { - algorithms: algorithm, - audience: clientId - }); - } catch (exception) { - const message = exception.message; - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); - } - - if (jwtClaims.iss !== TOKEN_ISSUER && jwtClaims.iss !== HTTPS_TOKEN_ISSUER) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct provider - expected: ${TOKEN_ISSUER} or ${HTTPS_TOKEN_ISSUER} | from: ${jwtClaims.iss}`); - } - - if (jwtClaims.sub !== id) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); - } - - if (clientId && jwtClaims.aud !== clientId) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not authorized for this clientId.`); - } - - return jwtClaims; -} // Returns a promise that fulfills if this user id is valid. - - -function validateAuthData(authData, options = {}) { - return verifyIdToken(authData, options); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; // Helpers functions to convert the RSA certs to PEM (from jwks-rsa) - -function rsaPublicKeyToPEM(modulusB64, exponentB64) { - const modulus = new Buffer(modulusB64, 'base64'); - const exponent = new Buffer(exponentB64, 'base64'); - const modulusHex = prepadSigned(modulus.toString('hex')); - const exponentHex = prepadSigned(exponent.toString('hex')); - const modlen = modulusHex.length / 2; - const explen = exponentHex.length / 2; - const encodedModlen = encodeLengthHex(modlen); - const encodedExplen = encodeLengthHex(explen); - const encodedPubkey = '30' + encodeLengthHex(modlen + explen + encodedModlen.length / 2 + encodedExplen.length / 2 + 2) + '02' + encodedModlen + modulusHex + '02' + encodedExplen + exponentHex; - const der = new Buffer(encodedPubkey, 'hex').toString('base64'); - let pem = '-----BEGIN RSA PUBLIC KEY-----\n'; - pem += `${der.match(/.{1,64}/g).join('\n')}`; - pem += '\n-----END RSA PUBLIC KEY-----\n'; - return pem; -} - -function prepadSigned(hexStr) { - const msb = hexStr[0]; - - if (msb < '0' || msb > '7') { - return `00${hexStr}`; - } - - return hexStr; -} - -function toHex(number) { - const nstr = number.toString(16); - - if (nstr.length % 2) { - return `0${nstr}`; - } - - return nstr; -} - -function encodeLengthHex(n) { - if (n <= 127) { - return toHex(n); - } - - const nHex = toHex(n); - const lengthOfLengthByte = 128 + nHex.length / 2; - return toHex(lengthOfLengthByte) + nHex; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dvb2dsZS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwcyIsImp3dCIsIlRPS0VOX0lTU1VFUiIsIkhUVFBTX1RPS0VOX0lTU1VFUiIsImNhY2hlIiwiZ2V0R29vZ2xlS2V5QnlLZXlJZCIsImtleUlkIiwiZXhwaXJlc0F0IiwiRGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImtleXMiLCJKU09OIiwicGFyc2UiLCJwZW1zIiwicmVkdWNlIiwibiIsIm1vZHVsdXMiLCJlIiwiZXhwb3NhbnQiLCJraWQiLCJPYmplY3QiLCJhc3NpZ24iLCJyc2FQdWJsaWNLZXlUb1BFTSIsImhlYWRlcnMiLCJleHBpcmUiLCJtYXRjaCIsImdldFRpbWUiLCJOdW1iZXIiLCJnZXRIZWFkZXJGcm9tVG9rZW4iLCJ0b2tlbiIsImRlY29kZWRUb2tlbiIsImRlY29kZSIsImNvbXBsZXRlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiaGVhZGVyIiwidmVyaWZ5SWRUb2tlbiIsImlkX3Rva2VuIiwiaWQiLCJjbGllbnRJZCIsImFsZyIsImFsZ29yaXRobSIsImp3dENsYWltcyIsImdvb2dsZUtleSIsInZlcmlmeSIsImFsZ29yaXRobXMiLCJhdWRpZW5jZSIsImV4Y2VwdGlvbiIsIm1lc3NhZ2UiLCJpc3MiLCJzdWIiLCJhdWQiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwidmFsaWRhdGVBcHBJZCIsIm1vZHVsZSIsImV4cG9ydHMiLCJtb2R1bHVzQjY0IiwiZXhwb25lbnRCNjQiLCJCdWZmZXIiLCJleHBvbmVudCIsIm1vZHVsdXNIZXgiLCJwcmVwYWRTaWduZWQiLCJleHBvbmVudEhleCIsIm1vZGxlbiIsImxlbmd0aCIsImV4cGxlbiIsImVuY29kZWRNb2RsZW4iLCJlbmNvZGVMZW5ndGhIZXgiLCJlbmNvZGVkRXhwbGVuIiwiZW5jb2RlZFB1YmtleSIsImRlciIsInBlbSIsImpvaW4iLCJoZXhTdHIiLCJtc2IiLCJ0b0hleCIsIm51bWJlciIsIm5zdHIiLCJuSGV4IiwibGVuZ3RoT2ZMZW5ndGhCeXRlIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxNQUFNRSxLQUFLLEdBQUdELE9BQU8sQ0FBQyxPQUFELENBQXJCOztBQUNBLE1BQU1FLEdBQUcsR0FBR0YsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7O0FBRUEsTUFBTUcsWUFBWSxHQUFHLHFCQUFyQjtBQUNBLE1BQU1DLGtCQUFrQixHQUFHLDZCQUEzQjtBQUVBLElBQUlDLEtBQUssR0FBRyxFQUFaLEMsQ0FFQTs7QUFDQSxTQUFTQyxtQkFBVCxDQUE2QkMsS0FBN0IsRUFBb0M7QUFDbEMsTUFBSUYsS0FBSyxDQUFDRSxLQUFELENBQUwsSUFBZ0JGLEtBQUssQ0FBQ0csU0FBTixHQUFrQixJQUFJQyxJQUFKLEVBQXRDLEVBQWtEO0FBQ2hELFdBQU9KLEtBQUssQ0FBQ0UsS0FBRCxDQUFaO0FBQ0Q7O0FBRUQsU0FBTyxJQUFJRyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDWCxJQUFBQSxLQUFLLENBQ0ZZLEdBREgsQ0FDUSw0Q0FEUixFQUNxREMsR0FBRyxJQUFJO0FBQ3hELFVBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELE1BQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixRQUFBQSxJQUFJLElBQUlFLEtBQUssQ0FBQ0MsUUFBTixDQUFlLE1BQWYsQ0FBUjtBQUNELE9BRkQ7QUFHQUosTUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sS0FBUCxFQUFjLE1BQU07QUFDbEIsY0FBTTtBQUFFRyxVQUFBQTtBQUFGLFlBQVdDLElBQUksQ0FBQ0Ms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R0FBUDtBQUNEOztBQUVELFNBQVNWLFlBQVQsQ0FBc0JZLE1BQXRCLEVBQThCO0FBQzVCLFFBQU1DLEdBQUcsR0FBR0QsTUFBTSxDQUFDLENBQUQsQ0FBbEI7O0FBQ0EsTUFBSUMsR0FBRyxHQUFHLEdBQU4sSUFBYUEsR0FBRyxHQUFHLEdBQXZCLEVBQTRCO0FBQzFCLFdBQVEsS0FBSUQsTUFBTyxFQUFuQjtBQUNEOztBQUNELFNBQU9BLE1BQVA7QUFDRDs7QUFFRCxTQUFTRSxLQUFULENBQWVDLE1BQWYsRUFBdUI7QUFDckIsUUFBTUMsSUFBSSxHQUFHRCxNQUFNLENBQUNyRSxRQUFQLENBQWdCLEVBQWhCLENBQWI7O0FBQ0EsTUFBSXNFLElBQUksQ0FBQ2IsTUFBTCxHQUFjLENBQWxCLEVBQXFCO0FBQ25CLFdBQVEsSUFBR2EsSUFBSyxFQUFoQjtBQUNEOztBQUNELFNBQU9BLElBQVA7QUFDRDs7QUFFRCxTQUFTVixlQUFULENBQXlCdEQsQ0FBekIsRUFBNEI7QUFDMUIsTUFBSUEsQ0FBQyxJQUFJLEdBQVQsRUFBYztBQUNaLFdBQU84RCxLQUFLLENBQUM5RCxDQUFELENBQVo7QUFDRDs7QUFDRCxRQUFNaUUsSUFBSSxHQUFHSCxLQUFLLENBQUM5RCxDQUFELENBQWxCO0FBQ0EsUUFBTWtFLGtCQUFrQixHQUFHLE1BQU1ELElBQUksQ0FBQ2QsTUFBTCxHQUFjLENBQS9DO0FBQ0EsU0FBT1csS0FBSyxDQUFDSSxrQkFBRCxDQUFMLEdBQTRCRCxJQUFuQztBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGdvb2dsZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IGp3dCA9IHJlcXVpcmUoJ2pzb253ZWJ0b2tlbicpO1xuXG5jb25zdCBUT0tFTl9JU1NVRVIgPSAnYWNjb3VudHMuZ29vZ2xlLmNvbSc7XG5jb25zdCBIVFRQU19UT0tFTl9JU1NVRVIgPSAnaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tJztcblxubGV0IGNhY2hlID0ge307XG5cbi8vIFJldHJpZXZlIEdvb2dsZSBTaWduaW4gS2V5cyAod2l0aCBjYWNoZSBjb250cm9sKVxuZnVuY3Rpb24gZ2V0R29vZ2xlS2V5QnlLZXlJZChrZXlJZCkge1xuICBpZiAoY2FjaGVba2V5SWRdICYmIGNhY2hlLmV4cGlyZXNBdCA+IG5ldyBEYXRlKCkpIHtcbiAgICByZXR1cm4gY2FjaGVba2V5SWRdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YzL2NlcnRzYCwgcmVzID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bmsudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsga2V5cyB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICBjb25zdCBwZW1zID0ga2V5cy5yZWR1Y2UoXG4gICAgICAgICAgICAocGVtcywgeyBuOiBtb2R1bHVzLCBlOiBleHBvc2FudCwga2lkIH0pID0+XG4gICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocGVtcywge1xuICAgICAgICAgICAgICAgIFtraWRdOiByc2FQdWJsaWNLZXlUb1BFTShtb2R1bHVzLCBleHBvc2FudCksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAge31cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHJlcy5oZWFkZXJzWydjYWNoZS1jb250cm9sJ10pIHtcbiAgICAgICAgICAgIHZhciBleHBpcmUgPSByZXMuaGVhZGVyc1snY2FjaGUtY29udHJvbCddLm1hdGNoKC9tYXgtYWdlPShbMC05XSspLyk7XG5cbiAgICAgICAgICAgIGlmIChleHBpcmUpIHtcbiAgICAgICAgICAgICAgY2FjaGUgPSBPYmplY3QuYXNzaWduKHt9LCBwZW1zLCB7XG4gICAgICAgICAgICAgICAgZXhwaXJlc0F0OiBuZXcgRGF0ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgTnVtYmVyKGV4cGlyZVsxXSkgKiAxMDAwXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzb2x2ZShwZW1zW2tleUlkXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCByZWplY3QpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhZGVyRnJvbVRva2VuKHRva2VuKSB7XG4gIGNvbnN0IGRlY29kZWRUb2tlbiA9IGp3dC5kZWNvZGUodG9rZW4sIHsgY29tcGxldGU6IHRydWUgfSk7XG5cbiAgaWYgKCFkZWNvZGVkVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYHByb3ZpZGVkIHRva2VuIGRvZXMgbm90IGRlY29kZSBhcyBKV1RgXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVkVG9rZW4uaGVhZGVyO1xufVxuXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlJZFRva2VuKHsgaWRfdG9rZW46IHRva2VuLCBpZCB9LCB7IGNsaWVudElkIH0pIHtcbiAgaWYgKCF0b2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgaWQgdG9rZW4gaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgeyBraWQ6IGtleUlkLCBhbGc6IGFsZ29yaXRobSB9ID0gZ2V0SGVhZGVyRnJvbVRva2VuKHRva2VuKTtcbiAgbGV0IGp3dENsYWltcztcbiAgY29uc3QgZ29vZ2xlS2V5ID0gYXdhaXQgZ2V0R29vZ2xlS2V5QnlLZXlJZChrZXlJZCk7XG5cbiAgdHJ5IHtcbiAgICBqd3RDbGFpbXMgPSBqd3QudmVyaWZ5KHRva2VuLCBnb29nbGVLZXksIHtcbiAgICAgIGFsZ29yaXRobXM6IGFsZ29yaXRobSxcbiAgICAgIGF1ZGllbmNlOiBjbGllbnRJZCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGV4Y2VwdGlvbi5tZXNzYWdlO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgJHttZXNzYWdlfWApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5pc3MgIT09IFRPS0VOX0lTU1VFUiAmJiBqd3RDbGFpbXMuaXNzICE9PSBIVFRQU19UT0tFTl9JU1NVRVIpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYGlkIHRva2VuIG5vdCBpc3N1ZWQgYnkgY29ycmVjdCBwcm92aWRlciAtIGV4cGVjdGVkOiAke1RPS0VOX0lTU1VFUn0gb3IgJHtIVFRQU19UT0tFTl9JU1NVRVJ9IHwgZnJvbTogJHtqd3RDbGFpbXMuaXNzfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5zdWIgIT09IGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBhdXRoIGRhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmBcbiAgICApO1xuICB9XG5cbiAgaWYgKGNsaWVudElkICYmIGp3dENsYWltcy5hdWQgIT09IGNsaWVudElkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBub3QgYXV0aG9yaXplZCBmb3IgdGhpcyBjbGllbnRJZC5gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBqd3RDbGFpbXM7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiB2ZXJpZnlJZFRva2VuKGF1dGhEYXRhLCBvcHRpb25zKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuXG4vLyBIZWxwZXJzIGZ1bmN0aW9ucyB0byBjb252ZXJ0IHRoZSBSU0EgY2VydHMgdG8gUEVNIChmcm9tIGp3a3MtcnNhKVxuZnVuY3Rpb24gcnNhUHVibGljS2V5VG9QRU0obW9kdWx1c0I2NCwgZXhwb25lbnRCNjQpIHtcbiAgY29uc3QgbW9kdWx1cyA9IG5ldyBCdWZmZXIobW9kdWx1c0I2NCwgJ2Jhc2U2NCcpO1xuICBjb25zdCBleHBvbmVudCA9IG5ldyBCdWZmZXIoZXhwb25lbnRCNjQsICdiYXNlNjQnKTtcbiAgY29uc3QgbW9kdWx1c0hleCA9IHByZXBhZFNpZ25lZChtb2R1bHVzLnRvU3RyaW5nKCdoZXgnKSk7XG4gIGNvbnN0IGV4cG9uZW50SGV4ID0gcHJlcGFkU2lnbmVkKGV4cG9uZW50LnRvU3RyaW5nKCdoZXgnKSk7XG4gIGNvbnN0IG1vZGxlbiA9IG1vZHVsdXNIZXgubGVuZ3RoIC8gMjtcbiAgY29uc3QgZXhwbGVuID0gZXhwb25lbnRIZXgubGVuZ3RoIC8gMjtcblxuICBjb25zdCBlbmNvZGVkTW9kbGVuID0gZW5jb2RlTGVuZ3RoSGV4KG1vZGxlbik7XG4gIGNvbnN0IGVuY29kZWRFeHBsZW4gPSBlbmNvZGVMZW5ndGhIZXgoZXhwbGVuKTtcbiAgY29uc3QgZW5jb2RlZFB1YmtleSA9XG4gICAgJzMwJyArXG4gICAgZW5jb2RlTGVuZ3RoSGV4KFxuICAgICAgbW9kbGVuICsgZXhwbGVuICsgZW5jb2RlZE1vZGxlbi5sZW5ndGggLyAyICsgZW5jb2RlZEV4cGxlbi5sZW5ndGggLyAyICsgMlxuICAgICkgK1xuICAgICcwMicgK1xuICAgIGVuY29kZWRNb2RsZW4gK1xuICAgIG1vZHVsdXNIZXggK1xuICAgICcwMicgK1xuICAgIGVuY29kZWRFeHBsZW4gK1xuICAgIGV4cG9uZW50SGV4O1xuXG4gIGNvbnN0IGRlciA9IG5ldyBCdWZmZXIoZW5jb2RlZFB1YmtleSwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKTtcblxuICBsZXQgcGVtID0gJy0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLVxcbic7XG4gIHBlbSArPSBgJHtkZXIubWF0Y2goLy57MSw2NH0vZykuam9pbignXFxuJyl9YDtcbiAgcGVtICs9ICdcXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXFxuJztcbiAgcmV0dXJuIHBlbTtcbn1cblxuZnVuY3Rpb24gcHJlcGFkU2lnbmVkKGhleFN0cikge1xuICBjb25zdCBtc2IgPSBoZXhTdHJbMF07XG4gIGlmIChtc2IgPCAnMCcgfHwgbXNiID4gJzcnKSB7XG4gICAgcmV0dXJuIGAwMCR7aGV4U3RyfWA7XG4gIH1cbiAgcmV0dXJuIGhleFN0cjtcbn1cblxuZnVuY3Rpb24gdG9IZXgobnVtYmVyKSB7XG4gIGNvbnN0IG5zdHIgPSBudW1iZXIudG9TdHJpbmcoMTYpO1xuICBpZiAobnN0ci5sZW5ndGggJSAyKSB7XG4gICAgcmV0dXJuIGAwJHtuc3RyfWA7XG4gIH1cbiAgcmV0dXJuIG5zdHI7XG59XG5cbmZ1bmN0aW9uIGVuY29kZUxlbmd0aEhleChuKSB7XG4gIGlmIChuIDw9IDEyNykge1xuICAgIHJldHVybiB0b0hleChuKTtcbiAgfVxuICBjb25zdCBuSGV4ID0gdG9IZXgobik7XG4gIGNvbnN0IGxlbmd0aE9mTGVuZ3RoQnl0ZSA9IDEyOCArIG5IZXgubGVuZ3RoIC8gMjtcbiAgcmV0dXJuIHRvSGV4KGxlbmd0aE9mTGVuZ3RoQnl0ZSkgKyBuSGV4O1xufVxuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/gpgames.js b/lib/Adapters/Auth/gpgames.js deleted file mode 100644 index 57d5686d06..0000000000 --- a/lib/Adapters/Auth/gpgames.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; - -/* Google Play Game Services -https://developers.google.com/games/services/web/api/players/get - -const authData = { - id: 'playerId', - access_token: 'token', -}; -*/ -const { - Parse -} = require('parse/node'); - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. - - -async function validateAuthData(authData) { - const response = await httpsRequest.get(`https://www.googleapis.com/games/v1/players/${authData.id}?access_token=${authData.access_token}`); - - if (!(response && response.playerId === authData.id)) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Google Play Games Services - authData is invalid for this user.'); - } -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dwZ2FtZXMuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVzcG9uc2UiLCJnZXQiLCJpZCIsImFjY2Vzc190b2tlbiIsInBsYXllcklkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7Ozs7Ozs7QUFRQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxlQUFlRSxnQkFBZixDQUFnQ0MsUUFBaEMsRUFBMEM7QUFDeEMsUUFBTUMsUUFBUSxHQUFHLE1BQU1ILFlBQVksQ0FBQ0ksR0FBYixDQUNwQiwrQ0FBOENGLFFBQVEsQ0FBQ0csRUFBRyxpQkFBZ0JILFFBQVEsQ0FBQ0ksWUFBYSxFQUQ1RSxDQUF2Qjs7QUFHQSxNQUFJLEVBQUVILFFBQVEsSUFBSUEsUUFBUSxDQUFDSSxRQUFULEtBQXNCTCxRQUFRLENBQUNHLEVBQTdDLENBQUosRUFBc0Q7QUFDcEQsVUFBTSxJQUFJUCxLQUFLLENBQUNVLEtBQVYsQ0FDSlYsS0FBSyxDQUFDVSxLQUFOLENBQVlDLGdCQURSLEVBRUosaUVBRkksQ0FBTjtBQUlEO0FBQ0YsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRURDLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmSixFQUFBQSxhQURlO0FBRWZULEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBHb29nbGUgUGxheSBHYW1lIFNlcnZpY2VzXG5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9nYW1lcy9zZXJ2aWNlcy93ZWIvYXBpL3BsYXllcnMvZ2V0XG5cbmNvbnN0IGF1dGhEYXRhID0ge1xuICBpZDogJ3BsYXllcklkJyxcbiAgYWNjZXNzX3Rva2VuOiAndG9rZW4nLFxufTtcbiovXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBodHRwc1JlcXVlc3QuZ2V0KFxuICAgIGBodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9nYW1lcy92MS9wbGF5ZXJzLyR7YXV0aERhdGEuaWR9P2FjY2Vzc190b2tlbj0ke2F1dGhEYXRhLmFjY2Vzc190b2tlbn1gXG4gICk7XG4gIGlmICghKHJlc3BvbnNlICYmIHJlc3BvbnNlLnBsYXllcklkID09PSBhdXRoRGF0YS5pZCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0dvb2dsZSBQbGF5IEdhbWVzIFNlcnZpY2VzIC0gYXV0aERhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/httpsRequest.js b/lib/Adapters/Auth/httpsRequest.js deleted file mode 100644 index ba7cba94ca..0000000000 --- a/lib/Adapters/Auth/httpsRequest.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -const https = require('https'); - -function makeCallback(resolve, reject, noJSON) { - return function (res) { - let data = ''; - res.on('data', chunk => { - data += chunk; - }); - res.on('end', () => { - if (noJSON) { - return resolve(data); - } - - try { - data = JSON.parse(data); - } catch (e) { - return reject(e); - } - - resolve(data); - }); - res.on('error', reject); - }; -} - -function get(options, noJSON = false) { - return new Promise((resolve, reject) => { - https.get(options, makeCallback(resolve, reject, noJSON)).on('error', reject); - }); -} - -function request(options, postData) { - return new Promise((resolve, reject) => { - const req = https.request(options, makeCallback(resolve, reject)); - req.on('error', reject); - req.write(postData); - req.end(); - }); -} - -module.exports = { - get, - request -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2h0dHBzUmVxdWVzdC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0Iiwibm9KU09OIiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJlIiwiZ2V0Iiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXF1ZXN0IiwicG9zdERhdGEiLCJyZXEiLCJ3cml0ZSIsImVuZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsT0FBRCxDQUFyQjs7QUFFQSxTQUFTQyxZQUFULENBQXNCQyxPQUF0QixFQUErQkMsTUFBL0IsRUFBdUNDLE1BQXZDLEVBQStDO0FBQzdDLFNBQU8sVUFBU0MsR0FBVCxFQUFjO0FBQ25CLFFBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixNQUFBQSxJQUFJLElBQUlFLEtBQVI7QUFDRCxLQUZEO0FBR0FILElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLEtBQVAsRUFBYyxNQUFNO0FBQ2xCLFVBQUlILE1BQUosRUFBWTtBQUNWLGVBQU9GLE9BQU8sQ0FBQ0ksSUFBRCxDQUFkO0FBQ0Q7O0FBQ0QsVUFBSTtBQUNGQSxRQUFBQSxJQUFJLEdBQUdHLElBQUksQ0FBQ0MsS0FBTCxDQUFXSixJQUFYLENBQVA7QUFDRCxPQUZELENBRUUsT0FBT0ssQ0FBUCxFQUFVO0FBQ1YsZUFBT1IsTUFBTSxDQUFDUSxDQUFELENBQWI7QUFDRDs7QUFDRFQsTUFBQUEsT0FBTyxDQUFDSSxJQUFELENBQVA7QUFDRCxLQVZEO0FBV0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE9BQVAsRUFBZ0JKLE1BQWhCO0FBQ0QsR0FqQkQ7QUFrQkQ7O0FBRUQsU0FBU1MsR0FBVCxDQUFhQyxPQUFiLEVBQXNCVCxNQUFNLEdBQUcsS0FBL0IsRUFBc0M7QUFDcEMsU0FBTyxJQUFJVSxPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDSixJQUFBQSxLQUFLLENBQ0ZhLEdBREgsQ0FDT0MsT0FEUCxFQUNnQlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsRUFBa0JDLE1BQWxCLENBRDVCLEVBRUdHLEVBRkgsQ0FFTSxPQUZOLEVBRWVKLE1BRmY7QUFHRCxHQUpNLENBQVA7QUFLRDs7QUFFRCxTQUFTWSxPQUFULENBQWlCRixPQUFqQixFQUEwQkcsUUFBMUIsRUFBb0M7QUFDbEMsU0FBTyxJQUFJRixPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDLFVBQU1jLEdBQUcsR0FBR2xCLEtBQUssQ0FBQ2dCLE9BQU4sQ0FBY0YsT0FBZCxFQUF1QlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsQ0FBbkMsQ0FBWjtBQUNBYyxJQUFBQSxHQUFHLENBQUNWLEVBQUosQ0FBTyxPQUFQLEVBQWdCSixNQUFoQjtBQUNBYyxJQUFBQSxHQUFHLENBQUNDLEtBQUosQ0FBVUYsUUFBVjtBQUNBQyxJQUFBQSxHQUFHLENBQUNFLEdBQUo7QUFDRCxHQUxNLENBQVA7QUFNRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQUVULEVBQUFBLEdBQUY7QUFBT0csRUFBQUE7QUFBUCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcblxuZnVuY3Rpb24gbWFrZUNhbGxiYWNrKHJlc29sdmUsIHJlamVjdCwgbm9KU09OKSB7XG4gIHJldHVybiBmdW5jdGlvbihyZXMpIHtcbiAgICBsZXQgZGF0YSA9ICcnO1xuICAgIHJlcy5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgfSk7XG4gICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBpZiAobm9KU09OKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGRhdGEpO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoZSk7XG4gICAgICB9XG4gICAgICByZXNvbHZlKGRhdGEpO1xuICAgIH0pO1xuICAgIHJlcy5vbignZXJyb3InLCByZWplY3QpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBnZXQob3B0aW9ucywgbm9KU09OID0gZmFsc2UpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChvcHRpb25zLCBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0LCBub0pTT04pKVxuICAgICAgLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0KG9wdGlvbnMsIHBvc3REYXRhKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gaHR0cHMucmVxdWVzdChvcHRpb25zLCBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSk7XG4gICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgcmVxLndyaXRlKHBvc3REYXRhKTtcbiAgICByZXEuZW5kKCk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHsgZ2V0LCByZXF1ZXN0IH07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/index.js b/lib/Adapters/Auth/index.js deleted file mode 100755 index 00dced2172..0000000000 --- a/lib/Adapters/Auth/index.js +++ /dev/null @@ -1,173 +0,0 @@ -"use strict"; - -var _AdapterLoader = _interopRequireDefault(require("../AdapterLoader")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const apple = require('./apple'); - -const gcenter = require('./gcenter'); - -const gpgames = require('./gpgames'); - -const facebook = require('./facebook'); - -const instagram = require('./instagram'); - -const linkedin = require('./linkedin'); - -const meetup = require('./meetup'); - -const google = require('./google'); - -const github = require('./github'); - -const twitter = require('./twitter'); - -const spotify = require('./spotify'); - -const digits = require('./twitter'); // digits tokens are validated by twitter - - -const janrainengage = require('./janrainengage'); - -const janraincapture = require('./janraincapture'); - -const line = require('./line'); - -const vkontakte = require('./vkontakte'); - -const qq = require('./qq'); - -const wechat = require('./wechat'); - -const weibo = require('./weibo'); - -const oauth2 = require('./oauth2'); - -const phantauth = require('./phantauth'); - -const microsoft = require('./microsoft'); - -const keycloak = require('./keycloak'); - -const ldap = require('./ldap'); - -const anonymous = { - validateAuthData: () => { - return Promise.resolve(); - }, - validateAppId: () => { - return Promise.resolve(); - } -}; -const providers = { - apple, - gcenter, - gpgames, - facebook, - instagram, - linkedin, - meetup, - google, - github, - twitter, - spotify, - anonymous, - digits, - janrainengage, - janraincapture, - line, - vkontakte, - qq, - wechat, - weibo, - phantauth, - microsoft, - keycloak, - ldap -}; - -function authDataValidator(adapter, appIds, options) { - return function (authData) { - return adapter.validateAuthData(authData, options).then(() => { - if (appIds) { - return adapter.validateAppId(appIds, authData, options); - } - - return Promise.resolve(); - }); - }; -} - -function loadAuthAdapter(provider, authOptions) { - let defaultAdapter = providers[provider]; - const providerOptions = authOptions[provider]; - - if (providerOptions && Object.prototype.hasOwnProperty.call(providerOptions, 'oauth2') && providerOptions['oauth2'] === true) { - defaultAdapter = oauth2; - } - - if (!defaultAdapter && !providerOptions) { - return; - } - - const adapter = Object.assign({}, defaultAdapter); - const appIds = providerOptions ? providerOptions.appIds : undefined; // Try the configuration methods - - if (providerOptions) { - const optionalAdapter = (0, _AdapterLoader.default)(providerOptions, undefined, providerOptions); - - if (optionalAdapter) { - ['validateAuthData', 'validateAppId'].forEach(key => { - if (optionalAdapter[key]) { - adapter[key] = optionalAdapter[key]; - } - }); - } - } // TODO: create a new module from validateAdapter() in - // src/Controllers/AdaptableController.js so we can use it here for adapter - // validation based on the src/Adapters/Auth/AuthAdapter.js expected class - // signature. - - - if (!adapter.validateAuthData || !adapter.validateAppId) { - return; - } - - return { - adapter, - appIds, - providerOptions - }; -} - -module.exports = function (authOptions = {}, enableAnonymousUsers = true) { - let _enableAnonymousUsers = enableAnonymousUsers; - - const setEnableAnonymousUsers = function (enable) { - _enableAnonymousUsers = enable; - }; // To handle the test cases on configuration - - - const getValidatorForProvider = function (provider) { - if (provider === 'anonymous' && !_enableAnonymousUsers) { - return; - } - - const { - adapter, - appIds, - providerOptions - } = loadAuthAdapter(provider, authOptions); - return authDataValidator(adapter, appIds, providerOptions); - }; - - return Object.freeze({ - getValidatorForProvider, - setEnableAnonymousUsers - }); -}; - -module.exports.loadAuthAdapter = loadAuthAdapter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luZGV4LmpzIl0sIm5hbWVzIjpbImFwcGxlIiwicmVxdWlyZSIsImdjZW50ZXIiLCJncGdhbWVzIiwiZmFjZWJvb2siLCJpbnN0YWdyYW0iLCJsaW5rZWRpbiIsIm1lZXR1cCIsImdvb2dsZSIsImdpdGh1YiIsInR3aXR0ZXIiLCJzcG90aWZ5IiwiZGlnaXRzIiwiamFucmFpbmVuZ2FnZSIsImphbnJhaW5jYXB0dXJlIiwibGluZSIsInZrb250YWt0ZSIsInFxIiwid2VjaGF0Iiwid2VpYm8iLCJvYXV0aDIiLCJwaGFudGF1dGgiLCJtaWNyb3NvZnQiLCJrZXljbG9hayIsImxkYXAiLCJhbm9ueW1vdXMiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUFwcElkIiwicHJvdmlkZXJzIiwiYXV0aERhdGFWYWxpZGF0b3IiLCJhZGFwdGVyIiwiYXBwSWRzIiwib3B0aW9ucyIsImF1dGhEYXRhIiwidGhlbiIsImxvYWRBdXRoQWRhcHRlciIsInByb3ZpZGVyIiwiYXV0aE9wdGlvbnMiLCJkZWZhdWx0QWRhcHRlciIsInByb3ZpZGVyT3B0aW9ucyIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFzc2lnbiIsInVuZGVmaW5lZCIsIm9wdGlvbmFsQWRhcHRlciIsImZvckVhY2giLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIiwiZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJfZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJzZXRFbmFibGVBbm9ueW1vdXNVc2VycyIsImVuYWJsZSIsImdldFZhbGlkYXRvckZvclByb3ZpZGVyIiwiZnJlZXplIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0FBRUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsU0FBRCxDQUFyQjs7QUFDQSxNQUFNQyxPQUFPLEdBQUdELE9BQU8sQ0FBQyxXQUFELENBQXZCOztBQUNB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Q0FBQ0MsT0FBUCxDQUFlZixlQUFmLEdBQWlDQSxlQUFqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2FkQWRhcHRlciBmcm9tICcuLi9BZGFwdGVyTG9hZGVyJztcblxuY29uc3QgYXBwbGUgPSByZXF1aXJlKCcuL2FwcGxlJyk7XG5jb25zdCBnY2VudGVyID0gcmVxdWlyZSgnLi9nY2VudGVyJyk7XG5jb25zdCBncGdhbWVzID0gcmVxdWlyZSgnLi9ncGdhbWVzJyk7XG5jb25zdCBmYWNlYm9vayA9IHJlcXVpcmUoJy4vZmFjZWJvb2snKTtcbmNvbnN0IGluc3RhZ3JhbSA9IHJlcXVpcmUoJy4vaW5zdGFncmFtJyk7XG5jb25zdCBsaW5rZWRpbiA9IHJlcXVpcmUoJy4vbGlua2VkaW4nKTtcbmNvbnN0IG1lZXR1cCA9IHJlcXVpcmUoJy4vbWVldHVwJyk7XG5jb25zdCBnb29nbGUgPSByZXF1aXJlKCcuL2dvb2dsZScpO1xuY29uc3QgZ2l0aHViID0gcmVxdWlyZSgnLi9naXRodWInKTtcbmNvbnN0IHR3aXR0ZXIgPSByZXF1aXJlKCcuL3R3aXR0ZXInKTtcbmNvbnN0IHNwb3RpZnkgPSByZXF1aXJlKCcuL3Nwb3RpZnknKTtcbmNvbnN0IGRpZ2l0cyA9IHJlcXVpcmUoJy4vdHdpdHRlcicpOyAvLyBkaWdpdHMgdG9rZW5zIGFyZSB2YWxpZGF0ZWQgYnkgdHdpdHRlclxuY29uc3QgamFucmFpbmVuZ2FnZSA9IHJlcXVpcmUoJy4vamFucmFpbmVuZ2FnZScpO1xuY29uc3QgamFucmFpbmNhcHR1cmUgPSByZXF1aXJlKCcuL2phbnJhaW5jYXB0dXJlJyk7XG5jb25zdCBsaW5lID0gcmVxdWlyZSgnLi9saW5lJyk7XG5jb25zdCB2a29udGFrdGUgPSByZXF1aXJlKCcuL3Zrb250YWt0ZScpO1xuY29uc3QgcXEgPSByZXF1aXJlKCcuL3FxJyk7XG5jb25zdCB3ZWNoYXQgPSByZXF1aXJlKCcuL3dlY2hhdCcpO1xuY29uc3Qgd2VpYm8gPSByZXF1aXJlKCcuL3dlaWJvJyk7XG5jb25zdCBvYXV0aDIgPSByZXF1aXJlKCcuL29hdXRoMicpO1xuY29uc3QgcGhhbnRhdXRoID0gcmVxdWlyZSgnLi9waGFudGF1dGgnKTtcbmNvbnN0IG1pY3Jvc29mdCA9IHJlcXVpcmUoJy4vbWljcm9zb2Z0Jyk7XG5jb25zdCBrZXljbG9hayA9IHJlcXVpcmUoJy4va2V5Y2xvYWsnKTtcbmNvbnN0IGxkYXAgPSByZXF1aXJlKCcuL2xkYXAnKTtcblxuY29uc3QgYW5vbnltb3VzID0ge1xuICB2YWxpZGF0ZUF1dGhEYXRhOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxuICB2YWxpZGF0ZUFwcElkOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxufTtcblxuY29uc3QgcHJvdmlkZXJzID0ge1xuICBhcHBsZSxcbiAgZ2NlbnRlcixcbiAgZ3BnYW1lcyxcbiAgZmFjZWJvb2ssXG4gIGluc3RhZ3JhbSxcbiAgbGlua2VkaW4sXG4gIG1lZXR1cCxcbiAgZ29vZ2xlLFxuICBnaXRodWIsXG4gIHR3aXR0ZXIsXG4gIHNwb3RpZnksXG4gIGFub255bW91cyxcbiAgZGlnaXRzLFxuICBqYW5yYWluZW5nYWdlLFxuICBqYW5yYWluY2FwdHVyZSxcbiAgbGluZSxcbiAgdmtvbnRha3RlLFxuICBxcSxcbiAgd2VjaGF0LFxuICB3ZWlibyxcbiAgcGhhbnRhdXRoLFxuICBtaWNyb3NvZnQsXG4gIGtleWNsb2FrLFxuICBsZGFwLFxufTtcblxuZnVuY3Rpb24gYXV0aERhdGFWYWxpZGF0b3IoYWRhcHRlciwgYXBwSWRzLCBvcHRpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgICByZXR1cm4gYWRhcHRlci52YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChhcHBJZHMpIHtcbiAgICAgICAgcmV0dXJuIGFkYXB0ZXIudmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9hZEF1dGhBZGFwdGVyKHByb3ZpZGVyLCBhdXRoT3B0aW9ucykge1xuICBsZXQgZGVmYXVsdEFkYXB0ZXIgPSBwcm92aWRlcnNbcHJvdmlkZXJdO1xuICBjb25zdCBwcm92aWRlck9wdGlvbnMgPSBhdXRoT3B0aW9uc1twcm92aWRlcl07XG4gIGlmIChcbiAgICBwcm92aWRlck9wdGlvbnMgJiZcbiAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocHJvdmlkZXJPcHRpb25zLCAnb2F1dGgyJykgJiZcbiAgICBwcm92aWRlck9wdGlvbnNbJ29hdXRoMiddID09PSB0cnVlXG4gICkge1xuICAgIGRlZmF1bHRBZGFwdGVyID0gb2F1dGgyO1xuICB9XG5cbiAgaWYgKCFkZWZhdWx0QWRhcHRlciAmJiAhcHJvdmlkZXJPcHRpb25zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgYWRhcHRlciA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRBZGFwdGVyKTtcbiAgY29uc3QgYXBwSWRzID0gcHJvdmlkZXJPcHRpb25zID8gcHJvdmlkZXJPcHRpb25zLmFwcElkcyA6IHVuZGVmaW5lZDtcblxuICAvLyBUcnkgdGhlIGNvbmZpZ3VyYXRpb24gbWV0aG9kc1xuICBpZiAocHJvdmlkZXJPcHRpb25zKSB7XG4gICAgY29uc3Qgb3B0aW9uYWxBZGFwdGVyID0gbG9hZEFkYXB0ZXIoXG4gICAgICBwcm92aWRlck9wdGlvbnMsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBwcm92aWRlck9wdGlvbnNcbiAgICApO1xuICAgIGlmIChvcHRpb25hbEFkYXB0ZXIpIHtcbiAgICAgIFsndmFsaWRhdGVBdXRoRGF0YScsICd2YWxpZGF0ZUFwcElkJ10uZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBpZiAob3B0aW9uYWxBZGFwdGVyW2tleV0pIHtcbiAgICAgICAgICBhZGFwdGVyW2tleV0gPSBvcHRpb25hbEFkYXB0ZXJba2V5XTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETzogY3JlYXRlIGEgbmV3IG1vZHVsZSBmcm9tIHZhbGlkYXRlQWRhcHRlcigpIGluXG4gIC8vIHNyYy9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyLmpzIHNvIHdlIGNhbiB1c2UgaXQgaGVyZSBmb3IgYWRhcHRlclxuICAvLyB2YWxpZGF0aW9uIGJhc2VkIG9uIHRoZSBzcmMvQWRhcHRlcnMvQXV0aC9BdXRoQWRhcHRlci5qcyBleHBlY3RlZCBjbGFzc1xuICAvLyBzaWduYXR1cmUuXG4gIGlmICghYWRhcHRlci52YWxpZGF0ZUF1dGhEYXRhIHx8ICFhZGFwdGVyLnZhbGlkYXRlQXBwSWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4geyBhZGFwdGVyLCBhcHBJZHMsIHByb3ZpZGVyT3B0aW9ucyB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhdXRoT3B0aW9ucyA9IHt9LCBlbmFibGVBbm9ueW1vdXNVc2VycyA9IHRydWUpIHtcbiAgbGV0IF9lbmFibGVBbm9ueW1vdXNVc2VycyA9IGVuYWJsZUFub255bW91c1VzZXJzO1xuICBjb25zdCBzZXRFbmFibGVBbm9ueW1vdXNVc2VycyA9IGZ1bmN0aW9uIChlbmFibGUpIHtcbiAgICBfZW5hYmxlQW5vbnltb3VzVXNlcnMgPSBlbmFibGU7XG4gIH07XG4gIC8vIFRvIGhhbmRsZSB0aGUgdGVzdCBjYXNlcyBvbiBjb25maWd1cmF0aW9uXG4gIGNvbnN0IGdldFZhbGlkYXRvckZvclByb3ZpZGVyID0gZnVuY3Rpb24gKHByb3ZpZGVyKSB7XG4gICAgaWYgKHByb3ZpZGVyID09PSAnYW5vbnltb3VzJyAmJiAhX2VuYWJsZUFub255bW91c1VzZXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBhZGFwdGVyLCBhcHBJZHMsIHByb3ZpZGVyT3B0aW9ucyB9ID0gbG9hZEF1dGhBZGFwdGVyKFxuICAgICAgcHJvdmlkZXIsXG4gICAgICBhdXRoT3B0aW9uc1xuICAgICk7XG5cbiAgICByZXR1cm4gYXV0aERhdGFWYWxpZGF0b3IoYWRhcHRlciwgYXBwSWRzLCBwcm92aWRlck9wdGlvbnMpO1xuICB9O1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBnZXRWYWxpZGF0b3JGb3JQcm92aWRlcixcbiAgICBzZXRFbmFibGVBbm9ueW1vdXNVc2VycyxcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5sb2FkQXV0aEFkYXB0ZXIgPSBsb2FkQXV0aEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/instagram.js b/lib/Adapters/Auth/instagram.js deleted file mode 100644 index 46032bbada..0000000000 --- a/lib/Adapters/Auth/instagram.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -// Helper functions for accessing the instagram API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); - -const defaultURL = 'https://graph.instagram.com/'; // Returns a promise that fulfills if this user id is valid. - -function validateAuthData(authData) { - const apiURL = authData.apiURL || defaultURL; - const path = `${apiURL}me?fields=id&access_token=${authData.access_token}`; - return httpsRequest.get(path).then(response => { - if (response && response.data && response.data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Instagram auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luc3RhZ3JhbS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJkZWZhdWx0VVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiYXBpVVJMIiwicGF0aCIsImFjY2Vzc190b2tlbiIsImdldCIsInRoZW4iLCJyZXNwb25zZSIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JELEtBQWxDOztBQUNBLE1BQU1FLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLE1BQU1FLFVBQVUsR0FBRyw4QkFBbkIsQyxDQUVBOztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxRQUFNQyxNQUFNLEdBQUdELFFBQVEsQ0FBQ0MsTUFBVCxJQUFtQkgsVUFBbEM7QUFDQSxRQUFNSSxJQUFJLEdBQUksR0FBRUQsTUFBTyw2QkFBNEJELFFBQVEsQ0FBQ0csWUFBYSxFQUF6RTtBQUNBLFNBQU9OLFlBQVksQ0FBQ08sR0FBYixDQUFpQkYsSUFBakIsRUFBdUJHLElBQXZCLENBQTRCQyxRQUFRLElBQUk7QUFDN0MsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLElBQXJCLElBQTZCRCxRQUFRLENBQUNDLElBQVQsQ0FBY0MsRUFBZCxJQUFvQlIsUUFBUSxDQUFDUSxFQUE5RCxFQUFrRTtBQUNoRTtBQUNEOztBQUNELFVBQU0sSUFBSWIsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZQyxnQkFEUixFQUVKLDBDQUZJLENBQU47QUFJRCxHQVJNLENBQVA7QUFTRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZKLEVBQUFBLGFBRGU7QUFFZlosRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgaW5zdGFncmFtIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5jb25zdCBkZWZhdWx0VVJMID0gJ2h0dHBzOi8vZ3JhcGguaW5zdGFncmFtLmNvbS8nO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgY29uc3QgYXBpVVJMID0gYXV0aERhdGEuYXBpVVJMIHx8IGRlZmF1bHRVUkw7XG4gIGNvbnN0IHBhdGggPSBgJHthcGlVUkx9bWU/ZmllbGRzPWlkJmFjY2Vzc190b2tlbj0ke2F1dGhEYXRhLmFjY2Vzc190b2tlbn1gO1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldChwYXRoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuZGF0YSAmJiByZXNwb25zZS5kYXRhLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnSW5zdGFncmFtIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/janraincapture.js b/lib/Adapters/Auth/janraincapture.js deleted file mode 100644 index d113cc5285..0000000000 --- a/lib/Adapters/Auth/janraincapture.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Janrain Capture API. -var Parse = require('parse/node').Parse; - -var querystring = require('querystring'); - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - return request(options.janrain_capture_host, authData.access_token).then(data => { - //successful response will have a "stat" (status) of 'ok' and a result node that stores the uuid, because that's all we asked for - //see: https://docs.janrain.com/api/registration/entity/#entity - if (data && data.stat == 'ok' && data.result == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain capture auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - //no-op - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(host, access_token) { - var query_string_data = querystring.stringify({ - access_token: access_token, - attribute_name: 'uuid' // we only need to pull the uuid for this access token to make sure it matches - - }); - return httpsRequest.get({ - host: host, - path: '/entity?' + query_string_data - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5jYXB0dXJlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsInF1ZXJ5c3RyaW5nIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3QiLCJqYW5yYWluX2NhcHR1cmVfaG9zdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwic3RhdCIsInJlc3VsdCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiaG9zdCIsInF1ZXJ5X3N0cmluZ19kYXRhIiwic3RyaW5naWZ5IiwiYXR0cmlidXRlX25hbWUiLCJnZXQiLCJwYXRoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsSUFBSUUsV0FBVyxHQUFHRCxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFDQSxNQUFNRSxZQUFZLEdBQUdGLE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNHLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT0MsT0FBTyxDQUFDRCxPQUFPLENBQUNFLG9CQUFULEVBQStCSCxRQUFRLENBQUNJLFlBQXhDLENBQVAsQ0FBNkRDLElBQTdELENBQ0xDLElBQUksSUFBSTtBQUNOO0FBQ0E7QUFDQSxRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsSUFBTCxJQUFhLElBQXJCLElBQTZCRCxJQUFJLENBQUNFLE1BQUwsSUFBZVIsUUFBUSxDQUFDUyxFQUF6RCxFQUE2RDtBQUMzRDtBQUNEOztBQUNELFVBQU0sSUFBSWQsS0FBSyxDQUFDZSxLQUFWLENBQ0pmLEtBQUssQ0FBQ2UsS0FBTixDQUFZQyxnQkFEUixFQUVKLGdEQUZJLENBQU47QUFJRCxHQVhJLENBQVA7QUFhRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkI7QUFDQSxTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1osT0FBVCxDQUFpQmEsSUFBakIsRUFBdUJYLFlBQXZCLEVBQXFDO0FBQ25DLE1BQUlZLGlCQUFpQixHQUFHbkIsV0FBVyxDQUFDb0IsU0FBWixDQUFzQjtBQUM1Q2IsSUFBQUEsWUFBWSxFQUFFQSxZQUQ4QjtBQUU1Q2MsSUFBQUEsY0FBYyxFQUFFLE1BRjRCLENBRXBCOztBQUZvQixHQUF0QixDQUF4QjtBQUtBLFNBQU9wQixZQUFZLENBQUNxQixHQUFiLENBQWlCO0FBQUVKLElBQUFBLElBQUksRUFBRUEsSUFBUjtBQUFjSyxJQUFBQSxJQUFJLEVBQUUsYUFBYUo7QUFBakMsR0FBakIsQ0FBUDtBQUNEOztBQUVESyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlYsRUFBQUEsYUFBYSxFQUFFQSxhQURBO0FBRWZiLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBKYW5yYWluIENhcHR1cmUgQVBJLlxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xudmFyIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHJlcXVlc3Qob3B0aW9ucy5qYW5yYWluX2NhcHR1cmVfaG9zdCwgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKFxuICAgIGRhdGEgPT4ge1xuICAgICAgLy9zdWNjZXNzZnVsIHJlc3BvbnNlIHdpbGwgaGF2ZSBhIFwic3RhdFwiIChzdGF0dXMpIG9mICdvaycgYW5kIGEgcmVzdWx0IG5vZGUgdGhhdCBzdG9yZXMgdGhlIHV1aWQsIGJlY2F1c2UgdGhhdCdzIGFsbCB3ZSBhc2tlZCBmb3JcbiAgICAgIC8vc2VlOiBodHRwczovL2RvY3MuamFucmFpbi5jb20vYXBpL3JlZ2lzdHJhdGlvbi9lbnRpdHkvI2VudGl0eVxuICAgICAgaWYgKGRhdGEgJiYgZGF0YS5zdGF0ID09ICdvaycgJiYgZGF0YS5yZXN1bHQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAnSmFucmFpbiBjYXB0dXJlIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICAgICk7XG4gICAgfVxuICApO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIC8vbm8tb3BcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChob3N0LCBhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIHF1ZXJ5X3N0cmluZ19kYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICBhY2Nlc3NfdG9rZW46IGFjY2Vzc190b2tlbixcbiAgICBhdHRyaWJ1dGVfbmFtZTogJ3V1aWQnLCAvLyB3ZSBvbmx5IG5lZWQgdG8gcHVsbCB0aGUgdXVpZCBmb3IgdGhpcyBhY2Nlc3MgdG9rZW4gdG8gbWFrZSBzdXJlIGl0IG1hdGNoZXNcbiAgfSk7XG5cbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoeyBob3N0OiBob3N0LCBwYXRoOiAnL2VudGl0eT8nICsgcXVlcnlfc3RyaW5nX2RhdGEgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/janrainengage.js b/lib/Adapters/Auth/janrainengage.js deleted file mode 100644 index d7c4774377..0000000000 --- a/lib/Adapters/Auth/janrainengage.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Janrain Engage API. -var httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; - -var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - return apiRequest(options.api_key, authData.auth_token).then(data => { - //successful response will have a "stat" (status) of 'ok' and a profile node with an identifier - //see: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data - if (data && data.stat == 'ok' && data.profile.identifier == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain engage auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - //no-op - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function apiRequest(api_key, auth_token) { - var post_data = querystring.stringify({ - token: auth_token, - apiKey: api_key, - format: 'json' - }); - var post_options = { - host: 'rpxnow.com', - path: '/api/v2/auth_info', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': post_data.length - } - }; - return httpsRequest.request(post_options, post_data); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5lbmdhZ2UuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwicXVlcnlzdHJpbmciLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiYXBpUmVxdWVzdCIsImFwaV9rZXkiLCJhdXRoX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdGF0IiwicHJvZmlsZSIsImlkZW50aWZpZXIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3RfZGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiYXBpS2V5IiwiZm9ybWF0IiwicG9zdF9vcHRpb25zIiwiaG9zdCIsInBhdGgiLCJtZXRob2QiLCJoZWFkZXJzIiwibGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLFNBQU9DLFVBQVUsQ0FBQ0QsT0FBTyxDQUFDRSxPQUFULEVBQWtCSCxRQUFRLENBQUNJLFVBQTNCLENBQVYsQ0FBaURDLElBQWpELENBQXNEQyxJQUFJLElBQUk7QUFDbkU7QUFDQTtBQUNBLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxJQUFMLElBQWEsSUFBckIsSUFBNkJELElBQUksQ0FBQ0UsT0FBTCxDQUFhQyxVQUFiLElBQTJCVCxRQUFRLENBQUNVLEVBQXJFLEVBQXlFO0FBQ3ZFO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJYixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLGdCQURSLEVBRUosK0NBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QjtBQUNBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTYixVQUFULENBQW9CQyxPQUFwQixFQUE2QkMsVUFBN0IsRUFBeUM7QUFDdkMsTUFBSVksU0FBUyxHQUFHbEIsV0FBVyxDQUFDbUIsU0FBWixDQUFzQjtBQUNwQ0MsSUFBQUEsS0FBSyxFQUFFZCxVQUQ2QjtBQUVwQ2UsSUFBQUEsTUFBTSxFQUFFaEIsT0FGNEI7QUFHcENpQixJQUFBQSxNQUFNLEVBQUU7QUFINEIsR0FBdEIsQ0FBaEI7QUFNQSxNQUFJQyxZQUFZLEdBQUc7QUFDakJDLElBQUFBLElBQUksRUFBRSxZQURXO0FBRWpCQyxJQUFBQSxJQUFJLEVBQUUsbUJBRlc7QUFHakJDLElBQUFBLE1BQU0sRUFBRSxNQUhTO0FBSWpCQyxJQUFBQSxPQUFPLEVBQUU7QUFDUCxzQkFBZ0IsbUNBRFQ7QUFFUCx3QkFBa0JULFNBQVMsQ0FBQ1U7QUFGckI7QUFKUSxHQUFuQjtBQVVBLFNBQU8vQixZQUFZLENBQUNnQyxPQUFiLENBQXFCTixZQUFyQixFQUFtQ0wsU0FBbkMsQ0FBUDtBQUNEOztBQUVEWSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmhCLEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmZCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgSmFucmFpbiBFbmdhZ2UgQVBJLlxudmFyIGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIHJldHVybiBhcGlSZXF1ZXN0KG9wdGlvbnMuYXBpX2tleSwgYXV0aERhdGEuYXV0aF90b2tlbikudGhlbihkYXRhID0+IHtcbiAgICAvL3N1Y2Nlc3NmdWwgcmVzcG9uc2Ugd2lsbCBoYXZlIGEgXCJzdGF0XCIgKHN0YXR1cykgb2YgJ29rJyBhbmQgYSBwcm9maWxlIG5vZGUgd2l0aCBhbiBpZGVudGlmaWVyXG4gICAgLy9zZWU6IGh0dHA6Ly9kZXZlbG9wZXJzLmphbnJhaW4uY29tL292ZXJ2aWV3L3NvY2lhbC1sb2dpbi9pZGVudGl0eS1wcm92aWRlcnMvdXNlci1wcm9maWxlLWRhdGEvI25vcm1hbGl6ZWQtdXNlci1wcm9maWxlLWRhdGFcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnN0YXQgPT0gJ29rJyAmJiBkYXRhLnByb2ZpbGUuaWRlbnRpZmllciA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0phbnJhaW4gZW5nYWdlIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICAvL25vLW9wXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIGFwaVJlcXVlc3QoYXBpX2tleSwgYXV0aF90b2tlbikge1xuICB2YXIgcG9zdF9kYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICB0b2tlbjogYXV0aF90b2tlbixcbiAgICBhcGlLZXk6IGFwaV9rZXksXG4gICAgZm9ybWF0OiAnanNvbicsXG4gIH0pO1xuXG4gIHZhciBwb3N0X29wdGlvbnMgPSB7XG4gICAgaG9zdDogJ3JweG5vdy5jb20nLFxuICAgIHBhdGg6ICcvYXBpL3YyL2F1dGhfaW5mbycsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogcG9zdF9kYXRhLmxlbmd0aCxcbiAgICB9LFxuICB9O1xuXG4gIHJldHVybiBodHRwc1JlcXVlc3QucmVxdWVzdChwb3N0X29wdGlvbnMsIHBvc3RfZGF0YSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/keycloak.js b/lib/Adapters/Auth/keycloak.js deleted file mode 100644 index ab5a498102..0000000000 --- a/lib/Adapters/Auth/keycloak.js +++ /dev/null @@ -1,125 +0,0 @@ -"use strict"; - -/* - # Parse Server Keycloak Authentication - - ## Keycloak `authData` - - ``` - { - "keycloak": { - "access_token": "access token you got from keycloak JS client authentication", - "id": "the id retrieved from client authentication in Keycloak", - "roles": ["the roles retrieved from client authentication in Keycloak"], - "groups": ["the groups retrieved from client authentication in Keycloak"] - } - } - ``` - - The authentication module will test if the authData is the same as the - userinfo oauth call, comparing the attributes - - Copy the JSON config file generated on Keycloak (https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter) - and paste it inside of a folder (Ex.: `auth/keycloak.json`) in your server. - - The options passed to Parse server: - - ``` - { - auth: { - keycloak: { - config: require(`./auth/keycloak.json`) - } - } - } - ``` -*/ -const { - Parse -} = require('parse/node'); - -const httpsRequest = require('./httpsRequest'); - -const arraysEqual = (_arr1, _arr2) => { - if (!Array.isArray(_arr1) || !Array.isArray(_arr2) || _arr1.length !== _arr2.length) return false; - - var arr1 = _arr1.concat().sort(); - - var arr2 = _arr2.concat().sort(); - - for (var i = 0; i < arr1.length; i++) { - if (arr1[i] !== arr2[i]) return false; - } - - return true; -}; - -const handleAuth = async ({ - access_token, - id, - roles, - groups -} = {}, { - config -} = {}) => { - if (!(access_token && id)) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing access token and/or User id'); - } - - if (!config || !(config['auth-server-url'] && config['realm'])) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing keycloak configuration'); - } - - try { - const response = await httpsRequest.get({ - host: config['auth-server-url'], - path: `/realms/${config['realm']}/protocol/openid-connect/userinfo`, - headers: { - Authorization: 'Bearer ' + access_token - } - }); - - if (response && response.data && response.data.sub == id && arraysEqual(response.data.roles, roles) && arraysEqual(response.data.groups, groups)) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication'); - } catch (e) { - if (e instanceof Parse.Error) { - throw e; - } - - const error = JSON.parse(e.text); - - if (error.error_description) { - throw new Parse.Error(Parse.Error.HOSTING_ERROR, error.error_description); - } else { - throw new Parse.Error(Parse.Error.HOSTING_ERROR, 'Could not connect to the authentication server'); - } - } -}; -/* - @param {Object} authData: the client provided authData - @param {string} authData.access_token: the access_token retrieved from client authentication in Keycloak - @param {string} authData.id: the id retrieved from client authentication in Keycloak - @param {Array} authData.roles: the roles retrieved from client authentication in Keycloak - @param {Array} authData.groups: the groups retrieved from client authentication in Keycloak - @param {Object} options: additional options - @param {Object} options.config: the config object passed during Parse Server instantiation -*/ - - -function validateAuthData(authData, options = {}) { - return handleAuth(authData, options); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2tleWNsb2FrLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsImFycmF5c0VxdWFsIiwiX2FycjEiLCJfYXJyMiIsIkFycmF5IiwiaXNBcnJheSIsImxlbmd0aCIsImFycjEiLCJjb25jYXQiLCJzb3J0IiwiYXJyMiIsImkiLCJoYW5kbGVBdXRoIiwiYWNjZXNzX3Rva2VuIiwiaWQiLCJyb2xlcyIsImdyb3VwcyIsImNvbmZpZyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInJlc3BvbnNlIiwiZ2V0IiwiaG9zdCIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImRhdGEiLCJzdWIiLCJlIiwiZXJyb3IiLCJKU09OIiwicGFyc2UiLCJ0ZXh0IiwiZXJyb3JfZGVzY3JpcHRpb24iLCJIT1NUSU5HX0VSUk9SIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQVlDLE9BQU8sQ0FBQyxZQUFELENBQXpCOztBQUNBLE1BQU1DLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUVBLE1BQU1FLFdBQVcsR0FBRyxDQUFDQyxLQUFELEVBQVFDLEtBQVIsS0FBa0I7QUFDcEMsTUFDRSxDQUFDQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0gsS0FBZCxDQUFELElBQ0EsQ0FBQ0UsS0FBSyxDQUFDQyxPQUFOLENBQWNGLEtBQWQsQ0FERCxJQUVBRCxLQUFLLENBQUNJLE1BQU4sS0FBaUJILEtBQUssQ0FBQ0csTUFIekIsRUFLRSxPQUFPLEtBQVA7O0FBRUYsTUFBSUMsSUFBSSxHQUFHTCxL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QUcsRUFBOUMsRUFBa0Q7QUFDaEQsU0FBT3pCLFVBQVUsQ0FBQ3dCLFFBQUQsRUFBV0MsT0FBWCxDQUFqQjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmSCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgIyBQYXJzZSBTZXJ2ZXIgS2V5Y2xvYWsgQXV0aGVudGljYXRpb25cblxuICAjIyBLZXljbG9hayBgYXV0aERhdGFgXG5cbiAgYGBgXG4gICAge1xuICAgICAgXCJrZXljbG9ha1wiOiB7XG4gICAgICAgIFwiYWNjZXNzX3Rva2VuXCI6IFwiYWNjZXNzIHRva2VuIHlvdSBnb3QgZnJvbSBrZXljbG9hayBKUyBjbGllbnQgYXV0aGVudGljYXRpb25cIixcbiAgICAgICAgXCJpZFwiOiBcInRoZSBpZCByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcIixcbiAgICAgICAgXCJyb2xlc1wiOiBbXCJ0aGUgcm9sZXMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXCJdLFxuICAgICAgICBcImdyb3Vwc1wiOiBbXCJ0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1wiXVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG5cbiAgVGhlIGF1dGhlbnRpY2F0aW9uIG1vZHVsZSB3aWxsIHRlc3QgaWYgdGhlIGF1dGhEYXRhIGlzIHRoZSBzYW1lIGFzIHRoZVxuICB1c2VyaW5mbyBvYXV0aCBjYWxsLCBjb21wYXJpbmcgdGhlIGF0dHJpYnV0ZXNcblxuICBDb3B5IHRoZSBKU09OIGNvbmZpZyBmaWxlIGdlbmVyYXRlZCBvbiBLZXljbG9hayAoaHR0cHM6Ly93d3cua2V5Y2xvYWsub3JnL2RvY3MvbGF0ZXN0L3NlY3VyaW5nX2FwcHMvaW5kZXguaHRtbCNfamF2YXNjcmlwdF9hZGFwdGVyKVxuICBhbmQgcGFzdGUgaXQgaW5zaWRlIG9mIGEgZm9sZGVyIChFeC46IGBhdXRoL2tleWNsb2FrLmpzb25gKSBpbiB5b3VyIHNlcnZlci5cblxuICBUaGUgb3B0aW9ucyBwYXNzZWQgdG8gUGFyc2Ugc2VydmVyOlxuXG4gIGBgYFxuICAgIHtcbiAgICAgIGF1dGg6IHtcbiAgICAgICAga2V5Y2xvYWs6IHtcbiAgICAgICAgICBjb25maWc6IHJlcXVpcmUoYC4vYXV0aC9rZXljbG9hay5qc29uYClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG5jb25zdCBhcnJheXNFcXVhbCA9IChfYXJyMSwgX2FycjIpID0+IHtcbiAgaWYgKFxuICAgICFBcnJheS5pc0FycmF5KF9hcnIxKSB8fFxuICAgICFBcnJheS5pc0FycmF5KF9hcnIyKSB8fFxuICAgIF9hcnIxLmxlbmd0aCAhPT0gX2FycjIubGVuZ3RoXG4gIClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGFycjEgPSBfYXJyMS5jb25jYXQoKS5zb3J0KCk7XG4gIHZhciBhcnIyID0gX2FycjIuY29uY2F0KCkuc29ydCgpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhcnIxW2ldICE9PSBhcnIyW2ldKSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmNvbnN0IGhhbmRsZUF1dGggPSBhc3luYyAoXG4gIHsgYWNjZXNzX3Rva2VuLCBpZCwgcm9sZXMsIGdyb3VwcyB9ID0ge30sXG4gIHsgY29uZmlnIH0gPSB7fVxuKSA9PiB7XG4gIGlmICghKGFjY2Vzc190b2tlbiAmJiBpZCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ01pc3NpbmcgYWNjZXNzIHRva2VuIGFuZC9vciBVc2VyIGlkJ1xuICAgICk7XG4gIH1cbiAgaWYgKCFjb25maWcgfHwgIShjb25maWdbJ2F1dGgtc2VydmVyLXVybCddICYmIGNvbmZpZ1sncmVhbG0nXSkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ01pc3Npbmcga2V5Y2xvYWsgY29uZmlndXJhdGlvbidcbiAgICApO1xuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICAgIGhvc3Q6IGNvbmZpZ1snYXV0aC1zZXJ2ZXItdXJsJ10sXG4gICAgICBwYXRoOiBgL3JlYWxtcy8ke2NvbmZpZ1sncmVhbG0nXX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdXNlcmluZm9gLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGlmIChcbiAgICAgIHJlc3BvbnNlICYmXG4gICAgICByZXNwb25zZS5kYXRhICYmXG4gICAgICByZXNwb25zZS5kYXRhLnN1YiA9PSBpZCAmJlxuICAgICAgYXJyYXlzRXF1YWwocmVzcG9uc2UuZGF0YS5yb2xlcywgcm9sZXMpICYmXG4gICAgICBhcnJheXNFcXVhbChyZXNwb25zZS5kYXRhLmdyb3VwcywgZ3JvdXBzKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0ludmFsaWQgYXV0aGVudGljYXRpb24nXG4gICAgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIGNvbnN0IGVycm9yID0gSlNPTi5wYXJzZShlLnRleHQpO1xuICAgIGlmIChlcnJvci5lcnJvcl9kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkhPU1RJTkdfRVJST1IsIGVycm9yLmVycm9yX2Rlc2NyaXB0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5IT1NUSU5HX0VSUk9SLFxuICAgICAgICAnQ291bGQgbm90IGNvbm5lY3QgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIHNlcnZlcidcbiAgICAgICk7XG4gICAgfVxuICB9XG59O1xuXG4vKlxuICBAcGFyYW0ge09iamVjdH0gYXV0aERhdGE6IHRoZSBjbGllbnQgcHJvdmlkZWQgYXV0aERhdGFcbiAgQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjogdGhlIGFjY2Vzc190b2tlbiByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcbiAgQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmlkOiB0aGUgaWQgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7QXJyYXl9ICBhdXRoRGF0YS5yb2xlczogdGhlIHJvbGVzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge0FycmF5fSAgYXV0aERhdGEuZ3JvdXBzOiB0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge09iamVjdH0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmNvbmZpZzogdGhlIGNvbmZpZyBvYmplY3QgcGFzc2VkIGR1cmluZyBQYXJzZSBTZXJ2ZXIgaW5zdGFudGlhdGlvblxuKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gaGFuZGxlQXV0aChhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/ldap.js b/lib/Adapters/Auth/ldap.js deleted file mode 100644 index 4990603518..0000000000 --- a/lib/Adapters/Auth/ldap.js +++ /dev/null @@ -1,83 +0,0 @@ -"use strict"; - -const ldapjs = require('ldapjs'); - -const Parse = require('parse/node').Parse; - -function validateAuthData(authData, options) { - if (!optionsAreValid(options)) { - return new Promise((_, reject) => { - reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP auth configuration missing')); - }); - } - - const client = ldapjs.createClient({ - url: options.url - }); - const userCn = typeof options.dn === 'string' ? options.dn.replace('{{id}}', authData.id) : `uid=${authData.id},${options.suffix}`; - return new Promise((resolve, reject) => { - client.bind(userCn, authData.password, err => { - if (err) { - client.destroy(err); - return reject(new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Wrong username or password')); - } - - if (typeof options.groupCn === 'string' && typeof options.groupFilter === 'string') { - searchForGroup(client, options, authData.id, resolve, reject); - } else { - client.unbind(); - client.destroy(); - resolve(); - } - }); - }); -} - -function optionsAreValid(options) { - return typeof options === 'object' && typeof options.suffix === 'string' && typeof options.url === 'string' && options.url.startsWith('ldap://'); -} - -function searchForGroup(client, options, id, resolve, reject) { - const filter = options.groupFilter.replace(/{{id}}/gi, id); - const opts = { - scope: 'sub', - filter: filter - }; - let found = false; - client.search(options.suffix, opts, (searchError, res) => { - if (searchError) { - client.unbind(); - client.destroy(); - return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); - } - - res.on('searchEntry', entry => { - if (entry.object.cn === options.groupCn) { - found = true; - client.unbind(); - client.destroy(); - return resolve(); - } - }); - res.on('end', () => { - if (!found) { - client.unbind(); - client.destroy(); - return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP: User not in group')); - } - }); - res.on('error', () => { - return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); - }); - }); -} - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xkYXAuanMiXSwibmFtZXMiOlsibGRhcGpzIiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsIm9wdGlvbnNBcmVWYWxpZCIsIlByb21pc2UiLCJfIiwicmVqZWN0IiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjbGllbnQiLCJjcmVhdGVDbGllbnQiLCJ1cmwiLCJ1c2VyQ24iLCJkbiIsInJlcGxhY2UiLCJpZCIsInN1ZmZpeCIsInJlc29sdmUiLCJiaW5kIiwicGFzc3dvcmQiLCJlcnIiLCJkZXN0cm95IiwiT0JKRUNUX05PVF9GT1VORCIsImdyb3VwQ24iLCJncm91cEZpbHRlciIsInNlYXJjaEZvckdyb3VwIiwidW5iaW5kIiwic3RhcnRzV2l0aCIsImZpbHRlciIsIm9wdHMiLCJzY29wZSIsImZvdW5kIiwic2VhcmNoIiwic2VhcmNoRXJyb3IiLCJyZXMiLCJvbiIsImVudHJ5Iiwib2JqZWN0IiwiY24iLCJ2YWxpZGF0ZUFwcElkIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFNQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUNBLE1BQU1DLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBcEM7O0FBRUEsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DQyxPQUFwQyxFQUE2QztBQUMzQyxNQUFJLENBQUNDLGVBQWUsQ0FBQ0QsT0FBRCxDQUFwQixFQUErQjtBQUM3QixXQUFPLElBQUlFLE9BQUosQ0FBWSxDQUFDQyxDQUFELEVBQUlDLE1BQUosS0FBZTtBQUNoQ0EsTUFBQUEsTUFBTSxDQUNKLElBQUlQLEtBQUssQ0FBQ1EsS0FBVixDQUNFUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMscUJBRGQsRUFFRSxpQ0FGRixDQURJLENBQU47QUFNRCxLQVBN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RUFBeUM7QUFDdkNRLFFBQUFBLEtBQUssR0FBRyxJQUFSO0FBQ0F0QixRQUFBQSxNQUFNLENBQUNpQixNQUFQO0FBQ0FqQixRQUFBQSxNQUFNLENBQUNZLE9BQVA7QUFDQSxlQUFPSixPQUFPLEVBQWQ7QUFDRDtBQUNGLEtBUEQ7QUFRQWlCLElBQUFBLEdBQUcsQ0FBQ0MsRUFBSixDQUFPLEtBQVAsRUFBYyxNQUFNO0FBQ2xCLFVBQUksQ0FBQ0osS0FBTCxFQUFZO0FBQ1Z0QixRQUFBQSxNQUFNLENBQUNpQixNQUFQO0FBQ0FqQixRQUFBQSxNQUFNLENBQUNZLE9BQVA7QUFDQSxlQUFPZixNQUFNLENBQ1gsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQ0VSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxxQkFEZCxFQUVFLHlCQUZGLENBRFcsQ0FBYjtBQU1EO0FBQ0YsS0FYRDtBQVlBMEIsSUFBQUEsR0FBRyxDQUFDQyxFQUFKLENBQU8sT0FBUCxFQUFnQixNQUFNO0FBQ3BCLGFBQU83QixNQUFNLENBQ1gsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQ0VSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxxQkFEZCxFQUVFLDBCQUZGLENBRFcsQ0FBYjtBQU1ELEtBUEQ7QUFRRCxHQXZDRDtBQXdDRDs7QUFFRCxTQUFTK0IsYUFBVCxHQUF5QjtBQUN2QixTQUFPbkMsT0FBTyxDQUFDYSxPQUFSLEVBQVA7QUFDRDs7QUFFRHVCLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmRixFQUFBQSxhQURlO0FBRWZ2QyxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgbGRhcGpzID0gcmVxdWlyZSgnbGRhcGpzJyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnNBcmVWYWxpZChvcHRpb25zKSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoXywgcmVqZWN0KSA9PiB7XG4gICAgICByZWplY3QoXG4gICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgJ0xEQVAgYXV0aCBjb25maWd1cmF0aW9uIG1pc3NpbmcnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBjbGllbnQgPSBsZGFwanMuY3JlYXRlQ2xpZW50KHsgdXJsOiBvcHRpb25zLnVybCB9KTtcbiAgY29uc3QgdXNlckNuID1cbiAgICB0eXBlb2Ygb3B0aW9ucy5kbiA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9ucy5kbi5yZXBsYWNlKCd7e2lkfX0nLCBhdXRoRGF0YS5pZClcbiAgICAgIDogYHVpZD0ke2F1dGhEYXRhLmlkfSwke29wdGlvbnMuc3VmZml4fWA7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjbGllbnQuYmluZCh1c2VyQ24sIGF1dGhEYXRhLnBhc3N3b3JkLCBlcnIgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBjbGllbnQuZGVzdHJveShlcnIpO1xuICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAnTERBUDogV3JvbmcgdXNlcm5hbWUgb3IgcGFzc3dvcmQnXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyb3VwQ24gPT09ICdzdHJpbmcnICYmXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyb3VwRmlsdGVyID09PSAnc3RyaW5nJ1xuICAgICAgKSB7XG4gICAgICAgIHNlYXJjaEZvckdyb3VwKGNsaWVudCwgb3B0aW9ucywgYXV0aERhdGEuaWQsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbGllbnQudW5iaW5kKCk7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG9wdGlvbnNBcmVWYWxpZChvcHRpb25zKSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnICYmXG4gICAgdHlwZW9mIG9wdGlvbnMuc3VmZml4ID09PSAnc3RyaW5nJyAmJlxuICAgIHR5cGVvZiBvcHRpb25zLnVybCA9PT0gJ3N0cmluZycgJiZcbiAgICBvcHRpb25zLnVybC5zdGFydHNXaXRoKCdsZGFwOi8vJylcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2VhcmNoRm9yR3JvdXAoY2xpZW50LCBvcHRpb25zLCBpZCwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIGNvbnN0IGZpbHRlciA9IG9wdGlvbnMuZ3JvdXBGaWx0ZXIucmVwbGFjZSgve3tpZH19L2dpLCBpZCk7XG4gIGNvbnN0IG9wdHMgPSB7XG4gICAgc2NvcGU6ICdzdWInLFxuICAgIGZpbHRlcjogZmlsdGVyLFxuICB9O1xuICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgY2xpZW50LnNlYXJjaChvcHRpb25zLnN1ZmZpeCwgb3B0cywgKHNlYXJjaEVycm9yLCByZXMpID0+IHtcbiAgICBpZiAoc2VhcmNoRXJyb3IpIHtcbiAgICAgIGNsaWVudC51bmJpbmQoKTtcbiAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdMREFQIGdyb3VwIHNlYXJjaCBmYWlsZWQnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICAgIHJlcy5vbignc2VhcmNoRW50cnknLCBlbnRyeSA9PiB7XG4gICAgICBpZiAoZW50cnkub2JqZWN0LmNuID09PSBvcHRpb25zLmdyb3VwQ24pIHtcbiAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICBjbGllbnQudW5iaW5kKCk7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgIGNsaWVudC51bmJpbmQoKTtcbiAgICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgICAnTERBUDogVXNlciBub3QgaW4gZ3JvdXAnXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJlcy5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdMREFQIGdyb3VwIHNlYXJjaCBmYWlsZWQnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/line.js b/lib/Adapters/Auth/line.js deleted file mode 100644 index 63b271cc2d..0000000000 --- a/lib/Adapters/Auth/line.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -// Helper functions for accessing the line API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. - - -function validateAuthData(authData) { - return request('profile', authData.access_token).then(response => { - if (response && response.userId && response.userId === authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Line auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - var options = { - host: 'api.line.me', - path: '/v2/' + path, - method: 'GET', - headers: { - Authorization: 'Bearer ' + access_token - } - }; - return httpsRequest.get(options); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmUuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJyZXNwb25zZSIsInVzZXJJZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicGF0aCIsIm9wdGlvbnMiLCJob3N0IiwibWV0aG9kIiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsU0FBRCxFQUFZRCxRQUFRLENBQUNFLFlBQXJCLENBQVAsQ0FBMENDLElBQTFDLENBQStDQyxRQUFRLElBQUk7QUFDaEUsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLE1BQXJCLElBQStCRCxRQUFRLENBQUNDLE1BQVQsS0FBb0JMLFFBQVEsQ0FBQ00sRUFBaEUsRUFBb0U7QUFDbEU7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUNKWCxLQUFLLENBQUNXLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixxQ0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUM7QUFDbkMsTUFBSVcsT0FBTyxHQUFHO0FBQ1pDLElBQUFBLElBQUksRUFBRSxhQURNO0FBRVpGLElBQUFBLElBQUksRUFBRSxTQUFTQSxJQUZIO0FBR1pHLElBQUFBLE1BQU0sRUFBRSxLQUhJO0FBSVpDLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWY7QUFEcEI7QUFKRyxHQUFkO0FBUUEsU0FBT0osWUFBWSxDQUFDb0IsR0FBYixDQUFpQkwsT0FBakIsQ0FBUDtBQUNEOztBQUVETSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlgsRUFBQUEsYUFBYSxFQUFFQSxhQURBO0FBRWZWLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBsaW5lIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgncHJvZmlsZScsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnVzZXJJZCAmJiByZXNwb25zZS51c2VySWQgPT09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnTGluZSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIG9wdGlvbnMgPSB7XG4gICAgaG9zdDogJ2FwaS5saW5lLm1lJyxcbiAgICBwYXRoOiAnL3YyLycgKyBwYXRoLFxuICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH07XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KG9wdGlvbnMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/linkedin.js b/lib/Adapters/Auth/linkedin.js deleted file mode 100644 index 61945e2867..0000000000 --- a/lib/Adapters/Auth/linkedin.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -// Helper functions for accessing the linkedin API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('me', authData.access_token, authData.is_mobile_sdk).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Linkedin auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token, is_mobile_sdk) { - var headers = { - Authorization: 'Bearer ' + access_token, - 'x-li-format': 'json' - }; - - if (is_mobile_sdk) { - headers['x-li-src'] = 'msdk'; - } - - return httpsRequest.get({ - host: 'api.linkedin.com', - path: '/v2/' + path, - headers: headers - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmtlZGluLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsInJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpc19tb2JpbGVfc2RrIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImdldCIsImhvc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLEVBQThCRixRQUFRLENBQUNHLGFBQXZDLENBQVAsQ0FBNkRDLElBQTdELENBQ0xDLElBQUksSUFBSTtBQUNOLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdOLFFBQVEsQ0FBQ00sRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUNKWCxLQUFLLENBQUNXLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5Q0FGSSxDQUFOO0FBSUQsR0FUSSxDQUFQO0FBV0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUNDLGFBQXJDLEVBQW9EO0FBQ2xELE1BQUlVLE9BQU8sR0FBRztBQUNaQyxJQUFBQSxhQUFhLEVBQUUsWUFBWVosWUFEZjtBQUVaLG1CQUFlO0FBRkgsR0FBZDs7QUFLQSxNQUFJQyxhQUFKLEVBQW1CO0FBQ2pCVSxJQUFBQSxPQUFPLENBQUMsVUFBRCxDQUFQLEdBQXNCLE1BQXRCO0FBQ0Q7O0FBQ0QsU0FBT2YsWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGtCQURnQjtBQUV0QkosSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJDLElBQUFBLE9BQU8sRUFBRUE7QUFIYSxHQUFqQixDQUFQO0FBS0Q7O0FBRURJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGxpbmtlZGluIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ21lJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuLCBhdXRoRGF0YS5pc19tb2JpbGVfc2RrKS50aGVuKFxuICAgIGRhdGEgPT4ge1xuICAgICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdMaW5rZWRpbiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICApO1xuICAgIH1cbiAgKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgYXBpIHJlcXVlc3RzXG5mdW5jdGlvbiByZXF1ZXN0KHBhdGgsIGFjY2Vzc190b2tlbiwgaXNfbW9iaWxlX3Nkaykge1xuICB2YXIgaGVhZGVycyA9IHtcbiAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgJ3gtbGktZm9ybWF0JzogJ2pzb24nLFxuICB9O1xuXG4gIGlmIChpc19tb2JpbGVfc2RrKSB7XG4gICAgaGVhZGVyc1sneC1saS1zcmMnXSA9ICdtc2RrJztcbiAgfVxuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7XG4gICAgaG9zdDogJ2FwaS5saW5rZWRpbi5jb20nLFxuICAgIHBhdGg6ICcvdjIvJyArIHBhdGgsXG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/meetup.js b/lib/Adapters/Auth/meetup.js deleted file mode 100644 index 9065517d05..0000000000 --- a/lib/Adapters/Auth/meetup.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -// Helper functions for accessing the meetup API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('member/self', authData.access_token).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Meetup auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'api.meetup.com', - path: '/2/' + path, - headers: { - Authorization: 'bearer ' + access_token - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21lZXR1cC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsYUFBRCxFQUFnQkQsUUFBUSxDQUFDRSxZQUF6QixDQUFQLENBQThDQyxJQUE5QyxDQUFtREMsSUFBSSxJQUFJO0FBQ2hFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdMLFFBQVEsQ0FBQ0ssRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUNKVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix1Q0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVCxPQUFULENBQWlCVSxJQUFqQixFQUF1QlQsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT0osWUFBWSxDQUFDYyxHQUFiLENBQWlCO0FBQ3RCQyxJQUFBQSxJQUFJLEVBQUUsZ0JBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsUUFBUUEsSUFGUTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZYjtBQURwQjtBQUhhLEdBQWpCLENBQVA7QUFPRDs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgbWVldHVwIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ21lbWJlci9zZWxmJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdNZWV0dXAgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnYXBpLm1lZXR1cC5jb20nLFxuICAgIHBhdGg6ICcvMi8nICsgcGF0aCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiAnYmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/microsoft.js b/lib/Adapters/Auth/microsoft.js deleted file mode 100644 index d88bb3cf0e..0000000000 --- a/lib/Adapters/Auth/microsoft.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -// Helper functions for accessing the microsoft graph API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user mail is valid. - - -function validateAuthData(authData) { - return request('me', authData.access_token).then(response => { - if (response && response.id && response.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Microsoft Graph auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'graph.microsoft.com', - path: '/v1.0/' + path, - headers: { - Authorization: 'Bearer ' + access_token - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21pY3Jvc29mdC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwiaG9zdCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsTUFBTUUsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxTQUFTRSxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsT0FBTyxDQUFDLElBQUQsRUFBT0QsUUFBUSxDQUFDRSxZQUFoQixDQUFQLENBQXFDQyxJQUFyQyxDQUNMQyxRQUFRLElBQUk7QUFDVixRQUFJQSxRQUFRLElBQUlBLFFBQVEsQ0FBQ0MsRUFBckIsSUFBMkJELFFBQVEsQ0FBQ0MsRUFBVCxJQUFlTCxRQUFRLENBQUNLLEVBQXZELEVBQTJEO0FBQ3pEO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJVCxLQUFLLENBQUNVLEtBQVYsQ0FDSlYsS0FBSyxDQUFDVSxLQUFOLENBQVlDLGdCQURSLEVBRUosZ0RBRkksQ0FBTjtBQUlELEdBVEksQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1QsT0FBVCxDQUFpQlUsSUFBakIsRUFBdUJULFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2MsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLHFCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFdBQVdBLElBRks7QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWI7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURjLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIG1pY3Jvc29mdCBncmFwaCBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBtYWlsIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oXG4gICAgcmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmlkICYmIHJlc3BvbnNlLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ01pY3Jvc29mdCBHcmFwaCBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICApO1xuICAgIH1cbiAgKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnZ3JhcGgubWljcm9zb2Z0LmNvbScsXG4gICAgcGF0aDogJy92MS4wLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICB9LFxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/oauth2.js b/lib/Adapters/Auth/oauth2.js deleted file mode 100644 index a7863a5c3f..0000000000 --- a/lib/Adapters/Auth/oauth2.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; - -/* - * This auth adapter is based on the OAuth 2.0 Token Introspection specification. - * See RFC 7662 for details (https://tools.ietf.org/html/rfc7662). - * It's purpose is to validate OAuth2 access tokens using the OAuth2 provider's - * token introspection endpoint (if implemented by the provider). - * - * The adapter accepts the following config parameters: - * - * 1. "tokenIntrospectionEndpointUrl" (string, required) - * The URL of the token introspection endpoint of the OAuth2 provider that - * issued the access token to the client that is to be validated. - * - * 2. "useridField" (string, optional) - * The name of the field in the token introspection response that contains - * the userid. If specified, it will be used to verify the value of the "id" - * field in the "authData" JSON that is coming from the client. - * This can be the "aud" (i.e. audience), the "sub" (i.e. subject) or the - * "username" field in the introspection response, but since only the - * "active" field is required and all other reponse fields are optional - * in the RFC, it has to be optional in this adapter as well. - * Default: - (undefined) - * - * 3. "appidField" (string, optional) - * The name of the field in the token introspection response that contains - * the appId of the client. If specified, it will be used to verify it's - * value against the set of appIds in the adapter config. The concept of - * appIds comes from the two major social login providers - * (Google and Facebook). They have not yet implemented the token - * introspection endpoint, but the concept can be valid for any OAuth2 - * provider. - * Default: - (undefined) - * - * 4. "appIds" (array of strings, required if appidField is defined) - * A set of appIds that are used to restrict accepted access tokens based - * on a specific field's value in the token introspection response. - * Default: - (undefined) - * - * 5. "authorizationHeader" (string, optional) - * The value of the "Authorization" HTTP header in requests sent to the - * introspection endpoint. It must contain the raw value. - * Thus if HTTP Basic authorization is to be used, it must contain the - * "Basic" string, followed by whitespace, then by the base64 encoded - * version of the concatenated + ":" + string. - * Eg. "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" - * - * The adapter expects requests with the following authData JSON: - * - * { - * "someadapter": { - * "id": "user's OAuth2 provider-specific id as a string", - * "access_token": "an authorized OAuth2 access token for the user", - * } - * } - */ -const Parse = require('parse/node').Parse; - -const url = require('url'); - -const querystring = require('querystring'); - -const httpsRequest = require('./httpsRequest'); - -const INVALID_ACCESS = 'OAuth2 access token is invalid for this user.'; -const INVALID_ACCESS_APPID = "OAuth2: the access_token's appID is empty or is not in the list of permitted appIDs in the auth configuration."; -const MISSING_APPIDS = 'OAuth2 configuration is missing the client app IDs ("appIds" config parameter).'; -const MISSING_URL = 'OAuth2 token introspection endpoint URL is missing from configuration!'; // Returns a promise that fulfills if this user id is valid. - -function validateAuthData(authData, options) { - return requestTokenInfo(options, authData.access_token).then(response => { - if (!response || !response.active || options.useridField && authData.id !== response[options.useridField]) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); - } - }); -} - -function validateAppId(appIds, authData, options) { - if (!options || !options.appidField) { - return Promise.resolve(); - } - - if (!appIds || appIds.length === 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_APPIDS); - } - - return requestTokenInfo(options, authData.access_token).then(response => { - if (!response || !response.active) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); - } - - const appidField = options.appidField; - - if (!response[appidField]) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); - } - - const responseValue = response[appidField]; - - if (!Array.isArray(responseValue) && appIds.includes(responseValue)) { - return; - } else if (Array.isArray(responseValue) && responseValue.some(appId => appIds.includes(appId))) { - return; - } else { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); - } - }); -} // A promise wrapper for requests to the OAuth2 token introspection endpoint. - - -function requestTokenInfo(options, access_token) { - if (!options || !options.tokenIntrospectionEndpointUrl) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_URL); - } - - const parsedUrl = url.parse(options.tokenIntrospectionEndpointUrl); - const postData = querystring.stringify({ - token: access_token - }); - const headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(postData) - }; - - if (options.authorizationHeader) { - headers['Authorization'] = options.authorizationHeader; - } - - const postOptions = { - hostname: parsedUrl.hostname, - path: parsedUrl.pathname, - method: 'POST', - headers: headers - }; - return httpsRequest.request(postOptions, postData); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL29hdXRoMi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJxdWVyeXN0cmluZyIsImh0dHBzUmVxdWVzdCIsIklOVkFMSURfQUNDRVNTIiwiSU5WQUxJRF9BQ0NFU1NfQVBQSUQiLCJNSVNTSU5HX0FQUElEUyIsIk1JU1NJTkdfVVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3RUb2tlbkluZm8iLCJhY2Nlc3NfdG9rZW4iLCJ0aGVuIiwicmVzcG9uc2UiLCJhY3RpdmUiLCJ1c2VyaWRGaWVsZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImFwcGlkRmllbGQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsInJlc3BvbnNlVmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJpbmNsdWRlcyIsInNvbWUiLCJhcHBJZCIsInRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsIiwicGFyc2VkVXJsIiwicGFyc2UiLCJwb3N0RGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiaGVhZGVycyIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJhdXRob3JpemF0aW9uSGVhZGVyIiwicG9zdE9wdGlvbnMiLCJob3N0bmFtZSIsInBhdGgiLCJwYXRobmFtZSIsIm1ldGhvZCIsInJlcXVlc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF1REEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFwQzs7QUFDQSxNQUFNRSxHQUFHLEdBQUdELE9BQU8sQ0FBQyxLQUFELENBQW5COztBQUNBLE1BQU1FLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQs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QUQsSUFBWSxDQUFDQSxPQUFPLENBQUNzQiw2QkFBekIsRUFBd0Q7QUFDdEQsVUFBTSxJQUFJakMsS0FBSyxDQUFDbUIsS0FBVixDQUFnQm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDWixXQUE5QyxDQUFOO0FBQ0Q7O0FBQ0QsUUFBTTBCLFNBQVMsR0FBR2hDLEdBQUcsQ0FBQ2lDLEtBQUosQ0FBVXhCLE9BQU8sQ0FBQ3NCLDZCQUFsQixDQUFsQjtBQUNBLFFBQU1HLFFBQVEsR0FBR2pDLFdBQVcsQ0FBQ2tDLFNBQVosQ0FBc0I7QUFDckNDLElBQUFBLEtBQUssRUFBRXpCO0FBRDhCLEdBQXRCLENBQWpCO0FBR0EsUUFBTTBCLE9BQU8sR0FBRztBQUNkLG9CQUFnQixtQ0FERjtBQUVkLHNCQUFrQkMsTUFBTSxDQUFDQyxVQUFQLENBQWtCTCxRQUFsQjtBQUZKLEdBQWhCOztBQUlBLE1BQUl6QixPQUFPLENBQUMrQixtQkFBWixFQUFpQztBQUMvQkgsSUFBQUEsT0FBTyxDQUFDLGVBQUQsQ0FBUCxHQUEyQjVCLE9BQU8sQ0FBQytCLG1CQUFuQztBQUNEOztBQUNELFFBQU1DLFdBQVcsR0FBRztBQUNsQkMsSUFBQUEsUUFBUSxFQUFFVixTQUFTLENBQUNVLFFBREY7QUFFbEJDLElBQUFBLElBQUksRUFBRVgsU0FBUyxDQUFDWSxRQUZFO0FBR2xCQyxJQUFBQSxNQUFNLEVBQUUsTUFIVTtBQUlsQlIsSUFBQUEsT0FBTyxFQUFFQTtBQUpTLEdBQXBCO0FBTUEsU0FBT25DLFlBQVksQ0FBQzRDLE9BQWIsQ0FBcUJMLFdBQXJCLEVBQWtDUCxRQUFsQyxDQUFQO0FBQ0Q7O0FBRURhLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmN0IsRUFBQUEsYUFBYSxFQUFFQSxhQURBO0FBRWZaLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFRoaXMgYXV0aCBhZGFwdGVyIGlzIGJhc2VkIG9uIHRoZSBPQXV0aCAyLjAgVG9rZW4gSW50cm9zcGVjdGlvbiBzcGVjaWZpY2F0aW9uLlxuICogU2VlIFJGQyA3NjYyIGZvciBkZXRhaWxzIChodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzY2MikuXG4gKiBJdCdzIHB1cnBvc2UgaXMgdG8gdmFsaWRhdGUgT0F1dGgyIGFjY2VzcyB0b2tlbnMgdXNpbmcgdGhlIE9BdXRoMiBwcm92aWRlcidzXG4gKiB0b2tlbiBpbnRyb3NwZWN0aW9uIGVuZHBvaW50IChpZiBpbXBsZW1lbnRlZCBieSB0aGUgcHJvdmlkZXIpLlxuICpcbiAqIFRoZSBhZGFwdGVyIGFjY2VwdHMgdGhlIGZvbGxvd2luZyBjb25maWcgcGFyYW1ldGVyczpcbiAqXG4gKiAxLiBcInRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsXCIgKHN0cmluZywgcmVxdWlyZWQpXG4gKiAgICAgIFRoZSBVUkwgb2YgdGhlIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQgb2YgdGhlIE9BdXRoMiBwcm92aWRlciB0aGF0XG4gKiAgICAgIGlzc3VlZCB0aGUgYWNjZXNzIHRva2VuIHRvIHRoZSBjbGllbnQgdGhhdCBpcyB0byBiZSB2YWxpZGF0ZWQuXG4gKlxuICogMi4gXCJ1c2VyaWRGaWVsZFwiIChzdHJpbmcsIG9wdGlvbmFsKVxuICogICAgICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaW4gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gcmVzcG9uc2UgdGhhdCBjb250YWluc1xuICogICAgICB0aGUgdXNlcmlkLiBJZiBzcGVjaWZpZWQsIGl0IHdpbGwgYmUgdXNlZCB0byB2ZXJpZnkgdGhlIHZhbHVlIG9mIHRoZSBcImlkXCJcbiAqICAgICAgZmllbGQgaW4gdGhlIFwiYXV0aERhdGFcIiBKU09OIHRoYXQgaXMgY29taW5nIGZyb20gdGhlIGNsaWVudC5cbiAqICAgICAgVGhpcyBjYW4gYmUgdGhlIFwiYXVkXCIgKGkuZS4gYXVkaWVuY2UpLCB0aGUgXCJzdWJcIiAoaS5lLiBzdWJqZWN0KSBvciB0aGVcbiAqICAgICAgXCJ1c2VybmFtZVwiIGZpZWxkIGluIHRoZSBpbnRyb3NwZWN0aW9uIHJlc3BvbnNlLCBidXQgc2luY2Ugb25seSB0aGVcbiAqICAgICAgXCJhY3RpdmVcIiBmaWVsZCBpcyByZXF1aXJlZCBhbmQgYWxsIG90aGVyIHJlcG9uc2UgZmllbGRzIGFyZSBvcHRpb25hbFxuICogICAgICBpbiB0aGUgUkZDLCBpdCBoYXMgdG8gYmUgb3B0aW9uYWwgaW4gdGhpcyBhZGFwdGVyIGFzIHdlbGwuXG4gKiAgICAgIERlZmF1bHQ6IC0gKHVuZGVmaW5lZClcbiAqXG4gKiAzLiBcImFwcGlkRmllbGRcIiAoc3RyaW5nLCBvcHRpb25hbClcbiAqICAgICAgVGhlIG5hbWUgb2YgdGhlIGZpZWxkIGluIHRoZSB0b2tlbiBpbnRyb3NwZWN0aW9uIHJlc3BvbnNlIHRoYXQgY29udGFpbnNcbiAqICAgICAgdGhlIGFwcElkIG9mIHRoZSBjbGllbnQuIElmIHNwZWNpZmllZCwgaXQgd2lsbCBiZSB1c2VkIHRvIHZlcmlmeSBpdCdzXG4gKiAgICAgIHZhbHVlIGFnYWluc3QgdGhlIHNldCBvZiBhcHBJZHMgaW4gdGhlIGFkYXB0ZXIgY29uZmlnLiBUaGUgY29uY2VwdCBvZlxuICogICAgICBhcHBJZHMgY29tZXMgZnJvbSB0aGUgdHdvIG1ham9yIHNvY2lhbCBsb2dpbiBwcm92aWRlcnNcbiAqICAgICAgKEdvb2dsZSBhbmQgRmFjZWJvb2spLiBUaGV5IGhhdmUgbm90IHlldCBpbXBsZW1lbnRlZCB0aGUgdG9rZW5cbiAqICAgICAgaW50cm9zcGVjdGlvbiBlbmRwb2ludCwgYnV0IHRoZSBjb25jZXB0IGNhbiBiZSB2YWxpZCBmb3IgYW55IE9BdXRoMlxuICogICAgICBwcm92aWRlci5cbiAqICAgICAgRGVmYXVsdDogLSAodW5kZWZpbmVkKVxuICpcbiAqIDQuIFwiYXBwSWRzXCIgKGFycmF5IG9mIHN0cmluZ3MsIHJlcXVpcmVkIGlmIGFwcGlkRmllbGQgaXMgZGVmaW5lZClcbiAqICAgICAgQSBzZXQgb2YgYXBwSWRzIHRoYXQgYXJlIHVzZWQgdG8gcmVzdHJpY3QgYWNjZXB0ZWQgYWNjZXNzIHRva2VucyBiYXNlZFxuICogICAgICBvbiBhIHNwZWNpZmljIGZpZWxkJ3MgdmFsdWUgaW4gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gcmVzcG9uc2UuXG4gKiAgICAgIERlZmF1bHQ6IC0gKHVuZGVmaW5lZClcbiAqXG4gKiA1LiBcImF1dGhvcml6YXRpb25IZWFkZXJcIiAoc3RyaW5nLCBvcHRpb25hbClcbiAqICAgICAgVGhlIHZhbHVlIG9mIHRoZSBcIkF1dGhvcml6YXRpb25cIiBIVFRQIGhlYWRlciBpbiByZXF1ZXN0cyBzZW50IHRvIHRoZVxuICogICAgICBpbnRyb3NwZWN0aW9uIGVuZHBvaW50LiBJdCBtdXN0IGNvbnRhaW4gdGhlIHJhdyB2YWx1ZS5cbiAqICAgICAgVGh1cyBpZiBIVFRQIEJhc2ljIGF1dGhvcml6YXRpb24gaXMgdG8gYmUgdXNlZCwgaXQgbXVzdCBjb250YWluIHRoZVxuICogICAgICBcIkJhc2ljXCIgc3RyaW5nLCBmb2xsb3dlZCBieSB3aGl0ZXNwYWNlLCB0aGVuIGJ5IHRoZSBiYXNlNjQgZW5jb2RlZFxuICogICAgICB2ZXJzaW9uIG9mIHRoZSBjb25jYXRlbmF0ZWQgPHVzZXJuYW1lPiArIFwiOlwiICsgPHBhc3N3b3JkPiBzdHJpbmcuXG4gKiAgICAgIEVnLiBcIkJhc2ljIGRYTmxjbTVoYldVNmNHRnpjM2R2Y21RPVwiXG4gKlxuICogVGhlIGFkYXB0ZXIgZXhwZWN0cyByZXF1ZXN0cyB3aXRoIHRoZSBmb2xsb3dpbmcgYXV0aERhdGEgSlNPTjpcbiAqXG4gKiB7XG4gKiAgIFwic29tZWFkYXB0ZXJcIjoge1xuICogICAgIFwiaWRcIjogXCJ1c2VyJ3MgT0F1dGgyIHByb3ZpZGVyLXNwZWNpZmljIGlkIGFzIGEgc3RyaW5nXCIsXG4gKiAgICAgXCJhY2Nlc3NfdG9rZW5cIjogXCJhbiBhdXRob3JpemVkIE9BdXRoMiBhY2Nlc3MgdG9rZW4gZm9yIHRoZSB1c2VyXCIsXG4gKiAgIH1cbiAqIH1cbiAqL1xuXG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcblxuY29uc3QgSU5WQUxJRF9BQ0NFU1MgPSAnT0F1dGgyIGFjY2VzcyB0b2tlbiBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJztcbmNvbnN0IElOVkFMSURfQUNDRVNTX0FQUElEID1cbiAgXCJPQXV0aDI6IHRoZSBhY2Nlc3NfdG9rZW4ncyBhcHBJRCBpcyBlbXB0eSBvciBpcyBub3QgaW4gdGhlIGxpc3Qgb2YgcGVybWl0dGVkIGFwcElEcyBpbiB0aGUgYXV0aCBjb25maWd1cmF0aW9uLlwiO1xuY29uc3QgTUlTU0lOR19BUFBJRFMgPVxuICAnT0F1dGgyIGNvbmZpZ3VyYXRpb24gaXMgbWlzc2luZyB0aGUgY2xpZW50IGFwcCBJRHMgKFwiYXBwSWRzXCIgY29uZmlnIHBhcmFtZXRlcikuJztcbmNvbnN0IE1JU1NJTkdfVVJMID1cbiAgJ09BdXRoMiB0b2tlbiBpbnRyb3NwZWN0aW9uIGVuZHBvaW50IFVSTCBpcyBtaXNzaW5nIGZyb20gY29uZmlndXJhdGlvbiEnO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHJlcXVlc3RUb2tlbkluZm8ob3B0aW9ucywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICBpZiAoXG4gICAgICAhcmVzcG9uc2UgfHxcbiAgICAgICFyZXNwb25zZS5hY3RpdmUgfHxcbiAgICAgIChvcHRpb25zLnVzZXJpZEZpZWxkICYmIGF1dGhEYXRhLmlkICE9PSByZXNwb25zZVtvcHRpb25zLnVzZXJpZEZpZWxkXSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTUyk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCAhb3B0aW9ucy5hcHBpZEZpZWxkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIGlmICghYXBwSWRzIHx8IGFwcElkcy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgTUlTU0lOR19BUFBJRFMpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0VG9rZW5JbmZvKG9wdGlvbnMsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UuYWN0aXZlKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgSU5WQUxJRF9BQ0NFU1MpO1xuICAgIH1cbiAgICBjb25zdCBhcHBpZEZpZWxkID0gb3B0aW9ucy5hcHBpZEZpZWxkO1xuICAgIGlmICghcmVzcG9uc2VbYXBwaWRGaWVsZF0pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTU19BUFBJRCk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3BvbnNlVmFsdWUgPSByZXNwb25zZVthcHBpZEZpZWxkXTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVzcG9uc2VWYWx1ZSkgJiYgYXBwSWRzLmluY2x1ZGVzKHJlc3BvbnNlVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkocmVzcG9uc2VWYWx1ZSkgJiZcbiAgICAgIHJlc3BvbnNlVmFsdWUuc29tZShhcHBJZCA9PiBhcHBJZHMuaW5jbHVkZXMoYXBwSWQpKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgSU5WQUxJRF9BQ0NFU1NfQVBQSUQpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIEEgcHJvbWlzZSB3cmFwcGVyIGZvciByZXF1ZXN0cyB0byB0aGUgT0F1dGgyIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQuXG5mdW5jdGlvbiByZXF1ZXN0VG9rZW5JbmZvKG9wdGlvbnMsIGFjY2Vzc190b2tlbikge1xuICBpZiAoIW9wdGlvbnMgfHwgIW9wdGlvbnMudG9rZW5JbnRyb3NwZWN0aW9uRW5kcG9pbnRVcmwpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgTUlTU0lOR19VUkwpO1xuICB9XG4gIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShvcHRpb25zLnRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsKTtcbiAgY29uc3QgcG9zdERhdGEgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoe1xuICAgIHRva2VuOiBhY2Nlc3NfdG9rZW4sXG4gIH0pO1xuICBjb25zdCBoZWFkZXJzID0ge1xuICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAnQ29udGVudC1MZW5ndGgnOiBCdWZmZXIuYnl0ZUxlbmd0aChwb3N0RGF0YSksXG4gIH07XG4gIGlmIChvcHRpb25zLmF1dGhvcml6YXRpb25IZWFkZXIpIHtcbiAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSBvcHRpb25zLmF1dGhvcml6YXRpb25IZWFkZXI7XG4gIH1cbiAgY29uc3QgcG9zdE9wdGlvbnMgPSB7XG4gICAgaG9zdG5hbWU6IHBhcnNlZFVybC5ob3N0bmFtZSxcbiAgICBwYXRoOiBwYXJzZWRVcmwucGF0aG5hbWUsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgfTtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5yZXF1ZXN0KHBvc3RPcHRpb25zLCBwb3N0RGF0YSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/phantauth.js b/lib/Adapters/Auth/phantauth.js deleted file mode 100644 index a85547aa55..0000000000 --- a/lib/Adapters/Auth/phantauth.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -/* - * PhantAuth was designed to simplify testing for applications using OpenID Connect - * authentication by making use of random generated users. - * - * To learn more, please go to: https://www.phantauth.net - */ -const { - Parse -} = require('parse/node'); - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. - - -function validateAuthData(authData) { - return request('auth/userinfo', authData.access_token).then(data => { - if (data && data.sub == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'PhantAuth auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'phantauth.net', - path: '/' + path, - headers: { - Authorization: 'bearer ' + access_token, - 'User-Agent': 'parse-server' - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3BoYW50YXV0aC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdWIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7Ozs7QUFPQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxTQUFTRSxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsT0FBTyxDQUFDLGVBQUQsRUFBa0JELFFBQVEsQ0FBQ0UsWUFBM0IsQ0FBUCxDQUFnREMsSUFBaEQsQ0FBcURDLElBQUksSUFBSTtBQUNsRSxRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsR0FBTCxJQUFZTCxRQUFRLENBQUNNLEVBQWpDLEVBQXFDO0FBQ25DO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJVixLQUFLLENBQUNXLEtBQVYsQ0FDSlgsS0FBSyxDQUFDVyxLQUFOLENBQVlDLGdCQURSLEVBRUosMENBRkksQ0FBTjtBQUlELEdBUk0sQ0FBUDtBQVNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsT0FBVCxDQUFpQlcsSUFBakIsRUFBdUJWLFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2UsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGVBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsTUFBTUEsSUFGVTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZZCxZQURwQjtBQUVQLG9CQUFjO0FBRlA7QUFIYSxHQUFqQixDQUFQO0FBUUQ7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUGhhbnRBdXRoIHdhcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0ZXN0aW5nIGZvciBhcHBsaWNhdGlvbnMgdXNpbmcgT3BlbklEIENvbm5lY3RcbiAqIGF1dGhlbnRpY2F0aW9uIGJ5IG1ha2luZyB1c2Ugb2YgcmFuZG9tIGdlbmVyYXRlZCB1c2Vycy5cbiAqXG4gKiBUbyBsZWFybiBtb3JlLCBwbGVhc2UgZ28gdG86IGh0dHBzOi8vd3d3LnBoYW50YXV0aC5uZXRcbiAqL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ2F1dGgvdXNlcmluZm8nLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5zdWIgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdQaGFudEF1dGggYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdwaGFudGF1dGgubmV0JyxcbiAgICBwYXRoOiAnLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdiZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgICdVc2VyLUFnZW50JzogJ3BhcnNlLXNlcnZlcicsXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/qq.js b/lib/Adapters/Auth/qq.js deleted file mode 100644 index 4d57399ed2..0000000000 --- a/lib/Adapters/Auth/qq.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; - -// Helper functions for accessing the qq Graph API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return graphRequest('me?access_token=' + authData.access_token).then(function (data) { - if (data && data.openid == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for qq graph requests. - - -function graphRequest(path) { - return httpsRequest.get('https://graph.qq.com/oauth2.0/' + path, true).then(data => { - return parseResponseData(data); - }); -} - -function parseResponseData(data) { - const starPos = data.indexOf('('); - const endPos = data.indexOf(')'); - - if (starPos == -1 || endPos == -1) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); - } - - data = data.substring(starPos + 1, endPos - 1); - return JSON.parse(data); -} - -module.exports = { - validateAppId, - validateAuthData, - parseResponseData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3FxLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwib3BlbmlkIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwicGFyc2VSZXNwb25zZURhdGEiLCJzdGFyUG9zIiwiaW5kZXhPZiIsImVuZFBvcyIsInN1YnN0cmluZyIsIkpTT04iLCJwYXJzZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxNQUFNQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUE1Qjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDLEMsQ0FFQTs7O0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DO0FBQ2xDLFNBQU9DLFlBQVksQ0FBQyxxQkFBcUJELFFBQVEsQ0FBQ0UsWUFBL0IsQ0FBWixDQUF5REMsSUFBekQsQ0FBOEQsVUFDbkVDLElBRG1FLEVBRW5FO0FBQ0EsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLE1BQUwsSUFBZUwsUUFBUSxDQUFDTSxFQUFwQyxFQUF3QztBQUN0QztBQUNEOztBQUNELFVBQU0sSUFBSVIsS0FBSyxDQUFDUyxLQUFWLENBQ0pULEtBQUssQ0FBQ1MsS0FBTixDQUFZQyxnQkFEUixFQUVKLG1DQUZJLENBQU47QUFJRCxHQVZNLENBQVA7QUFXRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNWLFlBQVQsQ0FBc0JXLElBQXRCLEVBQTRCO0FBQzFCLFNBQU9oQixZQUFZLENBQ2hCaUIsR0FESSxDQUNBLG1DQUFtQ0QsSUFEbkMsRUFDeUMsSUFEekMsRUFFSlQsSUFGSSxDQUVDQyxJQUFJLElBQUk7QUFDWixXQUFPVSxpQkFBaUIsQ0FBQ1YsSUFBRCxDQUF4QjtBQUNELEdBSkksQ0FBUDtBQUtEOztBQUVELFNBQVNVLGlCQUFULENBQTJCVixJQUEzQixFQUFpQztBQUMvQixRQUFNVyxPQUFPLEdBQUdYLElBQUksQ0FBQ1ksT0FBTCxDQUFhLEdBQWIsQ0FBaEI7QUFDQSxRQUFNQyxNQUFNLEdBQUdiLElBQUksQ0FBQ1ksT0FBTCxDQUFhLEdBQWIsQ0FBZjs7QUFDQSxNQUFJRCxPQUFPLElBQUksQ0FBQyxDQUFaLElBQWlCRSxNQUFNLElBQUksQ0FBQyxDQUFoQyxFQUFtQztBQUNqQyxVQUFNLElBQUluQixLQUFLLENBQUNTLEtBQVYsQ0FDSlQsS0FBSyxDQUFDUyxLQUFOLENBQVlDLGdCQURSLEVBRUosbUNBRkksQ0FBTjtBQUlEOztBQUNESixFQUFBQSxJQUFJLEdBQUdBLElBQUksQ0FBQ2MsU0FBTCxDQUFlSCxPQUFPLEdBQUcsQ0FBekIsRUFBNEJFLE1BQU0sR0FBRyxDQUFyQyxDQUFQO0FBQ0EsU0FBT0UsSUFBSSxDQUFDQyxLQUFMLENBQVdoQixJQUFYLENBQVA7QUFDRDs7QUFFRGlCLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmYixFQUFBQSxhQURlO0FBRWZWLEVBQUFBLGdCQUZlO0FBR2ZlLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHFxIEdyYXBoIEFQSS5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdCgnbWU/YWNjZXNzX3Rva2VuPScgKyBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZnVuY3Rpb24oXG4gICAgZGF0YVxuICApIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLm9wZW5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ3FxIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBxcSBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChwYXRoKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3RcbiAgICAuZ2V0KCdodHRwczovL2dyYXBoLnFxLmNvbS9vYXV0aDIuMC8nICsgcGF0aCwgdHJ1ZSlcbiAgICAudGhlbihkYXRhID0+IHtcbiAgICAgIHJldHVybiBwYXJzZVJlc3BvbnNlRGF0YShkYXRhKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VSZXNwb25zZURhdGEoZGF0YSkge1xuICBjb25zdCBzdGFyUG9zID0gZGF0YS5pbmRleE9mKCcoJyk7XG4gIGNvbnN0IGVuZFBvcyA9IGRhdGEuaW5kZXhPZignKScpO1xuICBpZiAoc3RhclBvcyA9PSAtMSB8fCBlbmRQb3MgPT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ3FxIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9XG4gIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhzdGFyUG9zICsgMSwgZW5kUG9zIC0gMSk7XG4gIHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbiAgcGFyc2VSZXNwb25zZURhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/spotify.js b/lib/Adapters/Auth/spotify.js deleted file mode 100644 index a4eda323f6..0000000000 --- a/lib/Adapters/Auth/spotify.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Spotify API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('me', authData.access_token).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId(appIds, authData) { - var access_token = authData.access_token; - - if (!appIds.length) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is not configured.'); - } - - return request('me', access_token).then(data => { - if (data && appIds.indexOf(data.id) != -1) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); - }); -} // A promisey wrapper for Spotify API requests. - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'api.spotify.com', - path: '/v1/' + path, - headers: { - Authorization: 'Bearer ' + access_token - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Nwb3RpZnkuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiYXBwSWRzIiwibGVuZ3RoIiwiaW5kZXhPZiIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLENBQVAsQ0FBcUNDLElBQXJDLENBQTBDQyxJQUFJLElBQUk7QUFDdkQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQ0pSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxnQkFEUixFQUVKLHdDQUZJLENBQU47QUFJRCxHQVJNLENBQVA7QUFTRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsQ0FBdUJDLE1BQXZCLEVBQStCVCxRQUEvQixFQUF5QztBQUN2QyxNQUFJRSxZQUFZLEdBQUdGLFFBQVEsQ0FBQ0UsWUFBNUI7O0FBQ0EsTUFBSSxDQUFDTyxNQUFNLENBQUNDLE1BQVosRUFBb0I7QUFDbEIsVUFBTSxJQUFJWixLQUFLLENBQUNRLEtBQVYsQ0FDSlIsS0FBSyxDQUFDUSxLQUFOLENBQVlDLGdCQURSLEVBRUosaUNBRkksQ0FBTjtBQUlEOztBQUNELFNBQU9OLE9BQU8sQ0FBQyxJQUFELEVBQU9DLFlBQVAsQ0FBUCxDQUE0QkMsSUFBNUIsQ0FBaUNDLElBQUksSUFBSTtBQUM5QyxRQUFJQSxJQUFJLElBQUlLLE1BQU0sQ0FBQ0UsT0FBUCxDQUFlUCxJQUFJLENBQUNDLEVBQXBCLEtBQTJCLENBQUMsQ0FBeEMsRUFBMkM7QUFDekM7QUFDRDs7QUFDRCxVQUFNLElBQUlQLEtBQUssQ0FBQ1EsS0FBVixDQUNKUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix3Q0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTTixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT04sWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGlCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWQ7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFNwb3RpZnkgQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhKSB7XG4gIHZhciBhY2Nlc3NfdG9rZW4gPSBhdXRoRGF0YS5hY2Nlc3NfdG9rZW47XG4gIGlmICghYXBwSWRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnU3BvdGlmeSBhdXRoIGlzIG5vdCBjb25maWd1cmVkLidcbiAgICApO1xuICB9XG4gIHJldHVybiByZXF1ZXN0KCdtZScsIGFjY2Vzc190b2tlbikudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBhcHBJZHMuaW5kZXhPZihkYXRhLmlkKSAhPSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIFNwb3RpZnkgQVBJIHJlcXVlc3RzLlxuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuc3BvdGlmeS5jb20nLFxuICAgIHBhdGg6ICcvdjEvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/twitter.js b/lib/Adapters/Auth/twitter.js deleted file mode 100644 index 75684e3834..0000000000 --- a/lib/Adapters/Auth/twitter.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; - -// Helper functions for accessing the twitter API. -var OAuth = require('./OAuth1Client'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - if (!options) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Twitter auth configuration missing'); - } - - options = handleMultipleConfigurations(authData, options); - var client = new OAuth(options); - client.host = 'api.twitter.com'; - client.auth_token = authData.auth_token; - client.auth_token_secret = authData.auth_token_secret; - return client.get('/1.1/account/verify_credentials.json').then(data => { - if (data && data.id_str == '' + authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -function handleMultipleConfigurations(authData, options) { - if (Array.isArray(options)) { - const consumer_key = authData.consumer_key; - - if (!consumer_key) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); - } - - options = options.filter(option => { - return option.consumer_key == consumer_key; - }); - - if (options.length == 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); - } - - options = options[0]; - } - - return options; -} - -module.exports = { - validateAppId, - validateAuthData, - handleMultipleConfigurations -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3R3aXR0ZXIuanMiXSwibmFtZXMiOlsiT0F1dGgiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zIiwiY2xpZW50IiwiaG9zdCIsImF1dGhfdG9rZW4iLCJhdXRoX3Rva2VuX3NlY3JldCIsImdldCIsInRoZW4iLCJkYXRhIiwiaWRfc3RyIiwiaWQiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uc3VtZXJfa2V5IiwiZmlsdGVyIiwib3B0aW9uIiwibGVuZ3RoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQW5COztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEMsQyxDQUVBOzs7QUFDQSxTQUFTQyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLE1BQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osVUFBTSxJQUFJSCxLQUFLLENBQUNJLEtBQVYsQ0FDSkosS0FBSyxDQUFDSSxLQUFOLENBQVlDLHFCQURSLEVBRUosb0NBRkksQ0FBTjtBQUlEOztBQUNERixFQUFBQSxPQUFPLEdBQUdHLDRCQUE0QixDQUFDSixRQUFELEVBQVdDLE9BQVgsQ0FBdEM7QUFDQSxNQUFJSSxNQUFNLEdBQUcsSUFBSVQsS0FBSixDQUFVSyxPQUFWLENBQWI7QUFDQUksRUFBQUEsTUFBTSxDQUFDQyxJQUFQLEdBQWMsaUJBQWQ7QUFDQUQsRUFBQUEsTUFBTSxDQUFDRSxVQUFQLEdBQW9CUCxRQUFRLENBQUNPLFVBQTdCO0FBQ0FGLEVBQUFBLE1BQU0sQ0FBQ0csaUJBQVAsR0FBMkJSLFFBQVEsQ0FBQ1EsaUJBQXBDO0FBRUEsU0FBT0gsTUFBTSxDQUFDSSxHQUFQLENBQVcsc0NBQVgsRUFBbURDLElBQW5ELENBQXdEQyxJQUFJLElBQUk7QUFDckUsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLE1BQUwsSUFBZSxLQUFLWixRQUFRLENBQUNhLEVBQXpDLEVBQTZDO0FBQzNDO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJZixLQUFLLENBQUNJLEtBQVYsQ0FDSkosS0FBSyxDQUFDSSxLQUFOLENBQVlZLGdCQURSLEVBRUosd0NBRkksQ0FBTjtBQUlELEdBUk0sQ0FBUDtBQVNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVELFNBQVNiLDRCQUFULENBQXNDSixRQUF0QyxFQUFnREMsT0FBaEQsRUFBeUQ7QUFDdkQsTUFBSWlCLEtBQUssQ0FBQ0MsT0FBTixDQUFjbEIsT0FBZCxDQUFKLEVBQTRCO0FBQzFCLFVBQU1tQixZQUFZLEdBQUdwQixRQUFRLENBQUNvQixZQUE5Qjs7QUFDQSxRQUFJLENBQUNBLFlBQUwsRUFBbUI7QUFDakIsWUFBTSxJQUFJdEIsS0FBSyxDQUFDSSxLQUFWLENBQ0pKLEtBQUssQ0FBQ0ksS0FBTixDQUFZWSxnQkFEUixFQUVKLHdDQUZJLENBQU47QUFJRDs7QUFDRGIsSUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNvQixNQUFSLENBQWVDLE1BQU0sSUFBSTtBQUNqQyxhQUFPQSxNQUFNLENBQUNGLFlBQVAsSUFBdUJBLFlBQTlCO0FBQ0QsS0FGUyxDQUFWOztBQUlBLFFBQUluQixPQUFPLENBQUNzQixNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSXpCLEtBQUssQ0FBQ0ksS0FBVixDQUNKSixLQUFLLENBQUNJLEtBQU4sQ0FBWVksZ0JBRFIsRUFFSix3Q0FGSSxDQUFOO0FBSUQ7O0FBQ0RiLElBQUFBLE9BQU8sR0FBR0EsT0FBTyxDQUFDLENBQUQsQ0FBakI7QUFDRDs7QUFDRCxTQUFPQSxPQUFQO0FBQ0Q7O0FBRUR1QixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlYsRUFBQUEsYUFEZTtBQUVmaEIsRUFBQUEsZ0JBRmU7QUFHZkssRUFBQUE7QUFIZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgdHdpdHRlciBBUEkuXG52YXIgT0F1dGggPSByZXF1aXJlKCcuL09BdXRoMUNsaWVudCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICdUd2l0dGVyIGF1dGggY29uZmlndXJhdGlvbiBtaXNzaW5nJ1xuICAgICk7XG4gIH1cbiAgb3B0aW9ucyA9IGhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMoYXV0aERhdGEsIG9wdGlvbnMpO1xuICB2YXIgY2xpZW50ID0gbmV3IE9BdXRoKG9wdGlvbnMpO1xuICBjbGllbnQuaG9zdCA9ICdhcGkudHdpdHRlci5jb20nO1xuICBjbGllbnQuYXV0aF90b2tlbiA9IGF1dGhEYXRhLmF1dGhfdG9rZW47XG4gIGNsaWVudC5hdXRoX3Rva2VuX3NlY3JldCA9IGF1dGhEYXRhLmF1dGhfdG9rZW5fc2VjcmV0O1xuXG4gIHJldHVybiBjbGllbnQuZ2V0KCcvMS4xL2FjY291bnQvdmVyaWZ5X2NyZWRlbnRpYWxzLmpzb24nKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWRfc3RyID09ICcnICsgYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdUd2l0dGVyIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucykpIHtcbiAgICBjb25zdCBjb25zdW1lcl9rZXkgPSBhdXRoRGF0YS5jb25zdW1lcl9rZXk7XG4gICAgaWYgKCFjb25zdW1lcl9rZXkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMuZmlsdGVyKG9wdGlvbiA9PiB7XG4gICAgICByZXR1cm4gb3B0aW9uLmNvbnN1bWVyX2tleSA9PSBjb25zdW1lcl9rZXk7XG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucy5sZW5ndGggPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICApO1xuICAgIH1cbiAgICBvcHRpb25zID0gb3B0aW9uc1swXTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG4gIGhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/vkontakte.js b/lib/Adapters/Auth/vkontakte.js deleted file mode 100644 index cba090645e..0000000000 --- a/lib/Adapters/Auth/vkontakte.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; // Helper functions for accessing the vkontakte API. - -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, params) { - return vkOAuth2Request(params).then(function (response) { - if (response && response.access_token) { - return request('api.vk.com', 'method/users.get?access_token=' + authData.access_token + '&v=' + params.apiVersion).then(function (response) { - if (response && response.response && response.response.length && response.response[0].id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is invalid for this user.'); - }); - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk appIds or appSecret is incorrect.'); - }); -} - -function vkOAuth2Request(params) { - return new Promise(function (resolve) { - if (!params || !params.appIds || !params.appIds.length || !params.appSecret || !params.appSecret.length) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is not configured. Missing appIds or appSecret.'); - } - - if (!params.apiVersion) { - params.apiVersion = '5.124'; - } - - resolve(); - }).then(function () { - return request('oauth.vk.com', 'access_token?client_id=' + params.appIds + '&client_secret=' + params.appSecret + '&v=' + params.apiVersion + '&grant_type=client_credentials'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(host, path) { - return httpsRequest.get('https://' + host + '/' + path); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Zrb250YWt0ZS5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJwYXJhbXMiLCJ2a09BdXRoMlJlcXVlc3QiLCJ0aGVuIiwicmVzcG9uc2UiLCJhY2Nlc3NfdG9rZW4iLCJyZXF1ZXN0IiwiYXBpVmVyc2lvbiIsImxlbmd0aCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiUHJvbWlzZSIsInJlc29sdmUiLCJhcHBJZHMiLCJhcHBTZWNyZXQiLCJ2YWxpZGF0ZUFwcElkIiwiaG9zdCIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBRUEsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsTUFBcEMsRUFBNEM7QUFDMUMsU0FBT0MsZUFBZSxDQUFDRCxNQUFELENBQWYsQ0FBd0JFLElBQXhCLENBQTZCLFVBQVVDLFFBQVYsRUFBb0I7QUFDdEQsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLFlBQXpCLEVBQXVDO0FBQ3JDLGFBQU9DLE9BQU8sQ0FDWixZQURZLEVBRVosbUNBQ0VOLFFBQVEsQ0FBQ0ssWUFEWCxHQUVFLEtBRkYsR0FHRUosTUFBTSxDQUFDTSxVQUxHLENBQVAsQ0FNTEosSUFOSyxDQU1BLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsWUFDRUEsUUFBUSxJQUNSQSxRQUFRLENBQUNBLFFBRFQsSUFFQUEsUUFBUSxDQUFDQSxRQUFULENBQWtCSSxNQUZsQixJQUdBSixRQUFRLENBQUNBLFFBQVQsQ0FBa0IsQ0FBbEIsRUFBcUJLLEVBQXJCLElBQTJCVCxRQUFRLENBQUNTLEVBSnRDLEVBS0U7QUFDQTtBQUNEOztBQUNELGNBQU0sSUFBSVgsS0FBSyxDQUFDWSxLQUFWLENBQ0paLEtBQUssQ0FBQ1ksS0FBTixDQUFZQyxnQkFEUixFQUVKLG1DQUZJLENBQU47QUFJRCxPQW5CTSxDQUFQO0FBb0JEOztBQUNELFVBQU0sSUFBSWIsS0FBSyxDQUFDWSxLQUFWLENBQ0paLEtBQUssQ0FBQ1ksS0FBTixDQUFZQyxnQkFEUixFQUVKLHNDQUZJLENBQU47QUFJRCxHQTNCTSxDQUFQO0FBNEJEOztBQUVELFNBQVNULGVBQVQsQ0FBeUJELE1BQXpCLEVBQWlDO0FBQy9CLFNBQU8sSUFBSVcsT0FBSixDQUFZLFVBQVVDLE9BQVYsRUFBbUI7QUFDcEMsUUFDRSxDQUFDWixNQUFELElBQ0EsQ0FBQ0EsTUFBTSxDQUFDYSxNQURSLElBRUEsQ0FBQ2IsTUFBTSxDQUFDYSxNQUFQLENBQWNOLE1BRmYsSUFHQSxDQUFDUCxNQUFNLENBQUNjLFNBSFIsSUFJQSxDQUFDZCxNQUFNLENBQUNjLFNBQVAsQ0FBaUJQLE1BTHBCLEVBTUU7QUFDQSxZQUFNLElBQUlWLEtBQUssQ0FBQ1ksS0FBVixDQUNKWixLQUFLLENBQUNZLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5REFGSSxDQUFOO0FBSUQ7O0FBQ0QsUUFBSSxDQUFDVixNQUFNLENBQUNNLFVBQVosRUFBd0I7QUFDdEJOLE1BQUFBLE1BQU0sQ0FBQ00sVUFBUCxHQUFvQixPQUFwQjtBQUNEOztBQUNETSxJQUFBQSxPQUFPO0FBQ1IsR0FqQk0sRUFpQkpWLElBakJJLENBaUJDLFlBQVk7QUFDbEIsV0FBT0csT0FBTyxDQUNaLGNBRFksRUFFWiw0QkFDRUwsTUFBTSxDQUFDYSxNQURULEdBRUUsaUJBRkYsR0FHRWIsTUFBTSxDQUFDYyxTQUhULEdBSUUsS0FKRixHQUtFZCxNQUFNLENBQUNNLFVBTFQsR0FNRSxnQ0FSVSxDQUFkO0FBVUQsR0E1Qk0sQ0FBUDtBQTZCRCxDLENBRUQ7OztBQUNBLFNBQVNTLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNQLE9BQVQsQ0FBaUJXLElBQWpCLEVBQXVCQyxJQUF2QixFQUE2QjtBQUMzQixTQUFPdEIsWUFBWSxDQUFDdUIsR0FBYixDQUFpQixhQUFhRixJQUFiLEdBQW9CLEdBQXBCLEdBQTBCQyxJQUEzQyxDQUFQO0FBQ0Q7O0FBRURFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmTCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZmpCLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHZrb250YWt0ZSBBUEkuXG5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIHBhcmFtcykge1xuICByZXR1cm4gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuYWNjZXNzX3Rva2VuKSB7XG4gICAgICByZXR1cm4gcmVxdWVzdChcbiAgICAgICAgJ2FwaS52ay5jb20nLFxuICAgICAgICAnbWV0aG9kL3VzZXJzLmdldD9hY2Nlc3NfdG9rZW49JyArXG4gICAgICAgICAgYXV0aERhdGEuYWNjZXNzX3Rva2VuICtcbiAgICAgICAgICAnJnY9JyArXG4gICAgICAgICAgcGFyYW1zLmFwaVZlcnNpb25cbiAgICAgICkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlc3BvbnNlICYmXG4gICAgICAgICAgcmVzcG9uc2UucmVzcG9uc2UgJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZS5sZW5ndGggJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZVswXS5pZCA9PSBhdXRoRGF0YS5pZFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1ZrIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1ZrIGFwcElkcyBvciBhcHBTZWNyZXQgaXMgaW5jb3JyZWN0LidcbiAgICApO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICBpZiAoXG4gICAgICAhcGFyYW1zIHx8XG4gICAgICAhcGFyYW1zLmFwcElkcyB8fFxuICAgICAgIXBhcmFtcy5hcHBJZHMubGVuZ3RoIHx8XG4gICAgICAhcGFyYW1zLmFwcFNlY3JldCB8fFxuICAgICAgIXBhcmFtcy5hcHBTZWNyZXQubGVuZ3RoXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdWayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLiBNaXNzaW5nIGFwcElkcyBvciBhcHBTZWNyZXQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuYXBpVmVyc2lvbikge1xuICAgICAgcGFyYW1zLmFwaVZlcnNpb24gPSAnNS4xMjQnO1xuICAgIH1cbiAgICByZXNvbHZlKCk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZXF1ZXN0KFxuICAgICAgJ29hdXRoLnZrLmNvbScsXG4gICAgICAnYWNjZXNzX3Rva2VuP2NsaWVudF9pZD0nICtcbiAgICAgICAgcGFyYW1zLmFwcElkcyArXG4gICAgICAgICcmY2xpZW50X3NlY3JldD0nICtcbiAgICAgICAgcGFyYW1zLmFwcFNlY3JldCArXG4gICAgICAgICcmdj0nICtcbiAgICAgICAgcGFyYW1zLmFwaVZlcnNpb24gK1xuICAgICAgICAnJmdyYW50X3R5cGU9Y2xpZW50X2NyZWRlbnRpYWxzJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QoaG9zdCwgcGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly8nICsgaG9zdCArICcvJyArIHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/wechat.js b/lib/Adapters/Auth/wechat.js deleted file mode 100644 index f1c429f593..0000000000 --- a/lib/Adapters/Auth/wechat.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; - -// Helper functions for accessing the WeChat Graph API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return graphRequest('auth?access_token=' + authData.access_token + '&openid=' + authData.id).then(function (data) { - if (data.errcode == 0) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'wechat auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for WeChat graph requests. - - -function graphRequest(path) { - return httpsRequest.get('https://api.weixin.qq.com/sns/' + path); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlY2hhdC5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJncmFwaFJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpZCIsInRoZW4iLCJkYXRhIiwiZXJyY29kZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxZQUFZLENBQ2pCLHVCQUF1QkQsUUFBUSxDQUFDRSxZQUFoQyxHQUErQyxVQUEvQyxHQUE0REYsUUFBUSxDQUFDRyxFQURwRCxDQUFaLENBRUxDLElBRkssQ0FFQSxVQUFTQyxJQUFULEVBQWU7QUFDcEIsUUFBSUEsSUFBSSxDQUFDQyxPQUFMLElBQWdCLENBQXBCLEVBQXVCO0FBQ3JCO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJUixLQUFLLENBQUNTLEtBQVYsQ0FDSlQsS0FBSyxDQUFDUyxLQUFOLENBQVlDLGdCQURSLEVBRUosdUNBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsWUFBVCxDQUFzQlcsSUFBdEIsRUFBNEI7QUFDMUIsU0FBT2hCLFlBQVksQ0FBQ2lCLEdBQWIsQ0FBaUIsbUNBQW1DRCxJQUFwRCxDQUFQO0FBQ0Q7O0FBRURFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmTixFQUFBQSxhQURlO0FBRWZWLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFdlQ2hhdCBHcmFwaCBBUEkuXG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiBncmFwaFJlcXVlc3QoXG4gICAgJ2F1dGg/YWNjZXNzX3Rva2VuPScgKyBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4gKyAnJm9wZW5pZD0nICsgYXV0aERhdGEuaWRcbiAgKS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZiAoZGF0YS5lcnJjb2RlID09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICd3ZWNoYXQgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIFdlQ2hhdCBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChwYXRoKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KCdodHRwczovL2FwaS53ZWl4aW4ucXEuY29tL3Nucy8nICsgcGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/weibo.js b/lib/Adapters/Auth/weibo.js deleted file mode 100644 index 701866d6ae..0000000000 --- a/lib/Adapters/Auth/weibo.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -// Helper functions for accessing the weibo Graph API. -var httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; - -var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return graphRequest(authData.access_token).then(function (data) { - if (data && data.uid == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'weibo auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for weibo graph requests. - - -function graphRequest(access_token) { - var postData = querystring.stringify({ - access_token: access_token - }); - var options = { - hostname: 'api.weibo.com', - path: '/oauth2/get_token_info', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(postData) - } - }; - return httpsRequest.request(options, postData); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlaWJvLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInF1ZXJ5c3RyaW5nIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiZ3JhcGhSZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJ1aWQiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3REYXRhIiwic3RyaW5naWZ5Iiwib3B0aW9ucyIsImhvc3RuYW1lIiwicGF0aCIsIm1ldGhvZCIsImhlYWRlcnMiLCJCdWZmZXIiLCJieXRlTGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsWUFBWSxDQUFDRCxRQUFRLENBQUNFLFlBQVYsQ0FBWixDQUFvQ0MsSUFBcEMsQ0FBeUMsVUFBU0MsSUFBVCxFQUFlO0FBQzdELFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxHQUFMLElBQVlMLFFBQVEsQ0FBQ00sRUFBakMsRUFBcUM7QUFDbkM7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUNKVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixzQ0FGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixZQUFULENBQXNCQyxZQUF0QixFQUFvQztBQUNsQyxNQUFJVSxRQUFRLEdBQUdkLFdBQVcsQ0FBQ2UsU0FBWixDQUFzQjtBQUNuQ1gsSUFBQUEsWUFBWSxFQUFFQTtBQURxQixHQUF0QixDQUFmO0FBR0EsTUFBSVksT0FBTyxHQUFHO0FBQ1pDLElBQUFBLFFBQVEsRUFBRSxlQURFO0FBRVpDLElBQUFBLElBQUksRUFBRSx3QkFGTTtBQUdaQyxJQUFBQSxNQUFNLEVBQUUsTUFISTtBQUlaQyxJQUFBQSxPQUFPLEVBQUU7QUFDUCxzQkFBZ0IsbUNBRFQ7QUFFUCx3QkFBa0JDLE1BQU0sQ0FBQ0MsVUFBUCxDQUFrQlIsUUFBbEI7QUFGWDtBQUpHLEdBQWQ7QUFTQSxTQUFPakIsWUFBWSxDQUFDMEIsT0FBYixDQUFxQlAsT0FBckIsRUFBOEJGLFFBQTlCLENBQVA7QUFDRDs7QUFFRFUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZkLEVBQUFBLGFBRGU7QUFFZlYsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgd2VpYm8gR3JhcGggQVBJLlxudmFyIGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiBncmFwaFJlcXVlc3QoYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnVpZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ3dlaWJvIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciB3ZWlibyBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIHBvc3REYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICBhY2Nlc3NfdG9rZW46IGFjY2Vzc190b2tlbixcbiAgfSk7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGhvc3RuYW1lOiAnYXBpLndlaWJvLmNvbScsXG4gICAgcGF0aDogJy9vYXV0aDIvZ2V0X3Rva2VuX2luZm8nLFxuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAgICdDb250ZW50LUxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHBvc3REYXRhKSxcbiAgICB9LFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LnJlcXVlc3Qob3B0aW9ucywgcG9zdERhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/CacheAdapter.js b/lib/Adapters/Cache/CacheAdapter.js deleted file mode 100644 index 60e6d6e501..0000000000 --- a/lib/Adapters/Cache/CacheAdapter.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.CacheAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface CacheAdapter - */ -class CacheAdapter { - /** - * Get a value in the cache - * @param {String} key Cache key to get - * @return {Promise} that will eventually resolve to the value in the cache. - */ - get(key) {} - /** - * Set a value in the cache - * @param {String} key Cache key to set - * @param {String} value Value to set the key - * @param {String} ttl Optional TTL - */ - - - put(key, value, ttl) {} - /** - * Remove a value from the cache. - * @param {String} key Cache key to remove - */ - - - del(key) {} - /** - * Empty a cache - */ - - - clear() {} - -} - -exports.CacheAdapter = CacheAdapter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9DYWNoZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiQ2FjaGVBZGFwdGVyIiwiZ2V0Iiwia2V5IiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7OztBQUdPLE1BQU1BLFlBQU4sQ0FBbUI7QUFDeEI7Ozs7O0FBS0FDLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNLENBQUU7QUFFWDs7Ozs7Ozs7QUFNQUMsRUFBQUEsR0FBRyxDQUFDRCxHQUFELEVBQU1FLEtBQU4sRUFBYUMsR0FBYixFQUFrQixDQUFFO0FBRXZCOzs7Ozs7QUFJQUMsRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU0sQ0FBRTtBQUVYOzs7OztBQUdBSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF6QmMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIENhY2hlQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGluIHRoZSBjYWNoZVxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byBnZXRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gdGhhdCB3aWxsIGV2ZW50dWFsbHkgcmVzb2x2ZSB0byB0aGUgdmFsdWUgaW4gdGhlIGNhY2hlLlxuICAgKi9cbiAgZ2V0KGtleSkge31cblxuICAvKipcbiAgICogU2V0IGEgdmFsdWUgaW4gdGhlIGNhY2hlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgQ2FjaGUga2V5IHRvIHNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVmFsdWUgdG8gc2V0IHRoZSBrZXlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR0bCBPcHRpb25hbCBUVExcbiAgICovXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHt9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHZhbHVlIGZyb20gdGhlIGNhY2hlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byByZW1vdmVcbiAgICovXG4gIGRlbChrZXkpIHt9XG5cbiAgLyoqXG4gICAqIEVtcHR5IGEgY2FjaGVcbiAgICovXG4gIGNsZWFyKCkge31cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCache.js b/lib/Adapters/Cache/InMemoryCache.js deleted file mode 100644 index b9a6543504..0000000000 --- a/lib/Adapters/Cache/InMemoryCache.js +++ /dev/null @@ -1,76 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.InMemoryCache = void 0; -const DEFAULT_CACHE_TTL = 5 * 1000; - -class InMemoryCache { - constructor({ - ttl = DEFAULT_CACHE_TTL - }) { - this.ttl = ttl; - this.cache = Object.create(null); - } - - get(key) { - const record = this.cache[key]; - - if (record == null) { - return null; - } // Has Record and isnt expired - - - if (isNaN(record.expire) || record.expire >= Date.now()) { - return record.value; - } // Record has expired - - - delete this.cache[key]; - return null; - } - - put(key, value, ttl = this.ttl) { - if (ttl < 0 || isNaN(ttl)) { - ttl = NaN; - } - - var record = { - value: value, - expire: ttl + Date.now() - }; - - if (!isNaN(record.expire)) { - record.timeout = setTimeout(() => { - this.del(key); - }, ttl); - } - - this.cache[key] = record; - } - - del(key) { - var record = this.cache[key]; - - if (record == null) { - return; - } - - if (record.timeout) { - clearTimeout(record.timeout); - } - - delete this.cache[key]; - } - - clear() { - this.cache = Object.create(null); - } - -} - -exports.InMemoryCache = InMemoryCache; -var _default = InMemoryCache; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlLmpzIl0sIm5hbWVzIjpbIkRFRkFVTFRfQ0FDSEVfVFRMIiwiSW5NZW1vcnlDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiY2FjaGUiLCJPYmplY3QiLCJjcmVhdGUiLCJnZXQiLCJrZXkiLCJyZWNvcmQiLCJpc05hTiIsImV4cGlyZSIsIkRhdGUiLCJub3ciLCJ2YWx1ZSIsInB1dCIsIk5hTiIsInRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiZGVsIiwiY2xlYXJUaW1lb3V0IiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE1BQU1BLGlCQUFpQixHQUFHLElBQUksSUFBOUI7O0FBRU8sTUFBTUMsYUFBTixDQUFvQjtBQUN6QkMsRUFBQUEsV0FBVyxDQUFDO0FBQUVDLElBQUFBLEdBQUcsR0FBR0g7QUFBUixHQUFELEVBQThCO0FBQ3ZDLFNBQUtHLEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLEtBQUwsR0FBYUMsTUFBTSxDQUFDQyxNQUFQLENBQWMsSUFBZCxDQUFiO0FBQ0Q7O0FBRURDLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsTUFBTSxHQUFHLEtBQUtMLEtBQUwsQ0FBV0ksR0FBWCxDQUFmOztBQUNBLFFBQUlDLE1BQU0sSUFBSSxJQUFkLEVBQW9CO0FBQ2xCLGFBQU8sSUFBUDtBQUNELEtBSk0sQ0FNUDs7O0FBQ0EsUUFBSUMsS0FBSyxDQUFDRCxNQUFNLENBQUNFLE1BQVIsQ0FBTCxJQUF3QkYsTUFBTSxDQUFDRSxNQUFQLElBQWlCQyxJQUFJLENBQUNDLEdBQUwsRUFBN0MsRUFBeUQ7QUFDdkQsYUFBT0osTUFBTSxDQUFDSyxLQUFkO0FBQ0QsS0FUTSxDQVdQOzs7QUFDQSxXQUFPLEtBQUtWLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0EsV0FBTyxJQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLEdBQUcsQ0FBQ1AsR0FBRCxFQUFNTSxLQUFOLEVBQWFYLEdBQUcsR0FBRyxLQUFLQSxHQUF4QixFQUE2QjtBQUM5QixRQUFJQSxHQUFHLEdBQUcsQ0FBTixJQUFXTyxLQUFLLENBQUNQLEdBQUQsQ0FBcEIsRUFBMkI7QUFDekJBLE1BQUFBLEdBQUcsR0FBR2EsR0FBTjtBQUNEOztBQUVELFFBQUlQLE1BQU0sR0FBRztBQUNYSyxNQUFBQSxLQUFLLEVBQUVBLEtBREk7QUFFWEgsTUFBQUEsTUFBTSxFQUFFUixHQUFHLEdBQUdTLElBQUksQ0FBQ0MsR0FBTDtBQUZILEtBQWI7O0FBS0EsUUFBSSxDQUFDSCxLQUFLLENBQUNELE1BQU0sQ0FBQ0UsTUFBUixDQUFWLEVBQTJCO0FBQ3pCRixNQUFBQSxNQUFNLENBQUNRLE9BQVAsR0FBaUJDLFVBQVUsQ0FBQyxNQUFNO0FBQ2hDLGFBQUtDLEdBQUwsQ0FBU1gsR0FBVDtBQUNELE9BRjBCLEVBRXhCTCxHQUZ3QixDQUEzQjtBQUdEOztBQUVELFNBQUtDLEtBQUwsQ0FBV0ksR0FBWCxJQUFrQkMsTUFBbEI7QUFDRDs7QUFFRFUsRUFBQUEsR0FBRyxDQUFDWCxHQUFELEVBQU07QUFDUCxRQUFJQyxNQUFNLEdBQUcsS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWI7O0FBQ0EsUUFBSUMsTUFBTSxJQUFJLElBQWQsRUFBb0I7QUFDbEI7QUFDRDs7QUFFRCxRQUFJQSxNQUFNLENBQUNRLE9BQVgsRUFBb0I7QUFDbEJHLE1BQUFBLFlBQVksQ0FBQ1gsTUFBTSxDQUFDUSxPQUFSLENBQVo7QUFDRDs7QUFDRCxXQUFPLEtBQUtiLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0Q7O0FBRURhLEVBQUFBLEtBQUssR0FBRztBQUNOLFNBQUtqQixLQUFMLEdBQWFDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLElBQWQsQ0FBYjtBQUNEOztBQXZEd0I7OztlQTBEWkwsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IERFRkFVTFRfQ0FDSEVfVFRMID0gNSAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBERUZBVUxUX0NBQ0hFX1RUTCB9KSB7XG4gICAgdGhpcy50dGwgPSB0dGw7XG4gICAgdGhpcy5jYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSGFzIFJlY29yZCBhbmQgaXNudCBleHBpcmVkXG4gICAgaWYgKGlzTmFOKHJlY29yZC5leHBpcmUpIHx8IHJlY29yZC5leHBpcmUgPj0gRGF0ZS5ub3coKSkge1xuICAgICAgcmV0dXJuIHJlY29yZC52YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBSZWNvcmQgaGFzIGV4cGlyZWRcbiAgICBkZWxldGUgdGhpcy5jYWNoZVtrZXldO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCA9IHRoaXMudHRsKSB7XG4gICAgaWYgKHR0bCA8IDAgfHwgaXNOYU4odHRsKSkge1xuICAgICAgdHRsID0gTmFOO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBleHBpcmU6IHR0bCArIERhdGUubm93KCksXG4gICAgfTtcblxuICAgIGlmICghaXNOYU4ocmVjb3JkLmV4cGlyZSkpIHtcbiAgICAgIHJlY29yZC50aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGVsKGtleSk7XG4gICAgICB9LCB0dGwpO1xuICAgIH1cblxuICAgIHRoaXMuY2FjaGVba2V5XSA9IHJlY29yZDtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB2YXIgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChyZWNvcmQudGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHJlY29yZC50aW1lb3V0KTtcbiAgICB9XG4gICAgZGVsZXRlIHRoaXMuY2FjaGVba2V5XTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEluTWVtb3J5Q2FjaGU7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCacheAdapter.js b/lib/Adapters/Cache/InMemoryCacheAdapter.js deleted file mode 100644 index ffc38ce5ec..0000000000 --- a/lib/Adapters/Cache/InMemoryCacheAdapter.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.InMemoryCacheAdapter = void 0; - -var _LRUCache = require("./LRUCache"); - -class InMemoryCacheAdapter { - constructor(ctx) { - this.cache = new _LRUCache.LRUCache(ctx); - } - - get(key) { - const record = this.cache.get(key); - - if (record === null) { - return Promise.resolve(null); - } - - return Promise.resolve(record); - } - - put(key, value, ttl) { - this.cache.put(key, value, ttl); - return Promise.resolve(); - } - - del(key) { - this.cache.del(key); - return Promise.resolve(); - } - - clear() { - this.cache.clear(); - return Promise.resolve(); - } - -} - -exports.InMemoryCacheAdapter = InMemoryCacheAdapter; -var _default = InMemoryCacheAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJJbk1lbW9yeUNhY2hlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiY3R4IiwiY2FjaGUiLCJMUlVDYWNoZSIsImdldCIsImtleSIsInJlY29yZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUVPLE1BQU1BLG9CQUFOLENBQTJCO0FBQ2hDQyxFQUFBQSxXQUFXLENBQUNDLEdBQUQsRUFBTTtBQUNmLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxrQkFBSixDQUFhRixHQUFiLENBQWI7QUFDRDs7QUFFREcsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU07QUFDUCxVQUFNQyxNQUFNLEdBQUcsS0FBS0osS0FBTCxDQUFXRSxHQUFYLENBQWVDLEdBQWYsQ0FBZjs7QUFDQSxRQUFJQyxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixhQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNEOztBQUNELFdBQU9ELE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkYsTUFBaEIsQ0FBUDtBQUNEOztBQUVERyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTUssS0FBTixFQUFhQyxHQUFiLEVBQWtCO0FBQ25CLFNBQUtULEtBQUwsQ0FBV08sR0FBWCxDQUFlSixHQUFmLEVBQW9CSyxLQUFwQixFQUEyQkMsR0FBM0I7QUFDQSxXQUFPSixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVESSxFQUFBQSxHQUFHLENBQUNQLEdBQUQsRUFBTTtBQUNQLFNBQUtILEtBQUwsQ0FBV1UsR0FBWCxDQUFlUCxHQUFmO0FBQ0EsV0FBT0UsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREssRUFBQUEsS0FBSyxHQUFHO0FBQ04sU0FBS1gsS0FBTCxDQUFXVyxLQUFYO0FBQ0EsV0FBT04sT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUExQitCOzs7ZUE2Qm5CVCxvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExSVUNhY2hlIH0gZnJvbSAnLi9MUlVDYWNoZSc7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKGN0eCkge1xuICAgIHRoaXMuY2FjaGUgPSBuZXcgTFJVQ2FjaGUoY3R4KTtcbiAgfVxuXG4gIGdldChrZXkpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgIGlmIChyZWNvcmQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVjb3JkKTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICB0aGlzLmNhY2hlLnB1dChrZXksIHZhbHVlLCB0dGwpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB0aGlzLmNhY2hlLmRlbChrZXkpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5NZW1vcnlDYWNoZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/LRUCache.js b/lib/Adapters/Cache/LRUCache.js deleted file mode 100644 index 9781621ecf..0000000000 --- a/lib/Adapters/Cache/LRUCache.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LRUCache = void 0; - -var _lruCache = _interopRequireDefault(require("lru-cache")); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class LRUCache { - constructor({ - ttl = _defaults.default.cacheTTL, - maxSize = _defaults.default.cacheMaxSize - }) { - this.cache = new _lruCache.default({ - max: maxSize, - maxAge: ttl - }); - } - - get(key) { - return this.cache.get(key) || null; - } - - put(key, value, ttl = this.ttl) { - this.cache.set(key, value, ttl); - } - - del(key) { - this.cache.del(key); - } - - clear() { - this.cache.reset(); - } - -} - -exports.LRUCache = LRUCache; -var _default = LRUCache; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyJdLCJuYW1lcyI6WyJMUlVDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiZGVmYXVsdHMiLCJjYWNoZVRUTCIsIm1heFNpemUiLCJjYWNoZU1heFNpemUiLCJjYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsImdldCIsImtleSIsInB1dCIsInZhbHVlIiwic2V0IiwiZGVsIiwiY2xlYXIiLCJyZXNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sTUFBTUEsUUFBTixDQUFlO0FBQ3BCQyxFQUFBQSxXQUFXLENBQUM7QUFBRUMsSUFBQUEsR0FBRyxHQUFHQyxrQkFBU0MsUUFBakI7QUFBMkJDLElBQUFBLE9BQU8sR0FBR0Ysa0JBQVNHO0FBQTlDLEdBQUQsRUFBK0Q7QUFDeEUsU0FBS0MsS0FBTCxHQUFhLElBQUlDLGlCQUFKLENBQVE7QUFDbkJDLE1BQUFBLEdBQUcsRUFBRUosT0FEYztBQUVuQkssTUFBQUEsTUFBTSxFQUFFUjtBQUZXLEtBQVIsQ0FBYjtBQUlEOztBQUVEUyxFQUFBQSxHQUFHLENBQUNDLEdBQUQsRUFBTTtBQUNQLFdBQU8sS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWVDLEdBQWYsS0FBdUIsSUFBOUI7QUFDRDs7QUFFREMsRUFBQUEsR0FBRyxDQUFDRCxHQUFELEVBQU1FLEtBQU4sRUFBYVosR0FBRyxHQUFHLEtBQUtBLEdBQXhCLEVBQTZCO0FBQzlCLFNBQUtLLEtBQUwsQ0FBV1EsR0FBWCxDQUFlSCxHQUFmLEVBQW9CRSxLQUFwQixFQUEyQlosR0FBM0I7QUFDRDs7QUFFRGMsRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxTQUFLTCxLQUFMLENBQVdTLEdBQVgsQ0FBZUosR0FBZjtBQUNEOztBQUVESyxFQUFBQSxLQUFLLEdBQUc7QUFDTixTQUFLVixLQUFMLENBQVdXLEtBQVg7QUFDRDs7QUF0Qm1COzs7ZUF5QlBsQixRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IExSVSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGNsYXNzIExSVUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBkZWZhdWx0cy5jYWNoZVRUTCwgbWF4U2l6ZSA9IGRlZmF1bHRzLmNhY2hlTWF4U2l6ZSB9KSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0dGwsXG4gICAgfSk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGtleSkgfHwgbnVsbDtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwgPSB0aGlzLnR0bCkge1xuICAgIHRoaXMuY2FjaGUuc2V0KGtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgdGhpcy5jYWNoZS5kZWwoa2V5KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUucmVzZXQoKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMUlVDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/NullCacheAdapter.js b/lib/Adapters/Cache/NullCacheAdapter.js deleted file mode 100644 index 639c544c94..0000000000 --- a/lib/Adapters/Cache/NullCacheAdapter.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.NullCacheAdapter = void 0; - -class NullCacheAdapter { - constructor() {} - - get() { - return new Promise(resolve => { - return resolve(null); - }); - } - - put() { - return Promise.resolve(); - } - - del() { - return Promise.resolve(); - } - - clear() { - return Promise.resolve(); - } - -} - -exports.NullCacheAdapter = NullCacheAdapter; -var _default = NullCacheAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIk51bGxDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsImdldCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwiZGVsIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxNQUFNQSxnQkFBTixDQUF1QjtBQUM1QkMsRUFBQUEsV0FBVyxHQUFHLENBQUU7O0FBRWhCQyxFQUFBQSxHQUFHLEdBQUc7QUFDSixXQUFPLElBQUlDLE9BQUosQ0FBWUMsT0FBTyxJQUFJO0FBQzVCLGFBQU9BLE9BQU8sQ0FBQyxJQUFELENBQWQ7QUFDRCxLQUZNLENBQVA7QUFHRDs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0YsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREUsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0gsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREcsRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFuQjJCOzs7ZUFzQmZKLGdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE51bGxDYWNoZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgZ2V0KCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgIH0pO1xuICB9XG5cbiAgcHV0KCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbCgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTnVsbENhY2hlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js b/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js deleted file mode 100644 index d4303d8803..0000000000 --- a/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js +++ /dev/null @@ -1,59 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.KeyPromiseQueue = void 0; - -// KeyPromiseQueue is a simple promise queue -// used to queue operations per key basis. -// Once the tail promise in the key-queue fulfills, -// the chain on that key will be cleared. -class KeyPromiseQueue { - constructor() { - this.queue = {}; - } - - enqueue(key, operation) { - const tuple = this.beforeOp(key); - const toAwait = tuple[1]; - const nextOperation = toAwait.then(operation); - const wrappedOperation = nextOperation.then(result => { - this.afterOp(key); - return result; - }); - tuple[1] = wrappedOperation; - return wrappedOperation; - } - - beforeOp(key) { - let tuple = this.queue[key]; - - if (!tuple) { - tuple = [0, Promise.resolve()]; - this.queue[key] = tuple; - } - - tuple[0]++; - return tuple; - } - - afterOp(key) { - const tuple = this.queue[key]; - - if (!tuple) { - return; - } - - tuple[0]--; - - if (tuple[0] <= 0) { - delete this.queue[key]; - return; - } - } - -} - -exports.KeyPromiseQueue = KeyPromiseQueue; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9LZXlQcm9taXNlUXVldWUuanMiXSwibmFtZXMiOlsiS2V5UHJvbWlzZVF1ZXVlIiwiY29uc3RydWN0b3IiLCJxdWV1ZSIsImVucXVldWUiLCJrZXkiLCJvcGVyYXRpb24iLCJ0dXBsZSIsImJlZm9yZU9wIiwidG9Bd2FpdCIsIm5leHRPcGVyYXRpb24iLCJ0aGVuIiwid3JhcHBlZE9wZXJhdGlvbiIsInJlc3VsdCIsImFmdGVyT3AiLCJQcm9taXNlIiwicmVzb2x2ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsZUFBTixDQUFzQjtBQUMzQkMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxHQUFhLEVBQWI7QUFDRDs7QUFFREMsRUFBQUEsT0FBTyxDQUFDQyxHQUFELEVBQU1DLFNBQU4sRUFBaUI7QUFDdEIsVUFBTUMsS0FBSyxHQUFHLEtBQUtDLFFBQUwsQ0FBY0gsR0FBZCxDQUFkO0FBQ0EsVUFBTUksT0FBTyxHQUFHRixLQUFLLENBQUMsQ0FBRCxDQUFyQjtBQUNBLFVBQU1HLGFBQWEsR0FBR0QsT0FBTyxDQUFDRSxJQUFSLENBQWFMLFNBQWIsQ0FBdEI7QUFDQSxVQUFNTSxnQkFBZ0IsR0FBR0YsYUFBYSxDQUFDQyxJQUFkLENBQW1CRSxNQUFNLElBQUk7QUFDcEQsV0FBS0MsT0FBTCxDQUFhVCxHQUFiO0FBQ0EsYUFBT1EsTUFBUDtBQUNELEtBSHdCLENBQXpCO0FBSUFOLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUwsR0FBV0ssZ0JBQVg7QUFDQSxXQUFPQSxnQkFBUDtBQUNEOztBQUVESixFQUFBQSxRQUFRLENBQUNILEdBQUQsRUFBTTtBQUNaLFFBQUlFLEtBQUssR0FBRyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBWjs7QUFDQSxRQUFJLENBQUNFLEtBQUwsRUFBWTtBQUNWQSxNQUFBQSxLQUFLLEdBQUcsQ0FBQyxDQUFELEVBQUlRLE9BQU8sQ0FBQ0MsT0FBUixFQUFKLENBQVI7QUFDQSxXQUFLYixLQUFMLENBQVdFLEdBQVgsSUFBa0JFLEtBQWxCO0FBQ0Q7O0FBQ0RBLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUw7QUFDQSxXQUFPQSxLQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLE9BQU8sQ0FBQ1QsR0FBRCxFQUFNO0FBQ1gsVUFBTUUsS0FBSyxHQUFHLEtBQUtKLEtBQUwsQ0FBV0UsR0FBWCxDQUFkOztBQUNBLFFBQUksQ0FBQ0UsS0FBTCxFQUFZO0FBQ1Y7QUFDRDs7QUFDREEsSUFBQUEsS0FBSyxDQUFDLENBQUQsQ0FBTDs7QUFDQSxRQUFJQSxLQUFLLENBQUMsQ0FBRCxDQUFMLElBQVksQ0FBaEIsRUFBbUI7QUFDakIsYUFBTyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBUDtBQUNBO0FBQ0Q7QUFDRjs7QUFyQzBCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gS2V5UHJvbWlzZVF1ZXVlIGlzIGEgc2ltcGxlIHByb21pc2UgcXVldWVcbi8vIHVzZWQgdG8gcXVldWUgb3BlcmF0aW9ucyBwZXIga2V5IGJhc2lzLlxuLy8gT25jZSB0aGUgdGFpbCBwcm9taXNlIGluIHRoZSBrZXktcXVldWUgZnVsZmlsbHMsXG4vLyB0aGUgY2hhaW4gb24gdGhhdCBrZXkgd2lsbCBiZSBjbGVhcmVkLlxuZXhwb3J0IGNsYXNzIEtleVByb21pc2VRdWV1ZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMucXVldWUgPSB7fTtcbiAgfVxuXG4gIGVucXVldWUoa2V5LCBvcGVyYXRpb24pIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMuYmVmb3JlT3Aoa2V5KTtcbiAgICBjb25zdCB0b0F3YWl0ID0gdHVwbGVbMV07XG4gICAgY29uc3QgbmV4dE9wZXJhdGlvbiA9IHRvQXdhaXQudGhlbihvcGVyYXRpb24pO1xuICAgIGNvbnN0IHdyYXBwZWRPcGVyYXRpb24gPSBuZXh0T3BlcmF0aW9uLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIHRoaXMuYWZ0ZXJPcChrZXkpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbiAgICB0dXBsZVsxXSA9IHdyYXBwZWRPcGVyYXRpb247XG4gICAgcmV0dXJuIHdyYXBwZWRPcGVyYXRpb247XG4gIH1cblxuICBiZWZvcmVPcChrZXkpIHtcbiAgICBsZXQgdHVwbGUgPSB0aGlzLnF1ZXVlW2tleV07XG4gICAgaWYgKCF0dXBsZSkge1xuICAgICAgdHVwbGUgPSBbMCwgUHJvbWlzZS5yZXNvbHZlKCldO1xuICAgICAgdGhpcy5xdWV1ZVtrZXldID0gdHVwbGU7XG4gICAgfVxuICAgIHR1cGxlWzBdKys7XG4gICAgcmV0dXJuIHR1cGxlO1xuICB9XG5cbiAgYWZ0ZXJPcChrZXkpIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMucXVldWVba2V5XTtcbiAgICBpZiAoIXR1cGxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHR1cGxlWzBdLS07XG4gICAgaWYgKHR1cGxlWzBdIDw9IDApIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnF1ZXVlW2tleV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/index.js b/lib/Adapters/Cache/RedisCacheAdapter/index.js deleted file mode 100644 index df8605d5f1..0000000000 --- a/lib/Adapters/Cache/RedisCacheAdapter/index.js +++ /dev/null @@ -1,130 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.RedisCacheAdapter = void 0; - -var _redis = _interopRequireDefault(require("redis")); - -var _logger = _interopRequireDefault(require("../../../logger")); - -var _KeyPromiseQueue = require("./KeyPromiseQueue"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const DEFAULT_REDIS_TTL = 30 * 1000; // 30 seconds in milliseconds - -const FLUSH_DB_KEY = '__flush_db__'; - -function debug() { - _logger.default.debug.apply(_logger.default, ['RedisCacheAdapter', ...arguments]); -} - -const isValidTTL = ttl => typeof ttl === 'number' && ttl > 0; - -class RedisCacheAdapter { - constructor(redisCtx, ttl = DEFAULT_REDIS_TTL) { - this.ttl = isValidTTL(ttl) ? ttl : DEFAULT_REDIS_TTL; - this.client = _redis.default.createClient(redisCtx); - this.queue = new _KeyPromiseQueue.KeyPromiseQueue(); - } - - handleShutdown() { - if (!this.client) { - return Promise.resolve(); - } - - return new Promise(resolve => { - this.client.quit(err => { - if (err) { - _logger.default.error('RedisCacheAdapter error on shutdown', { - error: err - }); - } - - resolve(); - }); - }); - } - - get(key) { - debug('get', key); - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.get(key, function (err, res) { - debug('-> get', key, res); - - if (!res) { - return resolve(null); - } - - resolve(JSON.parse(res)); - }); - })); - } - - put(key, value, ttl = this.ttl) { - value = JSON.stringify(value); - debug('put', key, value, ttl); - - if (ttl === 0) { - // ttl of zero is a logical no-op, but redis cannot set expire time of zero - return this.queue.enqueue(key, () => Promise.resolve()); - } - - if (ttl === Infinity) { - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.set(key, value, function () { - resolve(); - }); - })); - } - - if (!isValidTTL(ttl)) { - ttl = this.ttl; - } - - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.psetex(key, ttl, value, function () { - resolve(); - }); - })); - } - - del(key) { - debug('del', key); - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.del(key, function () { - resolve(); - }); - })); - } - - clear() { - debug('clear'); - return this.queue.enqueue(FLUSH_DB_KEY, () => new Promise(resolve => { - this.client.flushdb(function () { - resolve(); - }); - })); - } // Used for testing - - - async getAllKeys() { - return new Promise((resolve, reject) => { - this.client.keys('*', (err, keys) => { - if (err) { - reject(err); - } else { - resolve(keys); - } - }); - }); - } - -} - -exports.RedisCacheAdapter = RedisCacheAdapter; -var _default = RedisCacheAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9pbmRleC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX1JFRElTX1RUTCIsIkZMVVNIX0RCX0tFWSIsImRlYnVnIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJpc1ZhbGlkVFRMIiwidHRsIiwiUmVkaXNDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInJlZGlzQ3R4IiwiY2xpZW50IiwicmVkaXMiLCJjcmVhdGVDbGllbnQiLCJxdWV1ZSIsIktleVByb21pc2VRdWV1ZSIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJxdWl0IiwiZXJyIiwiZXJyb3IiLCJnZXQiLCJrZXkiLCJlbnF1ZXVlIiwicmVzIiwiSlNPTiIsInBhcnNlIiwicHV0IiwidmFsdWUiLCJzdHJpbmdpZnkiLCJJbmZpbml0eSIsInNldCIsInBzZXRleCIsImRlbCIsImNsZWFyIiwiZmx1c2hkYiIsImdldEFsbEtleXMiLCJyZWplY3QiLCJrZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxpQkFBaUIsR0FBRyxLQUFLLElBQS9CLEMsQ0FBcUM7O0FBQ3JDLE1BQU1DLFlBQVksR0FBRyxjQUFyQjs7QUFFQSxTQUFTQyxLQUFULEdBQWlCO0FBQ2ZDLGtCQUFPRCxLQUFQLENBQWFFLEtBQWIsQ0FBbUJELGVBQW5CLEVBQTJCLENBQUMsbUJBQUQsRUFBc0IsR0FBR0UsU0FBekIsQ0FBM0I7QUFDRDs7QUFFRCxNQUFNQyxVQUFVLEdBQUlDLEdBQUQsSUFBUyxPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUEyQkEsR0FBRyxHQUFHLENBQTdEOztBQUVPLE1BQU1DLGlCQUFOLENBQXdCO0FBQzdCQyxFQUFBQSxXQUFXLENBQUNDLFFBQUQsRUFBV0gsR0FBRyxHQUFHUCxpQkFBakIsRUFBb0M7QUFDN0MsU0FBS08sR0FBTCxHQUFXRCxV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Q1gsR0FBRCxFQUFNO0FBQ1ByQixJQUFBQSxLQUFLLENBQUMsS0FBRCxFQUFRcUIsR0FBUixDQUFMO0FBQ0EsV0FBTyxLQUFLVCxLQUFMLENBQVdVLE9BQVgsQ0FDTEQsR0FESyxFQUVMLE1BQ0UsSUFBSU4sT0FBSixDQUFhQyxPQUFELElBQWE7QUFDdkIsV0FBS1AsTUFBTCxDQUFZdUIsR0FBWixDQUFnQlgsR0FBaEIsRUFBcUIsWUFBWTtBQUMvQkwsUUFBQUEsT0FBTztBQUNSLE9BRkQ7QUFHRCxLQUpELENBSEcsQ0FBUDtBQVNEOztBQUVEaUIsRUFBQUEsS0FBSyxHQUFHO0FBQ05qQyxJQUFBQSxLQUFLLENBQUMsT0FBRCxDQUFMO0FBQ0EsV0FBTyxLQUFLWSxLQUFMLENBQVdVLE9BQVgsQ0FDTHZCLFlBREssRUFFTCxNQUNFLElBQUlnQixPQUFKLENBQWFDLE9BQUQsSUFBYTtBQUN2QixXQUFLUCxNQUFMLENBQVl5QixPQUFaLENBQW9CLFlBQVk7QUFDOUJsQixRQUFBQSxPQUFPO0FBQ1IsT0FGRDtBQUdELEtBSkQsQ0FIRyxDQUFQO0FBU0QsR0FsRzRCLENBb0c3Qjs7O0FBQ0EsUUFBTW1CLFVBQU4sR0FBbUI7QUFDakIsV0FBTyxJQUFJcEIsT0FBSixDQUFZLENBQUNDLE9BQUQsRUFBVW9CLE1BQVYsS0FBcUI7QUFDdEMsV0FBSzNCLE1BQUwsQ0FBWTRCLElBQVosQ0FBaUIsR0FBakIsRUFBc0IsQ0FBQ25CLEdBQUQsRUFBTW1CLElBQU4sS0FBZTtBQUNuQyxZQUFJbkIsR0FBSixFQUFTO0FBQ1BrQixVQUFBQSxNQUFNLENBQUNsQixHQUFELENBQU47QUFDRCxTQUZELE1BRU87QUFDTEYsVUFBQUEsT0FBTyxDQUFDcUIsSUFBRCxDQUFQO0FBQ0Q7QUFDRixPQU5EO0FBT0QsS0FSTSxDQUFQO0FBU0Q7O0FBL0c0Qjs7O2VBa0hoQi9CLGlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcbmltcG9ydCB7IEtleVByb21pc2VRdWV1ZSB9IGZyb20gJy4vS2V5UHJvbWlzZVF1ZXVlJztcblxuY29uc3QgREVGQVVMVF9SRURJU19UVEwgPSAzMCAqIDEwMDA7IC8vIDMwIHNlY29uZHMgaW4gbWlsbGlzZWNvbmRzXG5jb25zdCBGTFVTSF9EQl9LRVkgPSAnX19mbHVzaF9kYl9fJztcblxuZnVuY3Rpb24gZGVidWcoKSB7XG4gIGxvZ2dlci5kZWJ1Zy5hcHBseShsb2dnZXIsIFsnUmVkaXNDYWNoZUFkYXB0ZXInLCAuLi5hcmd1bWVudHNdKTtcbn1cblxuY29uc3QgaXNWYWxpZFRUTCA9ICh0dGwpID0+IHR5cGVvZiB0dGwgPT09ICdudW1iZXInICYmIHR0bCA+IDA7XG5cbmV4cG9ydCBjbGFzcyBSZWRpc0NhY2hlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKHJlZGlzQ3R4LCB0dGwgPSBERUZBVUxUX1JFRElTX1RUTCkge1xuICAgIHRoaXMudHRsID0gaXNWYWxpZFRUTCh0dGwpID8gdHRsIDogREVGQVVMVF9SRURJU19UVEw7XG4gICAgdGhpcy5jbGllbnQgPSByZWRpcy5jcmVhdGVDbGllbnQocmVkaXNDdHgpO1xuICAgIHRoaXMucXVldWUgPSBuZXcgS2V5UHJvbWlzZVF1ZXVlKCk7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy5jbGllbnQucXVpdCgoZXJyKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1JlZGlzQ2FjaGVBZGFwdGVyIGVycm9yIG9uIHNodXRkb3duJywgeyBlcnJvcjogZXJyIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGRlYnVnKCdnZXQnLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoXG4gICAgICBrZXksXG4gICAgICAoKSA9PlxuICAgICAgICBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgIHRoaXMuY2xpZW50LmdldChrZXksIGZ1bmN0aW9uIChlcnIsIHJlcykge1xuICAgICAgICAgICAgZGVidWcoJy0+IGdldCcsIGtleSwgcmVzKTtcbiAgICAgICAgICAgIGlmICghcmVzKSB7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb2x2ZShKU09OLnBhcnNlKHJlcykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwdXQoa2V5LCB2YWx1ZSwgdHRsID0gdGhpcy50dGwpIHtcbiAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICBkZWJ1ZygncHV0Jywga2V5LCB2YWx1ZSwgdHRsKTtcblxuICAgIGlmICh0dGwgPT09IDApIHtcbiAgICAgIC8vIHR0bCBvZiB6ZXJvIGlzIGEgbG9naWNhbCBuby1vcCwgYnV0IHJlZGlzIGNhbm5vdCBzZXQgZXhwaXJlIHRpbWUgb2YgemVyb1xuICAgICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShrZXksICgpID0+IFByb21pc2UucmVzb2x2ZSgpKTtcbiAgICB9XG5cbiAgICBpZiAodHRsID09PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgICAga2V5LFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5zZXQoa2V5LCB2YWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzVmFsaWRUVEwodHRsKSkge1xuICAgICAgdHRsID0gdGhpcy50dGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIGtleSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgdGhpcy5jbGllbnQucHNldGV4KGtleSwgdHRsLCB2YWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgZGVidWcoJ2RlbCcsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIGtleSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgdGhpcy5jbGllbnQuZGVsKGtleSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICBkZWJ1ZygnY2xlYXInKTtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5lbnF1ZXVlKFxuICAgICAgRkxVU0hfREJfS0VZLFxuICAgICAgKCkgPT5cbiAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICB0aGlzLmNsaWVudC5mbHVzaGRiKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gVXNlZCBmb3IgdGVzdGluZ1xuICBhc3luYyBnZXRBbGxLZXlzKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudC5rZXlzKCcqJywgKGVyciwga2V5cykgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShrZXlzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVkaXNDYWNoZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Email/MailAdapter.js b/lib/Adapters/Email/MailAdapter.js deleted file mode 100644 index 217860c759..0000000000 --- a/lib/Adapters/Email/MailAdapter.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.MailAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface MailAdapter - * Mail Adapter prototype - * A MailAdapter should implement at least sendMail() - */ -class MailAdapter { - /** - * A method for sending mail - * @param options would have the parameters - * - to: the recipient - * - text: the raw text of the message - * - subject: the subject of the email - */ - sendMail(options) {} - /* You can implement those methods if you want - * to provide HTML templates etc... - */ - // sendVerificationEmail({ link, appName, user }) {} - // sendPasswordResetEmail({ link, appName, user }) {} - - -} - -exports.MailAdapter = MailAdapter; -var _default = MailAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9FbWFpbC9NYWlsQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJNYWlsQWRhcHRlciIsInNlbmRNYWlsIiwib3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7Ozs7O0FBS08sTUFBTUEsV0FBTixDQUFrQjtBQUN2Qjs7Ozs7OztBQU9BQyxFQUFBQSxRQUFRLENBQUNDLE9BQUQsRUFBVSxDQUFFO0FBRXBCOzs7QUFHQTtBQUNBOzs7QUFkdUI7OztlQWlCVkYsVyIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgTWFpbEFkYXB0ZXJcbiAqIE1haWwgQWRhcHRlciBwcm90b3R5cGVcbiAqIEEgTWFpbEFkYXB0ZXIgc2hvdWxkIGltcGxlbWVudCBhdCBsZWFzdCBzZW5kTWFpbCgpXG4gKi9cbmV4cG9ydCBjbGFzcyBNYWlsQWRhcHRlciB7XG4gIC8qKlxuICAgKiBBIG1ldGhvZCBmb3Igc2VuZGluZyBtYWlsXG4gICAqIEBwYXJhbSBvcHRpb25zIHdvdWxkIGhhdmUgdGhlIHBhcmFtZXRlcnNcbiAgICogLSB0bzogdGhlIHJlY2lwaWVudFxuICAgKiAtIHRleHQ6IHRoZSByYXcgdGV4dCBvZiB0aGUgbWVzc2FnZVxuICAgKiAtIHN1YmplY3Q6IHRoZSBzdWJqZWN0IG9mIHRoZSBlbWFpbFxuICAgKi9cbiAgc2VuZE1haWwob3B0aW9ucykge31cblxuICAvKiBZb3UgY2FuIGltcGxlbWVudCB0aG9zZSBtZXRob2RzIGlmIHlvdSB3YW50XG4gICAqIHRvIHByb3ZpZGUgSFRNTCB0ZW1wbGF0ZXMgZXRjLi4uXG4gICAqL1xuICAvLyBzZW5kVmVyaWZpY2F0aW9uRW1haWwoeyBsaW5rLCBhcHBOYW1lLCB1c2VyIH0pIHt9XG4gIC8vIHNlbmRQYXNzd29yZFJlc2V0RW1haWwoeyBsaW5rLCBhcHBOYW1lLCB1c2VyIH0pIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1haWxBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Files/FilesAdapter.js b/lib/Adapters/Files/FilesAdapter.js deleted file mode 100644 index e17cb707e7..0000000000 --- a/lib/Adapters/Files/FilesAdapter.js +++ /dev/null @@ -1,136 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.validateFilename = validateFilename; -exports.default = exports.FilesAdapter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/*eslint no-unused-vars: "off"*/ -// Files Adapter -// -// Allows you to change the file storage mechanism. -// -// Adapter classes must implement the following functions: -// * createFile(filename, data, contentType) -// * deleteFile(filename) -// * getFileData(filename) -// * getFileLocation(config, filename) -// Adapter classes should implement the following functions: -// * validateFilename(filename) -// * handleFileStream(filename, req, res, contentType) -// -// Default is GridFSBucketAdapter, which requires mongo -// and for the API server to be using the DatabaseController with Mongo -// database adapter. - -/** - * @module Adapters - */ - -/** - * @interface FilesAdapter - */ -class FilesAdapter { - /** Responsible for storing the file in order to be retrieved later by its filename - * - * @param {string} filename - the filename to save - * @param {*} data - the buffer of data from the file - * @param {string} contentType - the supposed contentType - * @discussion the contentType can be undefined if the controller was not able to determine it - * @param {object} options - (Optional) options to be passed to file adapter (S3 File Adapter Only) - * - tags: object containing key value pairs that will be stored with file - * - metadata: object containing key value pairs that will be sotred with file (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/add-object-metadata.html) - * @discussion options are not supported by all file adapters. Check the your adapter's documentation for compatibility - * - * @return {Promise} a promise that should fail if the storage didn't succeed - */ - createFile(filename, data, contentType, options) {} - /** Responsible for deleting the specified file - * - * @param {string} filename - the filename to delete - * - * @return {Promise} a promise that should fail if the deletion didn't succeed - */ - - - deleteFile(filename) {} - /** Responsible for retrieving the data of the specified file - * - * @param {string} filename - the name of file to retrieve - * - * @return {Promise} a promise that should pass with the file data or fail on error - */ - - - getFileData(filename) {} - /** Returns an absolute URL where the file can be accessed - * - * @param {Config} config - server configuration - * @param {string} filename - * - * @return {string} Absolute URL - */ - - - getFileLocation(config, filename) {} - /** Validate a filename for this adapter type - * - * @param {string} filename - * - * @returns {null|Parse.Error} null if there are no errors - */ - // validateFilename(filename: string): ?Parse.Error {} - - /** Handles Byte-Range Requests for Streaming - * - * @param {string} filename - * @param {object} req - * @param {object} res - * @param {string} contentType - * - * @returns {Promise} Data for byte range - */ - // handleFileStream(filename: string, res: any, req: any, contentType: string): Promise - - /** Responsible for retrieving metadata and tags - * - * @param {string} filename - the filename to retrieve metadata - * - * @return {Promise} a promise that should pass with metadata - */ - // getMetadata(filename: string): Promise {} - - -} -/** - * Simple filename validation - * - * @param filename - * @returns {null|Parse.Error} - */ - - -exports.FilesAdapter = FilesAdapter; - -function validateFilename(filename) { - if (filename.length > 128) { - return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); - } - - const regx = /^[_a-zA-Z0-9][a-zA-Z0-9@. ~_-]*$/; - - if (!filename.match(regx)) { - return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); - } - - return null; -} - -var _default = FilesAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9GaWxlc0FkYXB0ZXIuanMiXSwibmFtZXMiOlsiRmlsZXNBZGFwdGVyIiwiY3JlYXRlRmlsZSIsImZpbGVuYW1lIiwiZGF0YSIsImNvbnRlbnRUeXBlIiwib3B0aW9ucyIsImRlbGV0ZUZpbGUiLCJnZXRGaWxlRGF0YSIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsInZhbGlkYXRlRmlsZW5hbWUiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9GSUxFX05BTUUiLCJyZWd4IiwibWF0Y2giXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBbUJBOzs7O0FBbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBSUE7Ozs7QUFHQTs7O0FBR08sTUFBTUEsWUFBTixDQUFtQjtBQUN4Qjs7Ozs7Ozs7Ozs7OztBQWFBQyxFQUFBQSxVQUFVLENBQ1JDLFFBRFEsRUFFUkMsSUFGUSxFQUdSQyxXQUhRLEVBSVJDLE9BSlEsRUFLQyxDQUFFO0FBRWI7Ozs7Ozs7O0FBTUFDLEVBQUFBLFVBQVUsQ0FBQ0osUUFBRCxFQUE0QixDQUFFO0FBRXhDOzs7Ozs7OztBQU1BSyxFQUFBQSxXQUFXLENBQUNMLFFBQUQsRUFBaUMsQ0FBRTtBQUU5Qzs7Ozs7Ozs7O0FBT0FNLEVBQUFBLGVBQWUsQ0FBQ0MsTUFBRCxFQUFpQlAsUUFBakIsRUFBMkMsQ0FBRTtBQUU1RDs7Ozs7O0FBTUE7O0FBRUE7Ozs7Ozs7OztBQVNBOztBQUVBOzs7Ozs7QUFNQTs7O0FBdkV3QjtBQTBFMUI7Ozs7Ozs7Ozs7QUFNTyxTQUFTUSxnQkFBVCxDQUEwQlIsUUFBMUIsRUFBa0Q7QUFDdkQsTUFBSUEsUUFBUSxDQUFDUyxNQUFULEdBQWtCLEdBQXRCLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0Msb0JBQS9DLENBQVA7QUFDRDs7QUFFRCxRQUFNQyxJQUFJLEdBQUcsa0NBQWI7O0FBQ0EsTUFBSSxDQUFDYixRQUFRLENBQUNjLEtBQVQsQ0FBZUQsSUFBZixDQUFMLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUgsY0FBTUMsS0FBVixDQUNMRCxjQUFNQyxLQUFOLENBQVlDLGlCQURQLEVBRUwsdUNBRkssQ0FBUDtBQUlEOztBQUNELFNBQU8sSUFBUDtBQUNEOztlQUVjZCxZIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLy8gRmlsZXMgQWRhcHRlclxuLy9cbi8vIEFsbG93cyB5b3UgdG8gY2hhbmdlIHRoZSBmaWxlIHN0b3JhZ2UgbWVjaGFuaXNtLlxuLy9cbi8vIEFkYXB0ZXIgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogY3JlYXRlRmlsZShmaWxlbmFtZSwgZGF0YSwgY29udGVudFR5cGUpXG4vLyAqIGRlbGV0ZUZpbGUoZmlsZW5hbWUpXG4vLyAqIGdldEZpbGVEYXRhKGZpbGVuYW1lKVxuLy8gKiBnZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSlcbi8vIEFkYXB0ZXIgY2xhc3NlcyBzaG91bGQgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuLy8gKiB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKVxuLy8gKiBoYW5kbGVGaWxlU3RyZWFtKGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpXG4vL1xuLy8gRGVmYXVsdCBpcyBHcmlkRlNCdWNrZXRBZGFwdGVyLCB3aGljaCByZXF1aXJlcyBtb25nb1xuLy8gYW5kIGZvciB0aGUgQVBJIHNlcnZlciB0byBiZSB1c2luZyB0aGUgRGF0YWJhc2VDb250cm9sbGVyIHdpdGggTW9uZ29cbi8vIGRhdGFiYXNlIGFkYXB0ZXIuXG5cbmltcG9ydCB0eXBlIHsgQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29uZmlnJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgRmlsZXNBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWxlc0FkYXB0ZXIge1xuICAvKiogUmVzcG9uc2libGUgZm9yIHN0b3JpbmcgdGhlIGZpbGUgaW4gb3JkZXIgdG8gYmUgcmV0cmlldmVkIGxhdGVyIGJ5IGl0cyBmaWxlbmFtZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSB0aGUgZmlsZW5hbWUgdG8gc2F2ZVxuICAgKiBAcGFyYW0geyp9IGRhdGEgLSB0aGUgYnVmZmVyIG9mIGRhdGEgZnJvbSB0aGUgZmlsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudFR5cGUgLSB0aGUgc3VwcG9zZWQgY29udGVudFR5cGVcbiAgICogQGRpc2N1c3Npb24gdGhlIGNvbnRlbnRUeXBlIGNhbiBiZSB1bmRlZmluZWQgaWYgdGhlIGNvbnRyb2xsZXIgd2FzIG5vdCBhYmxlIHRvIGRldGVybWluZSBpdFxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIChPcHRpb25hbCkgb3B0aW9ucyB0byBiZSBwYXNzZWQgdG8gZmlsZSBhZGFwdGVyIChTMyBGaWxlIEFkYXB0ZXIgT25seSlcbiAgICogLSB0YWdzOiBvYmplY3QgY29udGFpbmluZyBrZXkgdmFsdWUgcGFpcnMgdGhhdCB3aWxsIGJlIHN0b3JlZCB3aXRoIGZpbGVcbiAgICogLSBtZXRhZGF0YTogb2JqZWN0IGNvbnRhaW5pbmcga2V5IHZhbHVlIHBhaXJzIHRoYXQgd2lsbCBiZSBzb3RyZWQgd2l0aCBmaWxlIChodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L3VzZXItZ3VpZGUvYWRkLW9iamVjdC1tZXRhZGF0YS5odG1sKVxuICAgKiBAZGlzY3Vzc2lvbiBvcHRpb25zIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IGFsbCBmaWxlIGFkYXB0ZXJzLiBDaGVjayB0aGUgeW91ciBhZGFwdGVyJ3MgZG9jdW1lbnRhdGlvbiBmb3IgY29tcGF0aWJpbGl0eVxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCBzaG91bGQgZmFpbCBpZiB0aGUgc3RvcmFnZSBkaWRuJ3Qgc3VjY2VlZFxuICAgKi9cbiAgY3JlYXRlRmlsZShcbiAgICBmaWxlbmFtZTogc3RyaW5nLFxuICAgIGRhdGEsXG4gICAgY29udGVudFR5cGU6IHN0cmluZyxcbiAgICBvcHRpb25zOiBPYmplY3RcbiAgKTogUHJvbWlzZSB7fVxuXG4gIC8qKiBSZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgdGhlIHNwZWNpZmllZCBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byBkZWxldGVcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgc2hvdWxkIGZhaWwgaWYgdGhlIGRlbGV0aW9uIGRpZG4ndCBzdWNjZWVkXG4gICAqL1xuICBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpOiBQcm9taXNlIHt9XG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgZmlsZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSB0aGUgbmFtZSBvZiBmaWxlIHRvIHJldHJpZXZlXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSB0aGF0IHNob3VsZCBwYXNzIHdpdGggdGhlIGZpbGUgZGF0YSBvciBmYWlsIG9uIGVycm9yXG4gICAqL1xuICBnZXRGaWxlRGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG5cbiAgLyoqIFJldHVybnMgYW4gYWJzb2x1dGUgVVJMIHdoZXJlIHRoZSBmaWxlIGNhbiBiZSBhY2Nlc3NlZFxuICAgKlxuICAgKiBAcGFyYW0ge0NvbmZpZ30gY29uZmlnIC0gc2VydmVyIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQWJzb2x1dGUgVVJMXG4gICAqL1xuICBnZXRGaWxlTG9jYXRpb24oY29uZmlnOiBDb25maWcsIGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge31cblxuICAvKiogVmFsaWRhdGUgYSBmaWxlbmFtZSBmb3IgdGhpcyBhZGFwdGVyIHR5cGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfSBudWxsIGlmIHRoZXJlIGFyZSBubyBlcnJvcnNcbiAgICovXG4gIC8vIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWU6IHN0cmluZyk6ID9QYXJzZS5FcnJvciB7fVxuXG4gIC8qKiBIYW5kbGVzIEJ5dGUtUmFuZ2UgUmVxdWVzdHMgZm9yIFN0cmVhbWluZ1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWVcbiAgICogQHBhcmFtIHtvYmplY3R9IHJlcVxuICAgKiBAcGFyYW0ge29iamVjdH0gcmVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50VHlwZVxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gRGF0YSBmb3IgYnl0ZSByYW5nZVxuICAgKi9cbiAgLy8gaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZTogc3RyaW5nLCByZXM6IGFueSwgcmVxOiBhbnksIGNvbnRlbnRUeXBlOiBzdHJpbmcpOiBQcm9taXNlXG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIG1ldGFkYXRhIGFuZCB0YWdzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byByZXRyaWV2ZSBtZXRhZGF0YVxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCBzaG91bGQgcGFzcyB3aXRoIG1ldGFkYXRhXG4gICAqL1xuICAvLyBnZXRNZXRhZGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG59XG5cbi8qKlxuICogU2ltcGxlIGZpbGVuYW1lIHZhbGlkYXRpb25cbiAqXG4gKiBAcGFyYW0gZmlsZW5hbWVcbiAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk6ID9QYXJzZS5FcnJvciB7XG4gIGlmIChmaWxlbmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCAnRmlsZW5hbWUgdG9vIGxvbmcuJyk7XG4gIH1cblxuICBjb25zdCByZWd4ID0gL15bX2EtekEtWjAtOV1bYS16QS1aMC05QC4gfl8tXSokLztcbiAgaWYgKCFmaWxlbmFtZS5tYXRjaChyZWd4KSkge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSxcbiAgICAgICdGaWxlbmFtZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJ1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGVzQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Files/GridFSBucketAdapter.js b/lib/Adapters/Files/GridFSBucketAdapter.js deleted file mode 100644 index e6abe0c03f..0000000000 --- a/lib/Adapters/Files/GridFSBucketAdapter.js +++ /dev/null @@ -1,273 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GridFSBucketAdapter = void 0; - -var _mongodb = require("mongodb"); - -var _FilesAdapter = require("./FilesAdapter"); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - GridFSBucketAdapter - Stores files in Mongo using GridStore - Requires the database adapter to be based on mongoclient - - - */ -// -disable-next -const crypto = require('crypto'); - -class GridFSBucketAdapter extends _FilesAdapter.FilesAdapter { - constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}, encryptionKey = undefined) { - super(); - this._databaseURI = mongoDatabaseURI; - this._algorithm = 'aes-256-gcm'; - this._encryptionKey = encryptionKey !== undefined ? crypto.createHash('sha256').update(String(encryptionKey)).digest('base64').substr(0, 32) : null; - const defaultMongoOptions = { - useNewUrlParser: true, - useUnifiedTopology: true - }; - this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); - } - - _connect() { - if (!this._connectionPromise) { - this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { - this._client = client; - return client.db(client.s.options.dbName); - }); - } - - return this._connectionPromise; - } - - _getBucket() { - return this._connect().then(database => new _mongodb.GridFSBucket(database)); - } // For a given config object, filename, and data, store a file - // Returns a promise - - - async createFile(filename, data, contentType, options = {}) { - const bucket = await this._getBucket(); - const stream = await bucket.openUploadStream(filename, { - metadata: options.metadata - }); - - if (this._encryptionKey !== null) { - try { - const iv = crypto.randomBytes(16); - const cipher = crypto.createCipheriv(this._algorithm, this._encryptionKey, iv); - const encryptedResult = Buffer.concat([cipher.update(data), cipher.final(), iv, cipher.getAuthTag()]); - await stream.write(encryptedResult); - } catch (err) { - return new Promise((resolve, reject) => { - return reject(err); - }); - } - } else { - await stream.write(data); - } - - stream.end(); - return new Promise((resolve, reject) => { - stream.on('finish', resolve); - stream.on('error', reject); - }); - } - - async deleteFile(filename) { - const bucket = await this._getBucket(); - const documents = await bucket.find({ - filename - }).toArray(); - - if (documents.length === 0) { - throw new Error('FileNotFound'); - } - - return Promise.all(documents.map(doc => { - return bucket.delete(doc._id); - })); - } - - async getFileData(filename) { - const bucket = await this._getBucket(); - const stream = bucket.openDownloadStreamByName(filename); - stream.read(); - return new Promise((resolve, reject) => { - const chunks = []; - stream.on('data', data => { - chunks.push(data); - }); - stream.on('end', () => { - const data = Buffer.concat(chunks); - - if (this._encryptionKey !== null) { - try { - const authTagLocation = data.length - 16; - const ivLocation = data.length - 32; - const authTag = data.slice(authTagLocation); - const iv = data.slice(ivLocation, authTagLocation); - const encrypted = data.slice(0, ivLocation); - const decipher = crypto.createDecipheriv(this._algorithm, this._encryptionKey, iv); - decipher.setAuthTag(authTag); - const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]); - return resolve(decrypted); - } catch (err) { - return reject(err); - } - } - - resolve(data); - }); - stream.on('error', err => { - reject(err); - }); - }); - } - - async rotateEncryptionKey(options = {}) { - var fileNames = []; - var oldKeyFileAdapter = {}; - const bucket = await this._getBucket(); - - if (options.oldKey !== undefined) { - oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions, options.oldKey); - } else { - oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions); - } - - if (options.fileNames !== undefined) { - fileNames = options.fileNames; - } else { - const fileNamesIterator = await bucket.find().toArray(); - fileNamesIterator.forEach(file => { - fileNames.push(file.filename); - }); - } - - return new Promise(resolve => { - var fileNamesNotRotated = fileNames; - var fileNamesRotated = []; - var fileNameTotal = fileNames.length; - var fileNameIndex = 0; - fileNames.forEach(fileName => { - oldKeyFileAdapter.getFileData(fileName).then(plainTextData => { - //Overwrite file with data encrypted with new key - this.createFile(fileName, plainTextData).then(() => { - fileNamesRotated.push(fileName); - fileNamesNotRotated = fileNamesNotRotated.filter(function (value) { - return value !== fileName; - }); - fileNameIndex += 1; - - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated - }); - } - }).catch(() => { - fileNameIndex += 1; - - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated - }); - } - }); - }).catch(() => { - fileNameIndex += 1; - - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated - }); - } - }); - }); - }); - } - - getFileLocation(config, filename) { - return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); - } - - async getMetadata(filename) { - const bucket = await this._getBucket(); - const files = await bucket.find({ - filename - }).toArray(); - - if (files.length === 0) { - return {}; - } - - const { - metadata - } = files[0]; - return { - metadata - }; - } - - async handleFileStream(filename, req, res, contentType) { - const bucket = await this._getBucket(); - const files = await bucket.find({ - filename - }).toArray(); - - if (files.length === 0) { - throw new Error('FileNotFound'); - } - - const parts = req.get('Range').replace(/bytes=/, '').split('-'); - const partialstart = parts[0]; - const partialend = parts[1]; - const start = parseInt(partialstart, 10); - const end = partialend ? parseInt(partialend, 10) : files[0].length - 1; - res.writeHead(206, { - 'Accept-Ranges': 'bytes', - 'Content-Length': end - start + 1, - 'Content-Range': 'bytes ' + start + '-' + end + '/' + files[0].length, - 'Content-Type': contentType - }); - const stream = bucket.openDownloadStreamByName(filename); - stream.start(start); - stream.on('data', chunk => { - res.write(chunk); - }); - stream.on('error', () => { - res.sendStatus(404); - }); - stream.on('end', () => { - res.end(); - }); - } - - handleShutdown() { - if (!this._client) { - return Promise.resolve(); - } - - return this._client.close(false); - } - - validateFilename(filename) { - return (0, _FilesAdapter.validateFilename)(filename); - } - -} - -exports.GridFSBucketAdapter = GridFSBucketAdapter; -var _default = GridFSBucketAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkRlNCdWNrZXRBZGFwdGVyLmpzIl0sIm5hbWVzIjpbImNyeXB0byIsInJlcXVpcmUiLCJHcmlkRlNCdWNrZXRBZGFwdGVyIiwiRmlsZXNBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJtb25nb0RhdGFiYXNlVVJJIiwiZGVmYXVsdHMiLCJEZWZhdWx0TW9uZ29VUkkiLCJtb25nb09wdGlvbnMiLCJlbmNyeXB0aW9uS2V5IiwidW5kZWZpbmVkIiwiX2RhdGFiYXNlVVJJIiwiX2FsZ29yaXRobSIsIl9lbmNyeXB0aW9uS2V5IiwiY3JlYXRlSGFzaCIsInVwZGF0ZSIsIlN0cmluZyIsImRpZ2VzdCIsInN1YnN0ciIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJfZ2V0QnVja2V0IiwiZGF0YWJhc2UiLCJHcmlkRlNCdWNrZXQiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJidWNrZXQiLCJzdHJlYW0iLCJvcGVuVXBsb2FkU3RyZWFtIiwibWV0YWRhdGEiLCJpdiIsInJhbmRvbUJ5dGVzIiwiY2lwaGVyIiwiY3JlYXRlQ2lwaGVyaXYiLCJlbmNyeXB0ZWRSZXN1bHQiLCJCdWZmZXIiLCJjb25jYXQiLCJmaW5hbCIsImdldEF1dGhUYWciLCJ3cml0ZSIsImVyciIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZW5kIiwib24iLCJkZWxldGVGaWxlIiwiZG9jdW1lbnRzIiwiZmluZCIsInRvQXJyYXkiLCJsZW5ndGgiLCJFcnJvciIsImFsbCIsIm1hcCIsImRvYyIsImRlbGV0ZSIsIl9pZCIsImdldEZpbGVEYXRhIiwib3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lIiwicmVhZCIsImNodW5rcyIsInB1c2giLCJhdXRoVGFnTG9jYXRpb24iLCJpdkxvY2F0aW9uIiwiYXV0aFRhZyIsInNsaWNlIiwiZW5jcnlwdGVkIiwiZGVjaXBoZXIiLCJjcmVhdGVEZWNpcGhlcml2Iiwic2V0QXV0aFRhZyIsImRlY3J5cHRlZCIsInJvdGF0ZUVuY3J5cHRpb25LZXkiLCJmaWxlTmFtZXMiLCJvbGRLZXlGaWxlQWRhcHRlciIsIm9sZEtleSIsImZpbGVOYW1lc0l0ZXJhdG9yIiwiZm9yRWFjaCIsImZpbGUiLCJmaWxlTmFtZXNOb3RSb3RhdGVkIiwiZmlsZU5hbWVzUm90YXRlZCIsImZpbGVOYW1lVG90YWwiLCJmaWxlTmFtZUluZGV4IiwiZmlsZU5hbWUiLCJwbGFpblRleHREYXRhIiwiZmlsdGVyIiwidmFsdWUiLCJyb3RhdGVkIiwibm90Um90YXRlZCIsImNhdGNoIiwiZ2V0RmlsZUxvY2F0aW9uIiwiY29uZmlnIiwibW91bnQiLCJhcHBsaWNhdGlvbklkIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwiZ2V0TWV0YWRhdGEiLCJmaWxlcyIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInBhcnRpYWxzdGFydCIsInBhcnRpYWxlbmQiLCJzdGFydCIsInBhcnNlSW50Iiwid3JpdGVIZWFkIiwiY2h1bmsiLCJzZW5kU3RhdHVzIiwiaGFuZGxlU2h1dGRvd24iLCJjbG9zZSIsInZhbGlkYXRlRmlsZW5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFTQTs7QUFDQTs7QUFDQTs7OztBQVhBOzs7Ozs7O0FBUUE7QUFJQSxNQUFNQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUVPLE1BQU1DLG1CQUFOLFNBQWtDQywwQkFBbEMsQ0FBK0M7QUFNcERDLEVBQUFBLFdBQVcsQ0FDVEMsZ0JB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QUZEO0FBR0FqRixJQUFBQSxNQUFNLENBQUNrQixFQUFQLENBQVUsT0FBVixFQUFtQixNQUFNO0FBQ3ZCcUQsTUFBQUEsR0FBRyxDQUFDVyxVQUFKLENBQWUsR0FBZjtBQUNELEtBRkQ7QUFHQWxGLElBQUFBLE1BQU0sQ0FBQ2tCLEVBQVAsQ0FBVSxLQUFWLEVBQWlCLE1BQU07QUFDckJxRCxNQUFBQSxHQUFHLENBQUN0RCxHQUFKO0FBQ0QsS0FGRDtBQUdEOztBQUVEa0UsRUFBQUEsY0FBYyxHQUFHO0FBQ2YsUUFBSSxDQUFDLEtBQUtoRyxPQUFWLEVBQW1CO0FBQ2pCLGFBQU8yQixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFdBQU8sS0FBSzVCLE9BQUwsQ0FBYWlHLEtBQWIsQ0FBbUIsS0FBbkIsQ0FBUDtBQUNEOztBQUVEQyxFQUFBQSxnQkFBZ0IsQ0FBQ3pGLFFBQUQsRUFBVztBQUN6QixXQUFPLG9DQUFpQkEsUUFBakIsQ0FBUDtBQUNEOztBQWxSbUQ7OztlQXFSdkN0QyxtQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuIEdyaWRGU0J1Y2tldEFkYXB0ZXJcbiBTdG9yZXMgZmlsZXMgaW4gTW9uZ28gdXNpbmcgR3JpZFN0b3JlXG4gUmVxdWlyZXMgdGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gYmUgYmFzZWQgb24gbW9uZ29jbGllbnRcblxuIEBmbG93IHdlYWtcbiAqL1xuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IE1vbmdvQ2xpZW50LCBHcmlkRlNCdWNrZXQsIERiIH0gZnJvbSAnbW9uZ29kYic7XG5pbXBvcnQgeyBGaWxlc0FkYXB0ZXIsIHZhbGlkYXRlRmlsZW5hbWUgfSBmcm9tICcuL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuY29uc3QgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbmV4cG9ydCBjbGFzcyBHcmlkRlNCdWNrZXRBZGFwdGVyIGV4dGVuZHMgRmlsZXNBZGFwdGVyIHtcbiAgX2RhdGFiYXNlVVJJOiBzdHJpbmc7XG4gIF9jb25uZWN0aW9uUHJvbWlzZTogUHJvbWlzZTxEYj47XG4gIF9tb25nb09wdGlvbnM6IE9iamVjdDtcbiAgX2FsZ29yaXRobTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1vbmdvRGF0YWJhc2VVUkkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksXG4gICAgbW9uZ29PcHRpb25zID0ge30sXG4gICAgZW5jcnlwdGlvbktleSA9IHVuZGVmaW5lZFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RhdGFiYXNlVVJJID0gbW9uZ29EYXRhYmFzZVVSSTtcbiAgICB0aGlzLl9hbGdvcml0aG0gPSAnYWVzLTI1Ni1nY20nO1xuICAgIHRoaXMuX2VuY3J5cHRpb25LZXkgPVxuICAgICAgZW5jcnlwdGlvbktleSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gY3J5cHRvXG4gICAgICAgICAgLmNyZWF0ZUhhc2goJ3NoYTI1NicpXG4gICAgICAgICAgLnVwZGF0ZShTdHJpbmcoZW5jcnlwdGlvbktleSkpXG4gICAgICAgICAgLmRpZ2VzdCgnYmFzZTY0JylcbiAgICAgICAgICAuc3Vic3RyKDAsIDMyKVxuICAgICAgICA6IG51bGw7XG4gICAgY29uc3QgZGVmYXVsdE1vbmdvT3B0aW9ucyA9IHtcbiAgICAgIHVzZU5ld1VybFBhcnNlcjogdHJ1ZSxcbiAgICAgIHVzZVVuaWZpZWRUb3BvbG9neTogdHJ1ZSxcbiAgICB9O1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdE1vbmdvT3B0aW9ucywgbW9uZ29PcHRpb25zKTtcbiAgfVxuXG4gIF9jb25uZWN0KCkge1xuICAgIGlmICghdGhpcy5fY29ubmVjdGlvblByb21pc2UpIHtcbiAgICAgIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlID0gTW9uZ29DbGllbnQuY29ubmVjdChcbiAgICAgICAgdGhpcy5fZGF0YWJhc2VVUkksXG4gICAgICAgIHRoaXMuX21vbmdvT3B0aW9uc1xuICAgICAgKS50aGVuKGNsaWVudCA9PiB7XG4gICAgICAgIHRoaXMuX2NsaWVudCA9IGNsaWVudDtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kYihjbGllbnQucy5vcHRpb25zLmRiTmFtZSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlO1xuICB9XG5cbiAgX2dldEJ1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpLnRoZW4oZGF0YWJhc2UgPT4gbmV3IEdyaWRGU0J1Y2tldChkYXRhYmFzZSkpO1xuICB9XG5cbiAgLy8gRm9yIGEgZ2l2ZW4gY29uZmlnIG9iamVjdCwgZmlsZW5hbWUsIGFuZCBkYXRhLCBzdG9yZSBhIGZpbGVcbiAgLy8gUmV0dXJucyBhIHByb21pc2VcbiAgYXN5bmMgY3JlYXRlRmlsZShmaWxlbmFtZTogc3RyaW5nLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgYnVja2V0Lm9wZW5VcGxvYWRTdHJlYW0oZmlsZW5hbWUsIHtcbiAgICAgIG1ldGFkYXRhOiBvcHRpb25zLm1ldGFkYXRhLFxuICAgIH0pO1xuICAgIGlmICh0aGlzLl9lbmNyeXB0aW9uS2V5ICE9PSBudWxsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpdiA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXJpdihcbiAgICAgICAgICB0aGlzLl9hbGdvcml0aG0sXG4gICAgICAgICAgdGhpcy5fZW5jcnlwdGlvbktleSxcbiAgICAgICAgICBpdlxuICAgICAgICApO1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRSZXN1bHQgPSBCdWZmZXIuY29uY2F0KFtcbiAgICAgICAgICBjaXBoZXIudXBkYXRlKGRhdGEpLFxuICAgICAgICAgIGNpcGhlci5maW5hbCgpLFxuICAgICAgICAgIGl2LFxuICAgICAgICAgIGNpcGhlci5nZXRBdXRoVGFnKCksXG4gICAgICAgIF0pO1xuICAgICAgICBhd2FpdCBzdHJlYW0ud3JpdGUoZW5jcnlwdGVkUmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHN0cmVhbS53cml0ZShkYXRhKTtcbiAgICB9XG4gICAgc3RyZWFtLmVuZCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBzdHJlYW0ub24oJ2ZpbmlzaCcsIHJlc29sdmUpO1xuICAgICAgc3RyZWFtLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBkb2N1bWVudHMgPSBhd2FpdCBidWNrZXQuZmluZCh7IGZpbGVuYW1lIH0pLnRvQXJyYXkoKTtcbiAgICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGaWxlTm90Rm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgZG9jdW1lbnRzLm1hcChkb2MgPT4ge1xuICAgICAgICByZXR1cm4gYnVja2V0LmRlbGV0ZShkb2MuX2lkKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGdldEZpbGVEYXRhKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBzdHJlYW0gPSBidWNrZXQub3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lKGZpbGVuYW1lKTtcbiAgICBzdHJlYW0ucmVhZCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIHN0cmVhbS5vbignZGF0YScsIGRhdGEgPT4ge1xuICAgICAgICBjaHVua3MucHVzaChkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBCdWZmZXIuY29uY2F0KGNodW5rcyk7XG4gICAgICAgIGlmICh0aGlzLl9lbmNyeXB0aW9uS2V5ICE9PSBudWxsKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGF1dGhUYWdMb2NhdGlvbiA9IGRhdGEubGVuZ3RoIC0gMTY7XG4gICAgICAgICAgICBjb25zdCBpdkxvY2F0aW9uID0gZGF0YS5sZW5ndGggLSAzMjtcbiAgICAgICAgICAgIGNvbnN0IGF1dGhUYWcgPSBkYXRhLnNsaWNlKGF1dGhUYWdMb2NhdGlvbik7XG4gICAgICAgICAgICBjb25zdCBpdiA9IGRhdGEuc2xpY2UoaXZMb2NhdGlvbiwgYXV0aFRhZ0xvY2F0aW9uKTtcbiAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZCA9IGRhdGEuc2xpY2UoMCwgaXZMb2NhdGlvbik7XG4gICAgICAgICAgICBjb25zdCBkZWNpcGhlciA9IGNyeXB0by5jcmVhdGVEZWNpcGhlcml2KFxuICAgICAgICAgICAgICB0aGlzLl9hbGdvcml0aG0sXG4gICAgICAgICAgICAgIHRoaXMuX2VuY3J5cHRpb25LZXksXG4gICAgICAgICAgICAgIGl2XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZGVjaXBoZXIuc2V0QXV0aFRhZyhhdXRoVGFnKTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IEJ1ZmZlci5jb25jYXQoW1xuICAgICAgICAgICAgICBkZWNpcGhlci51cGRhdGUoZW5jcnlwdGVkKSxcbiAgICAgICAgICAgICAgZGVjaXBoZXIuZmluYWwoKSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGVjcnlwdGVkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdlcnJvcicsIGVyciA9PiB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyByb3RhdGVFbmNyeXB0aW9uS2V5KG9wdGlvbnMgPSB7fSkge1xuICAgIHZhciBmaWxlTmFtZXMgPSBbXTtcbiAgICB2YXIgb2xkS2V5RmlsZUFkYXB0ZXIgPSB7fTtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBpZiAob3B0aW9ucy5vbGRLZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2xkS2V5RmlsZUFkYXB0ZXIgPSBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihcbiAgICAgICAgdGhpcy5fZGF0YWJhc2VVUkksXG4gICAgICAgIHRoaXMuX21vbmdvT3B0aW9ucyxcbiAgICAgICAgb3B0aW9ucy5vbGRLZXlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZEtleUZpbGVBZGFwdGVyID0gbmV3IEdyaWRGU0J1Y2tldEFkYXB0ZXIoXG4gICAgICAgIHRoaXMuX2RhdGFiYXNlVVJJLFxuICAgICAgICB0aGlzLl9tb25nb09wdGlvbnNcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmZpbGVOYW1lcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlTmFtZXMgPSBvcHRpb25zLmZpbGVOYW1lcztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZmlsZU5hbWVzSXRlcmF0b3IgPSBhd2FpdCBidWNrZXQuZmluZCgpLnRvQXJyYXkoKTtcbiAgICAgIGZpbGVOYW1lc0l0ZXJhdG9yLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgIGZpbGVOYW1lcy5wdXNoKGZpbGUuZmlsZW5hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHZhciBmaWxlTmFtZXNOb3RSb3RhdGVkID0gZmlsZU5hbWVzO1xuICAgICAgdmFyIGZpbGVOYW1lc1JvdGF0ZWQgPSBbXTtcbiAgICAgIHZhciBmaWxlTmFtZVRvdGFsID0gZmlsZU5hbWVzLmxlbmd0aDtcbiAgICAgIHZhciBmaWxlTmFtZUluZGV4ID0gMDtcbiAgICAgIGZpbGVOYW1lcy5mb3JFYWNoKGZpbGVOYW1lID0+IHtcbiAgICAgICAgb2xkS2V5RmlsZUFkYXB0ZXJcbiAgICAgICAgICAuZ2V0RmlsZURhdGEoZmlsZU5hbWUpXG4gICAgICAgICAgLnRoZW4ocGxhaW5UZXh0RGF0YSA9PiB7XG4gICAgICAgICAgICAvL092ZXJ3cml0ZSBmaWxlIHdpdGggZGF0YSBlbmNyeXB0ZWQgd2l0aCBuZXcga2V5XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUZpbGUoZmlsZU5hbWUsIHBsYWluVGV4dERhdGEpXG4gICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZXNSb3RhdGVkLnB1c2goZmlsZU5hbWUpO1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lc05vdFJvdGF0ZWQgPSBmaWxlTmFtZXNOb3RSb3RhdGVkLmZpbHRlcihmdW5jdGlvbiAoXG4gICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlICE9PSBmaWxlTmFtZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZUluZGV4ICs9IDE7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lSW5kZXggPT0gZmlsZU5hbWVUb3RhbCkge1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHJvdGF0ZWQ6IGZpbGVOYW1lc1JvdGF0ZWQsXG4gICAgICAgICAgICAgICAgICAgIG5vdFJvdGF0ZWQ6IGZpbGVOYW1lc05vdFJvdGF0ZWQsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgZmlsZU5hbWVJbmRleCArPSAxO1xuICAgICAgICAgICAgICAgIGlmIChmaWxlTmFtZUluZGV4ID09IGZpbGVOYW1lVG90YWwpIHtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICByb3RhdGVkOiBmaWxlTmFtZXNSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgICBub3RSb3RhdGVkOiBmaWxlTmFtZXNOb3RSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICBmaWxlTmFtZUluZGV4ICs9IDE7XG4gICAgICAgICAgICBpZiAoZmlsZU5hbWVJbmRleCA9PSBmaWxlTmFtZVRvdGFsKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgIHJvdGF0ZWQ6IGZpbGVOYW1lc1JvdGF0ZWQsXG4gICAgICAgICAgICAgICAgbm90Um90YXRlZDogZmlsZU5hbWVzTm90Um90YXRlZCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGNvbmZpZy5tb3VudCArXG4gICAgICAnL2ZpbGVzLycgK1xuICAgICAgY29uZmlnLmFwcGxpY2F0aW9uSWQgK1xuICAgICAgJy8nICtcbiAgICAgIGVuY29kZVVSSUNvbXBvbmVudChmaWxlbmFtZSlcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0TWV0YWRhdGEoZmlsZW5hbWUpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IGJ1Y2tldC5maW5kKHsgZmlsZW5hbWUgfSkudG9BcnJheSgpO1xuICAgIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3QgeyBtZXRhZGF0YSB9ID0gZmlsZXNbMF07XG4gICAgcmV0dXJuIHsgbWV0YWRhdGEgfTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUZpbGVTdHJlYW0oZmlsZW5hbWU6IHN0cmluZywgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCBidWNrZXQuZmluZCh7IGZpbGVuYW1lIH0pLnRvQXJyYXkoKTtcbiAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpbGVOb3RGb3VuZCcpO1xuICAgIH1cbiAgICBjb25zdCBwYXJ0cyA9IHJlcVxuICAgICAgLmdldCgnUmFuZ2UnKVxuICAgICAgLnJlcGxhY2UoL2J5dGVzPS8sICcnKVxuICAgICAgLnNwbGl0KCctJyk7XG4gICAgY29uc3QgcGFydGlhbHN0YXJ0ID0gcGFydHNbMF07XG4gICAgY29uc3QgcGFydGlhbGVuZCA9IHBhcnRzWzFdO1xuXG4gICAgY29uc3Qgc3RhcnQgPSBwYXJzZUludChwYXJ0aWFsc3RhcnQsIDEwKTtcbiAgICBjb25zdCBlbmQgPSBwYXJ0aWFsZW5kID8gcGFyc2VJbnQocGFydGlhbGVuZCwgMTApIDogZmlsZXNbMF0ubGVuZ3RoIC0gMTtcblxuICAgIHJlcy53cml0ZUhlYWQoMjA2LCB7XG4gICAgICAnQWNjZXB0LVJhbmdlcyc6ICdieXRlcycsXG4gICAgICAnQ29udGVudC1MZW5ndGgnOiBlbmQgLSBzdGFydCArIDEsXG4gICAgICAnQ29udGVudC1SYW5nZSc6ICdieXRlcyAnICsgc3RhcnQgKyAnLScgKyBlbmQgKyAnLycgKyBmaWxlc1swXS5sZW5ndGgsXG4gICAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gICAgfSk7XG4gICAgY29uc3Qgc3RyZWFtID0gYnVja2V0Lm9wZW5Eb3dubG9hZFN0cmVhbUJ5TmFtZShmaWxlbmFtZSk7XG4gICAgc3RyZWFtLnN0YXJ0KHN0YXJ0KTtcbiAgICBzdHJlYW0ub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICByZXMud3JpdGUoY2h1bmspO1xuICAgIH0pO1xuICAgIHN0cmVhbS5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICByZXMuc2VuZFN0YXR1cyg0MDQpO1xuICAgIH0pO1xuICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgcmVzLmVuZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLl9jbGllbnQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdyaWRGU0J1Y2tldEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Files/GridStoreAdapter.js b/lib/Adapters/Files/GridStoreAdapter.js deleted file mode 100644 index 5ff3c1e0e3..0000000000 --- a/lib/Adapters/Files/GridStoreAdapter.js +++ /dev/null @@ -1,182 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GridStoreAdapter = void 0; - -var _mongodb = require("mongodb"); - -var _FilesAdapter = require("./FilesAdapter"); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - GridStoreAdapter - Stores files in Mongo using GridStore - Requires the database adapter to be based on mongoclient - (GridStore is deprecated, Please use GridFSBucket instead) - - - */ -// -disable-next -class GridStoreAdapter extends _FilesAdapter.FilesAdapter { - constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}) { - super(); - this._databaseURI = mongoDatabaseURI; - const defaultMongoOptions = { - useNewUrlParser: true, - useUnifiedTopology: true - }; - this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); - } - - _connect() { - if (!this._connectionPromise) { - this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { - this._client = client; - return client.db(client.s.options.dbName); - }); - } - - return this._connectionPromise; - } // For a given config object, filename, and data, store a file - // Returns a promise - - - createFile(filename, data) { - return this._connect().then(database => { - const gridStore = new _mongodb.GridStore(database, filename, 'w'); - return gridStore.open(); - }).then(gridStore => { - return gridStore.write(data); - }).then(gridStore => { - return gridStore.close(); - }); - } - - deleteFile(filename) { - return this._connect().then(database => { - const gridStore = new _mongodb.GridStore(database, filename, 'r'); - return gridStore.open(); - }).then(gridStore => { - return gridStore.unlink(); - }).then(gridStore => { - return gridStore.close(); - }); - } - - getFileData(filename) { - return this._connect().then(database => { - return _mongodb.GridStore.exist(database, filename).then(() => { - const gridStore = new _mongodb.GridStore(database, filename, 'r'); - return gridStore.open(); - }); - }).then(gridStore => { - return gridStore.read(); - }); - } - - getFileLocation(config, filename) { - return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); - } - - async handleFileStream(filename, req, res, contentType) { - const stream = await this._connect().then(database => { - return _mongodb.GridStore.exist(database, filename).then(() => { - const gridStore = new _mongodb.GridStore(database, filename, 'r'); - return gridStore.open(); - }); - }); - handleRangeRequest(stream, req, res, contentType); - } - - handleShutdown() { - if (!this._client) { - return Promise.resolve(); - } - - return this._client.close(false); - } - - validateFilename(filename) { - return (0, _FilesAdapter.validateFilename)(filename); - } - -} // handleRangeRequest is licensed under Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). -// Author: LEROIB at weightingformypizza (https://weightingformypizza.wordpress.com/2015/06/24/stream-html5-media-content-like-video-audio-from-mongodb-using-express-and-gridstore/). - - -exports.GridStoreAdapter = GridStoreAdapter; - -function handleRangeRequest(stream, req, res, contentType) { - const buffer_size = 1024 * 1024; //1024Kb - // Range request, partial stream the file - - const parts = req.get('Range').replace(/bytes=/, '').split('-'); - let [start, end] = parts; - const notEnded = !end && end !== 0; - const notStarted = !start && start !== 0; // No end provided, we want all bytes - - if (notEnded) { - end = stream.length - 1; - } // No start provided, we're reading backwards - - - if (notStarted) { - start = stream.length - end; - end = start + end - 1; - } // Data exceeds the buffer_size, cap - - - if (end - start >= buffer_size) { - end = start + buffer_size - 1; - } - - const contentLength = end - start + 1; - res.writeHead(206, { - 'Content-Range': 'bytes ' + start + '-' + end + '/' + stream.length, - 'Accept-Ranges': 'bytes', - 'Content-Length': contentLength, - 'Content-Type': contentType - }); - stream.seek(start, function () { - // Get gridFile stream - const gridFileStream = stream.stream(true); - let bufferAvail = 0; - let remainingBytesToWrite = contentLength; - let totalBytesWritten = 0; // Write to response - - gridFileStream.on('data', function (data) { - bufferAvail += data.length; - - if (bufferAvail > 0) { - // slice returns the same buffer if overflowing - // safe to call in any case - const buffer = data.slice(0, remainingBytesToWrite); // Write the buffer - - res.write(buffer); // Increment total - - totalBytesWritten += buffer.length; // Decrement remaining - - remainingBytesToWrite -= data.length; // Decrement the available buffer - - bufferAvail -= buffer.length; - } // In case of small slices, all values will be good at that point - // we've written enough, end... - - - if (totalBytesWritten >= contentLength) { - stream.close(); - res.end(); - this.destroy(); - } - }); - }); -} - -var _default = GridStoreAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkU3RvcmVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkdyaWRTdG9yZUFkYXB0ZXIiLCJGaWxlc0FkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsIm1vbmdvRGF0YWJhc2VVUkkiLCJkZWZhdWx0cyIsIkRlZmF1bHRNb25nb1VSSSIsIm1vbmdvT3B0aW9ucyIsIl9kYXRhYmFzZVVSSSIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiZGF0YWJhc2UiLCJncmlkU3RvcmUiLCJHcmlkU3RvcmUiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsImRlbGV0ZUZpbGUiLCJ1bmxpbmsiLCJnZXRGaWxlRGF0YSIsImV4aXN0IiwicmVhZCIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsIm1vdW50IiwiYXBwbGljYXRpb25JZCIsImVuY29kZVVSSUNvbXBvbmVudCIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJjb250ZW50VHlwZSIsInN0cmVhbSIsImhhbmRsZVJhbmdlUmVxdWVzdCIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiYnVmZmVyX3NpemUiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInN0YXJ0IiwiZW5kIiwibm90RW5kZWQiLCJub3RTdGFydGVkIiwibGVuZ3RoIiwiY29udGVudExlbmd0aCIsIndyaXRlSGVhZCIsInNlZWsiLCJncmlkRmlsZVN0cmVhbSIsImJ1ZmZlckF2YWlsIiwicmVtYWluaW5nQnl0ZXNUb1dyaXRlIiwidG90YWxCeXRlc1dyaXR0ZW4iLCJvbiIsImJ1ZmZlciIsInNsaWNlIiwiZGVzdHJveSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVVBOztBQUNBOztBQUNBOzs7O0FBWkE7Ozs7Ozs7O0FBU0E7QUFLTyxNQUFNQSxnQkFBTixTQUErQkMsMEJBQS9CLENBQTRDO0FBS2pEQyxFQUFBQSxXQUFXLENBQUNDLGdCQUFnQixHQUFHQyxrQkFBU0MsZUFBN0IsRUFBOENDLFlBQVksR0FBRyxFQUE3RCxFQUFpRTtBQUMxRTtBQUNBLFNBQUtDLFlBQUwsR0FBb0JKLGdCQUFwQjtBQUVBLFVBQU1LLG1CQUFtQixHQUFHO0FBQzFCQyxNQUFBQSxlQUFlLEVBQUUsSUFEUztBQUUxQkMsTUFBQUEsa0JBQWtCLEVBQUU7QUFGTSxLQUE1QjtBQUlBLFNBQUtDLGFBQUwsR0FBcUJDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjTCxtQkFBZCxFQUFtQ0YsWUFBbkMsQ0FBckI7QUFDRDs7QUFFRFEsRUFBQUEsUUFBUSxHQUFHO0FBQ1QsUUFBSSxDQUFDLEtBQUtDLGtCQUFWLEVBQThCO0FBQzVCLFdBQUtBLGtCQUFMLEdBQTBCQyxxQkFBWUMsT0FBWixDQUN4QixLQUFLVixZQURtQixFQUV4QixLQUFLSSxhQUZtQixFQUd4Qk8sSUFId0IsQ0FHbkJDLE1BQU0sSUFBSTtBQUNmLGFBQUtDLE9BQUwsR0FBZUQsTUFBZjtBQUNBLGVBQU9BLE1BQU0sQ0FBQ0UsRUFBUCxDQUFVRixNQUFNLENBQUNHLENBQVAsQ0FBU0MsT0FBVCxDQUFpQkMsTUFBM0IsQ0FBUDtBQUNELE9BTnlCLENBQTFCO0FBT0Q7O0FBQ0QsV0FBTyxLQUFLVCxrQkFBWjtBQUNELEdBM0JnRCxDQTZCakQ7QUFDQTs7O0FBQ0FVLEVBQUFBLFVBQVUsQ0FBQ0MsUUFBRCxFQUFtQkMsSUFBbkIsRUFBeUI7QUFDakMsV0FBTyxLQUFLYixRQUFMLEdBQ0pJLElBREksQ0FDQ1UsUUFBUSxJQUFJO0FBQ2hC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QUFMO0FBQ0Q7QUFDRixLQXRCRDtBQXVCRCxHQTlCRDtBQStCRDs7ZUFFYzFFLGdCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gR3JpZFN0b3JlQWRhcHRlclxuIFN0b3JlcyBmaWxlcyBpbiBNb25nbyB1c2luZyBHcmlkU3RvcmVcbiBSZXF1aXJlcyB0aGUgZGF0YWJhc2UgYWRhcHRlciB0byBiZSBiYXNlZCBvbiBtb25nb2NsaWVudFxuIChHcmlkU3RvcmUgaXMgZGVwcmVjYXRlZCwgUGxlYXNlIHVzZSBHcmlkRlNCdWNrZXQgaW5zdGVhZClcblxuIEBmbG93IHdlYWtcbiAqL1xuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IE1vbmdvQ2xpZW50LCBHcmlkU3RvcmUsIERiIH0gZnJvbSAnbW9uZ29kYic7XG5pbXBvcnQgeyBGaWxlc0FkYXB0ZXIsIHZhbGlkYXRlRmlsZW5hbWUgfSBmcm9tICcuL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuXG5leHBvcnQgY2xhc3MgR3JpZFN0b3JlQWRhcHRlciBleHRlbmRzIEZpbGVzQWRhcHRlciB7XG4gIF9kYXRhYmFzZVVSSTogc3RyaW5nO1xuICBfY29ubmVjdGlvblByb21pc2U6IFByb21pc2U8RGI+O1xuICBfbW9uZ29PcHRpb25zOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IobW9uZ29EYXRhYmFzZVVSSSA9IGRlZmF1bHRzLkRlZmF1bHRNb25nb1VSSSwgbW9uZ29PcHRpb25zID0ge30pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RhdGFiYXNlVVJJID0gbW9uZ29EYXRhYmFzZVVSSTtcblxuICAgIGNvbnN0IGRlZmF1bHRNb25nb09wdGlvbnMgPSB7XG4gICAgICB1c2VOZXdVcmxQYXJzZXI6IHRydWUsXG4gICAgICB1c2VVbmlmaWVkVG9wb2xvZ3k6IHRydWUsXG4gICAgfTtcbiAgICB0aGlzLl9tb25nb09wdGlvbnMgPSBPYmplY3QuYXNzaWduKGRlZmF1bHRNb25nb09wdGlvbnMsIG1vbmdvT3B0aW9ucyk7XG4gIH1cblxuICBfY29ubmVjdCgpIHtcbiAgICBpZiAoIXRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlKSB7XG4gICAgICB0aGlzLl9jb25uZWN0aW9uUHJvbWlzZSA9IE1vbmdvQ2xpZW50LmNvbm5lY3QoXG4gICAgICAgIHRoaXMuX2RhdGFiYXNlVVJJLFxuICAgICAgICB0aGlzLl9tb25nb09wdGlvbnNcbiAgICAgICkudGhlbihjbGllbnQgPT4ge1xuICAgICAgICB0aGlzLl9jbGllbnQgPSBjbGllbnQ7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGIoY2xpZW50LnMub3B0aW9ucy5kYk5hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jb25uZWN0aW9uUHJvbWlzZTtcbiAgfVxuXG4gIC8vIEZvciBhIGdpdmVuIGNvbmZpZyBvYmplY3QsIGZpbGVuYW1lLCBhbmQgZGF0YSwgc3RvcmUgYSBmaWxlXG4gIC8vIFJldHVybnMgYSBwcm9taXNlXG4gIGNyZWF0ZUZpbGUoZmlsZW5hbWU6IHN0cmluZywgZGF0YSkge1xuICAgIHJldHVybiB0aGlzLl9jb25uZWN0KClcbiAgICAgIC50aGVuKGRhdGFiYXNlID0+IHtcbiAgICAgICAgY29uc3QgZ3JpZFN0b3JlID0gbmV3IEdyaWRTdG9yZShkYXRhYmFzZSwgZmlsZW5hbWUsICd3Jyk7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUub3BlbigpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGdyaWRTdG9yZSA9PiB7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUud3JpdGUoZGF0YSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZ3JpZFN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5jbG9zZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpXG4gICAgICAudGhlbihkYXRhYmFzZSA9PiB7XG4gICAgICAgIGNvbnN0IGdyaWRTdG9yZSA9IG5ldyBHcmlkU3RvcmUoZGF0YWJhc2UsIGZpbGVuYW1lLCAncicpO1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLm9wZW4oKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLnVubGluaygpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGdyaWRTdG9yZSA9PiB7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUuY2xvc2UoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0RmlsZURhdGEoZmlsZW5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jb25uZWN0KClcbiAgICAgIC50aGVuKGRhdGFiYXNlID0+IHtcbiAgICAgICAgcmV0dXJuIEdyaWRTdG9yZS5leGlzdChkYXRhYmFzZSwgZmlsZW5hbWUpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGdyaWRTdG9yZSA9IG5ldyBHcmlkU3RvcmUoZGF0YWJhc2UsIGZpbGVuYW1lLCAncicpO1xuICAgICAgICAgIHJldHVybiBncmlkU3RvcmUub3BlbigpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLnJlYWQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgY29uZmlnLm1vdW50ICtcbiAgICAgICcvZmlsZXMvJyArXG4gICAgICBjb25maWcuYXBwbGljYXRpb25JZCArXG4gICAgICAnLycgK1xuICAgICAgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVGaWxlU3RyZWFtKGZpbGVuYW1lOiBzdHJpbmcsIHJlcSwgcmVzLCBjb250ZW50VHlwZSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHRoaXMuX2Nvbm5lY3QoKS50aGVuKGRhdGFiYXNlID0+IHtcbiAgICAgIHJldHVybiBHcmlkU3RvcmUuZXhpc3QoZGF0YWJhc2UsIGZpbGVuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgY29uc3QgZ3JpZFN0b3JlID0gbmV3IEdyaWRTdG9yZShkYXRhYmFzZSwgZmlsZW5hbWUsICdyJyk7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUub3BlbigpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaGFuZGxlUmFuZ2VSZXF1ZXN0KHN0cmVhbSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKTtcbiAgfVxuXG4gIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGlmICghdGhpcy5fY2xpZW50KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jbGllbnQuY2xvc2UoZmFsc2UpO1xuICB9XG5cbiAgdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSkge1xuICAgIHJldHVybiB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKTtcbiAgfVxufVxuXG4vLyBoYW5kbGVSYW5nZVJlcXVlc3QgaXMgbGljZW5zZWQgdW5kZXIgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbiA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlIChodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnkvNC4wLykuXG4vLyBBdXRob3I6IExFUk9JQiBhdCB3ZWlnaHRpbmdmb3JteXBpenphIChodHRwczovL3dlaWdodGluZ2Zvcm15cGl6emEud29yZHByZXNzLmNvbS8yMDE1LzA2LzI0L3N0cmVhbS1odG1sNS1tZWRpYS1jb250ZW50LWxpa2UtdmlkZW8tYXVkaW8tZnJvbS1tb25nb2RiLXVzaW5nLWV4cHJlc3MtYW5kLWdyaWRzdG9yZS8pLlxuZnVuY3Rpb24gaGFuZGxlUmFuZ2VSZXF1ZXN0KHN0cmVhbSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gIGNvbnN0IGJ1ZmZlcl9zaXplID0gMTAyNCAqIDEwMjQ7IC8vMTAyNEtiXG4gIC8vIFJhbmdlIHJlcXVlc3QsIHBhcnRpYWwgc3RyZWFtIHRoZSBmaWxlXG4gIGNvbnN0IHBhcnRzID0gcmVxXG4gICAgLmdldCgnUmFuZ2UnKVxuICAgIC5yZXBsYWNlKC9ieXRlcz0vLCAnJylcbiAgICAuc3BsaXQoJy0nKTtcbiAgbGV0IFtzdGFydCwgZW5kXSA9IHBhcnRzO1xuICBjb25zdCBub3RFbmRlZCA9ICFlbmQgJiYgZW5kICE9PSAwO1xuICBjb25zdCBub3RTdGFydGVkID0gIXN0YXJ0ICYmIHN0YXJ0ICE9PSAwO1xuICAvLyBObyBlbmQgcHJvdmlkZWQsIHdlIHdhbnQgYWxsIGJ5dGVzXG4gIGlmIChub3RFbmRlZCkge1xuICAgIGVuZCA9IHN0cmVhbS5sZW5ndGggLSAxO1xuICB9XG4gIC8vIE5vIHN0YXJ0IHByb3ZpZGVkLCB3ZSdyZSByZWFkaW5nIGJhY2t3YXJkc1xuICBpZiAobm90U3RhcnRlZCkge1xuICAgIHN0YXJ0ID0gc3RyZWFtLmxlbmd0aCAtIGVuZDtcbiAgICBlbmQgPSBzdGFydCArIGVuZCAtIDE7XG4gIH1cblxuICAvLyBEYXRhIGV4Y2VlZHMgdGhlIGJ1ZmZlcl9zaXplLCBjYXBcbiAgaWYgKGVuZCAtIHN0YXJ0ID49IGJ1ZmZlcl9zaXplKSB7XG4gICAgZW5kID0gc3RhcnQgKyBidWZmZXJfc2l6ZSAtIDE7XG4gIH1cblxuICBjb25zdCBjb250ZW50TGVuZ3RoID0gZW5kIC0gc3RhcnQgKyAxO1xuXG4gIHJlcy53cml0ZUhlYWQoMjA2LCB7XG4gICAgJ0NvbnRlbnQtUmFuZ2UnOiAnYnl0ZXMgJyArIHN0YXJ0ICsgJy0nICsgZW5kICsgJy8nICsgc3RyZWFtLmxlbmd0aCxcbiAgICAnQWNjZXB0LVJhbmdlcyc6ICdieXRlcycsXG4gICAgJ0NvbnRlbnQtTGVuZ3RoJzogY29udGVudExlbmd0aCxcbiAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gIH0pO1xuXG4gIHN0cmVhbS5zZWVrKHN0YXJ0LCBmdW5jdGlvbigpIHtcbiAgICAvLyBHZXQgZ3JpZEZpbGUgc3RyZWFtXG4gICAgY29uc3QgZ3JpZEZpbGVTdHJlYW0gPSBzdHJlYW0uc3RyZWFtKHRydWUpO1xuICAgIGxldCBidWZmZXJBdmFpbCA9IDA7XG4gICAgbGV0IHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSA9IGNvbnRlbnRMZW5ndGg7XG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICAvLyBXcml0ZSB0byByZXNwb25zZVxuICAgIGdyaWRGaWxlU3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSkge1xuICAgICAgYnVmZmVyQXZhaWwgKz0gZGF0YS5sZW5ndGg7XG4gICAgICBpZiAoYnVmZmVyQXZhaWwgPiAwKSB7XG4gICAgICAgIC8vIHNsaWNlIHJldHVybnMgdGhlIHNhbWUgYnVmZmVyIGlmIG92ZXJmbG93aW5nXG4gICAgICAgIC8vIHNhZmUgdG8gY2FsbCBpbiBhbnkgY2FzZVxuICAgICAgICBjb25zdCBidWZmZXIgPSBkYXRhLnNsaWNlKDAsIHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSk7XG4gICAgICAgIC8vIFdyaXRlIHRoZSBidWZmZXJcbiAgICAgICAgcmVzLndyaXRlKGJ1ZmZlcik7XG4gICAgICAgIC8vIEluY3JlbWVudCB0b3RhbFxuICAgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICAvLyBEZWNyZW1lbnQgcmVtYWluaW5nXG4gICAgICAgIHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSAtPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgLy8gRGVjcmVtZW50IHRoZSBhdmFpbGFibGUgYnVmZmVyXG4gICAgICAgIGJ1ZmZlckF2YWlsIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICB9XG4gICAgICAvLyBJbiBjYXNlIG9mIHNtYWxsIHNsaWNlcywgYWxsIHZhbHVlcyB3aWxsIGJlIGdvb2QgYXQgdGhhdCBwb2ludFxuICAgICAgLy8gd2UndmUgd3JpdHRlbiBlbm91Z2gsIGVuZC4uLlxuICAgICAgaWYgKHRvdGFsQnl0ZXNXcml0dGVuID49IGNvbnRlbnRMZW5ndGgpIHtcbiAgICAgICAgc3RyZWFtLmNsb3NlKCk7XG4gICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBHcmlkU3RvcmVBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Logger/LoggerAdapter.js b/lib/Adapters/Logger/LoggerAdapter.js deleted file mode 100644 index ed88ce5000..0000000000 --- a/lib/Adapters/Logger/LoggerAdapter.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LoggerAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface LoggerAdapter - * Logger Adapter - * Allows you to change the logger mechanism - * Default is WinstonLoggerAdapter.js - */ -class LoggerAdapter { - constructor(options) {} - /** - * log - * @param {String} level - * @param {String} message - * @param {Object} metadata - */ - - - log(level, message - /* meta */ - ) {} - -} - -exports.LoggerAdapter = LoggerAdapter; -var _default = LoggerAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibGV2ZWwiLCJtZXNzYWdlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFHQTs7Ozs7O0FBTU8sTUFBTUEsYUFBTixDQUFvQjtBQUN6QkMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVUsQ0FBRTtBQUN2Qjs7Ozs7Ozs7QUFNQUMsRUFBQUEsR0FBRyxDQUFDQyxLQUFELEVBQVFDO0FBQVE7QUFBaEIsSUFBNEIsQ0FBRTs7QUFSUjs7O2VBV1pMLGEiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIExvZ2dlckFkYXB0ZXJcbiAqIExvZ2dlciBBZGFwdGVyXG4gKiBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgbG9nZ2VyIG1lY2hhbmlzbVxuICogRGVmYXVsdCBpcyBXaW5zdG9uTG9nZ2VyQWRhcHRlci5qc1xuICovXG5leHBvcnQgY2xhc3MgTG9nZ2VyQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHt9XG4gIC8qKlxuICAgKiBsb2dcbiAgICogQHBhcmFtIHtTdHJpbmd9IGxldmVsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtZXRhZGF0YVxuICAgKi9cbiAgbG9nKGxldmVsLCBtZXNzYWdlIC8qIG1ldGEgKi8pIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dlckFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLogger.js b/lib/Adapters/Logger/WinstonLogger.js deleted file mode 100644 index fca457a137..0000000000 --- a/lib/Adapters/Logger/WinstonLogger.js +++ /dev/null @@ -1,137 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.configureLogger = configureLogger; -exports.addTransport = addTransport; -exports.removeTransport = removeTransport; -exports.default = exports.logger = void 0; - -var _winston = _interopRequireWildcard(require("winston")); - -var _fs = _interopRequireDefault(require("fs")); - -var _path = _interopRequireDefault(require("path")); - -var _winstonDailyRotateFile = _interopRequireDefault(require("winston-daily-rotate-file")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const logger = _winston.default.createLogger(); - -exports.logger = logger; - -function configureTransports(options) { - const transports = []; - - if (options) { - const silent = options.silent; - delete options.silent; - - try { - if (!_lodash.default.isNil(options.dirname)) { - const parseServer = new _winstonDailyRotateFile.default(Object.assign({ - filename: 'parse-server.info', - json: true, - format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) - }, options)); - parseServer.name = 'parse-server'; - transports.push(parseServer); - const parseServerError = new _winstonDailyRotateFile.default(Object.assign({ - filename: 'parse-server.err', - json: true, - format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) - }, options, { - level: 'error' - })); - parseServerError.name = 'parse-server-error'; - transports.push(parseServerError); - } - } catch (e) { - /* */ - } - - const consoleFormat = options.json ? _winston.format.json() : _winston.format.simple(); - const consoleOptions = Object.assign({ - colorize: true, - name: 'console', - silent, - format: consoleFormat - }, options); - transports.push(new _winston.default.transports.Console(consoleOptions)); - } - - logger.configure({ - transports - }); -} - -function configureLogger({ - logsFolder = _defaults.default.logsFolder, - jsonLogs = _defaults.default.jsonLogs, - logLevel = _winston.default.level, - verbose = _defaults.default.verbose, - silent = _defaults.default.silent, - maxLogFiles -} = {}) { - if (verbose) { - logLevel = 'verbose'; - } - - _winston.default.level = logLevel; - const options = {}; - - if (logsFolder) { - if (!_path.default.isAbsolute(logsFolder)) { - logsFolder = _path.default.resolve(process.cwd(), logsFolder); - } - - try { - _fs.default.mkdirSync(logsFolder); - } catch (e) { - /* */ - } - } - - options.dirname = logsFolder; - options.level = logLevel; - options.silent = silent; - options.maxFiles = maxLogFiles; - - if (jsonLogs) { - options.json = true; - options.stringify = true; - } - - configureTransports(options); -} - -function addTransport(transport) { - // we will remove the existing transport - // before replacing it with a new one - removeTransport(transport.name); - logger.add(transport); -} - -function removeTransport(transport) { - const matchingTransport = logger.transports.find(t1 => { - return typeof transport === 'string' ? t1.name === transport : t1 === transport; - }); - - if (matchingTransport) { - logger.remove(matchingTransport); - } -} - -var _default = logger; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlci5qcyJdLCJuYW1lcyI6WyJsb2dnZXIiLCJ3aW5zdG9uIiwiY3JlYXRlTG9nZ2VyIiwiY29uZmlndXJlVHJhbnNwb3J0cyIsIm9wdGlvbnMiLCJ0cmFuc3BvcnRzIiwic2lsZW50IiwiXyIsImlzTmlsIiwiZGlybmFtZSIsInBhcnNlU2VydmVyIiwiRGFpbHlSb3RhdGVGaWxlIiwiT2JqZWN0IiwiYXNzaWduIiwiZmlsZW5hbWUiLCJqc29uIiwiZm9ybWF0IiwiY29tYmluZSIsInRpbWVzdGFtcCIsInNwbGF0IiwibmFtZSIsInB1c2giLCJwYXJzZVNlcnZlckVycm9yIiwibGV2ZWwiLCJlIiwiY29uc29sZUZvcm1hdCIsInNpbXBsZSIsImNvbnNvbGVPcHRpb25zIiwiY29sb3JpemUiLCJDb25zb2xlIiwiY29uZmlndXJlIiwiY29uZmlndXJlTG9nZ2VyIiwibG9nc0ZvbGRlciIsImRlZmF1bHRzIiwianNvbkxvZ3MiLCJsb2dMZXZlbCIsInZlcmJvc2UiLCJtYXhMb2dGaWxlcyIsInBhdGgiLCJpc0Fic29sdXRlIiwicmVzb2x2ZSIsInByb2Nlc3MiLCJjd2QiLCJmcyIsIm1rZGlyU3luYyIsIm1heEZpbGVzIiwic3RyaW5naWZ5IiwiYWRkVHJhbnNwb3J0IiwidHJhbnNwb3J0IiwicmVtb3ZlVHJhbnNwb3J0IiwiYWRkIiwibWF0Y2hpbmdUcmFuc3BvcnQiLCJmaW5kIiwidDEiLCJyZW1vdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxNQUFNLEdBQUdDLGlCQUFRQyxZQUFSLEVBQWY7Ozs7QUFFQSxTQUFTQyxtQkFBVCxDQUE2QkMsT0FBN0IsRUFBc0M7QUFDcEMsUUFBTUMsVUFBVSxHQUFHLEVBQW5COztBQUNBLE1BQUlELE9BQUosRUFBYTtBQUNYLFVBQU1FLE1BQU0sR0FBR0Ys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LCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IERhaWx5Um90YXRlRmlsZSBmcm9tICd3aW5zdG9uLWRhaWx5LXJvdGF0ZS1maWxlJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuXG5jb25zdCBsb2dnZXIgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcigpO1xuXG5mdW5jdGlvbiBjb25maWd1cmVUcmFuc3BvcnRzKG9wdGlvbnMpIHtcbiAgY29uc3QgdHJhbnNwb3J0cyA9IFtdO1xuICBpZiAob3B0aW9ucykge1xuICAgIGNvbnN0IHNpbGVudCA9IG9wdGlvbnMuc2lsZW50O1xuICAgIGRlbGV0ZSBvcHRpb25zLnNpbGVudDtcblxuICAgIHRyeSB7XG4gICAgICBpZiAoIV8uaXNOaWwob3B0aW9ucy5kaXJuYW1lKSkge1xuICAgICAgICBjb25zdCBwYXJzZVNlcnZlciA9IG5ldyBEYWlseVJvdGF0ZUZpbGUoXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6ICdwYXJzZS1zZXJ2ZXIuaW5mbycsXG4gICAgICAgICAgICAgIGpzb246IHRydWUsXG4gICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoXG4gICAgICAgICAgICAgICAgZm9ybWF0LnRpbWVzdGFtcCgpLFxuICAgICAgICAgICAgICAgIGZvcm1hdC5zcGxhdCgpLFxuICAgICAgICAgICAgICAgIGZvcm1hdC5qc29uKClcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBwYXJzZVNlcnZlci5uYW1lID0gJ3BhcnNlLXNlcnZlcic7XG4gICAgICAgIHRyYW5zcG9ydHMucHVzaChwYXJzZVNlcnZlcik7XG5cbiAgICAgICAgY29uc3QgcGFyc2VTZXJ2ZXJFcnJvciA9IG5ldyBEYWlseVJvdGF0ZUZpbGUoXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6ICdwYXJzZS1zZXJ2ZXIuZXJyJyxcbiAgICAgICAgICAgICAganNvbjogdHJ1ZSxcbiAgICAgICAgICAgICAgZm9ybWF0OiBmb3JtYXQuY29tYmluZShcbiAgICAgICAgICAgICAgICBmb3JtYXQudGltZXN0YW1wKCksXG4gICAgICAgICAgICAgICAgZm9ybWF0LnNwbGF0KCksXG4gICAgICAgICAgICAgICAgZm9ybWF0Lmpzb24oKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICB7IGxldmVsOiAnZXJyb3InIH1cbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICAgIHBhcnNlU2VydmVyRXJyb3IubmFtZSA9ICdwYXJzZS1zZXJ2ZXItZXJyb3InO1xuICAgICAgICB0cmFuc3BvcnRzLnB1c2gocGFyc2VTZXJ2ZXJFcnJvcik7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogKi9cbiAgICB9XG5cbiAgICBjb25zdCBjb25zb2xlRm9ybWF0ID0gb3B0aW9ucy5qc29uID8gZm9ybWF0Lmpzb24oKSA6IGZvcm1hdC5zaW1wbGUoKTtcbiAgICBjb25zdCBjb25zb2xlT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7XG4gICAgICAgIGNvbG9yaXplOiB0cnVlLFxuICAgICAgICBuYW1lOiAnY29uc29sZScsXG4gICAgICAgIHNpbGVudCxcbiAgICAgICAgZm9ybWF0OiBjb25zb2xlRm9ybWF0LFxuICAgICAgfSxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuXG4gICAgdHJhbnNwb3J0cy5wdXNoKG5ldyB3aW5zdG9uLnRyYW5zcG9ydHMuQ29uc29sZShjb25zb2xlT3B0aW9ucykpO1xuICB9XG5cbiAgbG9nZ2VyLmNvbmZpZ3VyZSh7XG4gICAgdHJhbnNwb3J0cyxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb25maWd1cmVMb2dnZXIoe1xuICBsb2dzRm9sZGVyID0gZGVmYXVsdHMubG9nc0ZvbGRlcixcbiAganNvbkxvZ3MgPSBkZWZhdWx0cy5qc29uTG9ncyxcbiAgbG9nTGV2ZWwgPSB3aW5zdG9uLmxldmVsLFxuICB2ZXJib3NlID0gZGVmYXVsdHMudmVyYm9zZSxcbiAgc2lsZW50ID0gZGVmYXVsdHMuc2lsZW50LFxuICBtYXhMb2dGaWxlcyxcbn0gPSB7fSkge1xuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ0xldmVsID0gJ3ZlcmJvc2UnO1xuICB9XG5cbiAgd2luc3Rvbi5sZXZlbCA9IGxvZ0xldmVsO1xuICBjb25zdCBvcHRpb25zID0ge307XG5cbiAgaWYgKGxvZ3NGb2xkZXIpIHtcbiAgICBpZiAoIXBhdGguaXNBYnNvbHV0ZShsb2dzRm9sZGVyKSkge1xuICAgICAgbG9nc0ZvbGRlciA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBsb2dzRm9sZGVyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGZzLm1rZGlyU3luYyhsb2dzRm9sZGVyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiAqL1xuICAgIH1cbiAgfVxuICBvcHRpb25zLmRpcm5hbWUgPSBsb2dzRm9sZGVyO1xuICBvcHRpb25zLmxldmVsID0gbG9nTGV2ZWw7XG4gIG9wdGlvbnMuc2lsZW50ID0gc2lsZW50O1xuICBvcHRpb25zLm1heEZpbGVzID0gbWF4TG9nRmlsZXM7XG5cbiAgaWYgKGpzb25Mb2dzKSB7XG4gICAgb3B0aW9ucy5qc29uID0gdHJ1ZTtcbiAgICBvcHRpb25zLnN0cmluZ2lmeSA9IHRydWU7XG4gIH1cbiAgY29uZmlndXJlVHJhbnNwb3J0cyhvcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgLy8gd2Ugd2lsbCByZW1vdmUgdGhlIGV4aXN0aW5nIHRyYW5zcG9ydFxuICAvLyBiZWZvcmUgcmVwbGFjaW5nIGl0IHdpdGggYSBuZXcgb25lXG4gIHJlbW92ZVRyYW5zcG9ydCh0cmFuc3BvcnQubmFtZSk7XG5cbiAgbG9nZ2VyLmFkZCh0cmFuc3BvcnQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJhbnNwb3J0KHRyYW5zcG9ydCkge1xuICBjb25zdCBtYXRjaGluZ1RyYW5zcG9ydCA9IGxvZ2dlci50cmFuc3BvcnRzLmZpbmQodDEgPT4ge1xuICAgIHJldHVybiB0eXBlb2YgdHJhbnNwb3J0ID09PSAnc3RyaW5nJ1xuICAgICAgPyB0MS5uYW1lID09PSB0cmFuc3BvcnRcbiAgICAgIDogdDEgPT09IHRyYW5zcG9ydDtcbiAgfSk7XG5cbiAgaWYgKG1hdGNoaW5nVHJhbnNwb3J0KSB7XG4gICAgbG9nZ2VyLnJlbW92ZShtYXRjaGluZ1RyYW5zcG9ydCk7XG4gIH1cbn1cblxuZXhwb3J0IHsgbG9nZ2VyIH07XG5leHBvcnQgZGVmYXVsdCBsb2dnZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLoggerAdapter.js b/lib/Adapters/Logger/WinstonLoggerAdapter.js deleted file mode 100644 index 9731f1816a..0000000000 --- a/lib/Adapters/Logger/WinstonLoggerAdapter.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.WinstonLoggerAdapter = void 0; - -var _LoggerAdapter = require("./LoggerAdapter"); - -var _WinstonLogger = require("./WinstonLogger"); - -const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; - -class WinstonLoggerAdapter extends _LoggerAdapter.LoggerAdapter { - constructor(options) { - super(); - - if (options) { - (0, _WinstonLogger.configureLogger)(options); - } - } - - log() { - return _WinstonLogger.logger.log.apply(_WinstonLogger.logger, arguments); - } - - addTransport(transport) { - // Note that this is calling addTransport - // from logger. See import - confusing. - // but this is not recursive. - (0, _WinstonLogger.addTransport)(transport); - } // custom query as winston is currently limited - - - query(options, callback = () => {}) { - if (!options) { - options = {}; - } // defaults to 7 days prior - - - const from = options.from || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); - const until = options.until || new Date(); - const limit = options.size || 10; - const order = options.order || 'desc'; - const level = options.level || 'info'; - const queryOptions = { - from, - until, - limit, - order - }; - return new Promise((resolve, reject) => { - _WinstonLogger.logger.query(queryOptions, (err, res) => { - if (err) { - callback(err); - return reject(err); - } - - if (level === 'error') { - callback(res['parse-server-error']); - resolve(res['parse-server-error']); - } else { - callback(res['parse-server']); - resolve(res['parse-server']); - } - }); - }); - } - -} - -exports.WinstonLoggerAdapter = WinstonLoggerAdapter; -var _default = WinstonLoggerAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXIuanMiXSwibmFtZXMiOlsiTUlMTElTRUNPTkRTX0lOX0FfREFZIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJhZGRUcmFuc3BvcnQiLCJ0cmFuc3BvcnQiLCJxdWVyeSIsImNhbGxiYWNrIiwiZnJvbSIsIkRhdGUiLCJub3ciLCJ1bnRpbCIsImxpbWl0Iiwic2l6ZSIsIm9yZGVyIiwibGV2ZWwiLCJxdWVyeU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImVyciIsInJlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLEtBQUssRUFBTCxHQUFVLEVBQVYsR0FBZSxJQUE3Qzs7QUFFTyxNQUFNQyxvQkFBTixTQUFtQ0MsNEJBQW5DLENBQWlEO0FBQ3REQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVTtBQUNuQjs7QUFDQSxRQUFJQSxPQUFKLEVBQWE7QUFDWCwwQ0FBZ0JBLE9BQWhCO0FBQ0Q7QUFDRjs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0Msc0JBQU9ELEdBQVAsQ0FBV0UsS0FBWCxDQUFpQkQscUJBQWpCLEVBQXlCRSxTQUF6QixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLFlBQVksQ0FBQ0MsU0FBRCxFQUFZO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLHFDQUFhQSxTQUFiO0FBQ0QsR0FqQnFELENBbUJ0RDs7O0FBQ0FDLEVBQUFBLEtBQUssQ0FBQ1AsT0FBRCxFQUFVUSxRQUFRLEdBQUcsTUFBTSxDQUFFLENBQTdCLEVBQStCO0FBQ2xDLFFBQUksQ0FBQ1IsT0FBTCxFQUFjO0FBQ1pBLE1BQUFBLE9BQU8sR0FBRyxFQUFWO0FBQ0QsS0FIaUMsQ0FJbEM7OztBQUNBLFVBQU1TLElBQUksR0FDUlQsT0FBTyxDQUFDUyxJQUFSLElBQWdCLElBQUlDLElBQUosQ0FBU0EsSUFBSSxDQUFDQyxHQUFMLEtBQWEsSUFBSWYscUJBQTFCLENBRGxCO0FBRUEsVUFBTWdCLEtBQUssR0FBR1osT0FBTyxDQUFDWSxLQUFSLElBQWlCLElBQUlGLElBQUosRUFBL0I7QUFDQSxVQUFNRyxLQUFLLEdBQUdiLE9BQU8sQ0FBQ2MsSUFBUixJQUFnQixFQUE5QjtBQUNBLFVBQU1DLEtBQUssR0FBR2YsT0FBTyxDQUFDZSxLQUFSLElBQWlCLE1BQS9CO0FBQ0EsVUFBTUMsS0FBSyxHQUFHaEIsT0FBTyxDQUFDZ0IsS0FBUixJQUFpQixNQUEvQjtBQUVBLFVBQU1DLFlBQVksR0FBRztBQUNuQlIsTUFBQUEsSUFEbUI7QUFFbkJHLE1BQUFBLEtBRm1CO0FBR25CQyxNQUFBQSxLQUhtQjtBQUluQkUsTUFBQUE7QUFKbUIsS0FBckI7QUFPQSxXQUFPLElBQUlHLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDdENsQiw0QkFBT0ssS0FBUCxDQUFhVSxZQUFiLEVBQTJCLENBQUNJLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQ3ZDLFlBQUlELEdBQUosRUFBUztBQUNQYixVQUFBQSxRQUFRLENBQUNhLEdBQUQsQ0FBUjtBQUNBLGlCQUFPRCxNQUFNLENBQUNDLEdBQUQsQ0FBYjtBQUNEOztBQUVELFlBQUlMLEtBQUssS0FBSyxPQUFkLEVBQXVCO0FBQ3JCUixVQUFBQSxRQUFRLENBQUNjLEdBQUcsQ0FBQyxvQkFBRCxDQUFKLENBQVI7QUFDQUgsVUFBQUEsT0FBTyxDQUFDRyxHQUFHLENBQUMsb0JBQUQsQ0FBSixDQUFQO0FBQ0QsU0FIRCxNQUdPO0FBQ0xkLFVBQUFBLFFBQVEsQ0FBQ2MsR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFSO0FBQ0FILFVBQUFBLE9BQU8sQ0FBQ0csR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFQO0FBQ0Q7QUFDRixPQWJEO0FBY0QsS0FmTSxDQUFQO0FBZ0JEOztBQXZEcUQ7OztlQTBEekN6QixvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgbG9nZ2VyLCBhZGRUcmFuc3BvcnQsIGNvbmZpZ3VyZUxvZ2dlciB9IGZyb20gJy4vV2luc3RvbkxvZ2dlcic7XG5cbmNvbnN0IE1JTExJU0VDT05EU19JTl9BX0RBWSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBXaW5zdG9uTG9nZ2VyQWRhcHRlciBleHRlbmRzIExvZ2dlckFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgY29uZmlndXJlTG9nZ2VyKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGxvZygpIHtcbiAgICByZXR1cm4gbG9nZ2VyLmxvZy5hcHBseShsb2dnZXIsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KSB7XG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgY2FsbGluZyBhZGRUcmFuc3BvcnRcbiAgICAvLyBmcm9tIGxvZ2dlci4gIFNlZSBpbXBvcnQgLSBjb25mdXNpbmcuXG4gICAgLy8gYnV0IHRoaXMgaXMgbm90IHJlY3Vyc2l2ZS5cbiAgICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfVxuXG4gIC8vIGN1c3RvbSBxdWVyeSBhcyB3aW5zdG9uIGlzIGN1cnJlbnRseSBsaW1pdGVkXG4gIHF1ZXJ5KG9wdGlvbnMsIGNhbGxiYWNrID0gKCkgPT4ge30pIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gNyBkYXlzIHByaW9yXG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBvcHRpb25zLmZyb20gfHwgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gb3B0aW9ucy51bnRpbCB8fCBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IGxpbWl0ID0gb3B0aW9ucy5zaXplIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCAnZGVzYyc7XG4gICAgY29uc3QgbGV2ZWwgPSBvcHRpb25zLmxldmVsIHx8ICdpbmZvJztcblxuICAgIGNvbnN0IHF1ZXJ5T3B0aW9ucyA9IHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIGxpbWl0LFxuICAgICAgb3JkZXIsXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsb2dnZXIucXVlcnkocXVlcnlPcHRpb25zLCAoZXJyLCByZXMpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxldmVsID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgY2FsbGJhY2socmVzWydwYXJzZS1zZXJ2ZXItZXJyb3InXSk7XG4gICAgICAgICAgcmVzb2x2ZShyZXNbJ3BhcnNlLXNlcnZlci1lcnJvciddKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYWxsYmFjayhyZXNbJ3BhcnNlLXNlcnZlciddKTtcbiAgICAgICAgICByZXNvbHZlKHJlc1sncGFyc2Utc2VydmVyJ10pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBXaW5zdG9uTG9nZ2VyQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/MessageQueue/EventEmitterMQ.js b/lib/Adapters/MessageQueue/EventEmitterMQ.js deleted file mode 100644 index ddf372cd6d..0000000000 --- a/lib/Adapters/MessageQueue/EventEmitterMQ.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.EventEmitterMQ = void 0; - -var _events = _interopRequireDefault(require("events")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const emitter = new _events.default.EventEmitter(); -const subscriptions = new Map(); - -function unsubscribe(channel) { - if (!subscriptions.has(channel)) { - //console.log('No channel to unsub from'); - return; - } //console.log('unsub ', channel); - - - emitter.removeListener(channel, subscriptions.get(channel)); - subscriptions.delete(channel); -} - -class Publisher { - constructor(emitter) { - this.emitter = emitter; - } - - publish(channel, message) { - this.emitter.emit(channel, message); - } - -} - -class Consumer extends _events.default.EventEmitter { - constructor(emitter) { - super(); - this.emitter = emitter; - } - - subscribe(channel) { - unsubscribe(channel); - - const handler = message => { - this.emit('message', channel, message); - }; - - subscriptions.set(channel, handler); - this.emitter.on(channel, handler); - } - - unsubscribe(channel) { - unsubscribe(channel); - } - -} - -function createPublisher() { - return new Publisher(emitter); -} - -function createSubscriber() { - return new Consumer(emitter); -} - -const EventEmitterMQ = { - createPublisher, - createSubscriber -}; -exports.EventEmitterMQ = EventEmitterMQ; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9NZXNzYWdlUXVldWUvRXZlbnRFbWl0dGVyTVEuanMiXSwibmFtZXMiOlsiZW1pdHRlciIsImV2ZW50cyIsIkV2ZW50RW1pdHRlciIsInN1YnNjcmlwdGlvbnMiLCJNYXAiLCJ1bnN1YnNjcmliZSIsImNoYW5uZWwiLCJoYXMiLCJyZW1vdmVMaXN0ZW5lciIsImdldCIsImRlbGV0ZSIsIlB1Ymxpc2hlciIsImNvbnN0cnVjdG9yIiwicHVibGlzaCIsIm1lc3NhZ2UiLCJlbWl0IiwiQ29uc3VtZXIiLCJzdWJzY3JpYmUiLCJoYW5kbGVyIiwic2V0Iiwib24iLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwiRXZlbnRFbWl0dGVyTVEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBLE1BQU1BLE9BQU8sR0FBRyxJQUFJQyxnQkFBT0MsWUFBWCxFQUFoQjtBQUNBLE1BQU1DLGFBQWEsR0FBRyxJQUFJQyxHQUFKLEVBQXRCOztBQUVBLFNBQVNDLFdBQVQsQ0FBcUJDLE9BQXJCLEVBQXNDO0FBQ3BDLE1BQUksQ0FBQ0gsYUFBYSxDQUFDSSxHQUFkLENBQWtCRCxPQUFsQixDQUFMLEVBQWlDO0FBQy9CO0FBQ0E7QUFDRCxHQUptQyxDQUtwQzs7O0FBQ0FOLEVBQUFBLE9BQU8sQ0FBQ1EsY0FBUixDQUF1QkYsT0FBdkIsRUFBZ0NILGFBQWEsQ0FBQ00sR0FBZCxDQUFrQkgsT0FBbEIsQ0FBaEM7QUFDQUgsRUFBQUEsYUFBYSxDQUFDTyxNQUFkLENBQXFCSixPQUFyQjtBQUNEOztBQUVELE1BQU1LLFNBQU4sQ0FBZ0I7QUFHZEMsRUFBQUEsV0FBVyxDQUFDWixPQUFELEVBQWU7QUFDeEIsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRURhLEVBQUFBLE9BQU8sQ0FBQ1AsT0FBRCxFQUFrQlEsT0FBbEIsRUFBeUM7QUFDOUMsU0FBS2QsT0FBTCxDQUFhZSxJQUFiLENBQWtCVCxPQUFsQixFQUEyQlEsT0FBM0I7QUFDRDs7QUFUYTs7QUFZaEIsTUFBTUUsUUFBTixTQUF1QmYsZ0JBQU9DLFlBQTlCLENBQTJDO0FBR3pDVSxFQUFBQSxXQUFXLENBQUNaLE9BQUQsRUFBZTtBQUN4QjtBQUNBLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVEaUIsRUFBQUEsU0FBUyxDQUFDWCxPQUFELEVBQXdCO0FBQy9CRCxJQUFBQSxXQUFXLENBQUNDLE9BQUQsQ0FBWDs7QUFDQSxVQUFNWSxPQUFPLEdBQUdKLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQlQsT0FBckIsRUFBOEJRLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQVgsSUFBQUEsYUFBYSxDQUFDZ0IsR0FBZCxDQUFrQmIsT0FBbEIsRUFBMkJZLE9BQTNCO0FBQ0EsU0FBS2xCLE9BQUwsQ0FBYW9CLEVBQWIsQ0FBZ0JkLE9BQWhCLEVBQXlCWSxPQUF6QjtBQUNEOztBQUVEYixFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBd0I7QUFDakNELElBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxDQUFYO0FBQ0Q7O0FBbkJ3Qzs7QUFzQjNDLFNBQVNlLGVBQVQsR0FBZ0M7QUFDOUIsU0FBTyxJQUFJVixTQUFKLENBQWNYLE9BQWQsQ0FBUDtBQUNEOztBQUVELFNBQVNzQixnQkFBVCxHQUFpQztBQUMvQixTQUFPLElBQUlOLFFBQUosQ0FBYWhCLE9BQWIsQ0FBUDtBQUNEOztBQUVELE1BQU11QixjQUFjLEdBQUc7QUFDckJGLEVBQUFBLGVBRHFCO0FBRXJCQyxFQUFBQTtBQUZxQixDQUF2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuY29uc3QgZW1pdHRlciA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG5jb25zdCBzdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuXG5mdW5jdGlvbiB1bnN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpIHtcbiAgaWYgKCFzdWJzY3JpcHRpb25zLmhhcyhjaGFubmVsKSkge1xuICAgIC8vY29uc29sZS5sb2coJ05vIGNoYW5uZWwgdG8gdW5zdWIgZnJvbScpO1xuICAgIHJldHVybjtcbiAgfVxuICAvL2NvbnNvbGUubG9nKCd1bnN1YiAnLCBjaGFubmVsKTtcbiAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihjaGFubmVsLCBzdWJzY3JpcHRpb25zLmdldChjaGFubmVsKSk7XG4gIHN1YnNjcmlwdGlvbnMuZGVsZXRlKGNoYW5uZWwpO1xufVxuXG5jbGFzcyBQdWJsaXNoZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgfVxuXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtaXR0ZXIuZW1pdChjaGFubmVsLCBtZXNzYWdlKTtcbiAgfVxufVxuXG5jbGFzcyBDb25zdW1lciBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICB9XG5cbiAgc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHVuc3Vic2NyaWJlKGNoYW5uZWwpO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBtZXNzYWdlID0+IHtcbiAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIGNoYW5uZWwsIG1lc3NhZ2UpO1xuICAgIH07XG4gICAgc3Vic2NyaXB0aW9ucy5zZXQoY2hhbm5lbCwgaGFuZGxlcik7XG4gICAgdGhpcy5lbWl0dGVyLm9uKGNoYW5uZWwsIGhhbmRsZXIpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdW5zdWJzY3JpYmUoY2hhbm5lbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgUHVibGlzaGVyKGVtaXR0ZXIpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgQ29uc3VtZXIoZW1pdHRlcik7XG59XG5cbmNvbnN0IEV2ZW50RW1pdHRlck1RID0ge1xuICBjcmVhdGVQdWJsaXNoZXIsXG4gIGNyZWF0ZVN1YnNjcmliZXIsXG59O1xuXG5leHBvcnQgeyBFdmVudEVtaXR0ZXJNUSB9O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/EventEmitterPubSub.js b/lib/Adapters/PubSub/EventEmitterPubSub.js deleted file mode 100644 index e5f1670d83..0000000000 --- a/lib/Adapters/PubSub/EventEmitterPubSub.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.EventEmitterPubSub = void 0; - -var _events = _interopRequireDefault(require("events")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const emitter = new _events.default.EventEmitter(); - -class Publisher { - constructor(emitter) { - this.emitter = emitter; - } - - publish(channel, message) { - this.emitter.emit(channel, message); - } - -} - -class Subscriber extends _events.default.EventEmitter { - constructor(emitter) { - super(); - this.emitter = emitter; - this.subscriptions = new Map(); - } - - subscribe(channel) { - const handler = message => { - this.emit('message', channel, message); - }; - - this.subscriptions.set(channel, handler); - this.emitter.on(channel, handler); - } - - unsubscribe(channel) { - if (!this.subscriptions.has(channel)) { - return; - } - - this.emitter.removeListener(channel, this.subscriptions.get(channel)); - this.subscriptions.delete(channel); - } - -} - -function createPublisher() { - return new Publisher(emitter); -} - -function createSubscriber() { - return new Subscriber(emitter); -} - -const EventEmitterPubSub = { - createPublisher, - createSubscriber -}; -exports.EventEmitterPubSub = EventEmitterPubSub; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvRXZlbnRFbWl0dGVyUHViU3ViLmpzIl0sIm5hbWVzIjpbImVtaXR0ZXIiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsInB1Ymxpc2giLCJjaGFubmVsIiwibWVzc2FnZSIsImVtaXQiLCJTdWJzY3JpYmVyIiwic3Vic2NyaXB0aW9ucyIsIk1hcCIsInN1YnNjcmliZSIsImhhbmRsZXIiLCJzZXQiLCJvbiIsInVuc3Vic2NyaWJlIiwiaGFzIiwicmVtb3ZlTGlzdGVuZXIiLCJnZXQiLCJkZWxldGUiLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwiRXZlbnRFbWl0dGVyUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxNQUFNQSxPQUFPLEdBQUcsSUFBSUMsZ0JBQU9DLFlBQVgsRUFBaEI7O0FBRUEsTUFBTUMsU0FBTixDQUFnQjtBQUdkQyxFQUFBQSxXQUFXLENBQUNKLE9BQUQsRUFBZTtBQUN4QixTQUFLQSxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREssRUFBQUEsT0FBTyxDQUFDQyxPQUFELEVBQWtCQyxPQUFsQixFQUF5QztBQUM5QyxTQUFLUCxPQUFMLENBQWFRLElBQWIsQ0FBa0JGLE9BQWxCLEVBQTJCQyxPQUEzQjtBQUNEOztBQVRhOztBQVloQixNQUFNRSxVQUFOLFNBQXlCUixnQkFBT0MsWUFBaEMsQ0FBNkM7QUFJM0NFLEVBQUFBLFdBQVcsQ0FBQ0osT0FBRCxFQUFlO0FBQ3hCO0FBQ0EsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS1UsYUFBTCxHQUFxQixJQUFJQyxHQUFKLEVBQXJCO0FBQ0Q7O0FBRURDLEVBQUFBLFNBQVMsQ0FBQ04sT0FBRCxFQUF3QjtBQUMvQixVQUFNTyxPQUFPLEdBQUdOLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQkYsT0FBckIsRUFBOEJDLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQSxTQUFLRyxhQUFMLENBQW1CSSxHQUFuQixDQUF1QlIsT0FBdkIsRUFBZ0NPLE9BQWhDO0FBQ0EsU0FBS2IsT0FBTCxDQUFhZSxFQUFiLENBQWdCVCxPQUFoQixFQUF5Qk8sT0FBekI7QUFDRDs7QUFFREcsRUFBQUEsV0FBVyxDQUFDVixPQUFELEVBQXdCO0FBQ2pDLFFBQUksQ0FBQyxLQUFLSSxhQUFMLENBQW1CTyxHQUFuQixDQUF1QlgsT0FBdkIsQ0FBTCxFQUFzQztBQUNwQztBQUNEOztBQUNELFNBQUtOLE9BQUwsQ0FBYWtCLGNBQWIsQ0FBNEJaLE9BQTVCLEVBQXFDLEtBQUtJLGFBQUwsQ0FBbUJTLEdBQW5CLENBQXVCYixPQUF2QixDQUFyQztBQUNBLFNBQUtJLGFBQUwsQ0FBbUJVLE1BQW5CLENBQTBCZCxPQUExQjtBQUNEOztBQXhCMEM7O0FBMkI3QyxTQUFTZSxlQUFULEdBQWdDO0FBQzlCLFNBQU8sSUFBSWxCLFNBQUosQ0FBY0gsT0FBZCxDQUFQO0FBQ0Q7O0FBRUQsU0FBU3NCLGdCQUFULEdBQWlDO0FBQy9CLFNBQU8sSUFBSWIsVUFBSixDQUFlVCxPQUFmLENBQVA7QUFDRDs7QUFFRCxNQUFNdUIsa0JBQWtCLEdBQUc7QUFDekJGLEVBQUFBLGVBRHlCO0FBRXpCQyxFQUFBQTtBQUZ5QixDQUEzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuY29uc3QgZW1pdHRlciA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG5cbmNsYXNzIFB1Ymxpc2hlciB7XG4gIGVtaXR0ZXI6IGFueTtcblxuICBjb25zdHJ1Y3RvcihlbWl0dGVyOiBhbnkpIHtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICB9XG5cbiAgcHVibGlzaChjaGFubmVsOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZW1pdHRlci5lbWl0KGNoYW5uZWwsIG1lc3NhZ2UpO1xuICB9XG59XG5cbmNsYXNzIFN1YnNjcmliZXIgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgZW1pdHRlcjogYW55O1xuICBzdWJzY3JpcHRpb25zOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIHN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBoYW5kbGVyID0gbWVzc2FnZSA9PiB7XG4gICAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCBjaGFubmVsLCBtZXNzYWdlKTtcbiAgICB9O1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5zZXQoY2hhbm5lbCwgaGFuZGxlcik7XG4gICAgdGhpcy5lbWl0dGVyLm9uKGNoYW5uZWwsIGhhbmRsZXIpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN1YnNjcmlwdGlvbnMuaGFzKGNoYW5uZWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihjaGFubmVsLCB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNoYW5uZWwpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZGVsZXRlKGNoYW5uZWwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVB1Ymxpc2hlcigpOiBhbnkge1xuICByZXR1cm4gbmV3IFB1Ymxpc2hlcihlbWl0dGVyKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlU3Vic2NyaWJlcigpOiBhbnkge1xuICByZXR1cm4gbmV3IFN1YnNjcmliZXIoZW1pdHRlcik7XG59XG5cbmNvbnN0IEV2ZW50RW1pdHRlclB1YlN1YiA9IHtcbiAgY3JlYXRlUHVibGlzaGVyLFxuICBjcmVhdGVTdWJzY3JpYmVyLFxufTtcblxuZXhwb3J0IHsgRXZlbnRFbWl0dGVyUHViU3ViIH07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/PubSub/PubSubAdapter.js b/lib/Adapters/PubSub/PubSubAdapter.js deleted file mode 100644 index 77e50d7e44..0000000000 --- a/lib/Adapters/PubSub/PubSubAdapter.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PubSubAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface PubSubAdapter - */ -class PubSubAdapter { - /** - * @returns {PubSubAdapter.Publisher} - */ - static createPublisher() {} - /** - * @returns {PubSubAdapter.Subscriber} - */ - - - static createSubscriber() {} - -} -/** - * @interface Publisher - * @memberof PubSubAdapter - */ - - -exports.PubSubAdapter = PubSubAdapter; -var _default = PubSubAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUHViU3ViQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJQdWJTdWJBZGFwdGVyIiwiY3JlYXRlUHVibGlzaGVyIiwiY3JlYXRlU3Vic2NyaWJlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBR0E7OztBQUdPLE1BQU1BLGFBQU4sQ0FBb0I7QUFDekI7OztBQUdBLFNBQU9DLGVBQVAsR0FBeUIsQ0FBRTtBQUMzQjs7Ozs7QUFHQSxTQUFPQyxnQkFBUCxHQUEwQixDQUFFOztBQVJIO0FBVzNCOzs7Ozs7O2VBOEJlRixhIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJzXG4gKi9cbi8qKlxuICogQGludGVyZmFjZSBQdWJTdWJBZGFwdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJTdWJBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQdWJTdWJBZGFwdGVyLlB1Ymxpc2hlcn1cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVQdWJsaXNoZXIoKSB7fVxuICAvKipcbiAgICogQHJldHVybnMge1B1YlN1YkFkYXB0ZXIuU3Vic2NyaWJlcn1cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVTdWJzY3JpYmVyKCkge31cbn1cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFB1Ymxpc2hlclxuICogQG1lbWJlcm9mIFB1YlN1YkFkYXB0ZXJcbiAqL1xuaW50ZXJmYWNlIFB1Ymxpc2hlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2hhbm5lbCB0aGUgY2hhbm5lbCBpbiB3aGljaCB0byBwdWJsaXNoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIHRoZSBtZXNzYWdlIHRvIHB1Ymxpc2hcbiAgICovXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkO1xufVxuXG4vKipcbiAqIEBpbnRlcmZhY2UgU3Vic2NyaWJlclxuICogQG1lbWJlcm9mIFB1YlN1YkFkYXB0ZXJcbiAqL1xuaW50ZXJmYWNlIFN1YnNjcmliZXIge1xuICAvKipcbiAgICogY2FsbGVkIHdoZW4gYSBuZXcgc3Vic2NyaXB0aW9uIHRoZSBjaGFubmVsIGlzIHJlcXVpcmVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsIHRoZSBjaGFubmVsIHRvIHN1YnNjcmliZVxuICAgKi9cbiAgc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGNhbGxlZCB3aGVuIHRoZSBzdWJzY3JpcHRpb24gZnJvbSB0aGUgY2hhbm5lbCBzaG91bGQgYmUgc3RvcHBlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2hhbm5lbFxuICAgKi9cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUHViU3ViQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/PubSub/RedisPubSub.js b/lib/Adapters/PubSub/RedisPubSub.js deleted file mode 100644 index cb4a03c10a..0000000000 --- a/lib/Adapters/PubSub/RedisPubSub.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.RedisPubSub = void 0; - -var _redis = _interopRequireDefault(require("redis")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function createPublisher({ - redisURL, - redisOptions = {} -}) { - redisOptions.no_ready_check = true; - return _redis.default.createClient(redisURL, redisOptions); -} - -function createSubscriber({ - redisURL, - redisOptions = {} -}) { - redisOptions.no_ready_check = true; - return _redis.default.createClient(redisURL, redisOptions); -} - -const RedisPubSub = { - createPublisher, - createSubscriber -}; -exports.RedisPubSub = RedisPubSub; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUmVkaXNQdWJTdWIuanMiXSwibmFtZXMiOlsiY3JlYXRlUHVibGlzaGVyIiwicmVkaXNVUkwiLCJyZWRpc09wdGlvbnMiLCJub19yZWFkeV9jaGVjayIsInJlZGlzIiwiY3JlYXRlQ2xpZW50IiwiY3JlYXRlU3Vic2NyaWJlciIsIlJlZGlzUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxTQUFTQSxlQUFULENBQXlCO0FBQUVDLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQXpCLEVBQStEO0FBQzdEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELFNBQVNJLGdCQUFULENBQTBCO0FBQUVMLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQTFCLEVBQWdFO0FBQzlEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELE1BQU1LLFdBQVcsR0FBRztBQUNsQlAsRUFBQUEsZUFEa0I7QUFFbEJNLEVBQUFBO0FBRmtCLENBQXBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5jb25zdCBSZWRpc1B1YlN1YiA9IHtcbiAgY3JlYXRlUHVibGlzaGVyLFxuICBjcmVhdGVTdWJzY3JpYmVyLFxufTtcblxuZXhwb3J0IHsgUmVkaXNQdWJTdWIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Push/PushAdapter.js b/lib/Adapters/Push/PushAdapter.js deleted file mode 100644 index 494c52bc1f..0000000000 --- a/lib/Adapters/Push/PushAdapter.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ -// Push Adapter -// -// Allows you to change the push notification mechanism. -// -// Adapter classes must implement the following functions: -// * getValidPushTypes() -// * send(devices, installations, pushStatus) -// -// Default is ParsePushAdapter, which uses GCM for -// android push and APNS for ios push. - -/** - * @module Adapters - */ - -/** - * @interface PushAdapter - */ -class PushAdapter { - /** - * @param {any} body - * @param {Parse.Installation[]} installations - * @param {any} pushStatus - * @returns {Promise} - */ - send(body, installations, pushStatus) {} - /** - * Get an array of valid push types. - * @returns {Array} An array of valid push types - */ - - - getValidPushTypes() { - return []; - } - -} - -exports.PushAdapter = PushAdapter; -var _default = PushAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIlB1c2hBZGFwdGVyIiwic2VuZCIsImJvZHkiLCJpbnN0YWxsYXRpb25zIiwicHVzaFN0YXR1cyIsImdldFZhbGlkUHVzaFR5cGVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7OztBQUdBOzs7QUFHTyxNQUFNQSxXQUFOLENBQWtCO0FBQ3ZCOzs7Ozs7QUFNQUMsRUFBQUEsSUFBSSxDQUFDQyxJQUFELEVBQVlDLGFBQVosRUFBa0NDLFVBQWxDLEVBQWdFLENBQUU7QUFFdEU7Ozs7OztBQUlBQyxFQUFBQSxpQkFBaUIsR0FBYTtBQUM1QixXQUFPLEVBQVA7QUFDRDs7QUFmc0I7OztlQWtCVkwsVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vLyBQdXNoIEFkYXB0ZXJcbi8vXG4vLyBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgcHVzaCBub3RpZmljYXRpb24gbWVjaGFuaXNtLlxuLy9cbi8vIEFkYXB0ZXIgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogZ2V0VmFsaWRQdXNoVHlwZXMoKVxuLy8gKiBzZW5kKGRldmljZXMsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMpXG4vL1xuLy8gRGVmYXVsdCBpcyBQYXJzZVB1c2hBZGFwdGVyLCB3aGljaCB1c2VzIEdDTSBmb3Jcbi8vIGFuZHJvaWQgcHVzaCBhbmQgQVBOUyBmb3IgaW9zIHB1c2guXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgUHVzaEFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFB1c2hBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSBib2R5XG4gICAqIEBwYXJhbSB7UGFyc2UuSW5zdGFsbGF0aW9uW119IGluc3RhbGxhdGlvbnNcbiAgICogQHBhcmFtIHthbnl9IHB1c2hTdGF0dXNcbiAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAqL1xuICBzZW5kKGJvZHk6IGFueSwgaW5zdGFsbGF0aW9uczogYW55W10sIHB1c2hTdGF0dXM6IGFueSk6ID9Qcm9taXNlPCo+IHt9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBhcnJheSBvZiB2YWxpZCBwdXNoIHR5cGVzLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IEFuIGFycmF5IG9mIHZhbGlkIHB1c2ggdHlwZXNcbiAgICovXG4gIGdldFZhbGlkUHVzaFR5cGVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoCollection.js b/lib/Adapters/Storage/Mongo/MongoCollection.js deleted file mode 100644 index 306cb2d098..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoCollection.js +++ /dev/null @@ -1,229 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const mongodb = require('mongodb'); - -const Collection = mongodb.Collection; - -class MongoCollection { - constructor(mongoCollection) { - this._mongoCollection = mongoCollection; - } // Does a find with "smart indexing". - // Currently this just means, if it needs a geoindex and there is - // none, then build the geoindex. - // This could be improved a lot but it's not clear if that's a good - // idea. Or even if this behavior is a good idea. - - - find(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - } = {}) { - // Support for Full Text Search - $text - if (keys && keys.$score) { - delete keys.$score; - keys.score = { - $meta: 'textScore' - }; - } - - return this._rawFind(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - }).catch(error => { - // Check for "no geoindex" error - if (error.code != 17007 && !error.message.match(/unable to find index for .geoNear/)) { - throw error; - } // Figure out what key needs an index - - - const key = error.message.match(/field=([A-Za-z_0-9]+) /)[1]; - - if (!key) { - throw error; - } - - var index = {}; - index[key] = '2d'; - return this._mongoCollection.createIndex(index) // Retry, but just once. - .then(() => this._rawFind(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - })); - }); - } - /** - * Collation to support case insensitive queries - */ - - - static caseInsensitiveCollation() { - return { - locale: 'en_US', - strength: 2 - }; - } - - _rawFind(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - } = {}) { - let findOperation = this._mongoCollection.find(query, { - skip, - limit, - sort, - readPreference, - hint - }); - - if (keys) { - findOperation = findOperation.project(keys); - } - - if (caseInsensitive) { - findOperation = findOperation.collation(MongoCollection.caseInsensitiveCollation()); - } - - if (maxTimeMS) { - findOperation = findOperation.maxTimeMS(maxTimeMS); - } - - return explain ? findOperation.explain(explain) : findOperation.toArray(); - } - - count(query, { - skip, - limit, - sort, - maxTimeMS, - readPreference, - hint - } = {}) { - // If query is empty, then use estimatedDocumentCount instead. - // This is due to countDocuments performing a scan, - // which greatly increases execution time when being run on large collections. - // See https://github.com/Automattic/mongoose/issues/6713 for more info regarding this problem. - if (typeof query !== 'object' || !Object.keys(query).length) { - return this._mongoCollection.estimatedDocumentCount({ - maxTimeMS - }); - } - - const countOperation = this._mongoCollection.countDocuments(query, { - skip, - limit, - sort, - maxTimeMS, - readPreference, - hint - }); - - return countOperation; - } - - distinct(field, query) { - return this._mongoCollection.distinct(field, query); - } - - aggregate(pipeline, { - maxTimeMS, - readPreference, - hint, - explain - } = {}) { - return this._mongoCollection.aggregate(pipeline, { - maxTimeMS, - readPreference, - hint, - explain - }).toArray(); - } - - insertOne(object, session) { - return this._mongoCollection.insertOne(object, { - session - }); - } // Atomically updates data in the database for a single (first) object that matched the query - // If there is nothing that matches the query - does insert - // Postgres Note: `INSERT ... ON CONFLICT UPDATE` that is available since 9.5. - - - upsertOne(query, update, session) { - return this._mongoCollection.updateOne(query, update, { - upsert: true, - session - }); - } - - updateOne(query, update) { - return this._mongoCollection.updateOne(query, update); - } - - updateMany(query, update, session) { - return this._mongoCollection.updateMany(query, update, { - session - }); - } - - deleteMany(query, session) { - return this._mongoCollection.deleteMany(query, { - session - }); - } - - _ensureSparseUniqueIndexInBackground(indexRequest) { - return new Promise((resolve, reject) => { - this._mongoCollection.createIndex(indexRequest, { - unique: true, - background: true, - sparse: true - }, error => { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); - } - - drop() { - return this._mongoCollection.drop(); - } - -} - -exports.default = MongoCollection; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb2RiIiwicmVxdWlyZSIsIkNvbGxlY3Rpb24iLCJNb25nb0NvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsIm1vbmdvQ29sbGVjdGlvbiIsIl9tb25nb0NvbGxlY3Rpb24iLCJmaW5kIiwicXVlcnkiLCJza2lwIiwibGltaXQiLCJzb3J0Iiwia2V5cyIsIm1heFRpbWVNUyIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCIkc2NvcmUiLCJzY29yZSIsIiRtZXRhIiwiX3Jhd0ZpbmQiLCJjYXRjaCIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJtYXRjaCIsImtleSIsImluZGV4IiwiY3JlYXRlSW5kZXgiLCJ0aGVuIiwiY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uIiwibG9jYWxlIiwic3RyZW5ndGgiLCJmaW5kT3BlcmF0aW9uIiwicHJvamVjdCIsImNvbGxhdGlvbiIsInRvQXJyYXkiLCJjb3VudCIsIk9iamVjdCIsImxlbmd0aCIsImVzdGltYXRlZERvY3VtZW50Q291bnQiLCJjb3VudE9wZXJhdGlvbiIsImNvdW50RG9jdW1lbnRzIiwiZGlzdGluY3QiLCJmaWVsZCIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwiaW5zZXJ0T25lIiwib2JqZWN0Iiwic2Vzc2lvbiIsInVwc2VydE9uZSIsInVwZGF0ZSIsInVwZGF0ZU9uZSIsInVwc2VydCIsInVwZGF0ZU1hbnkiLCJkZWxldGVNYW55IiwiX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kIiwiaW5kZXhSZXF1ZXN0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ1bmlxdWUiLCJiYWNrZ3JvdW5kIiwic3BhcnNlIiwiZHJvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLE9BQU8sR0FBR0Ms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TWtDIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IENvbGxlY3Rpb24gPSBtb25nb2RiLkNvbGxlY3Rpb247XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1vbmdvQ29sbGVjdGlvbiB7XG4gIF9tb25nb0NvbGxlY3Rpb246IENvbGxlY3Rpb247XG5cbiAgY29uc3RydWN0b3IobW9uZ29Db2xsZWN0aW9uOiBDb2xsZWN0aW9uKSB7XG4gICAgdGhpcy5fbW9uZ29Db2xsZWN0aW9uID0gbW9uZ29Db2xsZWN0aW9uO1xuICB9XG5cbiAgLy8gRG9lcyBhIGZpbmQgd2l0aCBcInNtYXJ0IGluZGV4aW5nXCIuXG4gIC8vIEN1cnJlbnRseSB0aGlzIGp1c3QgbWVhbnMsIGlmIGl0IG5lZWRzIGEgZ2VvaW5kZXggYW5kIHRoZXJlIGlzXG4gIC8vIG5vbmUsIHRoZW4gYnVpbGQgdGhlIGdlb2luZGV4LlxuICAvLyBUaGlzIGNvdWxkIGJlIGltcHJvdmVkIGEgbG90IGJ1dCBpdCdzIG5vdCBjbGVhciBpZiB0aGF0J3MgYSBnb29kXG4gIC8vIGlkZWEuIE9yIGV2ZW4gaWYgdGhpcyBiZWhhdmlvciBpcyBhIGdvb2QgaWRlYS5cbiAgZmluZChcbiAgICBxdWVyeSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgfSA9IHt9XG4gICkge1xuICAgIC8vIFN1cHBvcnQgZm9yIEZ1bGwgVGV4dCBTZWFyY2ggLSAkdGV4dFxuICAgIGlmIChrZXlzICYmIGtleXMuJHNjb3JlKSB7XG4gICAgICBkZWxldGUga2V5cy4kc2NvcmU7XG4gICAgICBrZXlzLnNjb3JlID0geyAkbWV0YTogJ3RleHRTY29yZScgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Jhd0ZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICBrZXlzLFxuICAgICAgbWF4VGltZU1TLFxuICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICBoaW50LFxuICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgZXhwbGFpbixcbiAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAvLyBDaGVjayBmb3IgXCJubyBnZW9pbmRleFwiIGVycm9yXG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yLmNvZGUgIT0gMTcwMDcgJiZcbiAgICAgICAgIWVycm9yLm1lc3NhZ2UubWF0Y2goL3VuYWJsZSB0byBmaW5kIGluZGV4IGZvciAuZ2VvTmVhci8pXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBGaWd1cmUgb3V0IHdoYXQga2V5IG5lZWRzIGFuIGluZGV4XG4gICAgICBjb25zdCBrZXkgPSBlcnJvci5tZXNzYWdlLm1hdGNoKC9maWVsZD0oW0EtWmEtel8wLTldKykgLylbMV07XG4gICAgICBpZiAoIWtleSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgdmFyIGluZGV4ID0ge307XG4gICAgICBpbmRleFtrZXldID0gJzJkJztcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvblxuICAgICAgICAgIC5jcmVhdGVJbmRleChpbmRleClcbiAgICAgICAgICAvLyBSZXRyeSwgYnV0IGp1c3Qgb25jZS5cbiAgICAgICAgICAudGhlbigoKSA9PlxuICAgICAgICAgICAgdGhpcy5fcmF3RmluZChxdWVyeSwge1xuICAgICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgICAgbWF4VGltZU1TLFxuICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICAgICAgICBleHBsYWluLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbGxhdGlvbiB0byBzdXBwb3J0IGNhc2UgaW5zZW5zaXRpdmUgcXVlcmllc1xuICAgKi9cbiAgc3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpIHtcbiAgICByZXR1cm4geyBsb2NhbGU6ICdlbl9VUycsIHN0cmVuZ3RoOiAyIH07XG4gIH1cblxuICBfcmF3RmluZChcbiAgICBxdWVyeSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgfSA9IHt9XG4gICkge1xuICAgIGxldCBmaW5kT3BlcmF0aW9uID0gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgIGhpbnQsXG4gICAgfSk7XG5cbiAgICBpZiAoa2V5cykge1xuICAgICAgZmluZE9wZXJhdGlvbiA9IGZpbmRPcGVyYXRpb24ucHJvamVjdChrZXlzKTtcbiAgICB9XG5cbiAgICBpZiAoY2FzZUluc2Vuc2l0aXZlKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5jb2xsYXRpb24oXG4gICAgICAgIE1vbmdvQ29sbGVjdGlvbi5jYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24oKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAobWF4VGltZU1TKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5tYXhUaW1lTVMobWF4VGltZU1TKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwbGFpbiA/IGZpbmRPcGVyYXRpb24uZXhwbGFpbihleHBsYWluKSA6IGZpbmRPcGVyYXRpb24udG9BcnJheSgpO1xuICB9XG5cbiAgY291bnQocXVlcnksIHsgc2tpcCwgbGltaXQsIHNvcnQsIG1heFRpbWVNUywgcmVhZFByZWZlcmVuY2UsIGhpbnQgfSA9IHt9KSB7XG4gICAgLy8gSWYgcXVlcnkgaXMgZW1wdHksIHRoZW4gdXNlIGVzdGltYXRlZERvY3VtZW50Q291bnQgaW5zdGVhZC5cbiAgICAvLyBUaGlzIGlzIGR1ZSB0byBjb3VudERvY3VtZW50cyBwZXJmb3JtaW5nIGEgc2NhbixcbiAgICAvLyB3aGljaCBncmVhdGx5IGluY3JlYXNlcyBleGVjdXRpb24gdGltZSB3aGVuIGJlaW5nIHJ1biBvbiBsYXJnZSBjb2xsZWN0aW9ucy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvbW9uZ29vc2UvaXNzdWVzLzY3MTMgZm9yIG1vcmUgaW5mbyByZWdhcmRpbmcgdGhpcyBwcm9ibGVtLlxuICAgIGlmICh0eXBlb2YgcXVlcnkgIT09ICdvYmplY3QnIHx8ICFPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmVzdGltYXRlZERvY3VtZW50Q291bnQoe1xuICAgICAgICBtYXhUaW1lTVMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudE9wZXJhdGlvbiA9IHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jb3VudERvY3VtZW50cyhxdWVyeSwge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgc29ydCxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICB9KTtcblxuICAgIHJldHVybiBjb3VudE9wZXJhdGlvbjtcbiAgfVxuXG4gIGRpc3RpbmN0KGZpZWxkLCBxdWVyeSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZGlzdGluY3QoZmllbGQsIHF1ZXJ5KTtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZShwaXBlbGluZSwgeyBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBleHBsYWluIH0gPSB7fSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb25cbiAgICAgIC5hZ2dyZWdhdGUocGlwZWxpbmUsIHsgbWF4VGltZU1TLCByZWFkUHJlZmVyZW5jZSwgaGludCwgZXhwbGFpbiB9KVxuICAgICAgLnRvQXJyYXkoKTtcbiAgfVxuXG4gIGluc2VydE9uZShvYmplY3QsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmluc2VydE9uZShvYmplY3QsIHsgc2Vzc2lvbiB9KTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgdXBkYXRlcyBkYXRhIGluIHRoZSBkYXRhYmFzZSBmb3IgYSBzaW5nbGUgKGZpcnN0KSBvYmplY3QgdGhhdCBtYXRjaGVkIHRoZSBxdWVyeVxuICAvLyBJZiB0aGVyZSBpcyBub3RoaW5nIHRoYXQgbWF0Y2hlcyB0aGUgcXVlcnkgLSBkb2VzIGluc2VydFxuICAvLyBQb3N0Z3JlcyBOb3RlOiBgSU5TRVJUIC4uLiBPTiBDT05GTElDVCBVUERBVEVgIHRoYXQgaXMgYXZhaWxhYmxlIHNpbmNlIDkuNS5cbiAgdXBzZXJ0T25lKHF1ZXJ5LCB1cGRhdGUsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlLCB7XG4gICAgICB1cHNlcnQ6IHRydWUsXG4gICAgICBzZXNzaW9uLFxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlT25lKHF1ZXJ5LCB1cGRhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlKTtcbiAgfVxuXG4gIHVwZGF0ZU1hbnkocXVlcnksIHVwZGF0ZSwgc2Vzc2lvbikge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24udXBkYXRlTWFueShxdWVyeSwgdXBkYXRlLCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBkZWxldGVNYW55KHF1ZXJ5LCBzZXNzaW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5kZWxldGVNYW55KHF1ZXJ5LCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhSZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChcbiAgICAgICAgaW5kZXhSZXF1ZXN0LFxuICAgICAgICB7IHVuaXF1ZTogdHJ1ZSwgYmFja2dyb3VuZDogdHJ1ZSwgc3BhcnNlOiB0cnVlIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBkcm9wKCkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZHJvcCgpO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js b/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js deleted file mode 100644 index 88e30fc139..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +++ /dev/null @@ -1,365 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function mongoFieldToParseSchemaField(type) { - if (type[0] === '*') { - return { - type: 'Pointer', - targetClass: type.slice(1) - }; - } - - if (type.startsWith('relation<')) { - return { - type: 'Relation', - targetClass: type.slice('relation<'.length, type.length - 1) - }; - } - - switch (type) { - case 'number': - return { - type: 'Number' - }; - - case 'string': - return { - type: 'String' - }; - - case 'boolean': - return { - type: 'Boolean' - }; - - case 'date': - return { - type: 'Date' - }; - - case 'map': - case 'object': - return { - type: 'Object' - }; - - case 'array': - return { - type: 'Array' - }; - - case 'geopoint': - return { - type: 'GeoPoint' - }; - - case 'file': - return { - type: 'File' - }; - - case 'bytes': - return { - type: 'Bytes' - }; - - case 'polygon': - return { - type: 'Polygon' - }; - } -} - -const nonFieldSchemaKeys = ['_id', '_metadata', '_client_permissions']; - -function mongoSchemaFieldsToParseSchemaFields(schema) { - var fieldNames = Object.keys(schema).filter(key => nonFieldSchemaKeys.indexOf(key) === -1); - var response = fieldNames.reduce((obj, fieldName) => { - obj[fieldName] = mongoFieldToParseSchemaField(schema[fieldName]); - - if (schema._metadata && schema._metadata.fields_options && schema._metadata.fields_options[fieldName]) { - obj[fieldName] = Object.assign({}, obj[fieldName], schema._metadata.fields_options[fieldName]); - } - - return obj; - }, {}); - response.ACL = { - type: 'ACL' - }; - response.createdAt = { - type: 'Date' - }; - response.updatedAt = { - type: 'Date' - }; - response.objectId = { - type: 'String' - }; - return response; -} - -const emptyCLPS = Object.freeze({ - find: {}, - count: {}, - get: {}, - create: {}, - update: {}, - delete: {}, - addField: {}, - protectedFields: {} -}); -const defaultCLPS = Object.freeze({ - find: { - '*': true - }, - count: { - '*': true - }, - get: { - '*': true - }, - create: { - '*': true - }, - update: { - '*': true - }, - delete: { - '*': true - }, - addField: { - '*': true - }, - protectedFields: { - '*': [] - } -}); - -function mongoSchemaToParseSchema(mongoSchema) { - let clps = defaultCLPS; - let indexes = {}; - - if (mongoSchema._metadata) { - if (mongoSchema._metadata.class_permissions) { - clps = _objectSpread(_objectSpread({}, emptyCLPS), mongoSchema._metadata.class_permissions); - } - - if (mongoSchema._metadata.indexes) { - indexes = _objectSpread({}, mongoSchema._metadata.indexes); - } - } - - return { - className: mongoSchema._id, - fields: mongoSchemaFieldsToParseSchemaFields(mongoSchema), - classLevelPermissions: clps, - indexes: indexes - }; -} - -function _mongoSchemaQueryFromNameQuery(name, query) { - const object = { - _id: name - }; - - if (query) { - Object.keys(query).forEach(key => { - object[key] = query[key]; - }); - } - - return object; -} // Returns a type suitable for inserting into mongo _SCHEMA collection. -// Does no validation. That is expected to be done in Parse Server. - - -function parseFieldTypeToMongoFieldType({ - type, - targetClass -}) { - switch (type) { - case 'Pointer': - return `*${targetClass}`; - - case 'Relation': - return `relation<${targetClass}>`; - - case 'Number': - return 'number'; - - case 'String': - return 'string'; - - case 'Boolean': - return 'boolean'; - - case 'Date': - return 'date'; - - case 'Object': - return 'object'; - - case 'Array': - return 'array'; - - case 'GeoPoint': - return 'geopoint'; - - case 'File': - return 'file'; - - case 'Bytes': - return 'bytes'; - - case 'Polygon': - return 'polygon'; - } -} - -class MongoSchemaCollection { - constructor(collection) { - this._collection = collection; - } - - _fetchAllSchemasFrom_SCHEMA() { - return this._collection._rawFind({}).then(schemas => schemas.map(mongoSchemaToParseSchema)); - } - - _fetchOneSchemaFrom_SCHEMA(name) { - return this._collection._rawFind(_mongoSchemaQueryFromNameQuery(name), { - limit: 1 - }).then(results => { - if (results.length === 1) { - return mongoSchemaToParseSchema(results[0]); - } else { - throw undefined; - } - }); - } // Atomically find and delete an object based on query. - - - findAndDeleteSchema(name) { - return this._collection._mongoCollection.findOneAndDelete(_mongoSchemaQueryFromNameQuery(name)); - } - - insertSchema(schema) { - return this._collection.insertOne(schema).then(result => mongoSchemaToParseSchema(result.ops[0])).catch(error => { - if (error.code === 11000) { - //Mongo's duplicate key error - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Class already exists.'); - } else { - throw error; - } - }); - } - - updateSchema(name, update) { - return this._collection.updateOne(_mongoSchemaQueryFromNameQuery(name), update); - } - - upsertSchema(name, query, update) { - return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update); - } // Add a field to the schema. If database does not support the field - // type (e.g. mongo doesn't support more than one GeoPoint in a class) reject with an "Incorrect Type" - // Parse error with a desciptive message. If the field already exists, this function must - // not modify the schema, and must reject with DUPLICATE_VALUE error. - // If this is called for a class that doesn't exist, this function must create that class. - // TODO: throw an error if an unsupported field type is passed. Deciding whether a type is supported - // should be the job of the adapter. Some adapters may not support GeoPoint at all. Others may - // Support additional types that Mongo doesn't, like Money, or something. - // TODO: don't spend an extra query on finding the schema if the type we are trying to add isn't a GeoPoint. - - - addFieldIfNotExists(className, fieldName, fieldType) { - return this._fetchOneSchemaFrom_SCHEMA(className).then(schema => { - // If a field with this name already exists, it will be handled elsewhere. - if (schema.fields[fieldName] != undefined) { - return; - } // The schema exists. Check for existing GeoPoints. - - - if (fieldType.type === 'GeoPoint') { - // Make sure there are not other geopoint fields - if (Object.keys(schema.fields).some(existingField => schema.fields[existingField].type === 'GeoPoint')) { - throw new _node.default.Error(_node.default.Error.INCORRECT_TYPE, 'MongoDB only supports one GeoPoint field in a class.'); - } - } - - return; - }, error => { - // If error is undefined, the schema doesn't exist, and we can create the schema with the field. - // If some other error, reject with it. - if (error === undefined) { - return; - } - - throw error; - }).then(() => { - const { - type, - targetClass - } = fieldType, - fieldOptions = _objectWithoutProperties(fieldType, ["type", "targetClass"]); // We use $exists and $set to avoid overwriting the field type if it - // already exists. (it could have added inbetween the last query and the update) - - - if (fieldOptions && Object.keys(fieldOptions).length > 0) { - return this.upsertSchema(className, { - [fieldName]: { - $exists: false - } - }, { - $set: { - [fieldName]: parseFieldTypeToMongoFieldType({ - type, - targetClass - }), - [`_metadata.fields_options.${fieldName}`]: fieldOptions - } - }); - } else { - return this.upsertSchema(className, { - [fieldName]: { - $exists: false - } - }, { - $set: { - [fieldName]: parseFieldTypeToMongoFieldType({ - type, - targetClass - }) - } - }); - } - }); - } - -} // Exported for testing reasons and because we haven't moved all mongo schema format -// related logic into the database adapter yet. - - -MongoSchemaCollection._TESTmongoSchemaToParseSchema = mongoSchemaToParseSchema; -MongoSchemaCollection.parseFieldTypeToMongoFieldType = parseFieldTypeToMongoFieldType; -var _default = MongoSchemaCollection; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU2NoZW1hQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkIiwidHlwZSIsInRhcmdldENsYXNzIiwic2xpY2UiLCJzdGFydHNXaXRoIiwibGVuZ3RoIiwibm9uRmllbGRTY2hlbWFLZXlzIiwibW9uZ29TY2hlbWFGaWVsZHNUb1BhcnNlU2NoZW1hRmllbGRzIiwic2NoZW1hIiwiZmllbGROYW1lcyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJpbmRleE9mIiwicmVzcG9uc2UiLCJyZWR1Y2UiLCJvYmoiLCJmaWVsZE5hbWUiLCJfbWV0YWRhdGEiLCJmaWVsZHNfb3B0aW9ucyIsImFzc2lnbiIsIkFDTCIsImNyZWF0ZWRBdCIsInVwZGF0ZWRBdCIsIm9iamVjdElkIiwiZW1wdHlDTFBTIiwiZnJlZXplIiwiZmluZCIsImNvdW50IiwiZ2V0IiwiY3JlYXRlIiwidXBkYXRlIiwiZGVsZXRlIiwiYWRkRmllbGQiLCJwcm90ZWN0ZWRGaWVsZHMiLCJkZWZhdWx0Q0xQUyIsIm1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSIsIm1vbmdvU2NoZW1hIiwiY2xwcyIsImluZGV4ZXMiLCJjbGFzc19wZXJtaXNzaW9ucyIsImNsYXNzTmFtZSIsIl9pZCIsImZpZWxkcyIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIl9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeSIsIm5hbWUiLCJxdWVyeSIsIm9iamVjdCIsImZvckVhY2giLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsImNvbGxlY3Rpb24iLCJfY29sbGVjdGlvbiIsIl9mZXRjaEFsbFNjaGVtYXNGcm9tX1NDSEVNQSIsIl9yYXdGaW5kIiwidGhlbiIsInNjaGVtYXMiLCJtYXAiLCJfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQSIsImxpbWl0IiwicmVzdWx0cyIsInVuZGVmaW5lZCIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJfbW9uZ29Db2xsZWN0aW9uIiwiZmluZE9uZUFuZERlbGV0ZSIsImluc2VydFNjaGVtYSIsImluc2VydE9uZSIsInJlc3VsdCIsIm9wcyIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiUGFyc2UiLCJFcnJvciIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZVNjaGVtYSIsInVwZGF0ZU9uZSIsInVwc2VydFNjaGVtYSIsInVwc2VydE9uZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJmaWVsZFR5cGUiLCJzb21lIiwiZXhpc3RpbmdGaWVsZCIsIklOQ09SUkVDVF9UWVBFIiwiZmllbGRPcHRpb25zIiwiJGV4aXN0cyIsIiRzZXQiLCJfVEVTVG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLFNBQVNBLDRCQUFULENBQXNDQyxJQUF0QyxFQUE0QztBQUMxQyxNQUFJQSxJQUFJLENBQUMsQ0FBRCxDQUFKLEtBQVksR0FBaEIsRUFBcUI7QUFDbkIsV0FBTztBQUNMQSxNQUFBQSxJQUFJLEVBQUUsU0FERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLENBQVg7QUFGUixLQUFQO0FBSUQ7O0FBQ0QsTUFBSUYsSUFBSSxDQUFDRyxVQUFMLENBQWdCLFdBQWhCLENBQUosRUFBa0M7QUFDaEMsV0FBTztBQUNMSCxNQUFBQSxJQUFJLEVBQUUsVUFERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLFlBQVlFLE1BQXZCLEVBQStCSixJQUFJLENBQUNJLE1BQUwsR0FBYyxDQUE3QztBQUZSLEtBQVA7QUFJRDs7QUFDRCxVQUFRSixJQUFSO0FBQ0UsU0FBSyxRQUFMO0FBQ0UsYUFBTztBQUFFQSxRQUFBQSxJQUFJLEVBQUU7QUFBUixPQUFQ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QUE4QixDQUFDO0FBQzFDbEQsY0FBQUEsSUFEMEM7QUFFMUNDLGNBQUFBO0FBRjBDLGFBQUQ7QUFEdkM7QUFEUixTQUhLLENBQVA7QUFZRDtBQUNGLEtBakVJLENBQVA7QUFrRUQ7O0FBN0l5QixDLENBZ0o1QjtBQUNBOzs7QUFDQWtELHFCQUFxQixDQUFDc0MsNkJBQXRCLEdBQXNEckQsd0JBQXREO0FBQ0FlLHFCQUFxQixDQUFDRCw4QkFBdEIsR0FBdURBLDhCQUF2RDtlQUVlQyxxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNb25nb0NvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5mdW5jdGlvbiBtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkKHR5cGUpIHtcbiAgaWYgKHR5cGVbMF0gPT09ICcqJykge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnUG9pbnRlcicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgxKSxcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3JlbGF0aW9uPCcpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgncmVsYXRpb248Jy5sZW5ndGgsIHR5cGUubGVuZ3RoIC0gMSksXG4gICAgfTtcbiAgfVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ051bWJlcicgfTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB7IHR5cGU6ICdCb29sZWFuJyB9O1xuICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0RhdGUnIH07XG4gICAgY2FzZSAnbWFwJzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICBjYXNlICdhcnJheSc6XG4gICAgICByZXR1cm4geyB0eXBlOiAnQXJyYXknIH07XG4gICAgY2FzZSAnZ2VvcG9pbnQnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0dlb1BvaW50JyB9O1xuICAgIGNhc2UgJ2ZpbGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0ZpbGUnIH07XG4gICAgY2FzZSAnYnl0ZXMnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0J5dGVzJyB9O1xuICAgIGNhc2UgJ3BvbHlnb24nOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1BvbHlnb24nIH07XG4gIH1cbn1cblxuY29uc3Qgbm9uRmllbGRTY2hlbWFLZXlzID0gWydfaWQnLCAnX21ldGFkYXRhJywgJ19jbGllbnRfcGVybWlzc2lvbnMnXTtcbmZ1bmN0aW9uIG1vbmdvU2NoZW1hRmllbGRzVG9QYXJzZVNjaGVtYUZpZWxkcyhzY2hlbWEpIHtcbiAgdmFyIGZpZWxkTmFtZXMgPSBPYmplY3Qua2V5cyhzY2hlbWEpLmZpbHRlcihcbiAgICAoa2V5KSA9PiBub25GaWVsZFNjaGVtYUtleXMuaW5kZXhPZihrZXkpID09PSAtMVxuICApO1xuICB2YXIgcmVzcG9uc2UgPSBmaWVsZE5hbWVzLnJlZHVjZSgob2JqLCBmaWVsZE5hbWUpID0+IHtcbiAgICBvYmpbZmllbGROYW1lXSA9IG1vbmdvRmllbGRUb1BhcnNlU2NoZW1hRmllbGQoc2NoZW1hW2ZpZWxkTmFtZV0pO1xuICAgIGlmIChcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICkge1xuICAgICAgb2JqW2ZpZWxkTmFtZV0gPSBPYmplY3QuYXNzaWduKFxuICAgICAgICB7fSxcbiAgICAgICAgb2JqW2ZpZWxkTmFtZV0sXG4gICAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xuICByZXNwb25zZS5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG4gIHJlc3BvbnNlLmNyZWF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLnVwZGF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLm9iamVjdElkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbmNvbnN0IGVtcHR5Q0xQUyA9IE9iamVjdC5mcmVlemUoe1xuICBmaW5kOiB7fSxcbiAgY291bnQ6IHt9LFxuICBnZXQ6IHt9LFxuICBjcmVhdGU6IHt9LFxuICB1cGRhdGU6IHt9LFxuICBkZWxldGU6IHt9LFxuICBhZGRGaWVsZDoge30sXG4gIHByb3RlY3RlZEZpZWxkczoge30sXG59KTtcblxuY29uc3QgZGVmYXVsdENMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDogeyAnKic6IHRydWUgfSxcbiAgY291bnQ6IHsgJyonOiB0cnVlIH0sXG4gIGdldDogeyAnKic6IHRydWUgfSxcbiAgY3JlYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICB1cGRhdGU6IHsgJyonOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyAnKic6IHRydWUgfSxcbiAgYWRkRmllbGQ6IHsgJyonOiB0cnVlIH0sXG4gIHByb3RlY3RlZEZpZWxkczogeyAnKic6IFtdIH0sXG59KTtcblxuZnVuY3Rpb24gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKG1vbmdvU2NoZW1hKSB7XG4gIGxldCBjbHBzID0gZGVmYXVsdENMUFM7XG4gIGxldCBpbmRleGVzID0ge307XG4gIGlmIChtb25nb1NjaGVtYS5fbWV0YWRhdGEpIHtcbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zKSB7XG4gICAgICBjbHBzID0geyAuLi5lbXB0eUNMUFMsIC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyB9O1xuICAgIH1cbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmluZGV4ZXMpIHtcbiAgICAgIGluZGV4ZXMgPSB7IC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5pbmRleGVzIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgY2xhc3NOYW1lOiBtb25nb1NjaGVtYS5faWQsXG4gICAgZmllbGRzOiBtb25nb1NjaGVtYUZpZWxkc1RvUGFyc2VTY2hlbWFGaWVsZHMobW9uZ29TY2hlbWEpLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogY2xwcyxcbiAgICBpbmRleGVzOiBpbmRleGVzLFxuICB9O1xufVxuXG5mdW5jdGlvbiBfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZTogc3RyaW5nLCBxdWVyeSkge1xuICBjb25zdCBvYmplY3QgPSB7IF9pZDogbmFtZSB9O1xuICBpZiAocXVlcnkpIHtcbiAgICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBvYmplY3Rba2V5XSA9IHF1ZXJ5W2tleV07XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxuLy8gUmV0dXJucyBhIHR5cGUgc3VpdGFibGUgZm9yIGluc2VydGluZyBpbnRvIG1vbmdvIF9TQ0hFTUEgY29sbGVjdGlvbi5cbi8vIERvZXMgbm8gdmFsaWRhdGlvbi4gVGhhdCBpcyBleHBlY3RlZCB0byBiZSBkb25lIGluIFBhcnNlIFNlcnZlci5cbmZ1bmN0aW9uIHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSh7IHR5cGUsIHRhcmdldENsYXNzIH0pIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICByZXR1cm4gYCoke3RhcmdldENsYXNzfWA7XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgcmV0dXJuIGByZWxhdGlvbjwke3RhcmdldENsYXNzfT5gO1xuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICByZXR1cm4gJ251bWJlcic7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiAnYm9vbGVhbic7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgICByZXR1cm4gJ2RhdGUnO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuICdhcnJheSc7XG4gICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgcmV0dXJuICdnZW9wb2ludCc7XG4gICAgY2FzZSAnRmlsZSc6XG4gICAgICByZXR1cm4gJ2ZpbGUnO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiAnYnl0ZXMnO1xuICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgcmV0dXJuICdwb2x5Z29uJztcbiAgfVxufVxuXG5jbGFzcyBNb25nb1NjaGVtYUNvbGxlY3Rpb24ge1xuICBfY29sbGVjdGlvbjogTW9uZ29Db2xsZWN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKGNvbGxlY3Rpb246IE1vbmdvQ29sbGVjdGlvbikge1xuICAgIHRoaXMuX2NvbGxlY3Rpb24gPSBjb2xsZWN0aW9uO1xuICB9XG5cbiAgX2ZldGNoQWxsU2NoZW1hc0Zyb21fU0NIRU1BKCkge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uXG4gICAgICAuX3Jhd0ZpbmQoe30pXG4gICAgICAudGhlbigoc2NoZW1hcykgPT4gc2NoZW1hcy5tYXAobW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKSk7XG4gIH1cblxuICBfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvblxuICAgICAgLl9yYXdGaW5kKF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSwgeyBsaW1pdDogMSB9KVxuICAgICAgLnRoZW4oKHJlc3VsdHMpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgcmV0dXJuIG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYShyZXN1bHRzWzBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gQXRvbWljYWxseSBmaW5kIGFuZCBkZWxldGUgYW4gb2JqZWN0IGJhc2VkIG9uIHF1ZXJ5LlxuICBmaW5kQW5kRGVsZXRlU2NoZW1hKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZmluZE9uZUFuZERlbGV0ZShcbiAgICAgIF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKVxuICAgICk7XG4gIH1cblxuICBpbnNlcnRTY2hlbWEoc2NoZW1hOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvblxuICAgICAgLmluc2VydE9uZShzY2hlbWEpXG4gICAgICAudGhlbigocmVzdWx0KSA9PiBtb25nb1NjaGVtYVRvUGFyc2VTY2hlbWEocmVzdWx0Lm9wc1swXSkpXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIC8vTW9uZ28ncyBkdXBsaWNhdGUga2V5IGVycm9yXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ0NsYXNzIGFscmVhZHkgZXhpc3RzLidcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZVNjaGVtYShuYW1lOiBzdHJpbmcsIHVwZGF0ZSkge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uLnVwZGF0ZU9uZShcbiAgICAgIF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSxcbiAgICAgIHVwZGF0ZVxuICAgICk7XG4gIH1cblxuICB1cHNlcnRTY2hlbWEobmFtZTogc3RyaW5nLCBxdWVyeTogc3RyaW5nLCB1cGRhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvbi51cHNlcnRPbmUoXG4gICAgICBfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZSwgcXVlcnkpLFxuICAgICAgdXBkYXRlXG4gICAgKTtcbiAgfVxuXG4gIC8vIEFkZCBhIGZpZWxkIHRvIHRoZSBzY2hlbWEuIElmIGRhdGFiYXNlIGRvZXMgbm90IHN1cHBvcnQgdGhlIGZpZWxkXG4gIC8vIHR5cGUgKGUuZy4gbW9uZ28gZG9lc24ndCBzdXBwb3J0IG1vcmUgdGhhbiBvbmUgR2VvUG9pbnQgaW4gYSBjbGFzcykgcmVqZWN0IHdpdGggYW4gXCJJbmNvcnJlY3QgVHlwZVwiXG4gIC8vIFBhcnNlIGVycm9yIHdpdGggYSBkZXNjaXB0aXZlIG1lc3NhZ2UuIElmIHRoZSBmaWVsZCBhbHJlYWR5IGV4aXN0cywgdGhpcyBmdW5jdGlvbiBtdXN0XG4gIC8vIG5vdCBtb2RpZnkgdGhlIHNjaGVtYSwgYW5kIG11c3QgcmVqZWN0IHdpdGggRFVQTElDQVRFX1ZBTFVFIGVycm9yLlxuICAvLyBJZiB0aGlzIGlzIGNhbGxlZCBmb3IgYSBjbGFzcyB0aGF0IGRvZXNuJ3QgZXhpc3QsIHRoaXMgZnVuY3Rpb24gbXVzdCBjcmVhdGUgdGhhdCBjbGFzcy5cblxuICAvLyBUT0RPOiB0aHJvdyBhbiBlcnJvciBpZiBhbiB1bnN1cHBvcnRlZCBmaWVsZCB0eXBlIGlzIHBhc3NlZC4gRGVjaWRpbmcgd2hldGhlciBhIHR5cGUgaXMgc3VwcG9ydGVkXG4gIC8vIHNob3VsZCBiZSB0aGUgam9iIG9mIHRoZSBhZGFwdGVyLiBTb21lIGFkYXB0ZXJzIG1heSBub3Qgc3VwcG9ydCBHZW9Qb2ludCBhdCBhbGwuIE90aGVycyBtYXlcbiAgLy8gU3VwcG9ydCBhZGRpdGlvbmFsIHR5cGVzIHRoYXQgTW9uZ28gZG9lc24ndCwgbGlrZSBNb25leSwgb3Igc29tZXRoaW5nLlxuXG4gIC8vIFRPRE86IGRvbid0IHNwZW5kIGFuIGV4dHJhIHF1ZXJ5IG9uIGZpbmRpbmcgdGhlIHNjaGVtYSBpZiB0aGUgdHlwZSB3ZSBhcmUgdHJ5aW5nIHRvIGFkZCBpc24ndCBhIEdlb1BvaW50LlxuICBhZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZywgZmllbGRUeXBlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShjbGFzc05hbWUpXG4gICAgICAudGhlbihcbiAgICAgICAgKHNjaGVtYSkgPT4ge1xuICAgICAgICAgIC8vIElmIGEgZmllbGQgd2l0aCB0aGlzIG5hbWUgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgaGFuZGxlZCBlbHNld2hlcmUuXG4gICAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBleGlzdHMuIENoZWNrIGZvciBleGlzdGluZyBHZW9Qb2ludHMuXG4gICAgICAgICAgaWYgKGZpZWxkVHlwZS50eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIG5vdCBvdGhlciBnZW9wb2ludCBmaWVsZHNcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuc29tZShcbiAgICAgICAgICAgICAgICAoZXhpc3RpbmdGaWVsZCkgPT5cbiAgICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNbZXhpc3RpbmdGaWVsZF0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICAgICdNb25nb0RCIG9ubHkgc3VwcG9ydHMgb25lIEdlb1BvaW50IGZpZWxkIGluIGEgY2xhc3MuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIC8vIElmIGVycm9yIGlzIHVuZGVmaW5lZCwgdGhlIHNjaGVtYSBkb2Vzbid0IGV4aXN0LCBhbmQgd2UgY2FuIGNyZWF0ZSB0aGUgc2NoZW1hIHdpdGggdGhlIGZpZWxkLlxuICAgICAgICAgIC8vIElmIHNvbWUgb3RoZXIgZXJyb3IsIHJlamVjdCB3aXRoIGl0LlxuICAgICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgdGFyZ2V0Q2xhc3MsIC4uLmZpZWxkT3B0aW9ucyB9ID0gZmllbGRUeXBlO1xuICAgICAgICAvLyBXZSB1c2UgJGV4aXN0cyBhbmQgJHNldCB0byBhdm9pZCBvdmVyd3JpdGluZyB0aGUgZmllbGQgdHlwZSBpZiBpdFxuICAgICAgICAvLyBhbHJlYWR5IGV4aXN0cy4gKGl0IGNvdWxkIGhhdmUgYWRkZWQgaW5iZXR3ZWVuIHRoZSBsYXN0IHF1ZXJ5IGFuZCB0aGUgdXBkYXRlKVxuICAgICAgICBpZiAoZmllbGRPcHRpb25zICYmIE9iamVjdC5rZXlzKGZpZWxkT3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVwc2VydFNjaGVtYShcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHsgW2ZpZWxkTmFtZV06IHsgJGV4aXN0czogZmFsc2UgfSB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAkc2V0OiB7XG4gICAgICAgICAgICAgICAgW2ZpZWxkTmFtZV06IHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgW2BfbWV0YWRhdGEuZmllbGRzX29wdGlvbnMuJHtmaWVsZE5hbWV9YF06IGZpZWxkT3B0aW9ucyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVwc2VydFNjaGVtYShcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHsgW2ZpZWxkTmFtZV06IHsgJGV4aXN0czogZmFsc2UgfSB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAkc2V0OiB7XG4gICAgICAgICAgICAgICAgW2ZpZWxkTmFtZV06IHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSh7XG4gICAgICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cblxuLy8gRXhwb3J0ZWQgZm9yIHRlc3RpbmcgcmVhc29ucyBhbmQgYmVjYXVzZSB3ZSBoYXZlbid0IG1vdmVkIGFsbCBtb25nbyBzY2hlbWEgZm9ybWF0XG4vLyByZWxhdGVkIGxvZ2ljIGludG8gdGhlIGRhdGFiYXNlIGFkYXB0ZXIgeWV0LlxuTW9uZ29TY2hlbWFDb2xsZWN0aW9uLl9URVNUbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hID0gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hO1xuTW9uZ29TY2hlbWFDb2xsZWN0aW9uLnBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZSA9IHBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZTtcblxuZXhwb3J0IGRlZmF1bHQgTW9uZ29TY2hlbWFDb2xsZWN0aW9uO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js b/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js deleted file mode 100644 index b407a600dc..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ /dev/null @@ -1,957 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.MongoStorageAdapter = void 0; - -var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); - -var _MongoSchemaCollection = _interopRequireDefault(require("./MongoSchemaCollection")); - -var _StorageAdapter = require("../StorageAdapter"); - -var _mongodbUrl = require("../../../vendor/mongodbUrl"); - -var _MongoTransform = require("./MongoTransform"); - -var _node = _interopRequireDefault(require("parse/node")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _defaults = _interopRequireDefault(require("../../../defaults")); - -var _logger = _interopRequireDefault(require("../../../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -// -disable-next -const mongodb = require('mongodb'); - -const MongoClient = mongodb.MongoClient; -const ReadPreference = mongodb.ReadPreference; -const MongoSchemaCollectionName = '_SCHEMA'; - -const storageAdapterAllCollections = mongoAdapter => { - return mongoAdapter.connect().then(() => mongoAdapter.database.collections()).then(collections => { - return collections.filter(collection => { - if (collection.namespace.match(/\.system\./)) { - return false; - } // TODO: If you have one app with a collection prefix that happens to be a prefix of another - // apps prefix, this will go very very badly. We should fix that somehow. - - - return collection.collectionName.indexOf(mongoAdapter._collectionPrefix) == 0; - }); - }); -}; - -const convertParseSchemaToMongoSchema = (_ref) => { - let schema = _extends({}, _ref); - - delete schema.fields._rperm; - delete schema.fields._wperm; - - if (schema.className === '_User') { - // Legacy mongo adapter knows about the difference between password and _hashed_password. - // Future database adapters will only know about _hashed_password. - // Note: Parse Server will bring back password with injectDefaultSchema, so we don't need - // to add _hashed_password back ever. - delete schema.fields._hashed_password; - } - - return schema; -}; // Returns { code, error } if invalid, or { result }, an object -// suitable for inserting into _SCHEMA collection, otherwise. - - -const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPermissions, indexes) => { - const mongoObject = { - _id: className, - objectId: 'string', - updatedAt: 'string', - createdAt: 'string', - _metadata: undefined - }; - - for (const fieldName in fields) { - const _fields$fieldName = fields[fieldName], - { - type, - targetClass - } = _fields$fieldName, - fieldOptions = _objectWithoutProperties(_fields$fieldName, ["type", "targetClass"]); - - mongoObject[fieldName] = _MongoSchemaCollection.default.parseFieldTypeToMongoFieldType({ - type, - targetClass - }); - - if (fieldOptions && Object.keys(fieldOptions).length > 0) { - mongoObject._metadata = mongoObject._metadata || {}; - mongoObject._metadata.fields_options = mongoObject._metadata.fields_options || {}; - mongoObject._metadata.fields_options[fieldName] = fieldOptions; - } - } - - if (typeof classLevelPermissions !== 'undefined') { - mongoObject._metadata = mongoObject._metadata || {}; - - if (!classLevelPermissions) { - delete mongoObject._metadata.class_permissions; - } else { - mongoObject._metadata.class_permissions = classLevelPermissions; - } - } - - if (indexes && typeof indexes === 'object' && Object.keys(indexes).length > 0) { - mongoObject._metadata = mongoObject._metadata || {}; - mongoObject._metadata.indexes = indexes; - } - - if (!mongoObject._metadata) { - // cleanup the unused _metadata - delete mongoObject._metadata; - } - - return mongoObject; -}; - -class MongoStorageAdapter { - // Private - // Public - constructor({ - uri = _defaults.default.DefaultMongoURI, - collectionPrefix = '', - mongoOptions = {} - }) { - this._uri = uri; - this._collectionPrefix = collectionPrefix; - this._mongoOptions = mongoOptions; - this._mongoOptions.useNewUrlParser = true; - this._mongoOptions.useUnifiedTopology = true; // MaxTimeMS is not a global MongoDB client option, it is applied per operation. - - this._maxTimeMS = mongoOptions.maxTimeMS; - this.canSortOnJoinTables = true; - delete mongoOptions.maxTimeMS; - } - - connect() { - if (this.connectionPromise) { - return this.connectionPromise; - } // parsing and re-formatting causes the auth value (if there) to get URI - // encoded - - - const encodedUri = (0, _mongodbUrl.format)((0, _mongodbUrl.parse)(this._uri)); - this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions).then(client => { - // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client - // Fortunately, we can get back the options and use them to select the proper DB. - // https://github.com/mongodb/node-mongodb-native/blob/2c35d76f08574225b8db02d7bef687123e6bb018/lib/mongo_client.js#L885 - const options = client.s.options; - const database = client.db(options.dbName); - - if (!database) { - delete this.connectionPromise; - return; - } - - database.on('error', () => { - delete this.connectionPromise; - }); - database.on('close', () => { - delete this.connectionPromise; - }); - this.client = client; - this.database = database; - }).catch(err => { - delete this.connectionPromise; - return Promise.reject(err); - }); - return this.connectionPromise; - } - - handleError(error) { - if (error && error.code === 13) { - // Unauthorized error - delete this.client; - delete this.database; - delete this.connectionPromise; - - _logger.default.error('Received unauthorized error', { - error: error - }); - } - - throw error; - } - - handleShutdown() { - if (!this.client) { - return Promise.resolve(); - } - - return this.client.close(false); - } - - _adaptiveCollection(name) { - return this.connect().then(() => this.database.collection(this._collectionPrefix + name)).then(rawCollection => new _MongoCollection.default(rawCollection)).catch(err => this.handleError(err)); - } - - _schemaCollection() { - return this.connect().then(() => this._adaptiveCollection(MongoSchemaCollectionName)).then(collection => new _MongoSchemaCollection.default(collection)); - } - - classExists(name) { - return this.connect().then(() => { - return this.database.listCollections({ - name: this._collectionPrefix + name - }).toArray(); - }).then(collections => { - return collections.length > 0; - }).catch(err => this.handleError(err)); - } - - setClassLevelPermissions(className, CLPs) { - return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { - $set: { - '_metadata.class_permissions': CLPs - } - })).catch(err => this.handleError(err)); - } - - setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields) { - if (submittedIndexes === undefined) { - return Promise.resolve(); - } - - if (Object.keys(existingIndexes).length === 0) { - existingIndexes = { - _id_: { - _id: 1 - } - }; - } - - const deletePromises = []; - const insertedIndexes = []; - Object.keys(submittedIndexes).forEach(name => { - const field = submittedIndexes[name]; - - if (existingIndexes[name] && field.__op !== 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); - } - - if (!existingIndexes[name] && field.__op === 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); - } - - if (field.__op === 'Delete') { - const promise = this.dropIndex(className, name); - deletePromises.push(promise); - delete existingIndexes[name]; - } else { - Object.keys(field).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(fields, key.indexOf('_p_') === 0 ? key.replace('_p_', '') : key)) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); - } - }); - existingIndexes[name] = field; - insertedIndexes.push({ - key: field, - name - }); - } - }); - let insertPromise = Promise.resolve(); - - if (insertedIndexes.length > 0) { - insertPromise = this.createIndexes(className, insertedIndexes); - } - - return Promise.all(deletePromises).then(() => insertPromise).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, { - $set: { - '_metadata.indexes': existingIndexes - } - })).catch(err => this.handleError(err)); - } - - setIndexesFromMongo(className) { - return this.getIndexes(className).then(indexes => { - indexes = indexes.reduce((obj, index) => { - if (index.key._fts) { - delete index.key._fts; - delete index.key._ftsx; - - for (const field in index.weights) { - index.key[field] = 'text'; - } - } - - obj[index.name] = index.key; - return obj; - }, {}); - return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { - $set: { - '_metadata.indexes': indexes - } - })); - }).catch(err => this.handleError(err)).catch(() => { - // Ignore if collection not found - return Promise.resolve(); - }); - } - - createClass(className, schema) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions, schema.indexes); - mongoObject._id = className; - return this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.insertSchema(mongoObject)).catch(err => this.handleError(err)); - } - - addFieldIfNotExists(className, fieldName, type) { - return this._schemaCollection().then(schemaCollection => schemaCollection.addFieldIfNotExists(className, fieldName, type)).then(() => this.createIndexesIfNeeded(className, fieldName, type)).catch(err => this.handleError(err)); - } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) - // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. - - - deleteClass(className) { - return this._adaptiveCollection(className).then(collection => collection.drop()).catch(error => { - // 'ns not found' means collection was already gone. Ignore deletion attempt. - if (error.message == 'ns not found') { - return; - } - - throw error; - }) // We've dropped the collection, now remove the _SCHEMA document - .then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.findAndDeleteSchema(className)).catch(err => this.handleError(err)); - } - - deleteAllClasses(fast) { - return storageAdapterAllCollections(this).then(collections => Promise.all(collections.map(collection => fast ? collection.deleteMany({}) : collection.drop()))); - } // Remove the column and all the data. For Relations, the _Join collection is handled - // specially, this function does not delete _Join columns. It should, however, indicate - // that the relation fields does not exist anymore. In mongo, this means removing it from - // the _SCHEMA collection. There should be no actual data in the collection under the same name - // as the relation column, so it's fine to attempt to delete it. If the fields listed to be - // deleted do not exist, this function should return successfully anyways. Checking for - // attempts to delete non-existent fields is the responsibility of Parse Server. - // Pointer field names are passed for legacy reasons: the original mongo - // format stored pointer field names differently in the database, and therefore - // needed to know the type of the field before it could delete it. Future database - // adapters should ignore the pointerFieldNames argument. All the field names are in - // fieldNames, they show up additionally in the pointerFieldNames database for use - // by the mongo adapter, which deals with the legacy mongo format. - // This function is not obligated to delete fields atomically. It is given the field - // names in a list so that databases that are capable of deleting fields atomically - // may do so. - // Returns a Promise. - - - deleteFields(className, schema, fieldNames) { - const mongoFormatNames = fieldNames.map(fieldName => { - if (schema.fields[fieldName].type === 'Pointer') { - return `_p_${fieldName}`; - } else { - return fieldName; - } - }); - const collectionUpdate = { - $unset: {} - }; - mongoFormatNames.forEach(name => { - collectionUpdate['$unset'][name] = null; - }); - const collectionFilter = { - $or: [] - }; - mongoFormatNames.forEach(name => { - collectionFilter['$or'].push({ - [name]: { - $exists: true - } - }); - }); - const schemaUpdate = { - $unset: {} - }; - fieldNames.forEach(name => { - schemaUpdate['$unset'][name] = null; - schemaUpdate['$unset'][`_metadata.fields_options.${name}`] = null; - }); - return this._adaptiveCollection(className).then(collection => collection.updateMany(collectionFilter, collectionUpdate)).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, schemaUpdate)).catch(err => this.handleError(err)); - } // Return a promise for all schemas known to this adapter, in Parse format. In case the - // schemas cannot be retrieved, returns a promise that rejects. Requirements for the - // rejection reason are TBD. - - - getAllClasses() { - return this._schemaCollection().then(schemasCollection => schemasCollection._fetchAllSchemasFrom_SCHEMA()).catch(err => this.handleError(err)); - } // Return a promise for the schema with the given name, in Parse format. If - // this adapter doesn't know about the schema, return a promise that rejects with - // undefined as the reason. - - - getClass(className) { - return this._schemaCollection().then(schemasCollection => schemasCollection._fetchOneSchemaFrom_SCHEMA(className)).catch(err => this.handleError(err)); - } // TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema, - // and should infer from the type. Or maybe does need the schema for validations. Or maybe needs - // the schema only for the legacy mongo format. We'll figure that out later. - - - createObject(className, schema, object, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoObject = (0, _MongoTransform.parseObjectToMongoObjectForCreate)(className, object, schema); - return this._adaptiveCollection(className).then(collection => collection.insertOne(mongoObject, transactionalSession)).catch(error => { - if (error.code === 11000) { - // Duplicate value - const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - err.underlyingError = error; - - if (error.message) { - const matches = error.message.match(/index:[\sa-zA-Z0-9_\-\.]+\$?([a-zA-Z_-]+)_1/); - - if (matches && Array.isArray(matches)) { - err.userInfo = { - duplicated_field: matches[1] - }; - } - } - - throw err; - } - - throw error; - }).catch(err => this.handleError(err)); - } // Remove all objects that match the given Parse Query. - // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. - // If there is some other error, reject with INTERNAL_SERVER_ERROR. - - - deleteObjectsByQuery(className, schema, query, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - return this._adaptiveCollection(className).then(collection => { - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return collection.deleteMany(mongoWhere, transactionalSession); - }).catch(err => this.handleError(err)).then(({ - result - }) => { - if (result.n === 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - return Promise.resolve(); - }, () => { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error'); - }); - } // Apply the update to all objects that match the given Parse Query. - - - updateObjectsByQuery(className, schema, query, update, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return this._adaptiveCollection(className).then(collection => collection.updateMany(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); - } // Atomically finds and updates an object based on query. - // Return value not currently well specified. - - - findOneAndUpdate(className, schema, query, update, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.findOneAndUpdate(mongoWhere, mongoUpdate, { - returnOriginal: false, - session: transactionalSession || undefined - })).then(result => (0, _MongoTransform.mongoObjectToParseObject)(className, result.value, schema)).catch(error => { - if (error.code === 11000) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - } - - throw error; - }).catch(err => this.handleError(err)); - } // Hopefully we can get rid of this. It's only used for config and hooks. - - - upsertOneObject(className, schema, query, update, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return this._adaptiveCollection(className).then(collection => collection.upsertOne(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); - } // Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }. - - - find(className, schema, query, { - skip, - limit, - sort, - keys, - readPreference, - hint, - caseInsensitive, - explain - }) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - - const mongoSort = _lodash.default.mapKeys(sort, (value, fieldName) => (0, _MongoTransform.transformKey)(className, fieldName, schema)); - - const mongoKeys = _lodash.default.reduce(keys, (memo, key) => { - if (key === 'ACL') { - memo['_rperm'] = 1; - memo['_wperm'] = 1; - } else { - memo[(0, _MongoTransform.transformKey)(className, key, schema)] = 1; - } - - return memo; - }, {}); // If we aren't requesting the `_id` field, we need to explicitly opt out - // of it. Doing so in parse-server is unusual, but it can allow us to - // optimize some queries with covering indexes. - - - if (keys && !mongoKeys._id) { - mongoKeys._id = 0; - } - - readPreference = this._parseReadPreference(readPreference); - return this.createTextIndexesIfNeeded(className, query, schema).then(() => this._adaptiveCollection(className)).then(collection => collection.find(mongoWhere, { - skip, - limit, - sort: mongoSort, - keys: mongoKeys, - maxTimeMS: this._maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - })).then(objects => { - if (explain) { - return objects; - } - - return objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema)); - }).catch(err => this.handleError(err)); - } - - ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { - schema = convertParseSchemaToMongoSchema(schema); - const indexCreationRequest = {}; - const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); - mongoFieldNames.forEach(fieldName => { - indexCreationRequest[fieldName] = options.indexType !== undefined ? options.indexType : 1; - }); - const defaultOptions = { - background: true, - sparse: true - }; - const indexNameOptions = indexName ? { - name: indexName - } : {}; - const ttlOptions = options.ttl !== undefined ? { - expireAfterSeconds: options.ttl - } : {}; - const caseInsensitiveOptions = caseInsensitive ? { - collation: _MongoCollection.default.caseInsensitiveCollation() - } : {}; - - const indexOptions = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultOptions), caseInsensitiveOptions), indexNameOptions), ttlOptions); - - return this._adaptiveCollection(className).then(collection => new Promise((resolve, reject) => collection._mongoCollection.createIndex(indexCreationRequest, indexOptions, error => error ? reject(error) : resolve()))).catch(err => this.handleError(err)); - } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't - // currently know which fields are nullable and which aren't, we ignore that criteria. - // As such, we shouldn't expose this function to users of parse until we have an out-of-band - // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, - // which is why we use sparse indexes. - - - ensureUniqueness(className, schema, fieldNames) { - schema = convertParseSchemaToMongoSchema(schema); - const indexCreationRequest = {}; - const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); - mongoFieldNames.forEach(fieldName => { - indexCreationRequest[fieldName] = 1; - }); - return this._adaptiveCollection(className).then(collection => collection._ensureSparseUniqueIndexInBackground(indexCreationRequest)).catch(error => { - if (error.code === 11000) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Tried to ensure field uniqueness for a class that already has duplicates.'); - } - - throw error; - }).catch(err => this.handleError(err)); - } // Used in tests - - - _rawFind(className, query) { - return this._adaptiveCollection(className).then(collection => collection.find(query, { - maxTimeMS: this._maxTimeMS - })).catch(err => this.handleError(err)); - } // Executes a count. - - - count(className, schema, query, readPreference, hint) { - schema = convertParseSchemaToMongoSchema(schema); - readPreference = this._parseReadPreference(readPreference); - return this._adaptiveCollection(className).then(collection => collection.count((0, _MongoTransform.transformWhere)(className, query, schema, true), { - maxTimeMS: this._maxTimeMS, - readPreference, - hint - })).catch(err => this.handleError(err)); - } - - distinct(className, schema, query, fieldName) { - schema = convertParseSchemaToMongoSchema(schema); - const isPointerField = schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; - const transformField = (0, _MongoTransform.transformKey)(className, fieldName, schema); - return this._adaptiveCollection(className).then(collection => collection.distinct(transformField, (0, _MongoTransform.transformWhere)(className, query, schema))).then(objects => { - objects = objects.filter(obj => obj != null); - return objects.map(object => { - if (isPointerField) { - return (0, _MongoTransform.transformPointerString)(schema, fieldName, object); - } - - return (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema); - }); - }).catch(err => this.handleError(err)); - } - - aggregate(className, schema, pipeline, readPreference, hint, explain) { - let isPointerField = false; - pipeline = pipeline.map(stage => { - if (stage.$group) { - stage.$group = this._parseAggregateGroupArgs(schema, stage.$group); - - if (stage.$group._id && typeof stage.$group._id === 'string' && stage.$group._id.indexOf('$_p_') >= 0) { - isPointerField = true; - } - } - - if (stage.$match) { - stage.$match = this._parseAggregateArgs(schema, stage.$match); - } - - if (stage.$project) { - stage.$project = this._parseAggregateProjectArgs(schema, stage.$project); - } - - if (stage.$geoNear && stage.$geoNear.query) { - stage.$geoNear.query = this._parseAggregateArgs(schema, stage.$geoNear.query); - } - - return stage; - }); - readPreference = this._parseReadPreference(readPreference); - return this._adaptiveCollection(className).then(collection => collection.aggregate(pipeline, { - readPreference, - maxTimeMS: this._maxTimeMS, - hint, - explain - })).then(results => { - results.forEach(result => { - if (Object.prototype.hasOwnProperty.call(result, '_id')) { - if (isPointerField && result._id) { - result._id = result._id.split('$')[1]; - } - - if (result._id == null || result._id == undefined || ['object', 'string'].includes(typeof result._id) && _lodash.default.isEmpty(result._id)) { - result._id = null; - } - - result.objectId = result._id; - delete result._id; - } - }); - return results; - }).then(objects => objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema))).catch(err => this.handleError(err)); - } // This function will recursively traverse the pipeline and convert any Pointer or Date columns. - // If we detect a pointer column we will rename the column being queried for to match the column - // in the database. We also modify the value to what we expect the value to be in the database - // as well. - // For dates, the driver expects a Date object, but we have a string coming in. So we'll convert - // the string to a Date so the driver can perform the necessary comparison. - // - // The goal of this method is to look for the "leaves" of the pipeline and determine if it needs - // to be converted. The pipeline can have a few different forms. For more details, see: - // https://docs.mongodb.com/manual/reference/operator/aggregation/ - // - // If the pipeline is an array, it means we are probably parsing an '$and' or '$or' operator. In - // that case we need to loop through all of it's children to find the columns being operated on. - // If the pipeline is an object, then we'll loop through the keys checking to see if the key name - // matches one of the schema columns. If it does match a column and the column is a Pointer or - // a Date, then we'll convert the value as described above. - // - // As much as I hate recursion...this seemed like a good fit for it. We're essentially traversing - // down a tree to find a "leaf node" and checking to see if it needs to be converted. - - - _parseAggregateArgs(schema, pipeline) { - if (pipeline === null) { - return null; - } else if (Array.isArray(pipeline)) { - return pipeline.map(value => this._parseAggregateArgs(schema, value)); - } else if (typeof pipeline === 'object') { - const returnValue = {}; - - for (const field in pipeline) { - if (schema.fields[field] && schema.fields[field].type === 'Pointer') { - if (typeof pipeline[field] === 'object') { - // Pass objects down to MongoDB...this is more than likely an $exists operator. - returnValue[`_p_${field}`] = pipeline[field]; - } else { - returnValue[`_p_${field}`] = `${schema.fields[field].targetClass}$${pipeline[field]}`; - } - } else if (schema.fields[field] && schema.fields[field].type === 'Date') { - returnValue[field] = this._convertToDate(pipeline[field]); - } else { - returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); - } - - if (field === 'objectId') { - returnValue['_id'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'createdAt') { - returnValue['_created_at'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'updatedAt') { - returnValue['_updated_at'] = returnValue[field]; - delete returnValue[field]; - } - } - - return returnValue; - } - - return pipeline; - } // This function is slightly different than the one above. Rather than trying to combine these - // two functions and making the code even harder to understand, I decided to split it up. The - // difference with this function is we are not transforming the values, only the keys of the - // pipeline. - - - _parseAggregateProjectArgs(schema, pipeline) { - const returnValue = {}; - - for (const field in pipeline) { - if (schema.fields[field] && schema.fields[field].type === 'Pointer') { - returnValue[`_p_${field}`] = pipeline[field]; - } else { - returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); - } - - if (field === 'objectId') { - returnValue['_id'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'createdAt') { - returnValue['_created_at'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'updatedAt') { - returnValue['_updated_at'] = returnValue[field]; - delete returnValue[field]; - } - } - - return returnValue; - } // This function is slightly different than the two above. MongoDB $group aggregate looks like: - // { $group: { _id: , : { : }, ... } } - // The could be a column name, prefixed with the '$' character. We'll look for - // these and check to see if it is a 'Pointer' or if it's one of createdAt, - // updatedAt or objectId and change it accordingly. - - - _parseAggregateGroupArgs(schema, pipeline) { - if (Array.isArray(pipeline)) { - return pipeline.map(value => this._parseAggregateGroupArgs(schema, value)); - } else if (typeof pipeline === 'object') { - const returnValue = {}; - - for (const field in pipeline) { - returnValue[field] = this._parseAggregateGroupArgs(schema, pipeline[field]); - } - - return returnValue; - } else if (typeof pipeline === 'string') { - const field = pipeline.substring(1); - - if (schema.fields[field] && schema.fields[field].type === 'Pointer') { - return `$_p_${field}`; - } else if (field == 'createdAt') { - return '$_created_at'; - } else if (field == 'updatedAt') { - return '$_updated_at'; - } - } - - return pipeline; - } // This function will attempt to convert the provided value to a Date object. Since this is part - // of an aggregation pipeline, the value can either be a string or it can be another object with - // an operator in it (like $gt, $lt, etc). Because of this I felt it was easier to make this a - // recursive method to traverse down to the "leaf node" which is going to be the string. - - - _convertToDate(value) { - if (typeof value === 'string') { - return new Date(value); - } - - const returnValue = {}; - - for (const field in value) { - returnValue[field] = this._convertToDate(value[field]); - } - - return returnValue; - } - - _parseReadPreference(readPreference) { - if (readPreference) { - readPreference = readPreference.toUpperCase(); - } - - switch (readPreference) { - case 'PRIMARY': - readPreference = ReadPreference.PRIMARY; - break; - - case 'PRIMARY_PREFERRED': - readPreference = ReadPreference.PRIMARY_PREFERRED; - break; - - case 'SECONDARY': - readPreference = ReadPreference.SECONDARY; - break; - - case 'SECONDARY_PREFERRED': - readPreference = ReadPreference.SECONDARY_PREFERRED; - break; - - case 'NEAREST': - readPreference = ReadPreference.NEAREST; - break; - - case undefined: - case null: - case '': - break; - - default: - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Not supported read preference.'); - } - - return readPreference; - } - - performInitialization() { - return Promise.resolve(); - } - - createIndex(className, index) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndex(index)).catch(err => this.handleError(err)); - } - - createIndexes(className, indexes) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndexes(indexes)).catch(err => this.handleError(err)); - } - - createIndexesIfNeeded(className, fieldName, type) { - if (type && type.type === 'Polygon') { - const index = { - [fieldName]: '2dsphere' - }; - return this.createIndex(className, index); - } - - return Promise.resolve(); - } - - createTextIndexesIfNeeded(className, query, schema) { - for (const fieldName in query) { - if (!query[fieldName] || !query[fieldName].$text) { - continue; - } - - const existingIndexes = schema.indexes; - - for (const key in existingIndexes) { - const index = existingIndexes[key]; - - if (Object.prototype.hasOwnProperty.call(index, fieldName)) { - return Promise.resolve(); - } - } - - const indexName = `${fieldName}_text`; - const textIndex = { - [indexName]: { - [fieldName]: 'text' - } - }; - return this.setIndexesWithSchemaFormat(className, textIndex, existingIndexes, schema.fields).catch(error => { - if (error.code === 85) { - // Index exist with different options - return this.setIndexesFromMongo(className); - } - - throw error; - }); - } - - return Promise.resolve(); - } - - getIndexes(className) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.indexes()).catch(err => this.handleError(err)); - } - - dropIndex(className, index) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndex(index)).catch(err => this.handleError(err)); - } - - dropAllIndexes(className) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndexes()).catch(err => this.handleError(err)); - } - - updateSchemaWithIndexes() { - return this.getAllClasses().then(classes => { - const promises = classes.map(schema => { - return this.setIndexesFromMongo(schema.className); - }); - return Promise.all(promises); - }).catch(err => this.handleError(err)); - } - - createTransactionalSession() { - const transactionalSection = this.client.startSession(); - transactionalSection.startTransaction(); - return Promise.resolve(transactionalSection); - } - - commitTransactionalSession(transactionalSection) { - return transactionalSection.commitTransaction().then(() => { - transactionalSection.endSession(); - }); - } - - abortTransactionalSession(transactionalSection) { - return transactionalSection.abortTransaction().then(() => { - transactionalSection.endSession(); - }); - } - -} - -exports.MongoStorageAdapter = MongoStorageAdapter; -var _default = MongoStorageAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsibW9uZ29kYiIsInJlcXVpcmUiLCJNb25nb0NsaWVudCIsIlJlYWRQcmVmZXJlbmNlIiwiTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSIsInN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnMiLCJtb25nb0FkYXB0ZXIiLCJjb25uZWN0IiwidGhlbiIsImRhdGFiYXNlIiwiY29sbGVjdGlvbnMiLCJmaWx0ZXIiLCJjb2xsZWN0aW9uIiwibmFtZXNwYWNlIiwibWF0Y2giLCJjb2xsZWN0aW9uTmFtZSIsImluZGV4T2YiLCJfY29sbGVjdGlvblByZWZpeCIsImNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEiLCJzY2hlbWEiLCJmaWVsZHMiLCJfcnBlcm0iLCJfd3Blcm0iLCJjbGFzc05hbWUiLCJfaGFzaGVkX3Bhc3N3b3JkIiwibW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lQW5kQ0xQIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsIm1vbmdvT2JqZWN0IiwiX2lkIiwib2JqZWN0SWQiLCJ1cGRhdGVkQXQiLCJjcmVhdGVkQXQiLCJfbWV0YWRhdGEiLCJ1bmRlZmluZWQiLCJmaWVsZE5hbWUiLCJ0eXBlIiwidGFyZ2V0Q2xhc3MiLCJmaWVsZE9wdGlvbnMiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiZmllbGRzX29wdGlvbnMiLCJjbGFzc19wZXJtaXNzaW9ucyIsIk1vbmdvU3RvcmFnZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInVyaSIsImRlZmF1bHRzIiwiRGVmYXVsdE1vbmdvVVJJIiwiY29sbGVjdGlvblByZWZpeCIsIm1vbmdvT3B0aW9ucyIsIl91cmkiLCJfbW9uZ29PcHRpb25zIiwidXNlTmV3VXJsUGFyc2VyIiwidXNlVW5pZmllZFRvcG9sb2d5IiwiX21heFRpbWVNUyIsIm1heFRpbWVNUyIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJjb25uZWN0aW9uUHJvbWlzZSIsImVuY29kZWRVcmkiLCJjbGllbnQiLCJvcHRpb25zIiwicyIsImRiIiwiZGJOYW1lIiwib24iLCJjYXRjaCIsImVyciIsIlByb21pc2UiLCJyZWplY3QiLCJoYW5kbGVFcnJvciIsImVycm9yIiwiY29kZSIsImxvZ2dlciIsImhhbmRsZVNodXRkb3duIiwicmVzb2x2ZSIsImNsb3NlIiwiX2FkYXB0aXZlQ29sbGVjdGlvbiIsIm5hbWUiLCJyYXdDb2xsZWN0aW9uIiwiTW9uZ29Db2xsZWN0aW9uIiwiX3NjaGVtYUNvbGxlY3Rpb24iLCJjbGFzc0V4aXN0cyIsImxpc3RDb2xsZWN0aW9ucyIsInRvQXJyYXkiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2NoZW1hQ29sbGVjdGlvbiIsInVwZGF0ZVNjaGVtYSIsIiRzZXQiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInN1Ym1pdHRlZEluZGV4ZXMiLCJleGlzdGluZ0luZGV4ZXMiLCJfaWRfIiwiZGVsZXRlUHJvbWlzZXMiLCJpbnNlcnRlZEluZGV4ZXMiLCJmb3JFYWNoIiwiZmllbGQiLCJfX29wIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJwcm9taXNlIiwiZHJvcEluZGV4IiwicHVzaCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlcGxhY2UiLCJpbnNlcnRQcm9taXNlIiwiY3JlYXRlSW5kZXhlcyIsImFsbCIsInNldEluZGV4ZXNGcm9tTW9uZ28iLCJnZXRJbmRleGVzIiwicmVkdWNlIiwib2JqIiwiaW5kZXgiLCJfZnRzIiwiX2Z0c3giLCJ3ZWlnaHRzIiwiY3JlYXRlQ2xhc3MiLCJpbnNlcnRTY2hlbWEiLCJhZGRGaWVsZElmTm90RXhpc3RzIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZGVsZXRlQ2xhc3MiLCJkcm9wIiwibWVzc2FnZSIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJkZWxldGVBbGxDbGFzc2VzIiwiZmFzdCIsIm1hcCIsImRlbGV0ZU1hbnkiLCJkZWxldGVGaWVsZHMiLCJmaWVsZE5hbWVzIiwibW9uZ29Gb3JtYXROYW1lcyIsImNvbGxlY3Rpb25VcGRhdGUiLCIkdW5zZXQiLCJjb2xsZWN0aW9uRmlsdGVyIiwiJG9yIiwiJGV4aXN0cyIsInNjaGVtYVVwZGF0ZSIsInVwZGF0ZU1hbnkiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hc0NvbGxlY3Rpb24iLCJfZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEiLCJnZXRDbGFzcyIsIl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BIiwiY3JlYXRlT2JqZWN0Iiwib2JqZWN0IiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJpbnNlcnRPbmUiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1bmRlcmx5aW5nRXJyb3IiLCJtYXRjaGVzIiwiQXJyYXkiLCJpc0FycmF5IiwidXNlckluZm8iLCJkdXBsaWNhdGVkX2ZpZWxkIiwiZGVsZXRlT2JqZWN0c0J5UXVlcnkiLCJxdWVyeSIsIm1vbmdvV2hlcmUiLCJyZXN1bHQiLCJuIiwiT0JKRUNUX05PVF9GT1VORCIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsInVwZGF0ZU9iamVjdHNCeVF1ZXJ5IiwidXBkYXRlIiwibW9uZ29VcGRhdGUiLCJmaW5kT25lQW5kVXBkYXRlIiwiX21vbmdvQ29sbGVjdGlvbiIsInJldHVybk9yaWdpbmFsIiwic2Vzc2lvbiIsInZhbHVlIiwidXBzZXJ0T25lT2JqZWN0IiwidXBzZXJ0T25lIiwiZmluZCIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJyZWFkUHJlZmVyZW5jZSIsImhpbnQiLCJjYXNlSW5zZW5zaXRpdmUiLCJleHBsYWluIiwibW9uZ29Tb3J0IiwiXyIsIm1hcEtleXMiLCJtb25nb0tleXMiLCJtZW1vIiwiX3BhcnNlUmVhZFByZWZlcmVuY2UiLCJjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkIiwib2JqZWN0cyIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwiaW5kZXhDcmVhdGlvblJlcXVlc3QiLCJtb25nb0ZpZWxkTmFtZXMiLCJpbmRleFR5cGUiLCJkZWZhdWx0T3B0aW9ucyIsImJhY2tncm91bmQiLCJzcGFyc2UiLCJpbmRleE5hbWVPcHRpb25zIiwidHRsT3B0aW9ucyIsInR0bCIsImV4cGlyZUFmdGVyU2Vjb25kcyIsImNhc2VJbnNlbnNpdGl2ZU9wdGlvbnMiLCJjb2xsYXRpb24iLCJjYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24iLCJpbmRleE9wdGlvbnMiLCJjcmVhdGVJbmRleCIsImVuc3VyZVVuaXF1ZW5lc3MiLCJfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQiLCJfcmF3RmluZCIsImNvdW50IiwiZGlzdGluY3QiLCJpc1BvaW50ZXJGaWVsZCIsInRyYW5zZm9ybUZpZWxkIiwiYWdncmVnYXRlIiwicGlwZWxpbmUiLCJzdGFnZSIsIiRncm91cCIsIl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyIsIiRtYXRjaCIsIl9wYXJzZUFnZ3JlZ2F0ZUFyZ3MiLCIkcHJvamVjdCIsIl9wYXJzZUFnZ3JlZ2F0ZVByb2plY3RBcmdzIiwiJGdlb05lYXIiLCJyZXN1bHRzIiwic3BsaXQiLCJpbmNsdWRlcyIsImlzRW1wdHkiLCJyZXR1cm5WYWx1ZSIsIl9jb252ZXJ0VG9EYXRlIiwic3Vic3RyaW5nIiwiRGF0ZSIsInRvVXBwZXJDYXNlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCIkdGV4dCIsInRleHRJbmRleCIsImRyb3BBbGxJbmRleGVzIiwiZHJvcEluZGV4ZXMiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsImNsYXNzZXMiLCJwcm9taXNlcyIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwidHJhbnNhY3Rpb25hbFNlY3Rpb24iLCJzdGFydFNlc3Npb24iLCJzdGFydFRyYW5zYWN0aW9uIiwiY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbiIsImVuZFNlc3Npb24iLCJhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOztBQUNBOztBQU9BOztBQUlBOztBQVNBOztBQUVBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7QUFDQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxTQUFELENBQXZCOztBQUNBLE1BQU1DLFdBQVcsR0FBR0YsT0FBTyxDQUFDRSxXQUE1QjtBQUNBLE1BQU1DLGNBQWMsR0FBR0gsT0FBTyxDQUFDRyxjQUEvQjtBQUVBLE1BQU1DLHlCQUF5QixHQUFHLFNBQWxDOztBQUVBLE1BQU1DLDRCQUE0QixHQUFHQyxZQUFZLElBQUk7QUFDbkQsU0FBT0EsWUFBWSxDQUNoQkMsT0FESSxHQUVKQyxJQUZJLENBRUMsTUFBTUYsWUFBWSxDQUFDRyxRQUFiLENBQXNCQyxXQUF0QixFQUZQLEVBR0pGLElBSEksQ0FHQ0UsV0FBVyxJQUFJO0FBQ25CLFdBQU9BLFdBQVcsQ0FBQ0MsTUFBWixDQUFtQkMsVUFBVSxJQUFJO0FBQ3RDLFVBQUlBLFVBQVUsQ0FBQ0MsU0FBWCxDQUFxQkMsS0FBckIsQ0FBMkIsWUFBM0IsQ0FBSixFQUE4QztBQUM1QyxlQUFPLEtBQVA7QUFDRCxPQUhxQyxDQUl0QztBQUNBOzs7QUFDQSxhQUNFRixVQUFVLENBQUNHLGNBQVgsQ0FBMEJDLE9BQTFCLENBQWtDVixZQUFZLENBQUNXLGlCQUEvQyxLQUFxRSxDQUR2RTtBQUdELEtBVE0sQ0FBUDtBQVVELEdBZEksQ0FBUDtBQWVELENBaEJEOztBQWtCQSxNQUFNQywrQkFBK0IsR0FBRyxVQUFtQjtBQUFBLE1BQWJDLE1BQWE7O0FBQ3pELFNBQU9BLE1B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QUFnQjhLLG9CQUFoQixDQUFQO0FBQ0Q7O0FBRURHLEVBQUFBLDBCQUEwQixDQUFDSCxvQkFBRCxFQUEyQztBQUNuRSxXQUFPQSxvQkFBb0IsQ0FBQ0ksaUJBQXJCLEdBQXlDdlAsSUFBekMsQ0FBOEMsTUFBTTtBQUN6RG1QLE1BQUFBLG9CQUFvQixDQUFDSyxVQUFyQjtBQUNELEtBRk0sQ0FBUDtBQUdEOztBQUVEQyxFQUFBQSx5QkFBeUIsQ0FBQ04sb0JBQUQsRUFBMkM7QUFDbEUsV0FBT0Esb0JBQW9CLENBQUNPLGdCQUFyQixHQUF3QzFQLElBQXhDLENBQTZDLE1BQU07QUFDeERtUCxNQUFBQSxvQkFBb0IsQ0FBQ0ssVUFBckI7QUFDRCxLQUZNLENBQVA7QUFHRDs7QUEzaUN3RDs7O2VBOGlDNUNsTixtQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgTW9uZ29Db2xsZWN0aW9uIGZyb20gJy4vTW9uZ29Db2xsZWN0aW9uJztcbmltcG9ydCBNb25nb1NjaGVtYUNvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb1NjaGVtYUNvbGxlY3Rpb24nO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7XG4gIFNjaGVtYVR5cGUsXG4gIFF1ZXJ5VHlwZSxcbiAgU3RvcmFnZUNsYXNzLFxuICBRdWVyeU9wdGlvbnMsXG59IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB7XG4gIHBhcnNlIGFzIHBhcnNlVXJsLFxuICBmb3JtYXQgYXMgZm9ybWF0VXJsLFxufSBmcm9tICcuLi8uLi8uLi92ZW5kb3IvbW9uZ29kYlVybCc7XG5pbXBvcnQge1xuICBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUsXG4gIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCxcbiAgdHJhbnNmb3JtS2V5LFxuICB0cmFuc2Zvcm1XaGVyZSxcbiAgdHJhbnNmb3JtVXBkYXRlLFxuICB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nLFxufSBmcm9tICcuL01vbmdvVHJhbnNmb3JtJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uLy4uL2RlZmF1bHRzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcblxuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5jb25zdCBtb25nb2RiID0gcmVxdWlyZSgnbW9uZ29kYicpO1xuY29uc3QgTW9uZ29DbGllbnQgPSBtb25nb2RiLk1vbmdvQ2xpZW50O1xuY29uc3QgUmVhZFByZWZlcmVuY2UgPSBtb25nb2RiLlJlYWRQcmVmZXJlbmNlO1xuXG5jb25zdCBNb25nb1NjaGVtYUNvbGxlY3Rpb25OYW1lID0gJ19TQ0hFTUEnO1xuXG5jb25zdCBzdG9yYWdlQWRhcHRlckFsbENvbGxlY3Rpb25zID0gbW9uZ29BZGFwdGVyID0+IHtcbiAgcmV0dXJuIG1vbmdvQWRhcHRlclxuICAgIC5jb25uZWN0KClcbiAgICAudGhlbigoKSA9PiBtb25nb0FkYXB0ZXIuZGF0YWJhc2UuY29sbGVjdGlvbnMoKSlcbiAgICAudGhlbihjb2xsZWN0aW9ucyA9PiB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbnMuZmlsdGVyKGNvbGxlY3Rpb24gPT4ge1xuICAgICAgICBpZiAoY29sbGVjdGlvbi5uYW1lc3BhY2UubWF0Y2goL1xcLnN5c3RlbVxcLi8pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IElmIHlvdSBoYXZlIG9uZSBhcHAgd2l0aCBhIGNvbGxlY3Rpb24gcHJlZml4IHRoYXQgaGFwcGVucyB0byBiZSBhIHByZWZpeCBvZiBhbm90aGVyXG4gICAgICAgIC8vIGFwcHMgcHJlZml4LCB0aGlzIHdpbGwgZ28gdmVyeSB2ZXJ5IGJhZGx5LiBXZSBzaG91bGQgZml4IHRoYXQgc29tZWhvdy5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBjb2xsZWN0aW9uLmNvbGxlY3Rpb25OYW1lLmluZGV4T2YobW9uZ29BZGFwdGVyLl9jb2xsZWN0aW9uUHJlZml4KSA9PSAwXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbn07XG5cbmNvbnN0IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEgPSAoeyAuLi5zY2hlbWEgfSkgPT4ge1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fcnBlcm07XG4gIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl93cGVybTtcblxuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIC8vIExlZ2FjeSBtb25nbyBhZGFwdGVyIGtub3dzIGFib3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gcGFzc3dvcmQgYW5kIF9oYXNoZWRfcGFzc3dvcmQuXG4gICAgLy8gRnV0dXJlIGRhdGFiYXNlIGFkYXB0ZXJzIHdpbGwgb25seSBrbm93IGFib3V0IF9oYXNoZWRfcGFzc3dvcmQuXG4gICAgLy8gTm90ZTogUGFyc2UgU2VydmVyIHdpbGwgYnJpbmcgYmFjayBwYXNzd29yZCB3aXRoIGluamVjdERlZmF1bHRTY2hlbWEsIHNvIHdlIGRvbid0IG5lZWRcbiAgICAvLyB0byBhZGQgX2hhc2hlZF9wYXNzd29yZCBiYWNrIGV2ZXIuXG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG4vLyBSZXR1cm5zIHsgY29kZSwgZXJyb3IgfSBpZiBpbnZhbGlkLCBvciB7IHJlc3VsdCB9LCBhbiBvYmplY3Rcbi8vIHN1aXRhYmxlIGZvciBpbnNlcnRpbmcgaW50byBfU0NIRU1BIGNvbGxlY3Rpb24sIG90aGVyd2lzZS5cbmNvbnN0IG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZUFuZENMUCA9IChcbiAgZmllbGRzLFxuICBjbGFzc05hbWUsXG4gIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgaW5kZXhlc1xuKSA9PiB7XG4gIGNvbnN0IG1vbmdvT2JqZWN0ID0ge1xuICAgIF9pZDogY2xhc3NOYW1lLFxuICAgIG9iamVjdElkOiAnc3RyaW5nJyxcbiAgICB1cGRhdGVkQXQ6ICdzdHJpbmcnLFxuICAgIGNyZWF0ZWRBdDogJ3N0cmluZycsXG4gICAgX21ldGFkYXRhOiB1bmRlZmluZWQsXG4gIH07XG5cbiAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gZmllbGRzKSB7XG4gICAgY29uc3QgeyB0eXBlLCB0YXJnZXRDbGFzcywgLi4uZmllbGRPcHRpb25zIH0gPSBmaWVsZHNbZmllbGROYW1lXTtcbiAgICBtb25nb09iamVjdFtcbiAgICAgIGZpZWxkTmFtZVxuICAgIF0gPSBNb25nb1NjaGVtYUNvbGxlY3Rpb24ucGFyc2VGaWVsZFR5cGVUb01vbmdvRmllbGRUeXBlKHtcbiAgICAgIHR5cGUsXG4gICAgICB0YXJnZXRDbGFzcyxcbiAgICB9KTtcbiAgICBpZiAoZmllbGRPcHRpb25zICYmIE9iamVjdC5rZXlzKGZpZWxkT3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhID0gbW9uZ29PYmplY3QuX21ldGFkYXRhIHx8IHt9O1xuICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhLmZpZWxkc19vcHRpb25zID1cbiAgICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhLmZpZWxkc19vcHRpb25zIHx8IHt9O1xuICAgICAgbW9uZ29PYmplY3QuX21ldGFkYXRhLmZpZWxkc19vcHRpb25zW2ZpZWxkTmFtZV0gPSBmaWVsZE9wdGlvbnM7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiBjbGFzc0xldmVsUGVybWlzc2lvbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgbW9uZ29PYmplY3QuX21ldGFkYXRhID0gbW9uZ29PYmplY3QuX21ldGFkYXRhIHx8IHt9O1xuICAgIGlmICghY2xhc3NMZXZlbFBlcm1pc3Npb25zKSB7XG4gICAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnMgPSBjbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgIGluZGV4ZXMgJiZcbiAgICB0eXBlb2YgaW5kZXhlcyA9PT0gJ29iamVjdCcgJiZcbiAgICBPYmplY3Qua2V5cyhpbmRleGVzKS5sZW5ndGggPiAwXG4gICkge1xuICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSA9IG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSB8fCB7fTtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuaW5kZXhlcyA9IGluZGV4ZXM7XG4gIH1cblxuICBpZiAoIW1vbmdvT2JqZWN0Ll9tZXRhZGF0YSkge1xuICAgIC8vIGNsZWFudXAgdGhlIHVudXNlZCBfbWV0YWRhdGFcbiAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhO1xuICB9XG5cbiAgcmV0dXJuIG1vbmdvT2JqZWN0O1xufTtcblxuZXhwb3J0IGNsYXNzIE1vbmdvU3RvcmFnZUFkYXB0ZXIgaW1wbGVtZW50cyBTdG9yYWdlQWRhcHRlciB7XG4gIC8vIFByaXZhdGVcbiAgX3VyaTogc3RyaW5nO1xuICBfY29sbGVjdGlvblByZWZpeDogc3RyaW5nO1xuICBfbW9uZ29PcHRpb25zOiBPYmplY3Q7XG4gIC8vIFB1YmxpY1xuICBjb25uZWN0aW9uUHJvbWlzZTogP1Byb21pc2U8YW55PjtcbiAgZGF0YWJhc2U6IGFueTtcbiAgY2xpZW50OiBNb25nb0NsaWVudDtcbiAgX21heFRpbWVNUzogP251bWJlcjtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgdXJpID0gZGVmYXVsdHMuRGVmYXVsdE1vbmdvVVJJLFxuICAgIGNvbGxlY3Rpb25QcmVmaXggPSAnJyxcbiAgICBtb25nb09wdGlvbnMgPSB7fSxcbiAgfTogYW55KSB7XG4gICAgdGhpcy5fdXJpID0gdXJpO1xuICAgIHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggPSBjb2xsZWN0aW9uUHJlZml4O1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucyA9IG1vbmdvT3B0aW9ucztcbiAgICB0aGlzLl9tb25nb09wdGlvbnMudXNlTmV3VXJsUGFyc2VyID0gdHJ1ZTtcbiAgICB0aGlzLl9tb25nb09wdGlvbnMudXNlVW5pZmllZFRvcG9sb2d5ID0gdHJ1ZTtcblxuICAgIC8vIE1heFRpbWVNUyBpcyBub3QgYSBnbG9iYWwgTW9uZ29EQiBjbGllbnQgb3B0aW9uLCBpdCBpcyBhcHBsaWVkIHBlciBvcGVyYXRpb24uXG4gICAgdGhpcy5fbWF4VGltZU1TID0gbW9uZ29PcHRpb25zLm1heFRpbWVNUztcbiAgICB0aGlzLmNhblNvcnRPbkpvaW5UYWJsZXMgPSB0cnVlO1xuICAgIGRlbGV0ZSBtb25nb09wdGlvbnMubWF4VGltZU1TO1xuICB9XG5cbiAgY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5jb25uZWN0aW9uUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgfVxuXG4gICAgLy8gcGFyc2luZyBhbmQgcmUtZm9ybWF0dGluZyBjYXVzZXMgdGhlIGF1dGggdmFsdWUgKGlmIHRoZXJlKSB0byBnZXQgVVJJXG4gICAgLy8gZW5jb2RlZFxuICAgIGNvbnN0IGVuY29kZWRVcmkgPSBmb3JtYXRVcmwocGFyc2VVcmwodGhpcy5fdXJpKSk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlID0gTW9uZ29DbGllbnQuY29ubmVjdChlbmNvZGVkVXJpLCB0aGlzLl9tb25nb09wdGlvbnMpXG4gICAgICAudGhlbihjbGllbnQgPT4ge1xuICAgICAgICAvLyBTdGFydGluZyBtb25nb0RCIDMuMCwgdGhlIE1vbmdvQ2xpZW50LmNvbm5lY3QgZG9uJ3QgcmV0dXJuIGEgREIgYW55bW9yZSBidXQgYSBjbGllbnRcbiAgICAgICAgLy8gRm9ydHVuYXRlbHksIHdlIGNhbiBnZXQgYmFjayB0aGUgb3B0aW9ucyBhbmQgdXNlIHRoZW0gdG8gc2VsZWN0IHRoZSBwcm9wZXIgREIuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb25nb2RiL25vZGUtbW9uZ29kYi1uYXRpdmUvYmxvYi8yYzM1ZDc2ZjA4NTc0MjI1YjhkYjAyZDdiZWY2ODcxMjNlNmJiMDE4L2xpYi9tb25nb19jbGllbnQuanMjTDg4NVxuICAgICAgICBjb25zdCBvcHRpb25zID0gY2xpZW50LnMub3B0aW9ucztcbiAgICAgICAgY29uc3QgZGF0YWJhc2UgPSBjbGllbnQuZGIob3B0aW9ucy5kYk5hbWUpO1xuICAgICAgICBpZiAoIWRhdGFiYXNlKSB7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGRhdGFiYXNlLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGFiYXNlLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgICAgICB0aGlzLmRhdGFiYXNlID0gZGF0YWJhc2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gIH1cblxuICBoYW5kbGVFcnJvcjxUPihlcnJvcjogPyhFcnJvciB8IFBhcnNlLkVycm9yKSk6IFByb21pc2U8VD4ge1xuICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSAxMykge1xuICAgICAgLy8gVW5hdXRob3JpemVkIGVycm9yXG4gICAgICBkZWxldGUgdGhpcy5jbGllbnQ7XG4gICAgICBkZWxldGUgdGhpcy5kYXRhYmFzZTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgbG9nZ2VyLmVycm9yKCdSZWNlaXZlZCB1bmF1dGhvcml6ZWQgZXJyb3InLCB7IGVycm9yOiBlcnJvciB9KTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICBfYWRhcHRpdmVDb2xsZWN0aW9uKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3QoKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5jb2xsZWN0aW9uKHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggKyBuYW1lKSlcbiAgICAgIC50aGVuKHJhd0NvbGxlY3Rpb24gPT4gbmV3IE1vbmdvQ29sbGVjdGlvbihyYXdDb2xsZWN0aW9uKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIF9zY2hlbWFDb2xsZWN0aW9uKCk6IFByb21pc2U8TW9uZ29TY2hlbWFDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSkpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IG5ldyBNb25nb1NjaGVtYUNvbGxlY3Rpb24oY29sbGVjdGlvbikpO1xuICB9XG5cbiAgY2xhc3NFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFiYXNlXG4gICAgICAgICAgLmxpc3RDb2xsZWN0aW9ucyh7IG5hbWU6IHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggKyBuYW1lIH0pXG4gICAgICAgICAgLnRvQXJyYXkoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihjb2xsZWN0aW9ucyA9PiB7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9ucy5sZW5ndGggPiAwO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHNldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWU6IHN0cmluZywgQ0xQczogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHtcbiAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnMnOiBDTFBzIH0sXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzdWJtaXR0ZWRJbmRleGVzOiBhbnksXG4gICAgZXhpc3RpbmdJbmRleGVzOiBhbnkgPSB7fSxcbiAgICBmaWVsZHM6IGFueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoc3VibWl0dGVkSW5kZXhlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhleGlzdGluZ0luZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdJbmRleGVzID0geyBfaWRfOiB7IF9pZDogMSB9IH07XG4gICAgfVxuICAgIGNvbnN0IGRlbGV0ZVByb21pc2VzID0gW107XG4gICAgY29uc3QgaW5zZXJ0ZWRJbmRleGVzID0gW107XG4gICAgT2JqZWN0LmtleXMoc3VibWl0dGVkSW5kZXhlcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gc3VibWl0dGVkSW5kZXhlc1tuYW1lXTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgIGBJbmRleCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5kcm9wSW5kZXgoY2xhc3NOYW1lLCBuYW1lKTtcbiAgICAgICAgZGVsZXRlUHJvbWlzZXMucHVzaChwcm9taXNlKTtcbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nSW5kZXhlc1tuYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5rZXlzKGZpZWxkKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgICAgZmllbGRzLFxuICAgICAgICAgICAgICBrZXkuaW5kZXhPZignX3BfJykgPT09IDAgPyBrZXkucmVwbGFjZSgnX3BfJywgJycpIDoga2V5XG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgICAgIGBGaWVsZCAke2tleX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBhZGQgaW5kZXguYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBleGlzdGluZ0luZGV4ZXNbbmFtZV0gPSBmaWVsZDtcbiAgICAgICAgaW5zZXJ0ZWRJbmRleGVzLnB1c2goe1xuICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbGV0IGluc2VydFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBpZiAoaW5zZXJ0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGluc2VydFByb21pc2UgPSB0aGlzLmNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lLCBpbnNlcnRlZEluZGV4ZXMpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVsZXRlUHJvbWlzZXMpXG4gICAgICAudGhlbigoKSA9PiBpbnNlcnRQcm9taXNlKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHtcbiAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuaW5kZXhlcyc6IGV4aXN0aW5nSW5kZXhlcyB9LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmdldEluZGV4ZXMoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oaW5kZXhlcyA9PiB7XG4gICAgICAgIGluZGV4ZXMgPSBpbmRleGVzLnJlZHVjZSgob2JqLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGlmIChpbmRleC5rZXkuX2Z0cykge1xuICAgICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzO1xuICAgICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzeDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gaW5kZXgud2VpZ2h0cykge1xuICAgICAgICAgICAgICBpbmRleC5rZXlbZmllbGRdID0gJ3RleHQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBvYmpbaW5kZXgubmFtZV0gPSBpbmRleC5rZXk7XG4gICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSwge30pO1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICAgJHNldDogeyAnX21ldGFkYXRhLmluZGV4ZXMnOiBpbmRleGVzIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIElnbm9yZSBpZiBjb2xsZWN0aW9uIG5vdCBmb3VuZFxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAoXG4gICAgICBzY2hlbWEuZmllbGRzLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgIHNjaGVtYS5pbmRleGVzXG4gICAgKTtcbiAgICBtb25nb09iamVjdC5faWQgPSBjbGFzc05hbWU7XG4gICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBzY2hlbWEuaW5kZXhlcyxcbiAgICAgIHt9LFxuICAgICAgc2NoZW1hLmZpZWxkc1xuICAgIClcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5pbnNlcnRTY2hlbWEobW9uZ29PYmplY3QpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgYWRkRmllbGRJZk5vdEV4aXN0cyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICB0eXBlOiBhbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmNyZWF0ZUluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWUsIGZpZWxkTmFtZSwgdHlwZSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBEcm9wcyBhIGNvbGxlY3Rpb24uIFJlc29sdmVzIHdpdGggdHJ1ZSBpZiBpdCB3YXMgYSBQYXJzZSBTY2hlbWEgKGVnLiBfVXNlciwgQ3VzdG9tLCBldGMuKVxuICAvLyBhbmQgcmVzb2x2ZXMgd2l0aCBmYWxzZSBpZiBpdCB3YXNuJ3QgKGVnLiBhIGpvaW4gdGFibGUpLiBSZWplY3RzIGlmIGRlbGV0aW9uIHdhcyBpbXBvc3NpYmxlLlxuICBkZWxldGVDbGFzcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uZHJvcCgpKVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIC8vICducyBub3QgZm91bmQnIG1lYW5zIGNvbGxlY3Rpb24gd2FzIGFscmVhZHkgZ29uZS4gSWdub3JlIGRlbGV0aW9uIGF0dGVtcHQuXG4gICAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgPT0gJ25zIG5vdCBmb3VuZCcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pXG4gICAgICAgIC8vIFdlJ3ZlIGRyb3BwZWQgdGhlIGNvbGxlY3Rpb24sIG5vdyByZW1vdmUgdGhlIF9TQ0hFTUEgZG9jdW1lbnRcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgICAgc2NoZW1hQ29sbGVjdGlvbi5maW5kQW5kRGVsZXRlU2NoZW1hKGNsYXNzTmFtZSlcbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICApO1xuICB9XG5cbiAgZGVsZXRlQWxsQ2xhc3NlcyhmYXN0OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnModGhpcykudGhlbihjb2xsZWN0aW9ucyA9PlxuICAgICAgUHJvbWlzZS5hbGwoXG4gICAgICAgIGNvbGxlY3Rpb25zLm1hcChjb2xsZWN0aW9uID0+XG4gICAgICAgICAgZmFzdCA/IGNvbGxlY3Rpb24uZGVsZXRlTWFueSh7fSkgOiBjb2xsZWN0aW9uLmRyb3AoKVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlbW92ZSB0aGUgY29sdW1uIGFuZCBhbGwgdGhlIGRhdGEuIEZvciBSZWxhdGlvbnMsIHRoZSBfSm9pbiBjb2xsZWN0aW9uIGlzIGhhbmRsZWRcbiAgLy8gc3BlY2lhbGx5LCB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGRlbGV0ZSBfSm9pbiBjb2x1bW5zLiBJdCBzaG91bGQsIGhvd2V2ZXIsIGluZGljYXRlXG4gIC8vIHRoYXQgdGhlIHJlbGF0aW9uIGZpZWxkcyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLiBJbiBtb25nbywgdGhpcyBtZWFucyByZW1vdmluZyBpdCBmcm9tXG4gIC8vIHRoZSBfU0NIRU1BIGNvbGxlY3Rpb24uICBUaGVyZSBzaG91bGQgYmUgbm8gYWN0dWFsIGRhdGEgaW4gdGhlIGNvbGxlY3Rpb24gdW5kZXIgdGhlIHNhbWUgbmFtZVxuICAvLyBhcyB0aGUgcmVsYXRpb24gY29sdW1uLCBzbyBpdCdzIGZpbmUgdG8gYXR0ZW1wdCB0byBkZWxldGUgaXQuIElmIHRoZSBmaWVsZHMgbGlzdGVkIHRvIGJlXG4gIC8vIGRlbGV0ZWQgZG8gbm90IGV4aXN0LCB0aGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gc3VjY2Vzc2Z1bGx5IGFueXdheXMuIENoZWNraW5nIGZvclxuICAvLyBhdHRlbXB0cyB0byBkZWxldGUgbm9uLWV4aXN0ZW50IGZpZWxkcyBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgUGFyc2UgU2VydmVyLlxuXG4gIC8vIFBvaW50ZXIgZmllbGQgbmFtZXMgYXJlIHBhc3NlZCBmb3IgbGVnYWN5IHJlYXNvbnM6IHRoZSBvcmlnaW5hbCBtb25nb1xuICAvLyBmb3JtYXQgc3RvcmVkIHBvaW50ZXIgZmllbGQgbmFtZXMgZGlmZmVyZW50bHkgaW4gdGhlIGRhdGFiYXNlLCBhbmQgdGhlcmVmb3JlXG4gIC8vIG5lZWRlZCB0byBrbm93IHRoZSB0eXBlIG9mIHRoZSBmaWVsZCBiZWZvcmUgaXQgY291bGQgZGVsZXRlIGl0LiBGdXR1cmUgZGF0YWJhc2VcbiAgLy8gYWRhcHRlcnMgc2hvdWxkIGlnbm9yZSB0aGUgcG9pbnRlckZpZWxkTmFtZXMgYXJndW1lbnQuIEFsbCB0aGUgZmllbGQgbmFtZXMgYXJlIGluXG4gIC8vIGZpZWxkTmFtZXMsIHRoZXkgc2hvdyB1cCBhZGRpdGlvbmFsbHkgaW4gdGhlIHBvaW50ZXJGaWVsZE5hbWVzIGRhdGFiYXNlIGZvciB1c2VcbiAgLy8gYnkgdGhlIG1vbmdvIGFkYXB0ZXIsIHdoaWNoIGRlYWxzIHdpdGggdGhlIGxlZ2FjeSBtb25nbyBmb3JtYXQuXG5cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBub3Qgb2JsaWdhdGVkIHRvIGRlbGV0ZSBmaWVsZHMgYXRvbWljYWxseS4gSXQgaXMgZ2l2ZW4gdGhlIGZpZWxkXG4gIC8vIG5hbWVzIGluIGEgbGlzdCBzbyB0aGF0IGRhdGFiYXNlcyB0aGF0IGFyZSBjYXBhYmxlIG9mIGRlbGV0aW5nIGZpZWxkcyBhdG9taWNhbGx5XG4gIC8vIG1heSBkbyBzby5cblxuICAvLyBSZXR1cm5zIGEgUHJvbWlzZS5cbiAgZGVsZXRlRmllbGRzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIGZpZWxkTmFtZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgbW9uZ29Gb3JtYXROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYF9wXyR7ZmllbGROYW1lfWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmllbGROYW1lO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IGNvbGxlY3Rpb25VcGRhdGUgPSB7ICR1bnNldDoge30gfTtcbiAgICBtb25nb0Zvcm1hdE5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb2xsZWN0aW9uVXBkYXRlWyckdW5zZXQnXVtuYW1lXSA9IG51bGw7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjb2xsZWN0aW9uRmlsdGVyID0geyAkb3I6IFtdIH07XG4gICAgbW9uZ29Gb3JtYXROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29sbGVjdGlvbkZpbHRlclsnJG9yJ10ucHVzaCh7IFtuYW1lXTogeyAkZXhpc3RzOiB0cnVlIH0gfSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBzY2hlbWFVcGRhdGUgPSB7ICR1bnNldDoge30gfTtcbiAgICBmaWVsZE5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBzY2hlbWFVcGRhdGVbJyR1bnNldCddW25hbWVdID0gbnVsbDtcbiAgICAgIHNjaGVtYVVwZGF0ZVsnJHVuc2V0J11bYF9tZXRhZGF0YS5maWVsZHNfb3B0aW9ucy4ke25hbWV9YF0gPSBudWxsO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24udXBkYXRlTWFueShjb2xsZWN0aW9uRmlsdGVyLCBjb2xsZWN0aW9uVXBkYXRlKVxuICAgICAgKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHNjaGVtYVVwZGF0ZSlcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBnZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8U3RvcmFnZUNsYXNzW10+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEoKVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gUmV0dXJuIGEgcHJvbWlzZSBmb3IgdGhlIHNjaGVtYSB3aXRoIHRoZSBnaXZlbiBuYW1lLCBpbiBQYXJzZSBmb3JtYXQuIElmXG4gIC8vIHRoaXMgYWRhcHRlciBkb2Vzbid0IGtub3cgYWJvdXQgdGhlIHNjaGVtYSwgcmV0dXJuIGEgcHJvbWlzZSB0aGF0IHJlamVjdHMgd2l0aFxuICAvLyB1bmRlZmluZWQgYXMgdGhlIHJlYXNvbi5cbiAgZ2V0Q2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPFN0b3JhZ2VDbGFzcz4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYXNDb2xsZWN0aW9uID0+XG4gICAgICAgIHNjaGVtYXNDb2xsZWN0aW9uLl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BKGNsYXNzTmFtZSlcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFRPRE86IEFzIHlldCBub3QgcGFydGljdWxhcmx5IHdlbGwgc3BlY2lmaWVkLiBDcmVhdGVzIGFuIG9iamVjdC4gTWF5YmUgc2hvdWxkbid0IGV2ZW4gbmVlZCB0aGUgc2NoZW1hLFxuICAvLyBhbmQgc2hvdWxkIGluZmVyIGZyb20gdGhlIHR5cGUuIE9yIG1heWJlIGRvZXMgbmVlZCB0aGUgc2NoZW1hIGZvciB2YWxpZGF0aW9ucy4gT3IgbWF5YmUgbmVlZHNcbiAgLy8gdGhlIHNjaGVtYSBvbmx5IGZvciB0aGUgbGVnYWN5IG1vbmdvIGZvcm1hdC4gV2UnbGwgZmlndXJlIHRoYXQgb3V0IGxhdGVyLlxuICBjcmVhdGVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIG9iamVjdDogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb09iamVjdCA9IHBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZShcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIG9iamVjdCxcbiAgICAgIHNjaGVtYVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uaW5zZXJ0T25lKG1vbmdvT2JqZWN0LCB0cmFuc2FjdGlvbmFsU2Vzc2lvbilcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIC8vIER1cGxpY2F0ZSB2YWx1ZVxuICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgZXJyLnVuZGVybHlpbmdFcnJvciA9IGVycm9yO1xuICAgICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gZXJyb3IubWVzc2FnZS5tYXRjaChcbiAgICAgICAgICAgICAgL2luZGV4OltcXHNhLXpBLVowLTlfXFwtXFwuXStcXCQ/KFthLXpBLVpfLV0rKV8xL1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzICYmIEFycmF5LmlzQXJyYXkobWF0Y2hlcykpIHtcbiAgICAgICAgICAgICAgZXJyLnVzZXJJbmZvID0geyBkdXBsaWNhdGVkX2ZpZWxkOiBtYXRjaGVzWzFdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBSZW1vdmUgYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIC8vIElmIG5vIG9iamVjdHMgbWF0Y2gsIHJlamVjdCB3aXRoIE9CSkVDVF9OT1RfRk9VTkQuIElmIG9iamVjdHMgYXJlIGZvdW5kIGFuZCBkZWxldGVkLCByZXNvbHZlIHdpdGggdW5kZWZpbmVkLlxuICAvLyBJZiB0aGVyZSBpcyBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBJTlRFUk5BTF9TRVJWRVJfRVJST1IuXG4gIGRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4ge1xuICAgICAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uZGVsZXRlTWFueShtb25nb1doZXJlLCB0cmFuc2FjdGlvbmFsU2Vzc2lvbik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpXG4gICAgICAudGhlbihcbiAgICAgICAgKHsgcmVzdWx0IH0pID0+IHtcbiAgICAgICAgICBpZiAocmVzdWx0Lm4gPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAgICAgJ09iamVjdCBub3QgZm91bmQuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICAgJ0RhdGFiYXNlIGFkYXB0ZXIgZXJyb3InXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgfVxuXG4gIC8vIEFwcGx5IHRoZSB1cGRhdGUgdG8gYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIHVwZGF0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1VwZGF0ZSA9IHRyYW5zZm9ybVVwZGF0ZShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi51cGRhdGVNYW55KG1vbmdvV2hlcmUsIG1vbmdvVXBkYXRlLCB0cmFuc2FjdGlvbmFsU2Vzc2lvbilcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgZmluZHMgYW5kIHVwZGF0ZXMgYW4gb2JqZWN0IGJhc2VkIG9uIHF1ZXJ5LlxuICAvLyBSZXR1cm4gdmFsdWUgbm90IGN1cnJlbnRseSB3ZWxsIHNwZWNpZmllZC5cbiAgZmluZE9uZUFuZFVwZGF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29VcGRhdGUgPSB0cmFuc2Zvcm1VcGRhdGUoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5maW5kT25lQW5kVXBkYXRlKG1vbmdvV2hlcmUsIG1vbmdvVXBkYXRlLCB7XG4gICAgICAgICAgcmV0dXJuT3JpZ2luYWw6IGZhbHNlLFxuICAgICAgICAgIHNlc3Npb246IHRyYW5zYWN0aW9uYWxTZXNzaW9uIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCByZXN1bHQudmFsdWUsIHNjaGVtYSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMTEwMDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIEhvcGVmdWxseSB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGlzLiBJdCdzIG9ubHkgdXNlZCBmb3IgY29uZmlnIGFuZCBob29rcy5cbiAgdXBzZXJ0T25lT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1VwZGF0ZSA9IHRyYW5zZm9ybVVwZGF0ZShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi51cHNlcnRPbmUobW9uZ29XaGVyZSwgbW9uZ29VcGRhdGUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBmaW5kLiBBY2NlcHRzOiBjbGFzc05hbWUsIHF1ZXJ5IGluIFBhcnNlIGZvcm1hdCwgYW5kIHsgc2tpcCwgbGltaXQsIHNvcnQgfS5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgfTogUXVlcnlPcHRpb25zXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvU29ydCA9IF8ubWFwS2V5cyhzb3J0LCAodmFsdWUsIGZpZWxkTmFtZSkgPT5cbiAgICAgIHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKVxuICAgICk7XG4gICAgY29uc3QgbW9uZ29LZXlzID0gXy5yZWR1Y2UoXG4gICAgICBrZXlzLFxuICAgICAgKG1lbW8sIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSAnQUNMJykge1xuICAgICAgICAgIG1lbW9bJ19ycGVybSddID0gMTtcbiAgICAgICAgICBtZW1vWydfd3Blcm0nXSA9IDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWVtb1t0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBrZXksIHNjaGVtYSldID0gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sXG4gICAgICB7fVxuICAgICk7XG5cbiAgICAvLyBJZiB3ZSBhcmVuJ3QgcmVxdWVzdGluZyB0aGUgYF9pZGAgZmllbGQsIHdlIG5lZWQgdG8gZXhwbGljaXRseSBvcHQgb3V0XG4gICAgLy8gb2YgaXQuIERvaW5nIHNvIGluIHBhcnNlLXNlcnZlciBpcyB1bnVzdWFsLCBidXQgaXQgY2FuIGFsbG93IHVzIHRvXG4gICAgLy8gb3B0aW1pemUgc29tZSBxdWVyaWVzIHdpdGggY292ZXJpbmcgaW5kZXhlcy5cbiAgICBpZiAoa2V5cyAmJiAhbW9uZ29LZXlzLl9pZCkge1xuICAgICAgbW9uZ29LZXlzLl9pZCA9IDA7XG4gICAgfVxuXG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmZpbmQobW9uZ29XaGVyZSwge1xuICAgICAgICAgIHNraXAsXG4gICAgICAgICAgbGltaXQsXG4gICAgICAgICAgc29ydDogbW9uZ29Tb3J0LFxuICAgICAgICAgIGtleXM6IG1vbmdvS2V5cyxcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBoaW50LFxuICAgICAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgICAgICBleHBsYWluLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ob2JqZWN0cyA9PiB7XG4gICAgICAgIGlmIChleHBsYWluKSB7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdHMubWFwKG9iamVjdCA9PlxuICAgICAgICAgIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGVuc3VyZUluZGV4KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXSxcbiAgICBpbmRleE5hbWU6ID9zdHJpbmcsXG4gICAgY2FzZUluc2Vuc2l0aXZlOiBib29sZWFuID0gZmFsc2UsXG4gICAgb3B0aW9ucz86IE9iamVjdCA9IHt9XG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGluZGV4Q3JlYXRpb25SZXF1ZXN0ID0ge307XG4gICAgY29uc3QgbW9uZ29GaWVsZE5hbWVzID0gZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+XG4gICAgICB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSlcbiAgICApO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID1cbiAgICAgICAgb3B0aW9ucy5pbmRleFR5cGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuaW5kZXhUeXBlIDogMTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zOiBPYmplY3QgPSB7IGJhY2tncm91bmQ6IHRydWUsIHNwYXJzZTogdHJ1ZSB9O1xuICAgIGNvbnN0IGluZGV4TmFtZU9wdGlvbnM6IE9iamVjdCA9IGluZGV4TmFtZSA/IHsgbmFtZTogaW5kZXhOYW1lIH0gOiB7fTtcbiAgICBjb25zdCB0dGxPcHRpb25zOiBPYmplY3QgPVxuICAgICAgb3B0aW9ucy50dGwgIT09IHVuZGVmaW5lZCA/IHsgZXhwaXJlQWZ0ZXJTZWNvbmRzOiBvcHRpb25zLnR0bCB9IDoge307XG4gICAgY29uc3QgY2FzZUluc2Vuc2l0aXZlT3B0aW9uczogT2JqZWN0ID0gY2FzZUluc2Vuc2l0aXZlXG4gICAgICA/IHsgY29sbGF0aW9uOiBNb25nb0NvbGxlY3Rpb24uY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uKCkgfVxuICAgICAgOiB7fTtcbiAgICBjb25zdCBpbmRleE9wdGlvbnM6IE9iamVjdCA9IHtcbiAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgLi4uY2FzZUluc2Vuc2l0aXZlT3B0aW9ucyxcbiAgICAgIC4uLmluZGV4TmFtZU9wdGlvbnMsXG4gICAgICAuLi50dGxPcHRpb25zLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKFxuICAgICAgICBjb2xsZWN0aW9uID0+XG4gICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT5cbiAgICAgICAgICAgIGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChcbiAgICAgICAgICAgICAgaW5kZXhDcmVhdGlvblJlcXVlc3QsXG4gICAgICAgICAgICAgIGluZGV4T3B0aW9ucyxcbiAgICAgICAgICAgICAgZXJyb3IgPT4gKGVycm9yID8gcmVqZWN0KGVycm9yKSA6IHJlc29sdmUoKSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBDcmVhdGUgYSB1bmlxdWUgaW5kZXguIFVuaXF1ZSBpbmRleGVzIG9uIG51bGxhYmxlIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQuIFNpbmNlIHdlIGRvbid0XG4gIC8vIGN1cnJlbnRseSBrbm93IHdoaWNoIGZpZWxkcyBhcmUgbnVsbGFibGUgYW5kIHdoaWNoIGFyZW4ndCwgd2UgaWdub3JlIHRoYXQgY3JpdGVyaWEuXG4gIC8vIEFzIHN1Y2gsIHdlIHNob3VsZG4ndCBleHBvc2UgdGhpcyBmdW5jdGlvbiB0byB1c2VycyBvZiBwYXJzZSB1bnRpbCB3ZSBoYXZlIGFuIG91dC1vZi1iYW5kXG4gIC8vIFdheSBvZiBkZXRlcm1pbmluZyBpZiBhIGZpZWxkIGlzIG51bGxhYmxlLiBVbmRlZmluZWQgZG9lc24ndCBjb3VudCBhZ2FpbnN0IHVuaXF1ZW5lc3MsXG4gIC8vIHdoaWNoIGlzIHdoeSB3ZSB1c2Ugc3BhcnNlIGluZGV4ZXMuXG4gIGVuc3VyZVVuaXF1ZW5lc3MoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIGZpZWxkTmFtZXM6IHN0cmluZ1tdXG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PlxuICAgICAgdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwgZmllbGROYW1lLCBzY2hlbWEpXG4gICAgKTtcbiAgICBtb25nb0ZpZWxkTmFtZXMuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaW5kZXhDcmVhdGlvblJlcXVlc3RbZmllbGROYW1lXSA9IDE7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kKGluZGV4Q3JlYXRpb25SZXF1ZXN0KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ1RyaWVkIHRvIGVuc3VyZSBmaWVsZCB1bmlxdWVuZXNzIGZvciBhIGNsYXNzIHRoYXQgYWxyZWFkeSBoYXMgZHVwbGljYXRlcy4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBVc2VkIGluIHRlc3RzXG4gIF9yYXdGaW5kKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZmluZChxdWVyeSwge1xuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBjb3VudC5cbiAgY291bnQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgaGludDogP21peGVkXG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmNvdW50KHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSwgdHJ1ZSksIHtcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBoaW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgZGlzdGluY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgZmllbGROYW1lOiBzdHJpbmdcbiAgKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGlzUG9pbnRlckZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInO1xuICAgIGNvbnN0IHRyYW5zZm9ybUZpZWxkID0gdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwgZmllbGROYW1lLCBzY2hlbWEpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZGlzdGluY3QoXG4gICAgICAgICAgdHJhbnNmb3JtRmllbGQsXG4gICAgICAgICAgdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKVxuICAgICAgICApXG4gICAgICApXG4gICAgICAudGhlbihvYmplY3RzID0+IHtcbiAgICAgICAgb2JqZWN0cyA9IG9iamVjdHMuZmlsdGVyKG9iaiA9PiBvYmogIT0gbnVsbCk7XG4gICAgICAgIHJldHVybiBvYmplY3RzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgIGlmIChpc1BvaW50ZXJGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVBvaW50ZXJTdHJpbmcoc2NoZW1hLCBmaWVsZE5hbWUsIG9iamVjdCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IGFueSxcbiAgICBwaXBlbGluZTogYW55LFxuICAgIHJlYWRQcmVmZXJlbmNlOiA/c3RyaW5nLFxuICAgIGhpbnQ6ID9taXhlZCxcbiAgICBleHBsYWluPzogYm9vbGVhblxuICApIHtcbiAgICBsZXQgaXNQb2ludGVyRmllbGQgPSBmYWxzZTtcbiAgICBwaXBlbGluZSA9IHBpcGVsaW5lLm1hcChzdGFnZSA9PiB7XG4gICAgICBpZiAoc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgIHN0YWdlLiRncm91cCA9IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgc3RhZ2UuJGdyb3VwKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHN0YWdlLiRncm91cC5faWQgJiZcbiAgICAgICAgICB0eXBlb2Ygc3RhZ2UuJGdyb3VwLl9pZCA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICBzdGFnZS4kZ3JvdXAuX2lkLmluZGV4T2YoJyRfcF8nKSA+PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIGlzUG9pbnRlckZpZWxkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRtYXRjaCkge1xuICAgICAgICBzdGFnZS4kbWF0Y2ggPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBzdGFnZS4kbWF0Y2gpO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRwcm9qZWN0KSB7XG4gICAgICAgIHN0YWdlLiRwcm9qZWN0ID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVQcm9qZWN0QXJncyhcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgc3RhZ2UuJHByb2plY3RcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kZ2VvTmVhciAmJiBzdGFnZS4kZ2VvTmVhci5xdWVyeSkge1xuICAgICAgICBzdGFnZS4kZ2VvTmVhci5xdWVyeSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgc3RhZ2UuJGdlb05lYXIucXVlcnlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzdGFnZTtcbiAgICB9KTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmFnZ3JlZ2F0ZShwaXBlbGluZSwge1xuICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgJ19pZCcpKSB7XG4gICAgICAgICAgICBpZiAoaXNQb2ludGVyRmllbGQgJiYgcmVzdWx0Ll9pZCkge1xuICAgICAgICAgICAgICByZXN1bHQuX2lkID0gcmVzdWx0Ll9pZC5zcGxpdCgnJCcpWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICByZXN1bHQuX2lkID09IG51bGwgfHxcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgKFsnb2JqZWN0JywgJ3N0cmluZyddLmluY2x1ZGVzKHR5cGVvZiByZXN1bHQuX2lkKSAmJlxuICAgICAgICAgICAgICAgIF8uaXNFbXB0eShyZXN1bHQuX2lkKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXN1bHQuX2lkID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdC5vYmplY3RJZCA9IHJlc3VsdC5faWQ7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0Ll9pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pXG4gICAgICAudGhlbihvYmplY3RzID0+XG4gICAgICAgIG9iamVjdHMubWFwKG9iamVjdCA9PlxuICAgICAgICAgIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVjdXJzaXZlbHkgdHJhdmVyc2UgdGhlIHBpcGVsaW5lIGFuZCBjb252ZXJ0IGFueSBQb2ludGVyIG9yIERhdGUgY29sdW1ucy5cbiAgLy8gSWYgd2UgZGV0ZWN0IGEgcG9pbnRlciBjb2x1bW4gd2Ugd2lsbCByZW5hbWUgdGhlIGNvbHVtbiBiZWluZyBxdWVyaWVkIGZvciB0byBtYXRjaCB0aGUgY29sdW1uXG4gIC8vIGluIHRoZSBkYXRhYmFzZS4gV2UgYWxzbyBtb2RpZnkgdGhlIHZhbHVlIHRvIHdoYXQgd2UgZXhwZWN0IHRoZSB2YWx1ZSB0byBiZSBpbiB0aGUgZGF0YWJhc2VcbiAgLy8gYXMgd2VsbC5cbiAgLy8gRm9yIGRhdGVzLCB0aGUgZHJpdmVyIGV4cGVjdHMgYSBEYXRlIG9iamVjdCwgYnV0IHdlIGhhdmUgYSBzdHJpbmcgY29taW5nIGluLiBTbyB3ZSdsbCBjb252ZXJ0XG4gIC8vIHRoZSBzdHJpbmcgdG8gYSBEYXRlIHNvIHRoZSBkcml2ZXIgY2FuIHBlcmZvcm0gdGhlIG5lY2Vzc2FyeSBjb21wYXJpc29uLlxuICAvL1xuICAvLyBUaGUgZ29hbCBvZiB0aGlzIG1ldGhvZCBpcyB0byBsb29rIGZvciB0aGUgXCJsZWF2ZXNcIiBvZiB0aGUgcGlwZWxpbmUgYW5kIGRldGVybWluZSBpZiBpdCBuZWVkc1xuICAvLyB0byBiZSBjb252ZXJ0ZWQuIFRoZSBwaXBlbGluZSBjYW4gaGF2ZSBhIGZldyBkaWZmZXJlbnQgZm9ybXMuIEZvciBtb3JlIGRldGFpbHMsIHNlZTpcbiAgLy8gICAgIGh0dHBzOi8vZG9jcy5tb25nb2RiLmNvbS9tYW51YWwvcmVmZXJlbmNlL29wZXJhdG9yL2FnZ3JlZ2F0aW9uL1xuICAvL1xuICAvLyBJZiB0aGUgcGlwZWxpbmUgaXMgYW4gYXJyYXksIGl0IG1lYW5zIHdlIGFyZSBwcm9iYWJseSBwYXJzaW5nIGFuICckYW5kJyBvciAnJG9yJyBvcGVyYXRvci4gSW5cbiAgLy8gdGhhdCBjYXNlIHdlIG5lZWQgdG8gbG9vcCB0aHJvdWdoIGFsbCBvZiBpdCdzIGNoaWxkcmVuIHRvIGZpbmQgdGhlIGNvbHVtbnMgYmVpbmcgb3BlcmF0ZWQgb24uXG4gIC8vIElmIHRoZSBwaXBlbGluZSBpcyBhbiBvYmplY3QsIHRoZW4gd2UnbGwgbG9vcCB0aHJvdWdoIHRoZSBrZXlzIGNoZWNraW5nIHRvIHNlZSBpZiB0aGUga2V5IG5hbWVcbiAgLy8gbWF0Y2hlcyBvbmUgb2YgdGhlIHNjaGVtYSBjb2x1bW5zLiBJZiBpdCBkb2VzIG1hdGNoIGEgY29sdW1uIGFuZCB0aGUgY29sdW1uIGlzIGEgUG9pbnRlciBvclxuICAvLyBhIERhdGUsIHRoZW4gd2UnbGwgY29udmVydCB0aGUgdmFsdWUgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAvL1xuICAvLyBBcyBtdWNoIGFzIEkgaGF0ZSByZWN1cnNpb24uLi50aGlzIHNlZW1lZCBsaWtlIGEgZ29vZCBmaXQgZm9yIGl0LiBXZSdyZSBlc3NlbnRpYWxseSB0cmF2ZXJzaW5nXG4gIC8vIGRvd24gYSB0cmVlIHRvIGZpbmQgYSBcImxlYWYgbm9kZVwiIGFuZCBjaGVja2luZyB0byBzZWUgaWYgaXQgbmVlZHMgdG8gYmUgY29udmVydGVkLlxuICBfcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAocGlwZWxpbmUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT4gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgdmFsdWUpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHBpcGVsaW5lW2ZpZWxkXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIFBhc3Mgb2JqZWN0cyBkb3duIHRvIE1vbmdvREIuLi50aGlzIGlzIG1vcmUgdGhhbiBsaWtlbHkgYW4gJGV4aXN0cyBvcGVyYXRvci5cbiAgICAgICAgICAgIHJldHVyblZhbHVlW2BfcF8ke2ZpZWxkfWBdID0gcGlwZWxpbmVbZmllbGRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZVtcbiAgICAgICAgICAgICAgYF9wXyR7ZmllbGR9YFxuICAgICAgICAgICAgXSA9IGAke3NjaGVtYS5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzfSQke3BpcGVsaW5lW2ZpZWxkXX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJlxuICAgICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdEYXRlJ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKFxuICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgcGlwZWxpbmVbZmllbGRdXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfaWQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfY3JlYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbJ191cGRhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcGlwZWxpbmU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSBvbmUgYWJvdmUuIFJhdGhlciB0aGFuIHRyeWluZyB0byBjb21iaW5lIHRoZXNlXG4gIC8vIHR3byBmdW5jdGlvbnMgYW5kIG1ha2luZyB0aGUgY29kZSBldmVuIGhhcmRlciB0byB1bmRlcnN0YW5kLCBJIGRlY2lkZWQgdG8gc3BsaXQgaXQgdXAuIFRoZVxuICAvLyBkaWZmZXJlbmNlIHdpdGggdGhpcyBmdW5jdGlvbiBpcyB3ZSBhcmUgbm90IHRyYW5zZm9ybWluZyB0aGUgdmFsdWVzLCBvbmx5IHRoZSBrZXlzIG9mIHRoZVxuICAvLyBwaXBlbGluZS5cbiAgX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hOiBhbnksIHBpcGVsaW5lOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IHBpcGVsaW5lW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2lkJ10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2NyZWF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgIHJldHVyblZhbHVlWydfdXBkYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSB0d28gYWJvdmUuIE1vbmdvREIgJGdyb3VwIGFnZ3JlZ2F0ZSBsb29rcyBsaWtlOlxuICAvLyAgICAgeyAkZ3JvdXA6IHsgX2lkOiA8ZXhwcmVzc2lvbj4sIDxmaWVsZDE+OiB7IDxhY2N1bXVsYXRvcjE+IDogPGV4cHJlc3Npb24xPiB9LCAuLi4gfSB9XG4gIC8vIFRoZSA8ZXhwcmVzc2lvbj4gY291bGQgYmUgYSBjb2x1bW4gbmFtZSwgcHJlZml4ZWQgd2l0aCB0aGUgJyQnIGNoYXJhY3Rlci4gV2UnbGwgbG9vayBmb3JcbiAgLy8gdGhlc2UgPGV4cHJlc3Npb24+IGFuZCBjaGVjayB0byBzZWUgaWYgaXQgaXMgYSAnUG9pbnRlcicgb3IgaWYgaXQncyBvbmUgb2YgY3JlYXRlZEF0LFxuICAvLyB1cGRhdGVkQXQgb3Igb2JqZWN0SWQgYW5kIGNoYW5nZSBpdCBhY2NvcmRpbmdseS5cbiAgX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT5cbiAgICAgICAgdGhpcy5fcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hLCB2YWx1ZSlcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGlwZWxpbmUgPT09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyhcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgcGlwZWxpbmVbZmllbGRdXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGlwZWxpbmUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IHBpcGVsaW5lLnN1YnN0cmluZygxKTtcbiAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGAkX3BfJHtmaWVsZH1gO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICByZXR1cm4gJyRfY3JlYXRlZF9hdCc7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgIHJldHVybiAnJF91cGRhdGVkX2F0JztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBpcGVsaW5lO1xuICB9XG5cbiAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIGF0dGVtcHQgdG8gY29udmVydCB0aGUgcHJvdmlkZWQgdmFsdWUgdG8gYSBEYXRlIG9iamVjdC4gU2luY2UgdGhpcyBpcyBwYXJ0XG4gIC8vIG9mIGFuIGFnZ3JlZ2F0aW9uIHBpcGVsaW5lLCB0aGUgdmFsdWUgY2FuIGVpdGhlciBiZSBhIHN0cmluZyBvciBpdCBjYW4gYmUgYW5vdGhlciBvYmplY3Qgd2l0aFxuICAvLyBhbiBvcGVyYXRvciBpbiBpdCAobGlrZSAkZ3QsICRsdCwgZXRjKS4gQmVjYXVzZSBvZiB0aGlzIEkgZmVsdCBpdCB3YXMgZWFzaWVyIHRvIG1ha2UgdGhpcyBhXG4gIC8vIHJlY3Vyc2l2ZSBtZXRob2QgdG8gdHJhdmVyc2UgZG93biB0byB0aGUgXCJsZWFmIG5vZGVcIiB3aGljaCBpcyBnb2luZyB0byBiZSB0aGUgc3RyaW5nLlxuICBfY29udmVydFRvRGF0ZSh2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgIGZvciAoY29uc3QgZmllbGQgaW4gdmFsdWUpIHtcbiAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX2NvbnZlcnRUb0RhdGUodmFsdWVbZmllbGRdKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2U6ID9zdHJpbmcpOiA/c3RyaW5nIHtcbiAgICBpZiAocmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2UudG9VcHBlckNhc2UoKTtcbiAgICB9XG4gICAgc3dpdGNoIChyZWFkUHJlZmVyZW5jZSkge1xuICAgICAgY2FzZSAnUFJJTUFSWSc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuUFJJTUFSWTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdQUklNQVJZX1BSRUZFUlJFRCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuUFJJTUFSWV9QUkVGRVJSRUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnU0VDT05EQVJZJzpcbiAgICAgICAgcmVhZFByZWZlcmVuY2UgPSBSZWFkUHJlZmVyZW5jZS5TRUNPTkRBUlk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnU0VDT05EQVJZX1BSRUZFUlJFRCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuU0VDT05EQVJZX1BSRUZFUlJFRDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdORUFSRVNUJzpcbiAgICAgICAgcmVhZFByZWZlcmVuY2UgPSBSZWFkUHJlZmVyZW5jZS5ORUFSRVNUO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgY2FzZSBudWxsOlxuICAgICAgY2FzZSAnJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICAnTm90IHN1cHBvcnRlZCByZWFkIHByZWZlcmVuY2UuJ1xuICAgICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBwZXJmb3JtSW5pdGlhbGl6YXRpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgY3JlYXRlSW5kZXgoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4KGluZGV4KSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4ZXM6IGFueSkge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uY3JlYXRlSW5kZXhlcyhpbmRleGVzKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSkge1xuICAgIGlmICh0eXBlICYmIHR5cGUudHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICBjb25zdCBpbmRleCA9IHtcbiAgICAgICAgW2ZpZWxkTmFtZV06ICcyZHNwaGVyZScsXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlSW5kZXgoY2xhc3NOYW1lLCBpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNyZWF0ZVRleHRJbmRleGVzSWZOZWVkZWQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICBzY2hlbWE6IGFueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBxdWVyeSkge1xuICAgICAgaWYgKCFxdWVyeVtmaWVsZE5hbWVdIHx8ICFxdWVyeVtmaWVsZE5hbWVdLiR0ZXh0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhpc3RpbmdJbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBleGlzdGluZ0luZGV4ZXMpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBleGlzdGluZ0luZGV4ZXNba2V5XTtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChpbmRleCwgZmllbGROYW1lKSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXhOYW1lID0gYCR7ZmllbGROYW1lfV90ZXh0YDtcbiAgICAgIGNvbnN0IHRleHRJbmRleCA9IHtcbiAgICAgICAgW2luZGV4TmFtZV06IHsgW2ZpZWxkTmFtZV06ICd0ZXh0JyB9LFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0KFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHRleHRJbmRleCxcbiAgICAgICAgZXhpc3RpbmdJbmRleGVzLFxuICAgICAgICBzY2hlbWEuZmllbGRzXG4gICAgICApLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDg1KSB7XG4gICAgICAgICAgLy8gSW5kZXggZXhpc3Qgd2l0aCBkaWZmZXJlbnQgb3B0aW9uc1xuICAgICAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNGcm9tTW9uZ28oY2xhc3NOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBnZXRJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5pbmRleGVzKCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkcm9wSW5kZXgoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmRyb3BJbmRleChpbmRleCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkcm9wQWxsSW5kZXhlcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZHJvcEluZGV4ZXMoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzKCk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QWxsQ2xhc3NlcygpXG4gICAgICAudGhlbihjbGFzc2VzID0+IHtcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBjbGFzc2VzLm1hcChzY2hlbWEgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNGcm9tTW9uZ28oc2NoZW1hLmNsYXNzTmFtZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25hbFNlY3Rpb24gPSB0aGlzLmNsaWVudC5zdGFydFNlc3Npb24oKTtcbiAgICB0cmFuc2FjdGlvbmFsU2VjdGlvbi5zdGFydFRyYW5zYWN0aW9uKCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0cmFuc2FjdGlvbmFsU2VjdGlvbik7XG4gIH1cblxuICBjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2VjdGlvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmNvbW1pdFRyYW5zYWN0aW9uKCkudGhlbigoKSA9PiB7XG4gICAgICB0cmFuc2FjdGlvbmFsU2VjdGlvbi5lbmRTZXNzaW9uKCk7XG4gICAgfSk7XG4gIH1cblxuICBhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZWN0aW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlY3Rpb24uYWJvcnRUcmFuc2FjdGlvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgdHJhbnNhY3Rpb25hbFNlY3Rpb24uZW5kU2Vzc2lvbigpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1vbmdvU3RvcmFnZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoTransform.js b/lib/Adapters/Storage/Mongo/MongoTransform.js deleted file mode 100644 index d050f6841c..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoTransform.js +++ /dev/null @@ -1,1795 +0,0 @@ -"use strict"; - -var _logger = _interopRequireDefault(require("../../../logger")); - -var _lodash = _interopRequireDefault(require("lodash")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var mongodb = require('mongodb'); - -var Parse = require('parse/node').Parse; - -const transformKey = (className, fieldName, schema) => { - // Check if the schema is known since it's a built-in field. - switch (fieldName) { - case 'objectId': - return '_id'; - - case 'createdAt': - return '_created_at'; - - case 'updatedAt': - return '_updated_at'; - - case 'sessionToken': - return '_session_token'; - - case 'lastUsed': - return '_last_used'; - - case 'timesUsed': - return 'times_used'; - } - - if (schema.fields[fieldName] && schema.fields[fieldName].__type == 'Pointer') { - fieldName = '_p_' + fieldName; - } else if (schema.fields[fieldName] && schema.fields[fieldName].type == 'Pointer') { - fieldName = '_p_' + fieldName; - } - - return fieldName; -}; - -const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSchema) => { - // Check if the schema is known since it's a built-in field. - var key = restKey; - var timeField = false; - - switch (key) { - case 'objectId': - case '_id': - if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { - return { - key: key, - value: parseInt(restValue) - }; - } - - key = '_id'; - break; - - case 'createdAt': - case '_created_at': - key = '_created_at'; - timeField = true; - break; - - case 'updatedAt': - case '_updated_at': - key = '_updated_at'; - timeField = true; - break; - - case 'sessionToken': - case '_session_token': - key = '_session_token'; - break; - - case 'expiresAt': - case '_expiresAt': - key = 'expiresAt'; - timeField = true; - break; - - case '_email_verify_token_expires_at': - key = '_email_verify_token_expires_at'; - timeField = true; - break; - - case '_account_lockout_expires_at': - key = '_account_lockout_expires_at'; - timeField = true; - break; - - case '_failed_login_count': - key = '_failed_login_count'; - break; - - case '_perishable_token_expires_at': - key = '_perishable_token_expires_at'; - timeField = true; - break; - - case '_password_changed_at': - key = '_password_changed_at'; - timeField = true; - break; - - case '_rperm': - case '_wperm': - return { - key: key, - value: restValue - }; - - case 'lastUsed': - case '_last_used': - key = '_last_used'; - timeField = true; - break; - - case 'timesUsed': - case 'times_used': - key = 'times_used'; - timeField = true; - break; - } - - if (parseFormatSchema.fields[key] && parseFormatSchema.fields[key].type === 'Pointer' || !parseFormatSchema.fields[key] && restValue && restValue.__type == 'Pointer') { - key = '_p_' + key; - } // Handle atomic values - - - var value = transformTopLevelAtom(restValue); - - if (value !== CannotTransform) { - if (timeField && typeof value === 'string') { - value = new Date(value); - } - - if (restKey.indexOf('.') > 0) { - return { - key, - value: restValue - }; - } - - return { - key, - value - }; - } // Handle arrays - - - if (restValue instanceof Array) { - value = restValue.map(transformInteriorValue); - return { - key, - value - }; - } // Handle update operators - - - if (typeof restValue === 'object' && '__op' in restValue) { - return { - key, - value: transformUpdateOperator(restValue, false) - }; - } // Handle normal objects by recursing - - - value = mapValues(restValue, transformInteriorValue); - return { - key, - value - }; -}; - -const isRegex = value => { - return value && value instanceof RegExp; -}; - -const isStartsWithRegex = value => { - if (!isRegex(value)) { - return false; - } - - const matches = value.toString().match(/\/\^\\Q.*\\E\//); - return !!matches; -}; - -const isAllValuesRegexOrNone = values => { - if (!values || !Array.isArray(values) || values.length === 0) { - return true; - } - - const firstValuesIsRegex = isStartsWithRegex(values[0]); - - if (values.length === 1) { - return firstValuesIsRegex; - } - - for (let i = 1, length = values.length; i < length; ++i) { - if (firstValuesIsRegex !== isStartsWithRegex(values[i])) { - return false; - } - } - - return true; -}; - -const isAnyValueRegex = values => { - return values.some(function (value) { - return isRegex(value); - }); -}; - -const transformInteriorValue = restValue => { - if (restValue !== null && typeof restValue === 'object' && Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { - throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } // Handle atomic values - - - var value = transformInteriorAtom(restValue); - - if (value !== CannotTransform) { - return value; - } // Handle arrays - - - if (restValue instanceof Array) { - return restValue.map(transformInteriorValue); - } // Handle update operators - - - if (typeof restValue === 'object' && '__op' in restValue) { - return transformUpdateOperator(restValue, true); - } // Handle normal objects by recursing - - - return mapValues(restValue, transformInteriorValue); -}; - -const valueAsDate = value => { - if (typeof value === 'string') { - return new Date(value); - } else if (value instanceof Date) { - return value; - } - - return false; -}; - -function transformQueryKeyValue(className, key, value, schema, count = false) { - switch (key) { - case 'createdAt': - if (valueAsDate(value)) { - return { - key: '_created_at', - value: valueAsDate(value) - }; - } - - key = '_created_at'; - break; - - case 'updatedAt': - if (valueAsDate(value)) { - return { - key: '_updated_at', - value: valueAsDate(value) - }; - } - - key = '_updated_at'; - break; - - case 'expiresAt': - if (valueAsDate(value)) { - return { - key: 'expiresAt', - value: valueAsDate(value) - }; - } - - break; - - case '_email_verify_token_expires_at': - if (valueAsDate(value)) { - return { - key: '_email_verify_token_expires_at', - value: valueAsDate(value) - }; - } - - break; - - case 'objectId': - { - if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { - value = parseInt(value); - } - - return { - key: '_id', - value - }; - } - - case '_account_lockout_expires_at': - if (valueAsDate(value)) { - return { - key: '_account_lockout_expires_at', - value: valueAsDate(value) - }; - } - - break; - - case '_failed_login_count': - return { - key, - value - }; - - case 'sessionToken': - return { - key: '_session_token', - value - }; - - case '_perishable_token_expires_at': - if (valueAsDate(value)) { - return { - key: '_perishable_token_expires_at', - value: valueAsDate(value) - }; - } - - break; - - case '_password_changed_at': - if (valueAsDate(value)) { - return { - key: '_password_changed_at', - value: valueAsDate(value) - }; - } - - break; - - case '_rperm': - case '_wperm': - case '_perishable_token': - case '_email_verify_token': - return { - key, - value - }; - - case '$or': - case '$and': - case '$nor': - return { - key: key, - value: value.map(subQuery => transformWhere(className, subQuery, schema, count)) - }; - - case 'lastUsed': - if (valueAsDate(value)) { - return { - key: '_last_used', - value: valueAsDate(value) - }; - } - - key = '_last_used'; - break; - - case 'timesUsed': - return { - key: 'times_used', - value: value - }; - - default: - { - // Other auth data - const authDataMatch = key.match(/^authData\.([a-zA-Z0-9_]+)\.id$/); - - if (authDataMatch) { - const provider = authDataMatch[1]; // Special-case auth data. - - return { - key: `_auth_data_${provider}.id`, - value - }; - } - } - } - - const expectedTypeIsArray = schema && schema.fields[key] && schema.fields[key].type === 'Array'; - const expectedTypeIsPointer = schema && schema.fields[key] && schema.fields[key].type === 'Pointer'; - const field = schema && schema.fields[key]; - - if (expectedTypeIsPointer || !schema && value && value.__type === 'Pointer') { - key = '_p_' + key; - } // Handle query constraints - - - const transformedConstraint = transformConstraint(value, field, count); - - if (transformedConstraint !== CannotTransform) { - if (transformedConstraint.$text) { - return { - key: '$text', - value: transformedConstraint.$text - }; - } - - if (transformedConstraint.$elemMatch) { - return { - key: '$nor', - value: [{ - [key]: transformedConstraint - }] - }; - } - - return { - key, - value: transformedConstraint - }; - } - - if (expectedTypeIsArray && !(value instanceof Array)) { - return { - key, - value: { - $all: [transformInteriorAtom(value)] - } - }; - } // Handle atomic values - - - if (transformTopLevelAtom(value) !== CannotTransform) { - return { - key, - value: transformTopLevelAtom(value) - }; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `You cannot use ${value} as a query parameter.`); - } -} // Main exposed method to help run queries. -// restWhere is the "where" clause in REST API form. -// Returns the mongo form of the query. - - -function transformWhere(className, restWhere, schema, count = false) { - const mongoWhere = {}; - - for (const restKey in restWhere) { - const out = transformQueryKeyValue(className, restKey, restWhere[restKey], schema, count); - mongoWhere[out.key] = out.value; - } - - return mongoWhere; -} - -const parseObjectKeyValueToMongoObjectKeyValue = (restKey, restValue, schema) => { - // Check if the schema is known since it's a built-in field. - let transformedValue; - let coercedToDate; - - switch (restKey) { - case 'objectId': - return { - key: '_id', - value: restValue - }; - - case 'expiresAt': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: 'expiresAt', - value: coercedToDate - }; - - case '_email_verify_token_expires_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_email_verify_token_expires_at', - value: coercedToDate - }; - - case '_account_lockout_expires_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_account_lockout_expires_at', - value: coercedToDate - }; - - case '_perishable_token_expires_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_perishable_token_expires_at', - value: coercedToDate - }; - - case '_password_changed_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_password_changed_at', - value: coercedToDate - }; - - case '_failed_login_count': - case '_rperm': - case '_wperm': - case '_email_verify_token': - case '_hashed_password': - case '_perishable_token': - return { - key: restKey, - value: restValue - }; - - case 'sessionToken': - return { - key: '_session_token', - value: restValue - }; - - default: - // Auth data should have been transformed already - if (restKey.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'can only query on ' + restKey); - } // Trust that the auth data has been transformed and save it directly - - - if (restKey.match(/^_auth_data_[a-zA-Z0-9_]+$/)) { - return { - key: restKey, - value: restValue - }; - } - - } //skip straight to transformTopLevelAtom for Bytes, they don't show up in the schema for some reason - - - if (restValue && restValue.__type !== 'Bytes') { - //Note: We may not know the type of a field here, as the user could be saving (null) to a field - //That never existed before, meaning we can't infer the type. - if (schema.fields[restKey] && schema.fields[restKey].type == 'Pointer' || restValue.__type == 'Pointer') { - restKey = '_p_' + restKey; - } - } // Handle atomic values - - - var value = transformTopLevelAtom(restValue); - - if (value !== CannotTransform) { - return { - key: restKey, - value: value - }; - } // ACLs are handled before this method is called - // If an ACL key still exists here, something is wrong. - - - if (restKey === 'ACL') { - throw 'There was a problem transforming an ACL.'; - } // Handle arrays - - - if (restValue instanceof Array) { - value = restValue.map(transformInteriorValue); - return { - key: restKey, - value: value - }; - } // Handle normal objects by recursing - - - if (Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { - throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } - - value = mapValues(restValue, transformInteriorValue); - return { - key: restKey, - value - }; -}; - -const parseObjectToMongoObjectForCreate = (className, restCreate, schema) => { - restCreate = addLegacyACL(restCreate); - const mongoCreate = {}; - - for (const restKey in restCreate) { - if (restCreate[restKey] && restCreate[restKey].__type === 'Relation') { - continue; - } - - const { - key, - value - } = parseObjectKeyValueToMongoObjectKeyValue(restKey, restCreate[restKey], schema); - - if (value !== undefined) { - mongoCreate[key] = value; - } - } // Use the legacy mongo format for createdAt and updatedAt - - - if (mongoCreate.createdAt) { - mongoCreate._created_at = new Date(mongoCreate.createdAt.iso || mongoCreate.createdAt); - delete mongoCreate.createdAt; - } - - if (mongoCreate.updatedAt) { - mongoCreate._updated_at = new Date(mongoCreate.updatedAt.iso || mongoCreate.updatedAt); - delete mongoCreate.updatedAt; - } - - return mongoCreate; -}; // Main exposed method to help update old objects. - - -const transformUpdate = (className, restUpdate, parseFormatSchema) => { - const mongoUpdate = {}; - const acl = addLegacyACL(restUpdate); - - if (acl._rperm || acl._wperm || acl._acl) { - mongoUpdate.$set = {}; - - if (acl._rperm) { - mongoUpdate.$set._rperm = acl._rperm; - } - - if (acl._wperm) { - mongoUpdate.$set._wperm = acl._wperm; - } - - if (acl._acl) { - mongoUpdate.$set._acl = acl._acl; - } - } - - for (var restKey in restUpdate) { - if (restUpdate[restKey] && restUpdate[restKey].__type === 'Relation') { - continue; - } - - var out = transformKeyValueForUpdate(className, restKey, restUpdate[restKey], parseFormatSchema); // If the output value is an object with any $ keys, it's an - // operator that needs to be lifted onto the top level update - // object. - - if (typeof out.value === 'object' && out.value !== null && out.value.__op) { - mongoUpdate[out.value.__op] = mongoUpdate[out.value.__op] || {}; - mongoUpdate[out.value.__op][out.key] = out.value.arg; - } else { - mongoUpdate['$set'] = mongoUpdate['$set'] || {}; - mongoUpdate['$set'][out.key] = out.value; - } - } - - return mongoUpdate; -}; // Add the legacy _acl format. - - -const addLegacyACL = restObject => { - const restObjectCopy = _objectSpread({}, restObject); - - const _acl = {}; - - if (restObject._wperm) { - restObject._wperm.forEach(entry => { - _acl[entry] = { - w: true - }; - }); - - restObjectCopy._acl = _acl; - } - - if (restObject._rperm) { - restObject._rperm.forEach(entry => { - if (!(entry in _acl)) { - _acl[entry] = { - r: true - }; - } else { - _acl[entry].r = true; - } - }); - - restObjectCopy._acl = _acl; - } - - return restObjectCopy; -}; // A sentinel value that helper transformations return when they -// cannot perform a transformation - - -function CannotTransform() {} - -const transformInteriorAtom = atom => { - // TODO: check validity harder for the __type-defined types - if (typeof atom === 'object' && atom && !(atom instanceof Date) && atom.__type === 'Pointer') { - return { - __type: 'Pointer', - className: atom.className, - objectId: atom.objectId - }; - } else if (typeof atom === 'function' || typeof atom === 'symbol') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); - } else if (DateCoder.isValidJSON(atom)) { - return DateCoder.JSONToDatabase(atom); - } else if (BytesCoder.isValidJSON(atom)) { - return BytesCoder.JSONToDatabase(atom); - } else if (typeof atom === 'object' && atom && atom.$regex !== undefined) { - return new RegExp(atom.$regex); - } else { - return atom; - } -}; // Helper function to transform an atom from REST format to Mongo format. -// An atom is anything that can't contain other expressions. So it -// includes things where objects are used to represent other -// datatypes, like pointers and dates, but it does not include objects -// or arrays with generic stuff inside. -// Raises an error if this cannot possibly be valid REST format. -// Returns CannotTransform if it's just not an atom - - -function transformTopLevelAtom(atom, field) { - switch (typeof atom) { - case 'number': - case 'boolean': - case 'undefined': - return atom; - - case 'string': - if (field && field.type === 'Pointer') { - return `${field.targetClass}$${atom}`; - } - - return atom; - - case 'symbol': - case 'function': - throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); - - case 'object': - if (atom instanceof Date) { - // Technically dates are not rest format, but, it seems pretty - // clear what they should be transformed to, so let's just do it. - return atom; - } - - if (atom === null) { - return atom; - } // TODO: check validity harder for the __type-defined types - - - if (atom.__type == 'Pointer') { - return `${atom.className}$${atom.objectId}`; - } - - if (DateCoder.isValidJSON(atom)) { - return DateCoder.JSONToDatabase(atom); - } - - if (BytesCoder.isValidJSON(atom)) { - return BytesCoder.JSONToDatabase(atom); - } - - if (GeoPointCoder.isValidJSON(atom)) { - return GeoPointCoder.JSONToDatabase(atom); - } - - if (PolygonCoder.isValidJSON(atom)) { - return PolygonCoder.JSONToDatabase(atom); - } - - if (FileCoder.isValidJSON(atom)) { - return FileCoder.JSONToDatabase(atom); - } - - return CannotTransform; - - default: - // I don't think typeof can ever let us get here - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, `really did not expect value: ${atom}`); - } -} - -function relativeTimeToDate(text, now = new Date()) { - text = text.toLowerCase(); - let parts = text.split(' '); // Filter out whitespace - - parts = parts.filter(part => part !== ''); - const future = parts[0] === 'in'; - const past = parts[parts.length - 1] === 'ago'; - - if (!future && !past && text !== 'now') { - return { - status: 'error', - info: "Time should either start with 'in' or end with 'ago'" - }; - } - - if (future && past) { - return { - status: 'error', - info: "Time cannot have both 'in' and 'ago'" - }; - } // strip the 'ago' or 'in' - - - if (future) { - parts = parts.slice(1); - } else { - // past - parts = parts.slice(0, parts.length - 1); - } - - if (parts.length % 2 !== 0 && text !== 'now') { - return { - status: 'error', - info: 'Invalid time string. Dangling unit or number.' - }; - } - - const pairs = []; - - while (parts.length) { - pairs.push([parts.shift(), parts.shift()]); - } - - let seconds = 0; - - for (const [num, interval] of pairs) { - const val = Number(num); - - if (!Number.isInteger(val)) { - return { - status: 'error', - info: `'${num}' is not an integer.` - }; - } - - switch (interval) { - case 'yr': - case 'yrs': - case 'year': - case 'years': - seconds += val * 31536000; // 365 * 24 * 60 * 60 - - break; - - case 'wk': - case 'wks': - case 'week': - case 'weeks': - seconds += val * 604800; // 7 * 24 * 60 * 60 - - break; - - case 'd': - case 'day': - case 'days': - seconds += val * 86400; // 24 * 60 * 60 - - break; - - case 'hr': - case 'hrs': - case 'hour': - case 'hours': - seconds += val * 3600; // 60 * 60 - - break; - - case 'min': - case 'mins': - case 'minute': - case 'minutes': - seconds += val * 60; - break; - - case 'sec': - case 'secs': - case 'second': - case 'seconds': - seconds += val; - break; - - default: - return { - status: 'error', - info: `Invalid interval: '${interval}'` - }; - } - } - - const milliseconds = seconds * 1000; - - if (future) { - return { - status: 'success', - info: 'future', - result: new Date(now.valueOf() + milliseconds) - }; - } else if (past) { - return { - status: 'success', - info: 'past', - result: new Date(now.valueOf() - milliseconds) - }; - } else { - return { - status: 'success', - info: 'present', - result: new Date(now.valueOf()) - }; - } -} // Transforms a query constraint from REST API format to Mongo format. -// A constraint is something with fields like $lt. -// If it is not a valid constraint but it could be a valid something -// else, return CannotTransform. -// inArray is whether this is an array field. - - -function transformConstraint(constraint, field, count = false) { - const inArray = field && field.type && field.type === 'Array'; - - if (typeof constraint !== 'object' || !constraint) { - return CannotTransform; - } - - const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom; - - const transformer = atom => { - const result = transformFunction(atom, field); - - if (result === CannotTransform) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${JSON.stringify(atom)}`); - } - - return result; - }; // keys is the constraints in reverse alphabetical order. - // This is a hack so that: - // $regex is handled before $options - // $nearSphere is handled before $maxDistance - - - var keys = Object.keys(constraint).sort().reverse(); - var answer = {}; - - for (var key of keys) { - switch (key) { - case '$lt': - case '$lte': - case '$gt': - case '$gte': - case '$exists': - case '$ne': - case '$eq': - { - const val = constraint[key]; - - if (val && typeof val === 'object' && val.$relativeTime) { - if (field && field.type !== 'Date') { - throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with Date field'); - } - - switch (key) { - case '$exists': - case '$ne': - case '$eq': - throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'); - } - - const parserResult = relativeTimeToDate(val.$relativeTime); - - if (parserResult.status === 'success') { - answer[key] = parserResult.result; - break; - } - - _logger.default.info('Error while parsing relative date', parserResult); - - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $relativeTime (${key}) value. ${parserResult.info}`); - } - - answer[key] = transformer(val); - break; - } - - case '$in': - case '$nin': - { - const arr = constraint[key]; - - if (!(arr instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); - } - - answer[key] = _lodash.default.flatMap(arr, value => { - return (atom => { - if (Array.isArray(atom)) { - return value.map(transformer); - } else { - return transformer(atom); - } - })(value); - }); - break; - } - - case '$all': - { - const arr = constraint[key]; - - if (!(arr instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); - } - - answer[key] = arr.map(transformInteriorAtom); - const values = answer[key]; - - if (isAnyValueRegex(values) && !isAllValuesRegexOrNone(values)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + values); - } - - break; - } - - case '$regex': - var s = constraint[key]; - - if (typeof s !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad regex: ' + s); - } - - answer[key] = s; - break; - - case '$containedBy': - { - const arr = constraint[key]; - - if (!(arr instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $containedBy: should be an array`); - } - - answer.$elemMatch = { - $nin: arr.map(transformer) - }; - break; - } - - case '$options': - answer[key] = constraint[key]; - break; - - case '$text': - { - const search = constraint[key].$search; - - if (typeof search !== 'object') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $search, should be object`); - } - - if (!search.$term || typeof search.$term !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $term, should be string`); - } else { - answer[key] = { - $search: search.$term - }; - } - - if (search.$language && typeof search.$language !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $language, should be string`); - } else if (search.$language) { - answer[key].$language = search.$language; - } - - if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); - } else if (search.$caseSensitive) { - answer[key].$caseSensitive = search.$caseSensitive; - } - - if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); - } else if (search.$diacriticSensitive) { - answer[key].$diacriticSensitive = search.$diacriticSensitive; - } - - break; - } - - case '$nearSphere': - { - const point = constraint[key]; - - if (count) { - answer.$geoWithin = { - $centerSphere: [[point.longitude, point.latitude], constraint.$maxDistance] - }; - } else { - answer[key] = [point.longitude, point.latitude]; - } - - break; - } - - case '$maxDistance': - { - if (count) { - break; - } - - answer[key] = constraint[key]; - break; - } - // The SDKs don't seem to use these but they are documented in the - // REST API docs. - - case '$maxDistanceInRadians': - answer['$maxDistance'] = constraint[key]; - break; - - case '$maxDistanceInMiles': - answer['$maxDistance'] = constraint[key] / 3959; - break; - - case '$maxDistanceInKilometers': - answer['$maxDistance'] = constraint[key] / 6371; - break; - - case '$select': - case '$dontSelect': - throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, 'the ' + key + ' constraint is not supported yet'); - - case '$within': - var box = constraint[key]['$box']; - - if (!box || box.length != 2) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'malformatted $within arg'); - } - - answer[key] = { - $box: [[box[0].longitude, box[0].latitude], [box[1].longitude, box[1].latitude]] - }; - break; - - case '$geoWithin': - { - const polygon = constraint[key]['$polygon']; - const centerSphere = constraint[key]['$centerSphere']; - - if (polygon !== undefined) { - let points; - - if (typeof polygon === 'object' && polygon.__type === 'Polygon') { - if (!polygon.coordinates || polygon.coordinates.length < 3) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); - } - - points = polygon.coordinates; - } else if (polygon instanceof Array) { - if (polygon.length < 3) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); - } - - points = polygon; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); - } - - points = points.map(point => { - if (point instanceof Array && point.length === 2) { - Parse.GeoPoint._validate(point[1], point[0]); - - return point; - } - - if (!GeoPointCoder.isValidJSON(point)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value'); - } else { - Parse.GeoPoint._validate(point.latitude, point.longitude); - } - - return [point.longitude, point.latitude]; - }); - answer[key] = { - $polygon: points - }; - } else if (centerSphere !== undefined) { - if (!(centerSphere instanceof Array) || centerSphere.length < 2) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); - } // Get point, convert to geo point if necessary and validate - - - let point = centerSphere[0]; - - if (point instanceof Array && point.length === 2) { - point = new Parse.GeoPoint(point[1], point[0]); - } else if (!GeoPointCoder.isValidJSON(point)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); - } - - Parse.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate - - - const distance = centerSphere[1]; - - if (isNaN(distance) || distance < 0) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); - } - - answer[key] = { - $centerSphere: [[point.longitude, point.latitude], distance] - }; - } - - break; - } - - case '$geoIntersects': - { - const point = constraint[key]['$point']; - - if (!GeoPointCoder.isValidJSON(point)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); - } else { - Parse.GeoPoint._validate(point.latitude, point.longitude); - } - - answer[key] = { - $geometry: { - type: 'Point', - coordinates: [point.longitude, point.latitude] - } - }; - break; - } - - default: - if (key.match(/^\$+/)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad constraint: ' + key); - } - - return CannotTransform; - } - } - - return answer; -} // Transforms an update operator from REST format to mongo format. -// To be transformed, the input should have an __op field. -// If flatten is true, this will flatten operators to their static -// data format. For example, an increment of 2 would simply become a -// 2. -// The output for a non-flattened operator is a hash with __op being -// the mongo op, and arg being the argument. -// The output for a flattened operator is just a value. -// Returns undefined if this should be a no-op. - - -function transformUpdateOperator({ - __op, - amount, - objects -}, flatten) { - switch (__op) { - case 'Delete': - if (flatten) { - return undefined; - } else { - return { - __op: '$unset', - arg: '' - }; - } - - case 'Increment': - if (typeof amount !== 'number') { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'incrementing must provide a number'); - } - - if (flatten) { - return amount; - } else { - return { - __op: '$inc', - arg: amount - }; - } - - case 'Add': - case 'AddUnique': - if (!(objects instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - var toAdd = objects.map(transformInteriorAtom); - - if (flatten) { - return toAdd; - } else { - var mongoOp = { - Add: '$push', - AddUnique: '$addToSet' - }[__op]; - return { - __op: mongoOp, - arg: { - $each: toAdd - } - }; - } - - case 'Remove': - if (!(objects instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to remove must be an array'); - } - - var toRemove = objects.map(transformInteriorAtom); - - if (flatten) { - return []; - } else { - return { - __op: '$pullAll', - arg: toRemove - }; - } - - default: - throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, `The ${__op} operator is not supported yet.`); - } -} - -function mapValues(object, iterator) { - const result = {}; - Object.keys(object).forEach(key => { - result[key] = iterator(object[key]); - }); - return result; -} - -const nestedMongoObjectToNestedParseObject = mongoObject => { - switch (typeof mongoObject) { - case 'string': - case 'number': - case 'boolean': - case 'undefined': - return mongoObject; - - case 'symbol': - case 'function': - throw 'bad value in nestedMongoObjectToNestedParseObject'; - - case 'object': - if (mongoObject === null) { - return null; - } - - if (mongoObject instanceof Array) { - return mongoObject.map(nestedMongoObjectToNestedParseObject); - } - - if (mongoObject instanceof Date) { - return Parse._encode(mongoObject); - } - - if (mongoObject instanceof mongodb.Long) { - return mongoObject.toNumber(); - } - - if (mongoObject instanceof mongodb.Double) { - return mongoObject.value; - } - - if (BytesCoder.isValidDatabaseObject(mongoObject)) { - return BytesCoder.databaseToJSON(mongoObject); - } - - if (Object.prototype.hasOwnProperty.call(mongoObject, '__type') && mongoObject.__type == 'Date' && mongoObject.iso instanceof Date) { - mongoObject.iso = mongoObject.iso.toJSON(); - return mongoObject; - } - - return mapValues(mongoObject, nestedMongoObjectToNestedParseObject); - - default: - throw 'unknown js type'; - } -}; - -const transformPointerString = (schema, field, pointerString) => { - const objData = pointerString.split('$'); - - if (objData[0] !== schema.fields[field].targetClass) { - throw 'pointer to incorrect className'; - } - - return { - __type: 'Pointer', - className: objData[0], - objectId: objData[1] - }; -}; // Converts from a mongo-format object to a REST-format object. -// Does not strip out anything based on a lack of authentication. - - -const mongoObjectToParseObject = (className, mongoObject, schema) => { - switch (typeof mongoObject) { - case 'string': - case 'number': - case 'boolean': - case 'undefined': - return mongoObject; - - case 'symbol': - case 'function': - throw 'bad value in mongoObjectToParseObject'; - - case 'object': - { - if (mongoObject === null) { - return null; - } - - if (mongoObject instanceof Array) { - return mongoObject.map(nestedMongoObjectToNestedParseObject); - } - - if (mongoObject instanceof Date) { - return Parse._encode(mongoObject); - } - - if (mongoObject instanceof mongodb.Long) { - return mongoObject.toNumber(); - } - - if (mongoObject instanceof mongodb.Double) { - return mongoObject.value; - } - - if (BytesCoder.isValidDatabaseObject(mongoObject)) { - return BytesCoder.databaseToJSON(mongoObject); - } - - const restObject = {}; - - if (mongoObject._rperm || mongoObject._wperm) { - restObject._rperm = mongoObject._rperm || []; - restObject._wperm = mongoObject._wperm || []; - delete mongoObject._rperm; - delete mongoObject._wperm; - } - - for (var key in mongoObject) { - switch (key) { - case '_id': - restObject['objectId'] = '' + mongoObject[key]; - break; - - case '_hashed_password': - restObject._hashed_password = mongoObject[key]; - break; - - case '_acl': - break; - - case '_email_verify_token': - case '_perishable_token': - case '_perishable_token_expires_at': - case '_password_changed_at': - case '_tombstone': - case '_email_verify_token_expires_at': - case '_account_lockout_expires_at': - case '_failed_login_count': - case '_password_history': - // Those keys will be deleted if needed in the DB Controller - restObject[key] = mongoObject[key]; - break; - - case '_session_token': - restObject['sessionToken'] = mongoObject[key]; - break; - - case 'updatedAt': - case '_updated_at': - restObject['updatedAt'] = Parse._encode(new Date(mongoObject[key])).iso; - break; - - case 'createdAt': - case '_created_at': - restObject['createdAt'] = Parse._encode(new Date(mongoObject[key])).iso; - break; - - case 'expiresAt': - case '_expiresAt': - restObject['expiresAt'] = Parse._encode(new Date(mongoObject[key])); - break; - - case 'lastUsed': - case '_last_used': - restObject['lastUsed'] = Parse._encode(new Date(mongoObject[key])).iso; - break; - - case 'timesUsed': - case 'times_used': - restObject['timesUsed'] = mongoObject[key]; - break; - - case 'authData': - if (className === '_User') { - _logger.default.warn('ignoring authData in _User as this key is reserved to be synthesized of `_auth_data_*` keys'); - } else { - restObject['authData'] = mongoObject[key]; - } - - break; - - default: - // Check other auth data keys - var authDataMatch = key.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch && className === '_User') { - var provider = authDataMatch[1]; - restObject['authData'] = restObject['authData'] || {}; - restObject['authData'][provider] = mongoObject[key]; - break; - } - - if (key.indexOf('_p_') == 0) { - var newKey = key.substring(3); - - if (!schema.fields[newKey]) { - _logger.default.info('transform.js', 'Found a pointer column not in the schema, dropping it.', className, newKey); - - break; - } - - if (schema.fields[newKey].type !== 'Pointer') { - _logger.default.info('transform.js', 'Found a pointer in a non-pointer column, dropping it.', className, key); - - break; - } - - if (mongoObject[key] === null) { - break; - } - - restObject[newKey] = transformPointerString(schema, newKey, mongoObject[key]); - break; - } else if (key[0] == '_' && key != '__type') { - throw 'bad key in untransform: ' + key; - } else { - var value = mongoObject[key]; - - if (schema.fields[key] && schema.fields[key].type === 'File' && FileCoder.isValidDatabaseObject(value)) { - restObject[key] = FileCoder.databaseToJSON(value); - break; - } - - if (schema.fields[key] && schema.fields[key].type === 'GeoPoint' && GeoPointCoder.isValidDatabaseObject(value)) { - restObject[key] = GeoPointCoder.databaseToJSON(value); - break; - } - - if (schema.fields[key] && schema.fields[key].type === 'Polygon' && PolygonCoder.isValidDatabaseObject(value)) { - restObject[key] = PolygonCoder.databaseToJSON(value); - break; - } - - if (schema.fields[key] && schema.fields[key].type === 'Bytes' && BytesCoder.isValidDatabaseObject(value)) { - restObject[key] = BytesCoder.databaseToJSON(value); - break; - } - } - - restObject[key] = nestedMongoObjectToNestedParseObject(mongoObject[key]); - } - } - - const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); - const relationFields = {}; - relationFieldNames.forEach(relationFieldName => { - relationFields[relationFieldName] = { - __type: 'Relation', - className: schema.fields[relationFieldName].targetClass - }; - }); - return _objectSpread(_objectSpread({}, restObject), relationFields); - } - - default: - throw 'unknown js type'; - } -}; - -var DateCoder = { - JSONToDatabase(json) { - return new Date(json.iso); - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'Date'; - } - -}; -var BytesCoder = { - base64Pattern: new RegExp('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'), - - isBase64Value(object) { - if (typeof object !== 'string') { - return false; - } - - return this.base64Pattern.test(object); - }, - - databaseToJSON(object) { - let value; - - if (this.isBase64Value(object)) { - value = object; - } else { - value = object.buffer.toString('base64'); - } - - return { - __type: 'Bytes', - base64: value - }; - }, - - isValidDatabaseObject(object) { - return object instanceof mongodb.Binary || this.isBase64Value(object); - }, - - JSONToDatabase(json) { - return new mongodb.Binary(Buffer.from(json.base64, 'base64')); - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'Bytes'; - } - -}; -var GeoPointCoder = { - databaseToJSON(object) { - return { - __type: 'GeoPoint', - latitude: object[1], - longitude: object[0] - }; - }, - - isValidDatabaseObject(object) { - return object instanceof Array && object.length == 2; - }, - - JSONToDatabase(json) { - return [json.longitude, json.latitude]; - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; - } - -}; -var PolygonCoder = { - databaseToJSON(object) { - // Convert lng/lat -> lat/lng - const coords = object.coordinates[0].map(coord => { - return [coord[1], coord[0]]; - }); - return { - __type: 'Polygon', - coordinates: coords - }; - }, - - isValidDatabaseObject(object) { - const coords = object.coordinates[0]; - - if (object.type !== 'Polygon' || !(coords instanceof Array)) { - return false; - } - - for (let i = 0; i < coords.length; i++) { - const point = coords[i]; - - if (!GeoPointCoder.isValidDatabaseObject(point)) { - return false; - } - - Parse.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); - } - - return true; - }, - - JSONToDatabase(json) { - let coords = json.coordinates; // Add first point to the end to close polygon - - if (coords[0][0] !== coords[coords.length - 1][0] || coords[0][1] !== coords[coords.length - 1][1]) { - coords.push(coords[0]); - } - - const unique = coords.filter((item, index, ar) => { - let foundIndex = -1; - - for (let i = 0; i < ar.length; i += 1) { - const pt = ar[i]; - - if (pt[0] === item[0] && pt[1] === item[1]) { - foundIndex = i; - break; - } - } - - return foundIndex === index; - }); - - if (unique.length < 3) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); - } // Convert lat/long -> long/lat - - - coords = coords.map(coord => { - return [coord[1], coord[0]]; - }); - return { - type: 'Polygon', - coordinates: [coords] - }; - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'Polygon'; - } - -}; -var FileCoder = { - databaseToJSON(object) { - return { - __type: 'File', - name: object - }; - }, - - isValidDatabaseObject(object) { - return typeof object === 'string'; - }, - - JSONToDatabase(json) { - return json.name; - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'File'; - } - -}; -module.exports = { - transformKey, - parseObjectToMongoObjectForCreate, - transformUpdate, - transformWhere, - mongoObjectToParseObject, - relativeTimeToDate, - transformConstraint, - transformPointerString -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvVHJhbnNmb3JtLmpzIl0sIm5hbWVzIjpbIm1vbmdvZGIiLCJyZXF1aXJlIiwiUGFyc2UiLCJ0cmFuc2Zvcm1LZXkiLCJjbGFzc05hbWUiLCJmaWVsZE5hbWUiLCJzY2hlbWEiLCJmaWVsZHMiLCJfX3R5cGUiLCJ0eXBlIiwidHJhbnNmb3JtS2V5VmFsdWVGb3JVcGRhdGUiLCJyZXN0S2V5IiwicmVzdFZhbHVlIiwicGFyc2VGb3JtYXRTY2hlbWEiLCJrZXkiLCJ0aW1lRmllbGQiLCJpbmNsdWRlcyIsInZhbHVlIiwicGFyc2VJbnQiLCJ0cmFuc2Zvcm1Ub3BMZXZlbEF0b20iLCJDYW5ub3RUcmFuc2Zvcm0iLCJEYXRlIiwiaW5kZXhPZiIsIkFycmF5IiwibWFwIiwidHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSIsInRyYW5zZm9ybVVwZGF0ZU9wZXJhdG9yIiwibWFwVmFsdWVzIiwiaXNSZWdleCIsIlJlZ0V4cCIsImlzU3RhcnRzV2l0aFJlZ2V4IiwibWF0Y2hlcyIsInRvU3RyaW5nIiwibWF0Y2giLCJpc0FsbFZhbHVlc1JlZ2V4T3JOb25lIiwidmFsdWVzIiwiaXNBcnJheSIsImxlbmd0aCIsImZpcnN0VmFsdWVzSXNSZWdleCIsImkiLCJpc0FueVZhbHVlUmVnZXgiLCJzb21lIiwiT2JqZWN0Iiwia2V5cyIsIkVycm9yIiwiSU5WQUxJRF9ORVNURURfS0VZIiwidHJhbnNmb3JtSW50ZXJpb3JBdG9tIiwidmFsdWVBc0RhdGUiLCJ0cmFuc2Zvcm1RdWVyeUtleVZhbHVlIiwiY291bnQiLCJzdWJRdWVyeSIsInRyYW5zZm9ybVdoZXJlIiwiYXV0aERhdGFNYXRjaCIsInByb3ZpZGVyIiwiZXhwZWN0ZWRUeXBlSXNBcnJheSIsImV4cGVjdGVkVHlwZUlzUG9pbnRlciIsImZpZWxkIiwidHJhbnNmb3JtZWRDb25zdHJhaW50IiwidHJhbnNmb3JtQ29uc3RyYWludCIsIiR0ZXh0IiwiJGVsZW1NYXRjaCIsIiRhbGwiLCJJTlZBTElEX0pTT04iLCJyZXN0V2hlcmUiLCJtb25nb1doZXJlIiwib3V0IiwicGFyc2VPYmplY3RLZXlWYWx1ZVRvTW9uZ29PYmplY3RLZXlWYWx1ZSIsInRyYW5zZm9ybWVkVmFsdWUiLCJjb2VyY2VkVG9EYXRlIiwiSU5WQUxJRF9LRVlfTkFNRSIsInBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZSIsInJlc3RDcmVhdGUiLCJhZGRMZWdhY3lBQ0wiLCJtb25nb0NyZWF0ZSIsInVuZGVmaW5lZCIsImNyZWF0ZWRBdCIsIl9jcmVhdGVkX2F0IiwiaXNvIiwidXBkYXRlZEF0IiwiX3VwZGF0ZWRfYXQiLCJ0cmFuc2Zvcm1VcGRhdGUiLCJyZXN0VXBkYXRlIiwibW9uZ29VcGRhdGUiLCJhY2wiLCJfcnBlcm0iLCJfd3Blcm0iLCJfYWNsIiwiJHNldCIsIl9fb3AiLCJhcmciLCJyZXN0T2JqZWN0IiwicmVzdE9iamVjdENvcHkiLCJmb3JFYWNoIiwiZW50cnkiLCJ3IiwiciIsImF0b20iLCJvYmplY3RJZCIsIkRhdGVDb2RlciIsImlzVmFsaWRKU09OIiwiSlNPTlRvRGF0YWJhc2UiLCJCeXRlc0NvZGVyIiwiJHJlZ2V4IiwidGFyZ2V0Q2xhc3MiLCJHZW9Qb2ludENvZGVyIiwiUG9seWdvbkNvZGVyIiwiRmlsZUNvZGVyIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwicmVsYXRpdmVUaW1lVG9EYXRlIiwidGV4dCIsIm5vdyIsInRvTG93ZXJDYXNlIiwicGFydHMiLCJzcGxpdCIsImZpbHRlciIsInBhcnQiLCJmdXR1cmUiLCJwYXN0Iiwic3RhdHVzIiwiaW5mbyIsInNsaWNlIiwicGFpcnMiLCJwdXNoIiwic2hpZnQiLCJzZWNvbmRzIiwibnVtIiwiaW50ZXJ2YWwiLCJ2YWwiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJtaWxsaXNlY29uZHMiLCJyZXN1bHQiLCJ2YWx1ZU9mIiwiY29uc3RyYWludCIsImluQXJyYXkiLCJ0cmFuc2Zvcm1GdW5jdGlvbiIsInRyYW5zZm9ybWVyIiwiSlNPTiIsInN0cmluZ2lmeSIsInNvcnQiLCJyZXZlcnNlIiwiYW5zd2VyIiwiJHJlbGF0aXZlVGltZSIsInBhcnNlclJlc3VsdCIsImxvZyIsImFyciIsIl8iLCJmbGF0TWFwIiwicyIsIiRuaW4iLCJzZWFyY2giLCIkc2VhcmNoIiwiJHRlcm0iLCIkbGFuZ3VhZ2UiLCIkY2FzZVNlbnNpdGl2ZSIsIiRkaWFjcml0aWNTZW5zaXRpdmUiLCJwb2ludCIsIiRnZW9XaXRoaW4iLCIkY2VudGVyU3BoZXJlIiwibG9uZ2l0dWRlIiwibGF0aXR1ZGUiLCIkbWF4RGlzdGFuY2UiLCJDT01NQU5EX1VOQVZBSUxBQkxFIiwiYm94IiwiJGJveCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJwb2ludHMiLCJjb29yZGluYXRlcyIsIkdlb1BvaW50IiwiX3ZhbGlkYXRlIiwiJHBvbHlnb24iLCJkaXN0YW5jZSIsImlzTmFOIiwiJGdlb21ldHJ5IiwiYW1vdW50Iiwib2JqZWN0cyIsImZsYXR0ZW4iLCJ0b0FkZCIsIm1vbmdvT3AiLCJBZGQiLCJBZGRVbmlxdWUiLCIkZWFjaCIsInRvUmVtb3ZlIiwib2JqZWN0IiwiaXRlcmF0b3IiLCJuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QiLCJtb25nb09iamVjdCIsIl9lbmNvZGUiLCJMb25nIiwidG9OdW1iZXIiLCJEb3VibGUiLCJpc1ZhbGlkRGF0YWJhc2VPYmplY3QiLCJkYXRhYmFzZVRvSlNPTiIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInRvSlNPTiIsInRyYW5zZm9ybVBvaW50ZXJTdHJpbmciLCJwb2ludGVyU3RyaW5nIiwib2JqRGF0YSIsIm1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJ3YXJuIiwibmV3S2V5Iiwic3Vic3RyaW5nIiwicmVsYXRpb25GaWVsZE5hbWVzIiwicmVsYXRpb25GaWVsZHMiLCJyZWxhdGlvbkZpZWxkTmFtZSIsImpzb24iLCJiYXNlNjRQYXR0ZXJuIiwiaXNCYXNlNjRWYWx1ZSIsInRlc3QiLCJidWZmZXIiLCJiYXNlNjQiLCJCaW5hcnkiLCJCdWZmZXIiLCJmcm9tIiwiY29vcmRzIiwiY29vcmQiLCJwYXJzZUZsb2F0IiwidW5pcXVlIiwiaXRlbSIsImluZGV4IiwiYXIiLCJmb3VuZEluZGV4IiwicHQiLCJuYW1lIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7QUFDQTs7Ozs7Ozs7OztBQUNBLElBQUlBLE9BQU8sR0FBR0MsT0FBTyxDQUFDLFNBQUQsQ0FBckI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQzs7QUFFQSxNQUFNQyxZQUFZLEdBQUcsQ0FBQ0MsU0FBRCxFQUFZQyxTQUFaLEVBQXVCQyxNQUF2QixLQUFrQztBQUNyRDtBQUNBLFVBQVFELFNBQVI7QUFDRSxTQUFLLFVBQUw7QUFDRSxhQUFPLEtBQVA7O0FBQ0YsU0FBSyxXQUFMO0FBQ0UsYUFBTyxhQUFQOztBQUNGLFNBQUssV0FBTDtBQUNFLGFBQU8sYUFBUDs7QUFDRixTQUFLLGNBQUw7QUFDRSxhQUFPLGdCQUFQOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU8sWUFBUDs7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLFlBQVA7QUFaSjs7QUFlQSxNQUNFQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0YsU0FBZCxLQUNBQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0YsU0FBZCxFQUF5QkcsTUFBekIsSUFBbUMsU0FGckMsRUFHRTtBQUNBSCxJQUFBQSxTQUFTLEdBQUcsUUFBUUEsU0FBcEI7QUFDRCxHQUxELE1BS08sSUFDTEMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsS0FDQUMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsRUFBeUJJLElBQXpCLElBQWlDLFNBRjVCLEVBR0w7QUFDQUosSUFBQUEsU0FBUyxHQUFHLFFBQVFBLFNBQXBCO0FBQ0Q7O0FBRUQsU0FBT0EsU0FBUDtBQUNE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QUFLLElBQXZDLElBQStDQSxLQUFLLENBQUNULE1BQU4sS0FBaUIsTUFEbEU7QUFHRDs7QUFwQmEsQ0FBaEI7QUF1QkE0TixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmxPLEVBQUFBLFlBRGU7QUFFZm1FLEVBQUFBLGlDQUZlO0FBR2ZVLEVBQUFBLGVBSGU7QUFJZjdCLEVBQUFBLGNBSmU7QUFLZnNKLEVBQUFBLHdCQUxlO0FBTWY3RixFQUFBQSxrQkFOZTtBQU9mbEQsRUFBQUEsbUJBUGU7QUFRZjRJLEVBQUFBO0FBUmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbG9nIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xudmFyIG1vbmdvZGIgPSByZXF1aXJlKCdtb25nb2RiJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IHRyYW5zZm9ybUtleSA9IChjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKSA9PiB7XG4gIC8vIENoZWNrIGlmIHRoZSBzY2hlbWEgaXMga25vd24gc2luY2UgaXQncyBhIGJ1aWx0LWluIGZpZWxkLlxuICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgIGNhc2UgJ29iamVjdElkJzpcbiAgICAgIHJldHVybiAnX2lkJztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgICAgcmV0dXJuICdfY3JlYXRlZF9hdCc7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgIHJldHVybiAnX3VwZGF0ZWRfYXQnO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4gJ19zZXNzaW9uX3Rva2VuJztcbiAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICByZXR1cm4gJ19sYXN0X3VzZWQnO1xuICAgIGNhc2UgJ3RpbWVzVXNlZCc6XG4gICAgICByZXR1cm4gJ3RpbWVzX3VzZWQnO1xuICB9XG5cbiAgaWYgKFxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5fX3R5cGUgPT0gJ1BvaW50ZXInXG4gICkge1xuICAgIGZpZWxkTmFtZSA9ICdfcF8nICsgZmllbGROYW1lO1xuICB9IGVsc2UgaWYgKFxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09ICdQb2ludGVyJ1xuICApIHtcbiAgICBmaWVsZE5hbWUgPSAnX3BfJyArIGZpZWxkTmFtZTtcbiAgfVxuXG4gIHJldHVybiBmaWVsZE5hbWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1LZXlWYWx1ZUZvclVwZGF0ZSA9IChcbiAgY2xhc3NOYW1lLFxuICByZXN0S2V5LFxuICByZXN0VmFsdWUsXG4gIHBhcnNlRm9ybWF0U2NoZW1hXG4pID0+IHtcbiAgLy8gQ2hlY2sgaWYgdGhlIHNjaGVtYSBpcyBrbm93biBzaW5jZSBpdCdzIGEgYnVpbHQtaW4gZmllbGQuXG4gIHZhciBrZXkgPSByZXN0S2V5O1xuICB2YXIgdGltZUZpZWxkID0gZmFsc2U7XG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnb2JqZWN0SWQnOlxuICAgIGNhc2UgJ19pZCc6XG4gICAgICBpZiAoWydfR2xvYmFsQ29uZmlnJywgJ19HcmFwaFFMQ29uZmlnJ10uaW5jbHVkZXMoY2xhc3NOYW1lKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUludChyZXN0VmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19pZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgIGNhc2UgJ19jcmVhdGVkX2F0JzpcbiAgICAgIGtleSA9ICdfY3JlYXRlZF9hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICBjYXNlICdfdXBkYXRlZF9hdCc6XG4gICAgICBrZXkgPSAnX3VwZGF0ZWRfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgY2FzZSAnX3Nlc3Npb25fdG9rZW4nOlxuICAgICAga2V5ID0gJ19zZXNzaW9uX3Rva2VuJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgY2FzZSAnX2V4cGlyZXNBdCc6XG4gICAgICBrZXkgPSAnZXhwaXJlc0F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAga2V5ID0gJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIGtleSA9ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19mYWlsZWRfbG9naW5fY291bnQnOlxuICAgICAga2V5ID0gJ19mYWlsZWRfbG9naW5fY291bnQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICBrZXkgPSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAga2V5ID0gJ19wYXNzd29yZF9jaGFuZ2VkX2F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfcnBlcm0nOlxuICAgIGNhc2UgJ193cGVybSc6XG4gICAgICByZXR1cm4geyBrZXk6IGtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ2xhc3RVc2VkJzpcbiAgICBjYXNlICdfbGFzdF91c2VkJzpcbiAgICAgIGtleSA9ICdfbGFzdF91c2VkJztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgIGNhc2UgJ3RpbWVzX3VzZWQnOlxuICAgICAga2V5ID0gJ3RpbWVzX3VzZWQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgaWYgKFxuICAgIChwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgcGFyc2VGb3JtYXRTY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ1BvaW50ZXInKSB8fFxuICAgICghcGFyc2VGb3JtYXRTY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgIHJlc3RWYWx1ZSAmJlxuICAgICAgcmVzdFZhbHVlLl9fdHlwZSA9PSAnUG9pbnRlcicpXG4gICkge1xuICAgIGtleSA9ICdfcF8nICsga2V5O1xuICB9XG5cbiAgLy8gSGFuZGxlIGF0b21pYyB2YWx1ZXNcbiAgdmFyIHZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gIGlmICh2YWx1ZSAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgaWYgKHRpbWVGaWVsZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHJlc3RLZXkuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogcmVzdFZhbHVlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXNcbiAgaWYgKHJlc3RWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdmFsdWUgPSByZXN0VmFsdWUubWFwKHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSB1cGRhdGUgb3BlcmF0b3JzXG4gIGlmICh0eXBlb2YgcmVzdFZhbHVlID09PSAnb2JqZWN0JyAmJiAnX19vcCcgaW4gcmVzdFZhbHVlKSB7XG4gICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IocmVzdFZhbHVlLCBmYWxzZSkgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgdmFsdWUgPSBtYXBWYWx1ZXMocmVzdFZhbHVlLCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlKTtcbiAgcmV0dXJuIHsga2V5LCB2YWx1ZSB9O1xufTtcblxuY29uc3QgaXNSZWdleCA9IHZhbHVlID0+IHtcbiAgcmV0dXJuIHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwO1xufTtcblxuY29uc3QgaXNTdGFydHNXaXRoUmVnZXggPSB2YWx1ZSA9PiB7XG4gIGlmICghaXNSZWdleCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBtYXRjaGVzID0gdmFsdWUudG9TdHJpbmcoKS5tYXRjaCgvXFwvXFxeXFxcXFEuKlxcXFxFXFwvLyk7XG4gIHJldHVybiAhIW1hdGNoZXM7XG59O1xuXG5jb25zdCBpc0FsbFZhbHVlc1JlZ2V4T3JOb25lID0gdmFsdWVzID0+IHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0pO1xuICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBmaXJzdFZhbHVlc0lzUmVnZXg7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMSwgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGZpcnN0VmFsdWVzSXNSZWdleCAhPT0gaXNTdGFydHNXaXRoUmVnZXgodmFsdWVzW2ldKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgaXNBbnlWYWx1ZVJlZ2V4ID0gdmFsdWVzID0+IHtcbiAgcmV0dXJuIHZhbHVlcy5zb21lKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGlzUmVnZXgodmFsdWUpO1xuICB9KTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybUludGVyaW9yVmFsdWUgPSByZXN0VmFsdWUgPT4ge1xuICBpZiAoXG4gICAgcmVzdFZhbHVlICE9PSBudWxsICYmXG4gICAgdHlwZW9mIHJlc3RWYWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICBPYmplY3Qua2V5cyhyZXN0VmFsdWUpLnNvbWUoa2V5ID0+IGtleS5pbmNsdWRlcygnJCcpIHx8IGtleS5pbmNsdWRlcygnLicpKVxuICApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX05FU1RFRF9LRVksXG4gICAgICBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCJcbiAgICApO1xuICB9XG4gIC8vIEhhbmRsZSBhdG9taWMgdmFsdWVzXG4gIHZhciB2YWx1ZSA9IHRyYW5zZm9ybUludGVyaW9yQXRvbShyZXN0VmFsdWUpO1xuICBpZiAodmFsdWUgIT09IENhbm5vdFRyYW5zZm9ybSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXNcbiAgaWYgKHJlc3RWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgcmV0dXJuIHJlc3RWYWx1ZS5tYXAodHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG4gIH1cblxuICAvLyBIYW5kbGUgdXBkYXRlIG9wZXJhdG9yc1xuICBpZiAodHlwZW9mIHJlc3RWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ19fb3AnIGluIHJlc3RWYWx1ZSkge1xuICAgIHJldHVybiB0cmFuc2Zvcm1VcGRhdGVPcGVyYXRvcihyZXN0VmFsdWUsIHRydWUpO1xuICB9XG5cbiAgLy8gSGFuZGxlIG5vcm1hbCBvYmplY3RzIGJ5IHJlY3Vyc2luZ1xuICByZXR1cm4gbWFwVmFsdWVzKHJlc3RWYWx1ZSwgdHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG59O1xuXG5jb25zdCB2YWx1ZUFzRGF0ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbmV3IERhdGUodmFsdWUpO1xuICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1RdWVyeUtleVZhbHVlKGNsYXNzTmFtZSwga2V5LCB2YWx1ZSwgc2NoZW1hLCBjb3VudCA9IGZhbHNlKSB7XG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnY3JlYXRlZEF0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnX2NyZWF0ZWRfYXQnLCB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpIH07XG4gICAgICB9XG4gICAgICBrZXkgPSAnX2NyZWF0ZWRfYXQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnX3VwZGF0ZWRfYXQnLCB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpIH07XG4gICAgICB9XG4gICAgICBrZXkgPSAnX3VwZGF0ZWRfYXQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZXhwaXJlc0F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHsga2V5OiAnZXhwaXJlc0F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6ICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdvYmplY3RJZCc6IHtcbiAgICAgIGlmIChbJ19HbG9iYWxDb25maWcnLCAnX0dyYXBoUUxDb25maWcnXS5pbmNsdWRlcyhjbGFzc05hbWUpKSB7XG4gICAgICAgIHZhbHVlID0gcGFyc2VJbnQodmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsga2V5OiAnX2lkJywgdmFsdWUgfTtcbiAgICB9XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfZmFpbGVkX2xvZ2luX2NvdW50JzpcbiAgICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgICBjYXNlICdzZXNzaW9uVG9rZW4nOlxuICAgICAgcmV0dXJuIHsga2V5OiAnX3Nlc3Npb25fdG9rZW4nLCB2YWx1ZSB9O1xuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgaWYgKHZhbHVlQXNEYXRlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleTogJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfcGFzc3dvcmRfY2hhbmdlZF9hdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ19wYXNzd29yZF9jaGFuZ2VkX2F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3JwZXJtJzpcbiAgICBjYXNlICdfd3Blcm0nOlxuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuJzpcbiAgICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgICBjYXNlICckb3InOlxuICAgIGNhc2UgJyRhbmQnOlxuICAgIGNhc2UgJyRub3InOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2V5OiBrZXksXG4gICAgICAgIHZhbHVlOiB2YWx1ZS5tYXAoc3ViUXVlcnkgPT5cbiAgICAgICAgICB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHN1YlF1ZXJ5LCBzY2hlbWEsIGNvdW50KVxuICAgICAgICApLFxuICAgICAgfTtcbiAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ19sYXN0X3VzZWQnLCB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpIH07XG4gICAgICB9XG4gICAgICBrZXkgPSAnX2xhc3RfdXNlZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgICAgcmV0dXJuIHsga2V5OiAndGltZXNfdXNlZCcsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIGRlZmF1bHQ6IHtcbiAgICAgIC8vIE90aGVyIGF1dGggZGF0YVxuICAgICAgY29uc3QgYXV0aERhdGFNYXRjaCA9IGtleS5tYXRjaCgvXmF1dGhEYXRhXFwuKFthLXpBLVowLTlfXSspXFwuaWQkLyk7XG4gICAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgICBjb25zdCBwcm92aWRlciA9IGF1dGhEYXRhTWF0Y2hbMV07XG4gICAgICAgIC8vIFNwZWNpYWwtY2FzZSBhdXRoIGRhdGEuXG4gICAgICAgIHJldHVybiB7IGtleTogYF9hdXRoX2RhdGFfJHtwcm92aWRlcn0uaWRgLCB2YWx1ZSB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGV4cGVjdGVkVHlwZUlzQXJyYXkgPVxuICAgIHNjaGVtYSAmJiBzY2hlbWEuZmllbGRzW2tleV0gJiYgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdBcnJheSc7XG5cbiAgY29uc3QgZXhwZWN0ZWRUeXBlSXNQb2ludGVyID1cbiAgICBzY2hlbWEgJiYgc2NoZW1hLmZpZWxkc1trZXldICYmIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnUG9pbnRlcic7XG5cbiAgY29uc3QgZmllbGQgPSBzY2hlbWEgJiYgc2NoZW1hLmZpZWxkc1trZXldO1xuICBpZiAoXG4gICAgZXhwZWN0ZWRUeXBlSXNQb2ludGVyIHx8XG4gICAgKCFzY2hlbWEgJiYgdmFsdWUgJiYgdmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpXG4gICkge1xuICAgIGtleSA9ICdfcF8nICsga2V5O1xuICB9XG5cbiAgLy8gSGFuZGxlIHF1ZXJ5IGNvbnN0cmFpbnRzXG4gIGNvbnN0IHRyYW5zZm9ybWVkQ29uc3RyYWludCA9IHRyYW5zZm9ybUNvbnN0cmFpbnQodmFsdWUsIGZpZWxkLCBjb3VudCk7XG4gIGlmICh0cmFuc2Zvcm1lZENvbnN0cmFpbnQgIT09IENhbm5vdFRyYW5zZm9ybSkge1xuICAgIGlmICh0cmFuc2Zvcm1lZENvbnN0cmFpbnQuJHRleHQpIHtcbiAgICAgIHJldHVybiB7IGtleTogJyR0ZXh0JywgdmFsdWU6IHRyYW5zZm9ybWVkQ29uc3RyYWludC4kdGV4dCB9O1xuICAgIH1cbiAgICBpZiAodHJhbnNmb3JtZWRDb25zdHJhaW50LiRlbGVtTWF0Y2gpIHtcbiAgICAgIHJldHVybiB7IGtleTogJyRub3InLCB2YWx1ZTogW3sgW2tleV06IHRyYW5zZm9ybWVkQ29uc3RyYWludCB9XSB9O1xuICAgIH1cbiAgICByZXR1cm4geyBrZXksIHZhbHVlOiB0cmFuc2Zvcm1lZENvbnN0cmFpbnQgfTtcbiAgfVxuXG4gIGlmIChleHBlY3RlZFR5cGVJc0FycmF5ICYmICEodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICByZXR1cm4geyBrZXksIHZhbHVlOiB7ICRhbGw6IFt0cmFuc2Zvcm1JbnRlcmlvckF0b20odmFsdWUpXSB9IH07XG4gIH1cblxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICBpZiAodHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHZhbHVlKSAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHZhbHVlKSB9O1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgIGBZb3UgY2Fubm90IHVzZSAke3ZhbHVlfSBhcyBhIHF1ZXJ5IHBhcmFtZXRlci5gXG4gICAgKTtcbiAgfVxufVxuXG4vLyBNYWluIGV4cG9zZWQgbWV0aG9kIHRvIGhlbHAgcnVuIHF1ZXJpZXMuXG4vLyByZXN0V2hlcmUgaXMgdGhlIFwid2hlcmVcIiBjbGF1c2UgaW4gUkVTVCBBUEkgZm9ybS5cbi8vIFJldHVybnMgdGhlIG1vbmdvIGZvcm0gb2YgdGhlIHF1ZXJ5LlxuZnVuY3Rpb24gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCByZXN0V2hlcmUsIHNjaGVtYSwgY291bnQgPSBmYWxzZSkge1xuICBjb25zdCBtb25nb1doZXJlID0ge307XG4gIGZvciAoY29uc3QgcmVzdEtleSBpbiByZXN0V2hlcmUpIHtcbiAgICBjb25zdCBvdXQgPSB0cmFuc2Zvcm1RdWVyeUtleVZhbHVlKFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgcmVzdEtleSxcbiAgICAgIHJlc3RXaGVyZVtyZXN0S2V5XSxcbiAgICAgIHNjaGVtYSxcbiAgICAgIGNvdW50XG4gICAgKTtcbiAgICBtb25nb1doZXJlW291dC5rZXldID0gb3V0LnZhbHVlO1xuICB9XG4gIHJldHVybiBtb25nb1doZXJlO1xufVxuXG5jb25zdCBwYXJzZU9iamVjdEtleVZhbHVlVG9Nb25nb09iamVjdEtleVZhbHVlID0gKFxuICByZXN0S2V5LFxuICByZXN0VmFsdWUsXG4gIHNjaGVtYVxuKSA9PiB7XG4gIC8vIENoZWNrIGlmIHRoZSBzY2hlbWEgaXMga25vd24gc2luY2UgaXQncyBhIGJ1aWx0LWluIGZpZWxkLlxuICBsZXQgdHJhbnNmb3JtZWRWYWx1ZTtcbiAgbGV0IGNvZXJjZWRUb0RhdGU7XG4gIHN3aXRjaCAocmVzdEtleSkge1xuICAgIGNhc2UgJ29iamVjdElkJzpcbiAgICAgIHJldHVybiB7IGtleTogJ19pZCcsIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICBjYXNlICdleHBpcmVzQXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gbmV3IERhdGUodHJhbnNmb3JtZWRWYWx1ZSlcbiAgICAgICAgICA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdleHBpcmVzQXQnLCB2YWx1ZTogY29lcmNlZFRvRGF0ZSB9O1xuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICB0cmFuc2Zvcm1lZFZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gICAgICBjb2VyY2VkVG9EYXRlID1cbiAgICAgICAgdHlwZW9mIHRyYW5zZm9ybWVkVmFsdWUgPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyBuZXcgRGF0ZSh0cmFuc2Zvcm1lZFZhbHVlKVxuICAgICAgICAgIDogdHJhbnNmb3JtZWRWYWx1ZTtcbiAgICAgIHJldHVybiB7IGtleTogJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpXG4gICAgICAgICAgOiB0cmFuc2Zvcm1lZFZhbHVlO1xuICAgICAgcmV0dXJuIHsga2V5OiAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JywgdmFsdWU6IGNvZXJjZWRUb0RhdGUgfTtcbiAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpXG4gICAgICAgICAgOiB0cmFuc2Zvcm1lZFZhbHVlO1xuICAgICAgcmV0dXJuIHsga2V5OiAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gbmV3IERhdGUodHJhbnNmb3JtZWRWYWx1ZSlcbiAgICAgICAgICA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgY2FzZSAnX3JwZXJtJzpcbiAgICBjYXNlICdfd3Blcm0nOlxuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW4nOlxuICAgIGNhc2UgJ19oYXNoZWRfcGFzc3dvcmQnOlxuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICAgIHJldHVybiB7IGtleTogcmVzdEtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4geyBrZXk6ICdfc2Vzc2lvbl90b2tlbicsIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gQXV0aCBkYXRhIHNob3VsZCBoYXZlIGJlZW4gdHJhbnNmb3JtZWQgYWxyZWFkeVxuICAgICAgaWYgKHJlc3RLZXkubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICdjYW4gb25seSBxdWVyeSBvbiAnICsgcmVzdEtleVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gVHJ1c3QgdGhhdCB0aGUgYXV0aCBkYXRhIGhhcyBiZWVuIHRyYW5zZm9ybWVkIGFuZCBzYXZlIGl0IGRpcmVjdGx5XG4gICAgICBpZiAocmVzdEtleS5tYXRjaCgvXl9hdXRoX2RhdGFfW2EtekEtWjAtOV9dKyQvKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICAgIH1cbiAgfVxuICAvL3NraXAgc3RyYWlnaHQgdG8gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tIGZvciBCeXRlcywgdGhleSBkb24ndCBzaG93IHVwIGluIHRoZSBzY2hlbWEgZm9yIHNvbWUgcmVhc29uXG4gIGlmIChyZXN0VmFsdWUgJiYgcmVzdFZhbHVlLl9fdHlwZSAhPT0gJ0J5dGVzJykge1xuICAgIC8vTm90ZTogV2UgbWF5IG5vdCBrbm93IHRoZSB0eXBlIG9mIGEgZmllbGQgaGVyZSwgYXMgdGhlIHVzZXIgY291bGQgYmUgc2F2aW5nIChudWxsKSB0byBhIGZpZWxkXG4gICAgLy9UaGF0IG5ldmVyIGV4aXN0ZWQgYmVmb3JlLCBtZWFuaW5nIHdlIGNhbid0IGluZmVyIHRoZSB0eXBlLlxuICAgIGlmIChcbiAgICAgIChzY2hlbWEuZmllbGRzW3Jlc3RLZXldICYmIHNjaGVtYS5maWVsZHNbcmVzdEtleV0udHlwZSA9PSAnUG9pbnRlcicpIHx8XG4gICAgICByZXN0VmFsdWUuX190eXBlID09ICdQb2ludGVyJ1xuICAgICkge1xuICAgICAgcmVzdEtleSA9ICdfcF8nICsgcmVzdEtleTtcbiAgICB9XG4gIH1cblxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICB2YXIgdmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgaWYgKHZhbHVlICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiB2YWx1ZSB9O1xuICB9XG5cbiAgLy8gQUNMcyBhcmUgaGFuZGxlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkXG4gIC8vIElmIGFuIEFDTCBrZXkgc3RpbGwgZXhpc3RzIGhlcmUsIHNvbWV0aGluZyBpcyB3cm9uZy5cbiAgaWYgKHJlc3RLZXkgPT09ICdBQ0wnKSB7XG4gICAgdGhyb3cgJ1RoZXJlIHdhcyBhIHByb2JsZW0gdHJhbnNmb3JtaW5nIGFuIEFDTC4nO1xuICB9XG5cbiAgLy8gSGFuZGxlIGFycmF5c1xuICBpZiAocmVzdFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICB2YWx1ZSA9IHJlc3RWYWx1ZS5tYXAodHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG4gICAgcmV0dXJuIHsga2V5OiByZXN0S2V5LCB2YWx1ZTogdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgaWYgKFxuICAgIE9iamVjdC5rZXlzKHJlc3RWYWx1ZSkuc29tZShrZXkgPT4ga2V5LmluY2x1ZGVzKCckJykgfHwga2V5LmluY2x1ZGVzKCcuJykpXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfTkVTVEVEX0tFWSxcbiAgICAgIFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIlxuICAgICk7XG4gIH1cbiAgdmFsdWUgPSBtYXBWYWx1ZXMocmVzdFZhbHVlLCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlKTtcbiAgcmV0dXJuIHsga2V5OiByZXN0S2V5LCB2YWx1ZSB9O1xufTtcblxuY29uc3QgcGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlID0gKGNsYXNzTmFtZSwgcmVzdENyZWF0ZSwgc2NoZW1hKSA9PiB7XG4gIHJlc3RDcmVhdGUgPSBhZGRMZWdhY3lBQ0wocmVzdENyZWF0ZSk7XG4gIGNvbnN0IG1vbmdvQ3JlYXRlID0ge307XG4gIGZvciAoY29uc3QgcmVzdEtleSBpbiByZXN0Q3JlYXRlKSB7XG4gICAgaWYgKHJlc3RDcmVhdGVbcmVzdEtleV0gJiYgcmVzdENyZWF0ZVtyZXN0S2V5XS5fX3R5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHBhcnNlT2JqZWN0S2V5VmFsdWVUb01vbmdvT2JqZWN0S2V5VmFsdWUoXG4gICAgICByZXN0S2V5LFxuICAgICAgcmVzdENyZWF0ZVtyZXN0S2V5XSxcbiAgICAgIHNjaGVtYVxuICAgICk7XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1vbmdvQ3JlYXRlW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBVc2UgdGhlIGxlZ2FjeSBtb25nbyBmb3JtYXQgZm9yIGNyZWF0ZWRBdCBhbmQgdXBkYXRlZEF0XG4gIGlmIChtb25nb0NyZWF0ZS5jcmVhdGVkQXQpIHtcbiAgICBtb25nb0NyZWF0ZS5fY3JlYXRlZF9hdCA9IG5ldyBEYXRlKFxuICAgICAgbW9uZ29DcmVhdGUuY3JlYXRlZEF0LmlzbyB8fCBtb25nb0NyZWF0ZS5jcmVhdGVkQXRcbiAgICApO1xuICAgIGRlbGV0ZSBtb25nb0NyZWF0ZS5jcmVhdGVkQXQ7XG4gIH1cbiAgaWYgKG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdCkge1xuICAgIG1vbmdvQ3JlYXRlLl91cGRhdGVkX2F0ID0gbmV3IERhdGUoXG4gICAgICBtb25nb0NyZWF0ZS51cGRhdGVkQXQuaXNvIHx8IG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdFxuICAgICk7XG4gICAgZGVsZXRlIG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdDtcbiAgfVxuXG4gIHJldHVybiBtb25nb0NyZWF0ZTtcbn07XG5cbi8vIE1haW4gZXhwb3NlZCBtZXRob2QgdG8gaGVscCB1cGRhdGUgb2xkIG9iamVjdHMuXG5jb25zdCB0cmFuc2Zvcm1VcGRhdGUgPSAoY2xhc3NOYW1lLCByZXN0VXBkYXRlLCBwYXJzZUZvcm1hdFNjaGVtYSkgPT4ge1xuICBjb25zdCBtb25nb1VwZGF0ZSA9IHt9O1xuICBjb25zdCBhY2wgPSBhZGRMZWdhY3lBQ0wocmVzdFVwZGF0ZSk7XG4gIGlmIChhY2wuX3JwZXJtIHx8IGFjbC5fd3Blcm0gfHwgYWNsLl9hY2wpIHtcbiAgICBtb25nb1VwZGF0ZS4kc2V0ID0ge307XG4gICAgaWYgKGFjbC5fcnBlcm0pIHtcbiAgICAgIG1vbmdvVXBkYXRlLiRzZXQuX3JwZXJtID0gYWNsLl9ycGVybTtcbiAgICB9XG4gICAgaWYgKGFjbC5fd3Blcm0pIHtcbiAgICAgIG1vbmdvVXBkYXRlLiRzZXQuX3dwZXJtID0gYWNsLl93cGVybTtcbiAgICB9XG4gICAgaWYgKGFjbC5fYWNsKSB7XG4gICAgICBtb25nb1VwZGF0ZS4kc2V0Ll9hY2wgPSBhY2wuX2FjbDtcbiAgICB9XG4gIH1cbiAgZm9yICh2YXIgcmVzdEtleSBpbiByZXN0VXBkYXRlKSB7XG4gICAgaWYgKHJlc3RVcGRhdGVbcmVzdEtleV0gJiYgcmVzdFVwZGF0ZVtyZXN0S2V5XS5fX3R5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgb3V0ID0gdHJhbnNmb3JtS2V5VmFsdWVGb3JVcGRhdGUoXG4gICAgICBjbGFzc05hbWUsXG4gICAgICByZXN0S2V5LFxuICAgICAgcmVzdFVwZGF0ZVtyZXN0S2V5XSxcbiAgICAgIHBhcnNlRm9ybWF0U2NoZW1hXG4gICAgKTtcblxuICAgIC8vIElmIHRoZSBvdXRwdXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW55ICQga2V5cywgaXQncyBhblxuICAgIC8vIG9wZXJhdG9yIHRoYXQgbmVlZHMgdG8gYmUgbGlmdGVkIG9udG8gdGhlIHRvcCBsZXZlbCB1cGRhdGVcbiAgICAvLyBvYmplY3QuXG4gICAgaWYgKHR5cGVvZiBvdXQudmFsdWUgPT09ICdvYmplY3QnICYmIG91dC52YWx1ZSAhPT0gbnVsbCAmJiBvdXQudmFsdWUuX19vcCkge1xuICAgICAgbW9uZ29VcGRhdGVbb3V0LnZhbHVlLl9fb3BdID0gbW9uZ29VcGRhdGVbb3V0LnZhbHVlLl9fb3BdIHx8IHt9O1xuICAgICAgbW9uZ29VcGRhdGVbb3V0LnZhbHVlLl9fb3BdW291dC5rZXldID0gb3V0LnZhbHVlLmFyZztcbiAgICB9IGVsc2Uge1xuICAgICAgbW9uZ29VcGRhdGVbJyRzZXQnXSA9IG1vbmdvVXBkYXRlWyckc2V0J10gfHwge307XG4gICAgICBtb25nb1VwZGF0ZVsnJHNldCddW291dC5rZXldID0gb3V0LnZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtb25nb1VwZGF0ZTtcbn07XG5cbi8vIEFkZCB0aGUgbGVnYWN5IF9hY2wgZm9ybWF0LlxuY29uc3QgYWRkTGVnYWN5QUNMID0gcmVzdE9iamVjdCA9PiB7XG4gIGNvbnN0IHJlc3RPYmplY3RDb3B5ID0geyAuLi5yZXN0T2JqZWN0IH07XG4gIGNvbnN0IF9hY2wgPSB7fTtcblxuICBpZiAocmVzdE9iamVjdC5fd3Blcm0pIHtcbiAgICByZXN0T2JqZWN0Ll93cGVybS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIF9hY2xbZW50cnldID0geyB3OiB0cnVlIH07XG4gICAgfSk7XG4gICAgcmVzdE9iamVjdENvcHkuX2FjbCA9IF9hY2w7XG4gIH1cblxuICBpZiAocmVzdE9iamVjdC5fcnBlcm0pIHtcbiAgICByZXN0T2JqZWN0Ll9ycGVybS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmICghKGVudHJ5IGluIF9hY2wpKSB7XG4gICAgICAgIF9hY2xbZW50cnldID0geyByOiB0cnVlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfYWNsW2VudHJ5XS5yID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXN0T2JqZWN0Q29weS5fYWNsID0gX2FjbDtcbiAgfVxuXG4gIHJldHVybiByZXN0T2JqZWN0Q29weTtcbn07XG5cbi8vIEEgc2VudGluZWwgdmFsdWUgdGhhdCBoZWxwZXIgdHJhbnNmb3JtYXRpb25zIHJldHVybiB3aGVuIHRoZXlcbi8vIGNhbm5vdCBwZXJmb3JtIGEgdHJhbnNmb3JtYXRpb25cbmZ1bmN0aW9uIENhbm5vdFRyYW5zZm9ybSgpIHt9XG5cbmNvbnN0IHRyYW5zZm9ybUludGVyaW9yQXRvbSA9IGF0b20gPT4ge1xuICAvLyBUT0RPOiBjaGVjayB2YWxpZGl0eSBoYXJkZXIgZm9yIHRoZSBfX3R5cGUtZGVmaW5lZCB0eXBlc1xuICBpZiAoXG4gICAgdHlwZW9mIGF0b20gPT09ICdvYmplY3QnICYmXG4gICAgYXRvbSAmJlxuICAgICEoYXRvbSBpbnN0YW5jZW9mIERhdGUpICYmXG4gICAgYXRvbS5fX3R5cGUgPT09ICdQb2ludGVyJ1xuICApIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICBjbGFzc05hbWU6IGF0b20uY2xhc3NOYW1lLFxuICAgICAgb2JqZWN0SWQ6IGF0b20ub2JqZWN0SWQsXG4gICAgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXRvbSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgYXRvbSA9PT0gJ3N5bWJvbCcpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgY2Fubm90IHRyYW5zZm9ybSB2YWx1ZTogJHthdG9tfWBcbiAgICApO1xuICB9IGVsc2UgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBEYXRlQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gIH0gZWxzZSBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBCeXRlc0NvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhdG9tID09PSAnb2JqZWN0JyAmJiBhdG9tICYmIGF0b20uJHJlZ2V4ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChhdG9tLiRyZWdleCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGF0b207XG4gIH1cbn07XG5cbi8vIEhlbHBlciBmdW5jdGlvbiB0byB0cmFuc2Zvcm0gYW4gYXRvbSBmcm9tIFJFU1QgZm9ybWF0IHRvIE1vbmdvIGZvcm1hdC5cbi8vIEFuIGF0b20gaXMgYW55dGhpbmcgdGhhdCBjYW4ndCBjb250YWluIG90aGVyIGV4cHJlc3Npb25zLiBTbyBpdFxuLy8gaW5jbHVkZXMgdGhpbmdzIHdoZXJlIG9iamVjdHMgYXJlIHVzZWQgdG8gcmVwcmVzZW50IG90aGVyXG4vLyBkYXRhdHlwZXMsIGxpa2UgcG9pbnRlcnMgYW5kIGRhdGVzLCBidXQgaXQgZG9lcyBub3QgaW5jbHVkZSBvYmplY3RzXG4vLyBvciBhcnJheXMgd2l0aCBnZW5lcmljIHN0dWZmIGluc2lkZS5cbi8vIFJhaXNlcyBhbiBlcnJvciBpZiB0aGlzIGNhbm5vdCBwb3NzaWJseSBiZSB2YWxpZCBSRVNUIGZvcm1hdC5cbi8vIFJldHVybnMgQ2Fubm90VHJhbnNmb3JtIGlmIGl0J3MganVzdCBub3QgYW4gYXRvbVxuZnVuY3Rpb24gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKGF0b20sIGZpZWxkKSB7XG4gIHN3aXRjaCAodHlwZW9mIGF0b20pIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gYXRvbTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7ZmllbGQudGFyZ2V0Q2xhc3N9JCR7YXRvbX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0b207XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgYGNhbm5vdCB0cmFuc2Zvcm0gdmFsdWU6ICR7YXRvbX1gXG4gICAgICApO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoYXRvbSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgLy8gVGVjaG5pY2FsbHkgZGF0ZXMgYXJlIG5vdCByZXN0IGZvcm1hdCwgYnV0LCBpdCBzZWVtcyBwcmV0dHlcbiAgICAgICAgLy8gY2xlYXIgd2hhdCB0aGV5IHNob3VsZCBiZSB0cmFuc2Zvcm1lZCB0bywgc28gbGV0J3MganVzdCBkbyBpdC5cbiAgICAgICAgcmV0dXJuIGF0b207XG4gICAgICB9XG5cbiAgICAgIGlmIChhdG9tID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBhdG9tO1xuICAgICAgfVxuXG4gICAgICAvLyBUT0RPOiBjaGVjayB2YWxpZGl0eSBoYXJkZXIgZm9yIHRoZSBfX3R5cGUtZGVmaW5lZCB0eXBlc1xuICAgICAgaWYgKGF0b20uX190eXBlID09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7YXRvbS5jbGFzc05hbWV9JCR7YXRvbS5vYmplY3RJZH1gO1xuICAgICAgfVxuICAgICAgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gRGF0ZUNvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICAgICAgfVxuICAgICAgaWYgKEJ5dGVzQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEJ5dGVzQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gICAgICB9XG4gICAgICBpZiAoR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gR2VvUG9pbnRDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChQb2x5Z29uQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIFBvbHlnb25Db2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChGaWxlQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBDYW5ub3RUcmFuc2Zvcm07XG5cbiAgICBkZWZhdWx0OlxuICAgICAgLy8gSSBkb24ndCB0aGluayB0eXBlb2YgY2FuIGV2ZXIgbGV0IHVzIGdldCBoZXJlXG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgYHJlYWxseSBkaWQgbm90IGV4cGVjdCB2YWx1ZTogJHthdG9tfWBcbiAgICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVsYXRpdmVUaW1lVG9EYXRlKHRleHQsIG5vdyA9IG5ldyBEYXRlKCkpIHtcbiAgdGV4dCA9IHRleHQudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgcGFydHMgPSB0ZXh0LnNwbGl0KCcgJyk7XG5cbiAgLy8gRmlsdGVyIG91dCB3aGl0ZXNwYWNlXG4gIHBhcnRzID0gcGFydHMuZmlsdGVyKHBhcnQgPT4gcGFydCAhPT0gJycpO1xuXG4gIGNvbnN0IGZ1dHVyZSA9IHBhcnRzWzBdID09PSAnaW4nO1xuICBjb25zdCBwYXN0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV0gPT09ICdhZ28nO1xuXG4gIGlmICghZnV0dXJlICYmICFwYXN0ICYmIHRleHQgIT09ICdub3cnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIGluZm86IFwiVGltZSBzaG91bGQgZWl0aGVyIHN0YXJ0IHdpdGggJ2luJyBvciBlbmQgd2l0aCAnYWdvJ1wiLFxuICAgIH07XG4gIH1cblxuICBpZiAoZnV0dXJlICYmIHBhc3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgaW5mbzogXCJUaW1lIGNhbm5vdCBoYXZlIGJvdGggJ2luJyBhbmQgJ2FnbydcIixcbiAgICB9O1xuICB9XG5cbiAgLy8gc3RyaXAgdGhlICdhZ28nIG9yICdpbidcbiAgaWYgKGZ1dHVyZSkge1xuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcGFzdFxuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMCwgcGFydHMubGVuZ3RoIC0gMSk7XG4gIH1cblxuICBpZiAocGFydHMubGVuZ3RoICUgMiAhPT0gMCAmJiB0ZXh0ICE9PSAnbm93Jykge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICBpbmZvOiAnSW52YWxpZCB0aW1lIHN0cmluZy4gRGFuZ2xpbmcgdW5pdCBvciBudW1iZXIuJyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFpcnMgPSBbXTtcbiAgd2hpbGUgKHBhcnRzLmxlbmd0aCkge1xuICAgIHBhaXJzLnB1c2goW3BhcnRzLnNoaWZ0KCksIHBhcnRzLnNoaWZ0KCldKTtcbiAgfVxuXG4gIGxldCBzZWNvbmRzID0gMDtcbiAgZm9yIChjb25zdCBbbnVtLCBpbnRlcnZhbF0gb2YgcGFpcnMpIHtcbiAgICBjb25zdCB2YWwgPSBOdW1iZXIobnVtKTtcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgICBpbmZvOiBgJyR7bnVtfScgaXMgbm90IGFuIGludGVnZXIuYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgY2FzZSAneXInOlxuICAgICAgY2FzZSAneXJzJzpcbiAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgY2FzZSAneWVhcnMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDMxNTM2MDAwOyAvLyAzNjUgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3drJzpcbiAgICAgIGNhc2UgJ3drcyc6XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgIGNhc2UgJ3dlZWtzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiA2MDQ4MDA7IC8vIDcgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2QnOlxuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgIGNhc2UgJ2RheXMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDg2NDAwOyAvLyAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2hyJzpcbiAgICAgIGNhc2UgJ2hycyc6XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgIGNhc2UgJ2hvdXJzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiAzNjAwOyAvLyA2MCAqIDYwXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgY2FzZSAnbWlucyc6XG4gICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgY2FzZSAnbWludXRlcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsICogNjA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzZWMnOlxuICAgICAgY2FzZSAnc2Vjcyc6XG4gICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgY2FzZSAnc2Vjb25kcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICAgICAgaW5mbzogYEludmFsaWQgaW50ZXJ2YWw6ICcke2ludGVydmFsfSdgLFxuICAgICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1pbGxpc2Vjb25kcyA9IHNlY29uZHMgKiAxMDAwO1xuICBpZiAoZnV0dXJlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxuICAgICAgaW5mbzogJ2Z1dHVyZScsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMpLFxuICAgIH07XG4gIH0gZWxzZSBpZiAocGFzdCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcbiAgICAgIGluZm86ICdwYXN0JyxcbiAgICAgIHJlc3VsdDogbmV3IERhdGUobm93LnZhbHVlT2YoKSAtIG1pbGxpc2Vjb25kcyksXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXG4gICAgICBpbmZvOiAncHJlc2VudCcsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkpLFxuICAgIH07XG4gIH1cbn1cblxuLy8gVHJhbnNmb3JtcyBhIHF1ZXJ5IGNvbnN0cmFpbnQgZnJvbSBSRVNUIEFQSSBmb3JtYXQgdG8gTW9uZ28gZm9ybWF0LlxuLy8gQSBjb25zdHJhaW50IGlzIHNvbWV0aGluZyB3aXRoIGZpZWxkcyBsaWtlICRsdC5cbi8vIElmIGl0IGlzIG5vdCBhIHZhbGlkIGNvbnN0cmFpbnQgYnV0IGl0IGNvdWxkIGJlIGEgdmFsaWQgc29tZXRoaW5nXG4vLyBlbHNlLCByZXR1cm4gQ2Fubm90VHJhbnNmb3JtLlxuLy8gaW5BcnJheSBpcyB3aGV0aGVyIHRoaXMgaXMgYW4gYXJyYXkgZmllbGQuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Db25zdHJhaW50KGNvbnN0cmFpbnQsIGZpZWxkLCBjb3VudCA9IGZhbHNlKSB7XG4gIGNvbnN0IGluQXJyYXkgPSBmaWVsZCAmJiBmaWVsZC50eXBlICYmIGZpZWxkLnR5cGUgPT09ICdBcnJheSc7XG4gIGlmICh0eXBlb2YgY29uc3RyYWludCAhPT0gJ29iamVjdCcgfHwgIWNvbnN0cmFpbnQpIHtcbiAgICByZXR1cm4gQ2Fubm90VHJhbnNmb3JtO1xuICB9XG4gIGNvbnN0IHRyYW5zZm9ybUZ1bmN0aW9uID0gaW5BcnJheVxuICAgID8gdHJhbnNmb3JtSW50ZXJpb3JBdG9tXG4gICAgOiB0cmFuc2Zvcm1Ub3BMZXZlbEF0b207XG4gIGNvbnN0IHRyYW5zZm9ybWVyID0gYXRvbSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtRnVuY3Rpb24oYXRvbSwgZmllbGQpO1xuICAgIGlmIChyZXN1bHQgPT09IENhbm5vdFRyYW5zZm9ybSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGBiYWQgYXRvbTogJHtKU09OLnN0cmluZ2lmeShhdG9tKX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAvLyBrZXlzIGlzIHRoZSBjb25zdHJhaW50cyBpbiByZXZlcnNlIGFscGhhYmV0aWNhbCBvcmRlci5cbiAgLy8gVGhpcyBpcyBhIGhhY2sgc28gdGhhdDpcbiAgLy8gICAkcmVnZXggaXMgaGFuZGxlZCBiZWZvcmUgJG9wdGlvbnNcbiAgLy8gICAkbmVhclNwaGVyZSBpcyBoYW5kbGVkIGJlZm9yZSAkbWF4RGlzdGFuY2VcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhjb25zdHJhaW50KVxuICAgIC5zb3J0KClcbiAgICAucmV2ZXJzZSgpO1xuICB2YXIgYW5zd2VyID0ge307XG4gIGZvciAodmFyIGtleSBvZiBrZXlzKSB7XG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIGNhc2UgJyRsdCc6XG4gICAgICBjYXNlICckbHRlJzpcbiAgICAgIGNhc2UgJyRndCc6XG4gICAgICBjYXNlICckZ3RlJzpcbiAgICAgIGNhc2UgJyRleGlzdHMnOlxuICAgICAgY2FzZSAnJG5lJzpcbiAgICAgIGNhc2UgJyRlcSc6IHtcbiAgICAgICAgY29uc3QgdmFsID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC4kcmVsYXRpdmVUaW1lKSB7XG4gICAgICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgIT09ICdEYXRlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICckcmVsYXRpdmVUaW1lIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCBEYXRlIGZpZWxkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgY2FzZSAnJGV4aXN0cyc6XG4gICAgICAgICAgICBjYXNlICckbmUnOlxuICAgICAgICAgICAgY2FzZSAnJGVxJzpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnJHJlbGF0aXZlVGltZSBjYW4gb25seSBiZSB1c2VkIHdpdGggdGhlICRsdCwgJGx0ZSwgJGd0LCBhbmQgJGd0ZSBvcGVyYXRvcnMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcGFyc2VyUmVzdWx0ID0gcmVsYXRpdmVUaW1lVG9EYXRlKHZhbC4kcmVsYXRpdmVUaW1lKTtcbiAgICAgICAgICBpZiAocGFyc2VyUmVzdWx0LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSB7XG4gICAgICAgICAgICBhbnN3ZXJba2V5XSA9IHBhcnNlclJlc3VsdC5yZXN1bHQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsb2cuaW5mbygnRXJyb3Igd2hpbGUgcGFyc2luZyByZWxhdGl2ZSBkYXRlJywgcGFyc2VyUmVzdWx0KTtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICRyZWxhdGl2ZVRpbWUgKCR7a2V5fSkgdmFsdWUuICR7cGFyc2VyUmVzdWx0LmluZm99YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBhbnN3ZXJba2V5XSA9IHRyYW5zZm9ybWVyKHZhbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICckaW4nOlxuICAgICAgY2FzZSAnJG5pbic6IHtcbiAgICAgICAgY29uc3QgYXJyID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICcgKyBrZXkgKyAnIHZhbHVlJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSBfLmZsYXRNYXAoYXJyLCB2YWx1ZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIChhdG9tID0+IHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGF0b20pKSB7XG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5tYXAodHJhbnNmb3JtZXIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybWVyKGF0b20pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJGFsbCc6IHtcbiAgICAgICAgY29uc3QgYXJyID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICcgKyBrZXkgKyAnIHZhbHVlJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSBhcnIubWFwKHRyYW5zZm9ybUludGVyaW9yQXRvbSk7XG5cbiAgICAgICAgY29uc3QgdmFsdWVzID0gYW5zd2VyW2tleV07XG4gICAgICAgIGlmIChpc0FueVZhbHVlUmVnZXgodmFsdWVzKSAmJiAhaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSh2YWx1ZXMpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgJ0FsbCAkYWxsIHZhbHVlcyBtdXN0IGJlIG9mIHJlZ2V4IHR5cGUgb3Igbm9uZTogJyArIHZhbHVlc1xuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRyZWdleCc6XG4gICAgICAgIHZhciBzID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIHMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCByZWdleDogJyArIHMpO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0gcztcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyRjb250YWluZWRCeSc6IHtcbiAgICAgICAgY29uc3QgYXJyID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICRjb250YWluZWRCeTogc2hvdWxkIGJlIGFuIGFycmF5YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyLiRlbGVtTWF0Y2ggPSB7XG4gICAgICAgICAgJG5pbjogYXJyLm1hcCh0cmFuc2Zvcm1lciksXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG9wdGlvbnMnOlxuICAgICAgICBhbnN3ZXJba2V5XSA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyR0ZXh0Jzoge1xuICAgICAgICBjb25zdCBzZWFyY2ggPSBjb25zdHJhaW50W2tleV0uJHNlYXJjaDtcbiAgICAgICAgaWYgKHR5cGVvZiBzZWFyY2ggIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJHNlYXJjaCwgc2hvdWxkIGJlIG9iamVjdGBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc2VhcmNoLiR0ZXJtIHx8IHR5cGVvZiBzZWFyY2guJHRlcm0gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJHRlcm0sIHNob3VsZCBiZSBzdHJpbmdgXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhbnN3ZXJba2V5XSA9IHtcbiAgICAgICAgICAgICRzZWFyY2g6IHNlYXJjaC4kdGVybSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWFyY2guJGxhbmd1YWdlICYmIHR5cGVvZiBzZWFyY2guJGxhbmd1YWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGBiYWQgJHRleHQ6ICRsYW5ndWFnZSwgc2hvdWxkIGJlIHN0cmluZ2BcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHNlYXJjaC4kbGFuZ3VhZ2UpIHtcbiAgICAgICAgICBhbnN3ZXJba2V5XS4kbGFuZ3VhZ2UgPSBzZWFyY2guJGxhbmd1YWdlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzZWFyY2guJGNhc2VTZW5zaXRpdmUgJiZcbiAgICAgICAgICB0eXBlb2Ygc2VhcmNoLiRjYXNlU2Vuc2l0aXZlICE9PSAnYm9vbGVhbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJGNhc2VTZW5zaXRpdmUsIHNob3VsZCBiZSBib29sZWFuYFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRjYXNlU2Vuc2l0aXZlKSB7XG4gICAgICAgICAgYW5zd2VyW2tleV0uJGNhc2VTZW5zaXRpdmUgPSBzZWFyY2guJGNhc2VTZW5zaXRpdmU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICYmXG4gICAgICAgICAgdHlwZW9mIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICE9PSAnYm9vbGVhbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYGJhZCAkdGV4dDogJGRpYWNyaXRpY1NlbnNpdGl2ZSwgc2hvdWxkIGJlIGJvb2xlYW5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZSkge1xuICAgICAgICAgIGFuc3dlcltrZXldLiRkaWFjcml0aWNTZW5zaXRpdmUgPSBzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRuZWFyU3BoZXJlJzoge1xuICAgICAgICBjb25zdCBwb2ludCA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgYW5zd2VyLiRnZW9XaXRoaW4gPSB7XG4gICAgICAgICAgICAkY2VudGVyU3BoZXJlOiBbXG4gICAgICAgICAgICAgIFtwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXSxcbiAgICAgICAgICAgICAgY29uc3RyYWludC4kbWF4RGlzdGFuY2UsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYW5zd2VyW2tleV0gPSBbcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZV07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckbWF4RGlzdGFuY2UnOiB7XG4gICAgICAgIGlmIChjb3VudCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBTREtzIGRvbid0IHNlZW0gdG8gdXNlIHRoZXNlIGJ1dCB0aGV5IGFyZSBkb2N1bWVudGVkIGluIHRoZVxuICAgICAgLy8gUkVTVCBBUEkgZG9jcy5cbiAgICAgIGNhc2UgJyRtYXhEaXN0YW5jZUluUmFkaWFucyc6XG4gICAgICAgIGFuc3dlclsnJG1heERpc3RhbmNlJ10gPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG1heERpc3RhbmNlSW5NaWxlcyc6XG4gICAgICAgIGFuc3dlclsnJG1heERpc3RhbmNlJ10gPSBjb25zdHJhaW50W2tleV0gLyAzOTU5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRtYXhEaXN0YW5jZUluS2lsb21ldGVycyc6XG4gICAgICAgIGFuc3dlclsnJG1heERpc3RhbmNlJ10gPSBjb25zdHJhaW50W2tleV0gLyA2MzcxO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnJHNlbGVjdCc6XG4gICAgICBjYXNlICckZG9udFNlbGVjdCc6XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5DT01NQU5EX1VOQVZBSUxBQkxFLFxuICAgICAgICAgICd0aGUgJyArIGtleSArICcgY29uc3RyYWludCBpcyBub3Qgc3VwcG9ydGVkIHlldCdcbiAgICAgICAgKTtcblxuICAgICAgY2FzZSAnJHdpdGhpbic6XG4gICAgICAgIHZhciBib3ggPSBjb25zdHJhaW50W2tleV1bJyRib3gnXTtcbiAgICAgICAgaWYgKCFib3ggfHwgYm94Lmxlbmd0aCAhPSAyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgJ21hbGZvcm1hdHRlZCAkd2l0aGluIGFyZydcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICRib3g6IFtcbiAgICAgICAgICAgIFtib3hbMF0ubG9uZ2l0dWRlLCBib3hbMF0ubGF0aXR1ZGVdLFxuICAgICAgICAgICAgW2JveFsxXS5sb25naXR1ZGUsIGJveFsxXS5sYXRpdHVkZV0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyRnZW9XaXRoaW4nOiB7XG4gICAgICAgIGNvbnN0IHBvbHlnb24gPSBjb25zdHJhaW50W2tleV1bJyRwb2x5Z29uJ107XG4gICAgICAgIGNvbnN0IGNlbnRlclNwaGVyZSA9IGNvbnN0cmFpbnRba2V5XVsnJGNlbnRlclNwaGVyZSddO1xuICAgICAgICBpZiAocG9seWdvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbGV0IHBvaW50cztcbiAgICAgICAgICBpZiAodHlwZW9mIHBvbHlnb24gPT09ICdvYmplY3QnICYmIHBvbHlnb24uX190eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgICAgIGlmICghcG9seWdvbi5jb29yZGluYXRlcyB8fCBwb2x5Z29uLmNvb3JkaW5hdGVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7IFBvbHlnb24uY29vcmRpbmF0ZXMgc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBsb24vbGF0IHBhaXJzJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9pbnRzID0gcG9seWdvbi5jb29yZGluYXRlcztcbiAgICAgICAgICB9IGVsc2UgaWYgKHBvbHlnb24gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgaWYgKHBvbHlnb24ubGVuZ3RoIDwgMykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBHZW9Qb2ludHMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb2ludHMgPSBwb2x5Z29uO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgXCJiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGJlIFBvbHlnb24gb2JqZWN0IG9yIEFycmF5IG9mIFBhcnNlLkdlb1BvaW50J3NcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcG9pbnRzID0gcG9pbnRzLm1hcChwb2ludCA9PiB7XG4gICAgICAgICAgICBpZiAocG9pbnQgaW5zdGFuY2VvZiBBcnJheSAmJiBwb2ludC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICAgICAgICAgIHJldHVybiBwb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihwb2ludCkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWUnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBQYXJzZS5HZW9Qb2ludC5fdmFsaWRhdGUocG9pbnQubGF0aXR1ZGUsIHBvaW50LmxvbmdpdHVkZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gW3BvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGVdO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICAgJHBvbHlnb246IHBvaW50cyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGNlbnRlclNwaGVyZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKCEoY2VudGVyU3BoZXJlIGluc3RhbmNlb2YgQXJyYXkpIHx8IGNlbnRlclNwaGVyZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlOyAkY2VudGVyU3BoZXJlIHNob3VsZCBiZSBhbiBhcnJheSBvZiBQYXJzZS5HZW9Qb2ludCBhbmQgZGlzdGFuY2UnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBHZXQgcG9pbnQsIGNvbnZlcnQgdG8gZ2VvIHBvaW50IGlmIG5lY2Vzc2FyeSBhbmQgdmFsaWRhdGVcbiAgICAgICAgICBsZXQgcG9pbnQgPSBjZW50ZXJTcGhlcmVbMF07XG4gICAgICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBwb2ludCA9IG5ldyBQYXJzZS5HZW9Qb2ludChwb2ludFsxXSwgcG9pbnRbMF0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZEpTT04ocG9pbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlOyAkY2VudGVyU3BoZXJlIGdlbyBwb2ludCBpbnZhbGlkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgIC8vIEdldCBkaXN0YW5jZSBhbmQgdmFsaWRhdGVcbiAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGNlbnRlclNwaGVyZVsxXTtcbiAgICAgICAgICBpZiAoaXNOYU4oZGlzdGFuY2UpIHx8IGRpc3RhbmNlIDwgMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBkaXN0YW5jZSBpbnZhbGlkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYW5zd2VyW2tleV0gPSB7XG4gICAgICAgICAgICAkY2VudGVyU3BoZXJlOiBbW3BvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGVdLCBkaXN0YW5jZV0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRnZW9JbnRlcnNlY3RzJzoge1xuICAgICAgICBjb25zdCBwb2ludCA9IGNvbnN0cmFpbnRba2V5XVsnJHBvaW50J107XG4gICAgICAgIGlmICghR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihwb2ludCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9JbnRlcnNlY3QgdmFsdWU7ICRwb2ludCBzaG91bGQgYmUgR2VvUG9pbnQnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBQYXJzZS5HZW9Qb2ludC5fdmFsaWRhdGUocG9pbnQubGF0aXR1ZGUsIHBvaW50LmxvbmdpdHVkZSk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSB7XG4gICAgICAgICAgJGdlb21ldHJ5OiB7XG4gICAgICAgICAgICB0eXBlOiAnUG9pbnQnLFxuICAgICAgICAgICAgY29vcmRpbmF0ZXM6IFtwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChrZXkubWF0Y2goL15cXCQrLykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkIGNvbnN0cmFpbnQ6ICcgKyBrZXlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDYW5ub3RUcmFuc2Zvcm07XG4gICAgfVxuICB9XG4gIHJldHVybiBhbnN3ZXI7XG59XG5cbi8vIFRyYW5zZm9ybXMgYW4gdXBkYXRlIG9wZXJhdG9yIGZyb20gUkVTVCBmb3JtYXQgdG8gbW9uZ28gZm9ybWF0LlxuLy8gVG8gYmUgdHJhbnNmb3JtZWQsIHRoZSBpbnB1dCBzaG91bGQgaGF2ZSBhbiBfX29wIGZpZWxkLlxuLy8gSWYgZmxhdHRlbiBpcyB0cnVlLCB0aGlzIHdpbGwgZmxhdHRlbiBvcGVyYXRvcnMgdG8gdGhlaXIgc3RhdGljXG4vLyBkYXRhIGZvcm1hdC4gRm9yIGV4YW1wbGUsIGFuIGluY3JlbWVudCBvZiAyIHdvdWxkIHNpbXBseSBiZWNvbWUgYVxuLy8gMi5cbi8vIFRoZSBvdXRwdXQgZm9yIGEgbm9uLWZsYXR0ZW5lZCBvcGVyYXRvciBpcyBhIGhhc2ggd2l0aCBfX29wIGJlaW5nXG4vLyB0aGUgbW9uZ28gb3AsIGFuZCBhcmcgYmVpbmcgdGhlIGFyZ3VtZW50LlxuLy8gVGhlIG91dHB1dCBmb3IgYSBmbGF0dGVuZWQgb3BlcmF0b3IgaXMganVzdCBhIHZhbHVlLlxuLy8gUmV0dXJucyB1bmRlZmluZWQgaWYgdGhpcyBzaG91bGQgYmUgYSBuby1vcC5cblxuZnVuY3Rpb24gdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IoeyBfX29wLCBhbW91bnQsIG9iamVjdHMgfSwgZmxhdHRlbikge1xuICBzd2l0Y2ggKF9fb3ApIHtcbiAgICBjYXNlICdEZWxldGUnOlxuICAgICAgaWYgKGZsYXR0ZW4pIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IF9fb3A6ICckdW5zZXQnLCBhcmc6ICcnIH07XG4gICAgICB9XG5cbiAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgaWYgKHR5cGVvZiBhbW91bnQgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ2luY3JlbWVudGluZyBtdXN0IHByb3ZpZGUgYSBudW1iZXInXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmxhdHRlbikge1xuICAgICAgICByZXR1cm4gYW1vdW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgX19vcDogJyRpbmMnLCBhcmc6IGFtb3VudCB9O1xuICAgICAgfVxuXG4gICAgY2FzZSAnQWRkJzpcbiAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgaWYgKCEob2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICdvYmplY3RzIHRvIGFkZCBtdXN0IGJlIGFuIGFycmF5J1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdmFyIHRvQWRkID0gb2JqZWN0cy5tYXAodHJhbnNmb3JtSW50ZXJpb3JBdG9tKTtcbiAgICAgIGlmIChmbGF0dGVuKSB7XG4gICAgICAgIHJldHVybiB0b0FkZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBtb25nb09wID0ge1xuICAgICAgICAgIEFkZDogJyRwdXNoJyxcbiAgICAgICAgICBBZGRVbmlxdWU6ICckYWRkVG9TZXQnLFxuICAgICAgICB9W19fb3BdO1xuICAgICAgICByZXR1cm4geyBfX29wOiBtb25nb09wLCBhcmc6IHsgJGVhY2g6IHRvQWRkIH0gfTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ1JlbW92ZSc6XG4gICAgICBpZiAoIShvYmplY3RzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ29iamVjdHMgdG8gcmVtb3ZlIG11c3QgYmUgYW4gYXJyYXknXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YXIgdG9SZW1vdmUgPSBvYmplY3RzLm1hcCh0cmFuc2Zvcm1JbnRlcmlvckF0b20pO1xuICAgICAgaWYgKGZsYXR0ZW4pIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgX19vcDogJyRwdWxsQWxsJywgYXJnOiB0b1JlbW92ZSB9O1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuQ09NTUFORF9VTkFWQUlMQUJMRSxcbiAgICAgICAgYFRoZSAke19fb3B9IG9wZXJhdG9yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LmBcbiAgICAgICk7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcFZhbHVlcyhvYmplY3QsIGl0ZXJhdG9yKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHt9O1xuICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICByZXN1bHRba2V5XSA9IGl0ZXJhdG9yKG9iamVjdFtrZXldKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmNvbnN0IG5lc3RlZE1vbmdvT2JqZWN0VG9OZXN0ZWRQYXJzZU9iamVjdCA9IG1vbmdvT2JqZWN0ID0+IHtcbiAgc3dpdGNoICh0eXBlb2YgbW9uZ29PYmplY3QpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiBtb25nb09iamVjdDtcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgIHRocm93ICdiYWQgdmFsdWUgaW4gbmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0JztcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgaWYgKG1vbmdvT2JqZWN0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0Lm1hcChuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIHJldHVybiBQYXJzZS5fZW5jb2RlKG1vbmdvT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgbW9uZ29kYi5Mb25nKSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC50b051bWJlcigpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkRvdWJsZSkge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChCeXRlc0NvZGVyLmlzVmFsaWREYXRhYmFzZU9iamVjdChtb25nb09iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIEJ5dGVzQ29kZXIuZGF0YWJhc2VUb0pTT04obW9uZ29PYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb25nb09iamVjdCwgJ19fdHlwZScpICYmXG4gICAgICAgIG1vbmdvT2JqZWN0Ll9fdHlwZSA9PSAnRGF0ZScgJiZcbiAgICAgICAgbW9uZ29PYmplY3QuaXNvIGluc3RhbmNlb2YgRGF0ZVxuICAgICAgKSB7XG4gICAgICAgIG1vbmdvT2JqZWN0LmlzbyA9IG1vbmdvT2JqZWN0Lmlzby50b0pTT04oKTtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbWFwVmFsdWVzKG1vbmdvT2JqZWN0LCBuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyAndW5rbm93biBqcyB0eXBlJztcbiAgfVxufTtcblxuY29uc3QgdHJhbnNmb3JtUG9pbnRlclN0cmluZyA9IChzY2hlbWEsIGZpZWxkLCBwb2ludGVyU3RyaW5nKSA9PiB7XG4gIGNvbnN0IG9iakRhdGEgPSBwb2ludGVyU3RyaW5nLnNwbGl0KCckJyk7XG4gIGlmIChvYmpEYXRhWzBdICE9PSBzY2hlbWEuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzcykge1xuICAgIHRocm93ICdwb2ludGVyIHRvIGluY29ycmVjdCBjbGFzc05hbWUnO1xuICB9XG4gIHJldHVybiB7XG4gICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgY2xhc3NOYW1lOiBvYmpEYXRhWzBdLFxuICAgIG9iamVjdElkOiBvYmpEYXRhWzFdLFxuICB9O1xufTtcblxuLy8gQ29udmVydHMgZnJvbSBhIG1vbmdvLWZvcm1hdCBvYmplY3QgdG8gYSBSRVNULWZvcm1hdCBvYmplY3QuXG4vLyBEb2VzIG5vdCBzdHJpcCBvdXQgYW55dGhpbmcgYmFzZWQgb24gYSBsYWNrIG9mIGF1dGhlbnRpY2F0aW9uLlxuY29uc3QgbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0ID0gKGNsYXNzTmFtZSwgbW9uZ29PYmplY3QsIHNjaGVtYSkgPT4ge1xuICBzd2l0Y2ggKHR5cGVvZiBtb25nb09iamVjdCkge1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0O1xuICAgIGNhc2UgJ3N5bWJvbCc6XG4gICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgdGhyb3cgJ2JhZCB2YWx1ZSBpbiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QnO1xuICAgIGNhc2UgJ29iamVjdCc6IHtcbiAgICAgIGlmIChtb25nb09iamVjdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC5tYXAobmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICByZXR1cm4gUGFyc2UuX2VuY29kZShtb25nb09iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIG1vbmdvZGIuTG9uZykge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QudG9OdW1iZXIoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgbW9uZ29kYi5Eb3VibGUpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0LnZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QobW9uZ29PYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBCeXRlc0NvZGVyLmRhdGFiYXNlVG9KU09OKG1vbmdvT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdE9iamVjdCA9IHt9O1xuICAgICAgaWYgKG1vbmdvT2JqZWN0Ll9ycGVybSB8fCBtb25nb09iamVjdC5fd3Blcm0pIHtcbiAgICAgICAgcmVzdE9iamVjdC5fcnBlcm0gPSBtb25nb09iamVjdC5fcnBlcm0gfHwgW107XG4gICAgICAgIHJlc3RPYmplY3QuX3dwZXJtID0gbW9uZ29PYmplY3QuX3dwZXJtIHx8IFtdO1xuICAgICAgICBkZWxldGUgbW9uZ29PYmplY3QuX3JwZXJtO1xuICAgICAgICBkZWxldGUgbW9uZ29PYmplY3QuX3dwZXJtO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gbW9uZ29PYmplY3QpIHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICBjYXNlICdfaWQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnb2JqZWN0SWQnXSA9ICcnICsgbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19oYXNoZWRfcGFzc3dvcmQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdC5faGFzaGVkX3Bhc3N3b3JkID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19hY2wnOlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbic6XG4gICAgICAgICAgY2FzZSAnX3BlcmlzaGFibGVfdG9rZW4nOlxuICAgICAgICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgICAgIGNhc2UgJ19wYXNzd29yZF9jaGFuZ2VkX2F0JzpcbiAgICAgICAgICBjYXNlICdfdG9tYnN0b25lJzpcbiAgICAgICAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgICAgIGNhc2UgJ19hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCc6XG4gICAgICAgICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgICAgICAgY2FzZSAnX3Bhc3N3b3JkX2hpc3RvcnknOlxuICAgICAgICAgICAgLy8gVGhvc2Uga2V5cyB3aWxsIGJlIGRlbGV0ZWQgaWYgbmVlZGVkIGluIHRoZSBEQiBDb250cm9sbGVyXG4gICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnX3Nlc3Npb25fdG9rZW4nOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnc2Vzc2lvblRva2VuJ10gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgICAgICBjYXNlICdfdXBkYXRlZF9hdCc6XG4gICAgICAgICAgICByZXN0T2JqZWN0Wyd1cGRhdGVkQXQnXSA9IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgICAgICAgIG5ldyBEYXRlKG1vbmdvT2JqZWN0W2tleV0pXG4gICAgICAgICAgICApLmlzbztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2NyZWF0ZWRBdCc6XG4gICAgICAgICAgY2FzZSAnX2NyZWF0ZWRfYXQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnY3JlYXRlZEF0J10gPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICAgICAgICBuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKVxuICAgICAgICAgICAgKS5pc287XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdleHBpcmVzQXQnOlxuICAgICAgICAgIGNhc2UgJ19leHBpcmVzQXQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsnZXhwaXJlc0F0J10gPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKG1vbmdvT2JqZWN0W2tleV0pKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2xhc3RVc2VkJzpcbiAgICAgICAgICBjYXNlICdfbGFzdF91c2VkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ2xhc3RVc2VkJ10gPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICAgICAgICBuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKVxuICAgICAgICAgICAgKS5pc287XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgICAgICAgIGNhc2UgJ3RpbWVzX3VzZWQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsndGltZXNVc2VkJ10gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnYXV0aERhdGEnOlxuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgICBsb2cud2FybihcbiAgICAgICAgICAgICAgICAnaWdub3JpbmcgYXV0aERhdGEgaW4gX1VzZXIgYXMgdGhpcyBrZXkgaXMgcmVzZXJ2ZWQgdG8gYmUgc3ludGhlc2l6ZWQgb2YgYF9hdXRoX2RhdGFfKmAga2V5cydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlc3RPYmplY3RbJ2F1dGhEYXRhJ10gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIC8vIENoZWNrIG90aGVyIGF1dGggZGF0YSBrZXlzXG4gICAgICAgICAgICB2YXIgYXV0aERhdGFNYXRjaCA9IGtleS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgICAgICAgICAgaWYgKGF1dGhEYXRhTWF0Y2ggJiYgY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgICAgICAgICAgIHZhciBwcm92aWRlciA9IGF1dGhEYXRhTWF0Y2hbMV07XG4gICAgICAgICAgICAgIHJlc3RPYmplY3RbJ2F1dGhEYXRhJ10gPSByZXN0T2JqZWN0WydhdXRoRGF0YSddIHx8IHt9O1xuICAgICAgICAgICAgICByZXN0T2JqZWN0WydhdXRoRGF0YSddW3Byb3ZpZGVyXSA9IG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YoJ19wXycpID09IDApIHtcbiAgICAgICAgICAgICAgdmFyIG5ld0tleSA9IGtleS5zdWJzdHJpbmcoMyk7XG4gICAgICAgICAgICAgIGlmICghc2NoZW1hLmZpZWxkc1tuZXdLZXldKSB7XG4gICAgICAgICAgICAgICAgbG9nLmluZm8oXG4gICAgICAgICAgICAgICAgICAndHJhbnNmb3JtLmpzJyxcbiAgICAgICAgICAgICAgICAgICdGb3VuZCBhIHBvaW50ZXIgY29sdW1uIG5vdCBpbiB0aGUgc2NoZW1hLCBkcm9wcGluZyBpdC4nLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgbmV3S2V5XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoc2NoZW1hLmZpZWxkc1tuZXdLZXldLnR5cGUgIT09ICdQb2ludGVyJykge1xuICAgICAgICAgICAgICAgIGxvZy5pbmZvKFxuICAgICAgICAgICAgICAgICAgJ3RyYW5zZm9ybS5qcycsXG4gICAgICAgICAgICAgICAgICAnRm91bmQgYSBwb2ludGVyIGluIGEgbm9uLXBvaW50ZXIgY29sdW1uLCBkcm9wcGluZyBpdC4nLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobW9uZ29PYmplY3Rba2V5XSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3RPYmplY3RbbmV3S2V5XSA9IHRyYW5zZm9ybVBvaW50ZXJTdHJpbmcoXG4gICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgIG5ld0tleSxcbiAgICAgICAgICAgICAgICBtb25nb09iamVjdFtrZXldXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChrZXlbMF0gPT0gJ18nICYmIGtleSAhPSAnX190eXBlJykge1xuICAgICAgICAgICAgICB0aHJvdyAnYmFkIGtleSBpbiB1bnRyYW5zZm9ybTogJyArIGtleTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhciB2YWx1ZSA9IG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0ZpbGUnICYmXG4gICAgICAgICAgICAgICAgRmlsZUNvZGVyLmlzVmFsaWREYXRhYmFzZU9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gRmlsZUNvZGVyLmRhdGFiYXNlVG9KU09OKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldICYmXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdHZW9Qb2ludCcgJiZcbiAgICAgICAgICAgICAgICBHZW9Qb2ludENvZGVyLmlzVmFsaWREYXRhYmFzZU9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gR2VvUG9pbnRDb2Rlci5kYXRhYmFzZVRvSlNPTih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnUG9seWdvbicgJiZcbiAgICAgICAgICAgICAgICBQb2x5Z29uQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBQb2x5Z29uQ29kZXIuZGF0YWJhc2VUb0pTT04odmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0J5dGVzJyAmJlxuICAgICAgICAgICAgICAgIEJ5dGVzQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBCeXRlc0NvZGVyLmRhdGFiYXNlVG9KU09OKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gbmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KFxuICAgICAgICAgICAgICBtb25nb09iamVjdFtrZXldXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbGF0aW9uRmllbGROYW1lcyA9IE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZpbHRlcihcbiAgICAgICAgZmllbGROYW1lID0+IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nXG4gICAgICApO1xuICAgICAgY29uc3QgcmVsYXRpb25GaWVsZHMgPSB7fTtcbiAgICAgIHJlbGF0aW9uRmllbGROYW1lcy5mb3JFYWNoKHJlbGF0aW9uRmllbGROYW1lID0+IHtcbiAgICAgICAgcmVsYXRpb25GaWVsZHNbcmVsYXRpb25GaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbcmVsYXRpb25GaWVsZE5hbWVdLnRhcmdldENsYXNzLFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7IC4uLnJlc3RPYmplY3QsIC4uLnJlbGF0aW9uRmllbGRzIH07XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyAndW5rbm93biBqcyB0eXBlJztcbiAgfVxufTtcblxudmFyIERhdGVDb2RlciA9IHtcbiAgSlNPTlRvRGF0YWJhc2UoanNvbikge1xuICAgIHJldHVybiBuZXcgRGF0ZShqc29uLmlzbyk7XG4gIH0sXG5cbiAgaXNWYWxpZEpTT04odmFsdWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZS5fX3R5cGUgPT09ICdEYXRlJ1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgQnl0ZXNDb2RlciA9IHtcbiAgYmFzZTY0UGF0dGVybjogbmV3IFJlZ0V4cChcbiAgICAnXig/OltBLVphLXowLTkrL117NH0pKig/OltBLVphLXowLTkrL117Mn09PXxbQS1aYS16MC05Ky9dezN9PSk/JCdcbiAgKSxcbiAgaXNCYXNlNjRWYWx1ZShvYmplY3QpIHtcbiAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYmFzZTY0UGF0dGVybi50ZXN0KG9iamVjdCk7XG4gIH0sXG5cbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGlmICh0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KSkge1xuICAgICAgdmFsdWUgPSBvYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gb2JqZWN0LmJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdCeXRlcycsXG4gICAgICBiYXNlNjQ6IHZhbHVlLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkJpbmFyeSB8fCB0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KTtcbiAgfSxcblxuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgcmV0dXJuIG5ldyBtb25nb2RiLkJpbmFyeShCdWZmZXIuZnJvbShqc29uLmJhc2U2NCwgJ2Jhc2U2NCcpKTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJ1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgR2VvUG9pbnRDb2RlciA9IHtcbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogJ0dlb1BvaW50JyxcbiAgICAgIGxhdGl0dWRlOiBvYmplY3RbMV0sXG4gICAgICBsb25naXR1ZGU6IG9iamVjdFswXSxcbiAgICB9O1xuICB9LFxuXG4gIGlzVmFsaWREYXRhYmFzZU9iamVjdChvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgQXJyYXkgJiYgb2JqZWN0Lmxlbmd0aCA9PSAyO1xuICB9LFxuXG4gIEpTT05Ub0RhdGFiYXNlKGpzb24pIHtcbiAgICByZXR1cm4gW2pzb24ubG9uZ2l0dWRlLCBqc29uLmxhdGl0dWRlXTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgUG9seWdvbkNvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICAvLyBDb252ZXJ0IGxuZy9sYXQgLT4gbGF0L2xuZ1xuICAgIGNvbnN0IGNvb3JkcyA9IG9iamVjdC5jb29yZGluYXRlc1swXS5tYXAoY29vcmQgPT4ge1xuICAgICAgcmV0dXJuIFtjb29yZFsxXSwgY29vcmRbMF1dO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdQb2x5Z29uJyxcbiAgICAgIGNvb3JkaW5hdGVzOiBjb29yZHMsXG4gICAgfTtcbiAgfSxcblxuICBpc1ZhbGlkRGF0YWJhc2VPYmplY3Qob2JqZWN0KSB7XG4gICAgY29uc3QgY29vcmRzID0gb2JqZWN0LmNvb3JkaW5hdGVzWzBdO1xuICAgIGlmIChvYmplY3QudHlwZSAhPT0gJ1BvbHlnb24nIHx8ICEoY29vcmRzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29vcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludCA9IGNvb3Jkc1tpXTtcbiAgICAgIGlmICghR2VvUG9pbnRDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QocG9pbnQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwYXJzZUZsb2F0KHBvaW50WzFdKSwgcGFyc2VGbG9hdChwb2ludFswXSkpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcblxuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgbGV0IGNvb3JkcyA9IGpzb24uY29vcmRpbmF0ZXM7XG4gICAgLy8gQWRkIGZpcnN0IHBvaW50IHRvIHRoZSBlbmQgdG8gY2xvc2UgcG9seWdvblxuICAgIGlmIChcbiAgICAgIGNvb3Jkc1swXVswXSAhPT0gY29vcmRzW2Nvb3Jkcy5sZW5ndGggLSAxXVswXSB8fFxuICAgICAgY29vcmRzWzBdWzFdICE9PSBjb29yZHNbY29vcmRzLmxlbmd0aCAtIDFdWzFdXG4gICAgKSB7XG4gICAgICBjb29yZHMucHVzaChjb29yZHNbMF0pO1xuICAgIH1cbiAgICBjb25zdCB1bmlxdWUgPSBjb29yZHMuZmlsdGVyKChpdGVtLCBpbmRleCwgYXIpID0+IHtcbiAgICAgIGxldCBmb3VuZEluZGV4ID0gLTE7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IHB0ID0gYXJbaV07XG4gICAgICAgIGlmIChwdFswXSA9PT0gaXRlbVswXSAmJiBwdFsxXSA9PT0gaXRlbVsxXSkge1xuICAgICAgICAgIGZvdW5kSW5kZXggPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZm91bmRJbmRleCA9PT0gaW5kZXg7XG4gICAgfSk7XG4gICAgaWYgKHVuaXF1ZS5sZW5ndGggPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgJ0dlb0pTT046IExvb3AgbXVzdCBoYXZlIGF0IGxlYXN0IDMgZGlmZmVyZW50IHZlcnRpY2VzJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ29udmVydCBsYXQvbG9uZyAtPiBsb25nL2xhdFxuICAgIGNvb3JkcyA9IGNvb3Jkcy5tYXAoY29vcmQgPT4ge1xuICAgICAgcmV0dXJuIFtjb29yZFsxXSwgY29vcmRbMF1dO1xuICAgIH0pO1xuICAgIHJldHVybiB7IHR5cGU6ICdQb2x5Z29uJywgY29vcmRpbmF0ZXM6IFtjb29yZHNdIH07XG4gIH0sXG5cbiAgaXNWYWxpZEpTT04odmFsdWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZS5fX3R5cGUgPT09ICdQb2x5Z29uJ1xuICAgICk7XG4gIH0sXG59O1xuXG52YXIgRmlsZUNvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICBuYW1lOiBvYmplY3QsXG4gICAgfTtcbiAgfSxcblxuICBpc1ZhbGlkRGF0YWJhc2VPYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnO1xuICB9LFxuXG4gIEpTT05Ub0RhdGFiYXNlKGpzb24pIHtcbiAgICByZXR1cm4ganNvbi5uYW1lO1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnRmlsZSdcbiAgICApO1xuICB9LFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHRyYW5zZm9ybUtleSxcbiAgcGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlLFxuICB0cmFuc2Zvcm1VcGRhdGUsXG4gIHRyYW5zZm9ybVdoZXJlLFxuICBtb25nb09iamVjdFRvUGFyc2VPYmplY3QsXG4gIHJlbGF0aXZlVGltZVRvRGF0ZSxcbiAgdHJhbnNmb3JtQ29uc3RyYWludCxcbiAgdHJhbnNmb3JtUG9pbnRlclN0cmluZyxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresClient.js b/lib/Adapters/Storage/Postgres/PostgresClient.js deleted file mode 100644 index 9c2899b4d5..0000000000 --- a/lib/Adapters/Storage/Postgres/PostgresClient.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.createClient = createClient; - -const parser = require('./PostgresConfigParser'); - -function createClient(uri, databaseOptions) { - let dbOptions = {}; - databaseOptions = databaseOptions || {}; - - if (uri) { - dbOptions = parser.getDatabaseOptionsFromURI(uri); - } - - for (const key in databaseOptions) { - dbOptions[key] = databaseOptions[key]; - } - - const initOptions = dbOptions.initOptions || {}; - initOptions.noWarnings = process && process.env.TESTING; - - const pgp = require('pg-promise')(initOptions); - - const client = pgp(dbOptions); - - if (dbOptions.pgOptions) { - for (const key in dbOptions.pgOptions) { - pgp.pg.defaults[key] = dbOptions.pgOptions[key]; - } - } - - return { - client, - pgp - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ2xpZW50LmpzIl0sIm5hbWVzIjpbInBhcnNlciIsInJlcXVpcmUiLCJjcmVhdGVDbGllbnQiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJkYk9wdGlvbnMiLCJnZXREYXRhYmFzZU9wdGlvbnNGcm9tVVJJIiwia2V5IiwiaW5pdE9wdGlvbnMiLCJub1dhcm5pbmdzIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJwZ3AiLCJjbGllbnQiLCJwZ09wdGlvbnMiLCJwZyIsImRlZmF1bHRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsd0JBQUQsQ0FBdEI7O0FBRU8sU0FBU0MsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkJDLGVBQTNCLEVBQTRDO0FBQ2pELE1BQUlDLFNBQVMsR0FBRyxFQUFoQjtBQUNBRCxFQUFBQSxlQUFlLEdBQUdBLGVBQWUsSUFBSSxFQUFyQzs7QUFFQSxNQUFJRCxHQUFKLEVBQVM7QUFDUEUsSUFBQUEsU0FBUyxHQUFHTCxNQUFNLENBQUNNLHlCQUFQLENBQWlDSCxHQUFqQyxDQUFaO0FBQ0Q7O0FBRUQsT0FBSyxNQUFNSSxHQUFYLElBQWtCSCxlQUFsQixFQUFtQztBQUNqQ0MsSUFBQUEsU0FBUyxDQUFDRSxHQUFELENBQVQsR0FBaUJILGVBQWUsQ0FBQ0csR0FBRCxDQUFoQztBQUNEOztBQUVELFFBQU1DLFdBQVcsR0FBR0gsU0FBUyxDQUFDRyxXQUFWLElBQXlCLEVBQTdDO0FBQ0FBLEVBQUFBLFdBQVcsQ0FBQ0MsVUFBWixHQUF5QkMsT0FBTyxJQUFJQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBaEQ7O0FBRUEsUUFBTUMsR0FBRyxHQUFHWixPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCTyxXQUF0QixDQUFaOztBQUNBLFFBQU1NLE1BQU0sR0FBR0QsR0FBRyxDQUFDUixTQUFELENBQWxCOztBQUVBLE1BQUlBLFNBQVMsQ0FBQ1UsU0FBZCxFQUF5QjtBQUN2QixTQUFLLE1BQU1SLEdBQVgsSUFBa0JGLFNBQVMsQ0FBQ1UsU0FBNUIsRUFBdUM7QUFDckNGLE1BQUFBLEdBQUcsQ0FBQ0csRUFBSixDQUFPQyxRQUFQLENBQWdCVixHQUFoQixJQUF1QkYsU0FBUyxDQUFDVSxTQUFWLENBQW9CUixHQUFwQixDQUF2QjtBQUNEO0FBQ0Y7O0FBRUQsU0FBTztBQUFFTyxJQUFBQSxNQUFGO0FBQVVELElBQUFBO0FBQVYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgcGFyc2VyID0gcmVxdWlyZSgnLi9Qb3N0Z3Jlc0NvbmZpZ1BhcnNlcicpO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xpZW50KHVyaSwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBkYk9wdGlvbnMgPSB7fTtcbiAgZGF0YWJhc2VPcHRpb25zID0gZGF0YWJhc2VPcHRpb25zIHx8IHt9O1xuXG4gIGlmICh1cmkpIHtcbiAgICBkYk9wdGlvbnMgPSBwYXJzZXIuZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSh1cmkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gZGF0YWJhc2VPcHRpb25zKSB7XG4gICAgZGJPcHRpb25zW2tleV0gPSBkYXRhYmFzZU9wdGlvbnNba2V5XTtcbiAgfVxuXG4gIGNvbnN0IGluaXRPcHRpb25zID0gZGJPcHRpb25zLmluaXRPcHRpb25zIHx8IHt9O1xuICBpbml0T3B0aW9ucy5ub1dhcm5pbmdzID0gcHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HO1xuXG4gIGNvbnN0IHBncCA9IHJlcXVpcmUoJ3BnLXByb21pc2UnKShpbml0T3B0aW9ucyk7XG4gIGNvbnN0IGNsaWVudCA9IHBncChkYk9wdGlvbnMpO1xuXG4gIGlmIChkYk9wdGlvbnMucGdPcHRpb25zKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGJPcHRpb25zLnBnT3B0aW9ucykge1xuICAgICAgcGdwLnBnLmRlZmF1bHRzW2tleV0gPSBkYk9wdGlvbnMucGdPcHRpb25zW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2xpZW50LCBwZ3AgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresConfigParser.js b/lib/Adapters/Storage/Postgres/PostgresConfigParser.js deleted file mode 100644 index f6bea9303b..0000000000 --- a/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +++ /dev/null @@ -1,95 +0,0 @@ -"use strict"; - -const url = require('url'); - -const fs = require('fs'); - -function getDatabaseOptionsFromURI(uri) { - const databaseOptions = {}; - const parsedURI = url.parse(uri); - const queryParams = parseQueryParams(parsedURI.query); - const authParts = parsedURI.auth ? parsedURI.auth.split(':') : []; - databaseOptions.host = parsedURI.hostname || 'localhost'; - databaseOptions.port = parsedURI.port ? parseInt(parsedURI.port) : 5432; - databaseOptions.database = parsedURI.pathname ? parsedURI.pathname.substr(1) : undefined; - databaseOptions.user = authParts.length > 0 ? authParts[0] : ''; - databaseOptions.password = authParts.length > 1 ? authParts[1] : ''; - - if (queryParams.ssl && queryParams.ssl.toLowerCase() === 'true') { - databaseOptions.ssl = true; - } - - if (queryParams.ca || queryParams.pfx || queryParams.cert || queryParams.key || queryParams.passphrase || queryParams.rejectUnauthorized || queryParams.secureOptions) { - databaseOptions.ssl = {}; - - if (queryParams.ca) { - databaseOptions.ssl.ca = fs.readFileSync(queryParams.ca).toString(); - } - - if (queryParams.pfx) { - databaseOptions.ssl.pfx = fs.readFileSync(queryParams.pfx).toString(); - } - - if (queryParams.cert) { - databaseOptions.ssl.cert = fs.readFileSync(queryParams.cert).toString(); - } - - if (queryParams.key) { - databaseOptions.ssl.key = fs.readFileSync(queryParams.key).toString(); - } - - if (queryParams.passphrase) { - databaseOptions.ssl.passphrase = queryParams.passphrase; - } - - if (queryParams.rejectUnauthorized) { - databaseOptions.ssl.rejectUnauthorized = queryParams.rejectUnauthorized.toLowerCase() === 'true' ? true : false; - } - - if (queryParams.secureOptions) { - databaseOptions.ssl.secureOptions = parseInt(queryParams.secureOptions); - } - } - - databaseOptions.binary = queryParams.binary && queryParams.binary.toLowerCase() === 'true' ? true : false; - databaseOptions.client_encoding = queryParams.client_encoding; - databaseOptions.application_name = queryParams.application_name; - databaseOptions.fallback_application_name = queryParams.fallback_application_name; - - if (queryParams.poolSize) { - databaseOptions.poolSize = parseInt(queryParams.poolSize) || 10; - } - - if (queryParams.max) { - databaseOptions.max = parseInt(queryParams.max) || 10; - } - - if (queryParams.query_timeout) { - databaseOptions.query_timeout = parseInt(queryParams.query_timeout); - } - - if (queryParams.idleTimeoutMillis) { - databaseOptions.idleTimeoutMillis = parseInt(queryParams.idleTimeoutMillis); - } - - if (queryParams.keepAlive) { - databaseOptions.keepAlive = queryParams.keepAlive.toLowerCase() === 'true' ? true : false; - } - - return databaseOptions; -} - -function parseQueryParams(queryString) { - queryString = queryString || ''; - return queryString.split('&').reduce((p, c) => { - const parts = c.split('='); - p[decodeURIComponent(parts[0])] = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : ''; - return p; - }, {}); -} - -module.exports = { - parseQueryParams: parseQueryParams, - getDatabaseOptionsFromURI: getDatabaseOptionsFromURI -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ29uZmlnUGFyc2VyLmpzIl0sIm5hbWVzIjpbInVybCIsInJlcXVpcmUiLCJmcyIsImdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkkiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJwYXJzZWRVUkkiLCJwYXJzZSIsInF1ZXJ5UGFyYW1zIiwicGFyc2VRdWVyeVBhcmFtcyIsInF1ZXJ5IiwiYXV0aFBhcnRzIiwiYXV0aCIsInNwbGl0IiwiaG9zdCIsImhvc3RuYW1lIiwicG9ydCIsInBhcnNlSW50IiwiZGF0YWJhc2UiLCJwYXRobmFtZSIsInN1YnN0ciIsInVuZGVmaW5lZCIsInVzZXIiLCJsZW5ndGgiLCJwYXNzd29yZCIsInNzbCIsInRvTG93ZXJDYXNlIiwiY2EiLCJwZngiLCJjZXJ0Iiwia2V5IiwicGFzc3BocmFzZSIsInJlamVjdFVuYXV0aG9yaXplZCIsInNlY3VyZU9wdGlvbnMiLCJyZWFkRmlsZVN5bmMiLCJ0b1N0cmluZyIsImJpbmFyeSIsImNsaWVudF9lbmNvZGluZyIsImFwcGxpY2F0aW9uX25hbWUiLCJmYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lIiwicG9vbFNpemUiLCJtYXgiLCJxdWVyeV90aW1lb3V0IiwiaWRsZVRpbWVvdXRNaWxsaXMiLCJrZWVwQWxpdmUiLCJxdWVyeVN0cmluZyIsInJlZHVjZSIsInAiLCJjIiwicGFydHMiLCJkZWNvZGVVUklDb21wb25lbnQiLCJzbGljZSIsImpvaW4iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEdBQUcsR0FBR0MsT0FBTyxDQUFDLEtBQUQsQ0FBbkI7O0FBQ0EsTUFBTUMsRUFBRSxHQUFHRCxPQUFPLENBQUMsSUFBRCxDQUFsQjs7QUFDQSxTQUFTRSx5QkFBVCxDQUFtQ0MsR0FBbkMsRUFBd0M7QUFDdEMsUUFBTUMsZUFBZSxHQUFHLEVBQXhCO0FBRUEsUUFBTUMs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QUFGWixDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuZnVuY3Rpb24gZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSh1cmkpIHtcbiAgY29uc3QgZGF0YWJhc2VPcHRpb25zID0ge307XG5cbiAgY29uc3QgcGFyc2VkVVJJID0gdXJsLnBhcnNlKHVyaSk7XG4gIGNvbnN0IHF1ZXJ5UGFyYW1zID0gcGFyc2VRdWVyeVBhcmFtcyhwYXJzZWRVUkkucXVlcnkpO1xuICBjb25zdCBhdXRoUGFydHMgPSBwYXJzZWRVUkkuYXV0aCA/IHBhcnNlZFVSSS5hdXRoLnNwbGl0KCc6JykgOiBbXTtcblxuICBkYXRhYmFzZU9wdGlvbnMuaG9zdCA9IHBhcnNlZFVSSS5ob3N0bmFtZSB8fCAnbG9jYWxob3N0JztcbiAgZGF0YWJhc2VPcHRpb25zLnBvcnQgPSBwYXJzZWRVUkkucG9ydCA/IHBhcnNlSW50KHBhcnNlZFVSSS5wb3J0KSA6IDU0MzI7XG4gIGRhdGFiYXNlT3B0aW9ucy5kYXRhYmFzZSA9IHBhcnNlZFVSSS5wYXRobmFtZVxuICAgID8gcGFyc2VkVVJJLnBhdGhuYW1lLnN1YnN0cigxKVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGRhdGFiYXNlT3B0aW9ucy51c2VyID0gYXV0aFBhcnRzLmxlbmd0aCA+IDAgPyBhdXRoUGFydHNbMF0gOiAnJztcbiAgZGF0YWJhc2VPcHRpb25zLnBhc3N3b3JkID0gYXV0aFBhcnRzLmxlbmd0aCA+IDEgPyBhdXRoUGFydHNbMV0gOiAnJztcblxuICBpZiAocXVlcnlQYXJhbXMuc3NsICYmIHF1ZXJ5UGFyYW1zLnNzbC50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScpIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMuc3NsID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChcbiAgICBxdWVyeVBhcmFtcy5jYSB8fFxuICAgIHF1ZXJ5UGFyYW1zLnBmeCB8fFxuICAgIHF1ZXJ5UGFyYW1zLmNlcnQgfHxcbiAgICBxdWVyeVBhcmFtcy5rZXkgfHxcbiAgICBxdWVyeVBhcmFtcy5wYXNzcGhyYXNlIHx8XG4gICAgcXVlcnlQYXJhbXMucmVqZWN0VW5hdXRob3JpemVkIHx8XG4gICAgcXVlcnlQYXJhbXMuc2VjdXJlT3B0aW9uc1xuICApIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMuc3NsID0ge307XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLmNhKSB7XG4gICAgICBkYXRhYmFzZU9wdGlvbnMuc3NsLmNhID0gZnMucmVhZEZpbGVTeW5jKHF1ZXJ5UGFyYW1zLmNhKS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMucGZ4KSB7XG4gICAgICBkYXRhYmFzZU9wdGlvbnMuc3NsLnBmeCA9IGZzLnJlYWRGaWxlU3luYyhxdWVyeVBhcmFtcy5wZngpLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChxdWVyeVBhcmFtcy5jZXJ0KSB7XG4gICAgICBkYXRhYmFzZU9wdGlvbnMuc3NsLmNlcnQgPSBmcy5yZWFkRmlsZVN5bmMocXVlcnlQYXJhbXMuY2VydCkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLmtleSkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5rZXkgPSBmcy5yZWFkRmlsZVN5bmMocXVlcnlQYXJhbXMua2V5KS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMucGFzc3BocmFzZSkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5wYXNzcGhyYXNlID0gcXVlcnlQYXJhbXMucGFzc3BocmFzZTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnJlamVjdFVuYXV0aG9yaXplZCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5yZWplY3RVbmF1dGhvcml6ZWQgPVxuICAgICAgICBxdWVyeVBhcmFtcy5yZWplY3RVbmF1dGhvcml6ZWQudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnID8gdHJ1ZSA6IGZhbHNlO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMuc2VjdXJlT3B0aW9ucykge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5zZWN1cmVPcHRpb25zID0gcGFyc2VJbnQocXVlcnlQYXJhbXMuc2VjdXJlT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgZGF0YWJhc2VPcHRpb25zLmJpbmFyeSA9XG4gICAgcXVlcnlQYXJhbXMuYmluYXJ5ICYmIHF1ZXJ5UGFyYW1zLmJpbmFyeS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSdcbiAgICAgID8gdHJ1ZVxuICAgICAgOiBmYWxzZTtcblxuICBkYXRhYmFzZU9wdGlvbnMuY2xpZW50X2VuY29kaW5nID0gcXVlcnlQYXJhbXMuY2xpZW50X2VuY29kaW5nO1xuICBkYXRhYmFzZU9wdGlvbnMuYXBwbGljYXRpb25fbmFtZSA9IHF1ZXJ5UGFyYW1zLmFwcGxpY2F0aW9uX25hbWU7XG4gIGRhdGFiYXNlT3B0aW9ucy5mYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lID1cbiAgICBxdWVyeVBhcmFtcy5mYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lO1xuXG4gIGlmIChxdWVyeVBhcmFtcy5wb29sU2l6ZSkge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5wb29sU2l6ZSA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnBvb2xTaXplKSB8fCAxMDtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMubWF4KSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLm1heCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLm1heCkgfHwgMTA7XG4gIH1cbiAgaWYgKHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMucXVlcnlfdGltZW91dCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpO1xuICB9XG4gIGlmIChxdWVyeVBhcmFtcy5pZGxlVGltZW91dE1pbGxpcykge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5pZGxlVGltZW91dE1pbGxpcyA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLmlkbGVUaW1lb3V0TWlsbGlzKTtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMua2VlcEFsaXZlKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLmtlZXBBbGl2ZSA9XG4gICAgICBxdWVyeVBhcmFtcy5rZWVwQWxpdmUudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnID8gdHJ1ZSA6IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGRhdGFiYXNlT3B0aW9ucztcbn1cblxuZnVuY3Rpb24gcGFyc2VRdWVyeVBhcmFtcyhxdWVyeVN0cmluZykge1xuICBxdWVyeVN0cmluZyA9IHF1ZXJ5U3RyaW5nIHx8ICcnO1xuXG4gIHJldHVybiBxdWVyeVN0cmluZy5zcGxpdCgnJicpLnJlZHVjZSgocCwgYykgPT4ge1xuICAgIGNvbnN0IHBhcnRzID0gYy5zcGxpdCgnPScpO1xuICAgIHBbZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzBdKV0gPVxuICAgICAgcGFydHMubGVuZ3RoID4gMSA/IGRlY29kZVVSSUNvbXBvbmVudChwYXJ0cy5zbGljZSgxKS5qb2luKCc9JykpIDogJyc7XG4gICAgcmV0dXJuIHA7XG4gIH0sIHt9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUXVlcnlQYXJhbXM6IHBhcnNlUXVlcnlQYXJhbXMsXG4gIGdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkk6IGdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkksXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js deleted file mode 100644 index dc2a10f816..0000000000 --- a/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ /dev/null @@ -1,2496 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PostgresStorageAdapter = void 0; - -var _PostgresClient = require("./PostgresClient"); - -var _node = _interopRequireDefault(require("parse/node")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _sql = _interopRequireDefault(require("./sql")); - -var _StorageAdapter = require("../StorageAdapter"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const PostgresRelationDoesNotExistError = '42P01'; -const PostgresDuplicateRelationError = '42P07'; -const PostgresDuplicateColumnError = '42701'; -const PostgresMissingColumnError = '42703'; -const PostgresDuplicateObjectError = '42710'; -const PostgresUniqueIndexViolationError = '23505'; -const PostgresTransactionAbortedError = '25P02'; - -const logger = require('../../../logger'); - -const debug = function (...args) { - args = ['PG: ' + arguments[0]].concat(args.slice(1, args.length)); - const log = logger.getLogger(); - log.debug.apply(log, args); -}; - -const parseTypeToPostgresType = type => { - switch (type.type) { - case 'String': - return 'text'; - - case 'Date': - return 'timestamp with time zone'; - - case 'Object': - return 'jsonb'; - - case 'File': - return 'text'; - - case 'Boolean': - return 'boolean'; - - case 'Pointer': - return 'text'; - - case 'Number': - return 'double precision'; - - case 'GeoPoint': - return 'point'; - - case 'Bytes': - return 'jsonb'; - - case 'Polygon': - return 'polygon'; - - case 'Array': - if (type.contents && type.contents.type === 'String') { - return 'text[]'; - } else { - return 'jsonb'; - } - - default: - throw `no type for ${JSON.stringify(type)} yet`; - } -}; - -const ParseToPosgresComparator = { - $gt: '>', - $lt: '<', - $gte: '>=', - $lte: '<=' -}; -const mongoAggregateToPostgres = { - $dayOfMonth: 'DAY', - $dayOfWeek: 'DOW', - $dayOfYear: 'DOY', - $isoDayOfWeek: 'ISODOW', - $isoWeekYear: 'ISOYEAR', - $hour: 'HOUR', - $minute: 'MINUTE', - $second: 'SECOND', - $millisecond: 'MILLISECONDS', - $month: 'MONTH', - $week: 'WEEK', - $year: 'YEAR' -}; - -const toPostgresValue = value => { - if (typeof value === 'object') { - if (value.__type === 'Date') { - return value.iso; - } - - if (value.__type === 'File') { - return value.name; - } - } - - return value; -}; - -const transformValue = value => { - if (typeof value === 'object' && value.__type === 'Pointer') { - return value.objectId; - } - - return value; -}; // Duplicate from then mongo adapter... - - -const emptyCLPS = Object.freeze({ - find: {}, - get: {}, - count: {}, - create: {}, - update: {}, - delete: {}, - addField: {}, - protectedFields: {} -}); -const defaultCLPS = Object.freeze({ - find: { - '*': true - }, - get: { - '*': true - }, - count: { - '*': true - }, - create: { - '*': true - }, - update: { - '*': true - }, - delete: { - '*': true - }, - addField: { - '*': true - }, - protectedFields: { - '*': [] - } -}); - -const toParseSchema = schema => { - if (schema.className === '_User') { - delete schema.fields._hashed_password; - } - - if (schema.fields) { - delete schema.fields._wperm; - delete schema.fields._rperm; - } - - let clps = defaultCLPS; - - if (schema.classLevelPermissions) { - clps = _objectSpread(_objectSpread({}, emptyCLPS), schema.classLevelPermissions); - } - - let indexes = {}; - - if (schema.indexes) { - indexes = _objectSpread({}, schema.indexes); - } - - return { - className: schema.className, - fields: schema.fields, - classLevelPermissions: clps, - indexes - }; -}; - -const toPostgresSchema = schema => { - if (!schema) { - return schema; - } - - schema.fields = schema.fields || {}; - schema.fields._wperm = { - type: 'Array', - contents: { - type: 'String' - } - }; - schema.fields._rperm = { - type: 'Array', - contents: { - type: 'String' - } - }; - - if (schema.className === '_User') { - schema.fields._hashed_password = { - type: 'String' - }; - schema.fields._password_history = { - type: 'Array' - }; - } - - return schema; -}; - -const handleDotFields = object => { - Object.keys(object).forEach(fieldName => { - if (fieldName.indexOf('.') > -1) { - const components = fieldName.split('.'); - const first = components.shift(); - object[first] = object[first] || {}; - let currentObj = object[first]; - let next; - let value = object[fieldName]; - - if (value && value.__op === 'Delete') { - value = undefined; - } - /* eslint-disable no-cond-assign */ - - - while (next = components.shift()) { - /* eslint-enable no-cond-assign */ - currentObj[next] = currentObj[next] || {}; - - if (components.length === 0) { - currentObj[next] = value; - } - - currentObj = currentObj[next]; - } - - delete object[fieldName]; - } - }); - return object; -}; - -const transformDotFieldToComponents = fieldName => { - return fieldName.split('.').map((cmpt, index) => { - if (index === 0) { - return `"${cmpt}"`; - } - - return `'${cmpt}'`; - }); -}; - -const transformDotField = fieldName => { - if (fieldName.indexOf('.') === -1) { - return `"${fieldName}"`; - } - - const components = transformDotFieldToComponents(fieldName); - let name = components.slice(0, components.length - 1).join('->'); - name += '->>' + components[components.length - 1]; - return name; -}; - -const transformAggregateField = fieldName => { - if (typeof fieldName !== 'string') { - return fieldName; - } - - if (fieldName === '$_created_at') { - return 'createdAt'; - } - - if (fieldName === '$_updated_at') { - return 'updatedAt'; - } - - return fieldName.substr(1); -}; - -const validateKeys = object => { - if (typeof object == 'object') { - for (const key in object) { - if (typeof object[key] == 'object') { - validateKeys(object[key]); - } - - if (key.includes('$') || key.includes('.')) { - throw new _node.default.Error(_node.default.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } - } - } -}; // Returns the list of join tables on a schema - - -const joinTablesForSchema = schema => { - const list = []; - - if (schema) { - Object.keys(schema.fields).forEach(field => { - if (schema.fields[field].type === 'Relation') { - list.push(`_Join:${field}:${schema.className}`); - } - }); - } - - return list; -}; - -const buildWhereClause = ({ - schema, - query, - index, - caseInsensitive -}) => { - const patterns = []; - let values = []; - const sorts = []; - schema = toPostgresSchema(schema); - - for (const fieldName in query) { - const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; - const initialPatternsLength = patterns.length; - const fieldValue = query[fieldName]; // nothing in the schema, it's gonna blow up - - if (!schema.fields[fieldName]) { - // as it won't exist - if (fieldValue && fieldValue.$exists === false) { - continue; - } - } - - const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch) { - // TODO: Handle querying by _auth_data_provider, authData is stored in authData field - continue; - } else if (caseInsensitive && (fieldName === 'username' || fieldName === 'email')) { - patterns.push(`LOWER($${index}:name) = LOWER($${index + 1})`); - values.push(fieldName, fieldValue); - index += 2; - } else if (fieldName.indexOf('.') >= 0) { - let name = transformDotField(fieldName); - - if (fieldValue === null) { - patterns.push(`$${index}:raw IS NULL`); - values.push(name); - index += 1; - continue; - } else { - if (fieldValue.$in) { - name = transformDotFieldToComponents(fieldName).join('->'); - patterns.push(`($${index}:raw)::jsonb @> $${index + 1}::jsonb`); - values.push(name, JSON.stringify(fieldValue.$in)); - index += 2; - } else if (fieldValue.$regex) {// Handle later - } else if (typeof fieldValue !== 'object') { - patterns.push(`$${index}:raw = $${index + 1}::text`); - values.push(name, fieldValue); - index += 2; - } - } - } else if (fieldValue === null || fieldValue === undefined) { - patterns.push(`$${index}:name IS NULL`); - values.push(fieldName); - index += 1; - continue; - } else if (typeof fieldValue === 'string') { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'boolean') { - patterns.push(`$${index}:name = $${index + 1}`); // Can't cast boolean to double precision - - if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Number') { - // Should always return zero results - const MAX_INT_PLUS_ONE = 9223372036854775808; - values.push(fieldName, MAX_INT_PLUS_ONE); - } else { - values.push(fieldName, fieldValue); - } - - index += 2; - } else if (typeof fieldValue === 'number') { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (['$or', '$nor', '$and'].includes(fieldName)) { - const clauses = []; - const clauseValues = []; - fieldValue.forEach(subQuery => { - const clause = buildWhereClause({ - schema, - query: subQuery, - index, - caseInsensitive - }); - - if (clause.pattern.length > 0) { - clauses.push(clause.pattern); - clauseValues.push(...clause.values); - index += clause.values.length; - } - }); - const orOrAnd = fieldName === '$and' ? ' AND ' : ' OR '; - const not = fieldName === '$nor' ? ' NOT ' : ''; - patterns.push(`${not}(${clauses.join(orOrAnd)})`); - values.push(...clauseValues); - } - - if (fieldValue.$ne !== undefined) { - if (isArrayField) { - fieldValue.$ne = JSON.stringify([fieldValue.$ne]); - patterns.push(`NOT array_contains($${index}:name, $${index + 1})`); - } else { - if (fieldValue.$ne === null) { - patterns.push(`$${index}:name IS NOT NULL`); - values.push(fieldName); - index += 1; - continue; - } else { - // if not null, we need to manually exclude null - if (fieldValue.$ne.__type === 'GeoPoint') { - patterns.push(`($${index}:name <> POINT($${index + 1}, $${index + 2}) OR $${index}:name IS NULL)`); - } else { - if (fieldName.indexOf('.') >= 0) { - const constraintFieldName = transformDotField(fieldName); - patterns.push(`(${constraintFieldName} <> $${index} OR ${constraintFieldName} IS NULL)`); - } else { - patterns.push(`($${index}:name <> $${index + 1} OR $${index}:name IS NULL)`); - } - } - } - } - - if (fieldValue.$ne.__type === 'GeoPoint') { - const point = fieldValue.$ne; - values.push(fieldName, point.longitude, point.latitude); - index += 3; - } else { - // TODO: support arrays - values.push(fieldName, fieldValue.$ne); - index += 2; - } - } - - if (fieldValue.$eq !== undefined) { - if (fieldValue.$eq === null) { - patterns.push(`$${index}:name IS NULL`); - values.push(fieldName); - index += 1; - } else { - if (fieldName.indexOf('.') >= 0) { - values.push(fieldValue.$eq); - patterns.push(`${transformDotField(fieldName)} = $${index++}`); - } else { - values.push(fieldName, fieldValue.$eq); - patterns.push(`$${index}:name = $${index + 1}`); - index += 2; - } - } - } - - const isInOrNin = Array.isArray(fieldValue.$in) || Array.isArray(fieldValue.$nin); - - if (Array.isArray(fieldValue.$in) && isArrayField && schema.fields[fieldName].contents && schema.fields[fieldName].contents.type === 'String') { - const inPatterns = []; - let allowNull = false; - values.push(fieldName); - fieldValue.$in.forEach((listElem, listIndex) => { - if (listElem === null) { - allowNull = true; - } else { - values.push(listElem); - inPatterns.push(`$${index + 1 + listIndex - (allowNull ? 1 : 0)}`); - } - }); - - if (allowNull) { - patterns.push(`($${index}:name IS NULL OR $${index}:name && ARRAY[${inPatterns.join()}])`); - } else { - patterns.push(`$${index}:name && ARRAY[${inPatterns.join()}]`); - } - - index = index + 1 + inPatterns.length; - } else if (isInOrNin) { - var createConstraint = (baseArray, notIn) => { - const not = notIn ? ' NOT ' : ''; - - if (baseArray.length > 0) { - if (isArrayField) { - patterns.push(`${not} array_contains($${index}:name, $${index + 1})`); - values.push(fieldName, JSON.stringify(baseArray)); - index += 2; - } else { - // Handle Nested Dot Notation Above - if (fieldName.indexOf('.') >= 0) { - return; - } - - const inPatterns = []; - values.push(fieldName); - baseArray.forEach((listElem, listIndex) => { - if (listElem != null) { - values.push(listElem); - inPatterns.push(`$${index + 1 + listIndex}`); - } - }); - patterns.push(`$${index}:name ${not} IN (${inPatterns.join()})`); - index = index + 1 + inPatterns.length; - } - } else if (!notIn) { - values.push(fieldName); - patterns.push(`$${index}:name IS NULL`); - index = index + 1; - } else { - // Handle empty array - if (notIn) { - patterns.push('1 = 1'); // Return all values - } else { - patterns.push('1 = 2'); // Return no values - } - } - }; - - if (fieldValue.$in) { - createConstraint(_lodash.default.flatMap(fieldValue.$in, elt => elt), false); - } - - if (fieldValue.$nin) { - createConstraint(_lodash.default.flatMap(fieldValue.$nin, elt => elt), true); - } - } else if (typeof fieldValue.$in !== 'undefined') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $in value'); - } else if (typeof fieldValue.$nin !== 'undefined') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $nin value'); - } - - if (Array.isArray(fieldValue.$all) && isArrayField) { - if (isAnyValueRegexStartsWith(fieldValue.$all)) { - if (!isAllValuesRegexOrNone(fieldValue.$all)) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + fieldValue.$all); - } - - for (let i = 0; i < fieldValue.$all.length; i += 1) { - const value = processRegexPattern(fieldValue.$all[i].$regex); - fieldValue.$all[i] = value.substring(1) + '%'; - } - - patterns.push(`array_contains_all_regex($${index}:name, $${index + 1}::jsonb)`); - } else { - patterns.push(`array_contains_all($${index}:name, $${index + 1}::jsonb)`); - } - - values.push(fieldName, JSON.stringify(fieldValue.$all)); - index += 2; - } else if (Array.isArray(fieldValue.$all)) { - if (fieldValue.$all.length === 1) { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.$all[0].objectId); - index += 2; - } - } - - if (typeof fieldValue.$exists !== 'undefined') { - if (fieldValue.$exists) { - patterns.push(`$${index}:name IS NOT NULL`); - } else { - patterns.push(`$${index}:name IS NULL`); - } - - values.push(fieldName); - index += 1; - } - - if (fieldValue.$containedBy) { - const arr = fieldValue.$containedBy; - - if (!(arr instanceof Array)) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $containedBy: should be an array`); - } - - patterns.push(`$${index}:name <@ $${index + 1}::jsonb`); - values.push(fieldName, JSON.stringify(arr)); - index += 2; - } - - if (fieldValue.$text) { - const search = fieldValue.$text.$search; - let language = 'english'; - - if (typeof search !== 'object') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $search, should be object`); - } - - if (!search.$term || typeof search.$term !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $term, should be string`); - } - - if (search.$language && typeof search.$language !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $language, should be string`); - } else if (search.$language) { - language = search.$language; - } - - if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); - } else if (search.$caseSensitive) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive not supported, please use $regex or create a separate lower case column.`); - } - - if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); - } else if (search.$diacriticSensitive === false) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive - false not supported, install Postgres Unaccent Extension`); - } - - patterns.push(`to_tsvector($${index}, $${index + 1}:name) @@ to_tsquery($${index + 2}, $${index + 3})`); - values.push(language, fieldName, language, search.$term); - index += 4; - } - - if (fieldValue.$nearSphere) { - const point = fieldValue.$nearSphere; - const distance = fieldValue.$maxDistance; - const distanceInKM = distance * 6371 * 1000; - patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); - sorts.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) ASC`); - values.push(fieldName, point.longitude, point.latitude, distanceInKM); - index += 4; - } - - if (fieldValue.$within && fieldValue.$within.$box) { - const box = fieldValue.$within.$box; - const left = box[0].longitude; - const bottom = box[0].latitude; - const right = box[1].longitude; - const top = box[1].latitude; - patterns.push(`$${index}:name::point <@ $${index + 1}::box`); - values.push(fieldName, `((${left}, ${bottom}), (${right}, ${top}))`); - index += 2; - } - - if (fieldValue.$geoWithin && fieldValue.$geoWithin.$centerSphere) { - const centerSphere = fieldValue.$geoWithin.$centerSphere; - - if (!(centerSphere instanceof Array) || centerSphere.length < 2) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); - } // Get point, convert to geo point if necessary and validate - - - let point = centerSphere[0]; - - if (point instanceof Array && point.length === 2) { - point = new _node.default.GeoPoint(point[1], point[0]); - } else if (!GeoPointCoder.isValidJSON(point)) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); - } - - _node.default.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate - - - const distance = centerSphere[1]; - - if (isNaN(distance) || distance < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); - } - - const distanceInKM = distance * 6371 * 1000; - patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); - values.push(fieldName, point.longitude, point.latitude, distanceInKM); - index += 4; - } - - if (fieldValue.$geoWithin && fieldValue.$geoWithin.$polygon) { - const polygon = fieldValue.$geoWithin.$polygon; - let points; - - if (typeof polygon === 'object' && polygon.__type === 'Polygon') { - if (!polygon.coordinates || polygon.coordinates.length < 3) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); - } - - points = polygon.coordinates; - } else if (polygon instanceof Array) { - if (polygon.length < 3) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); - } - - points = polygon; - } else { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); - } - - points = points.map(point => { - if (point instanceof Array && point.length === 2) { - _node.default.GeoPoint._validate(point[1], point[0]); - - return `(${point[0]}, ${point[1]})`; - } - - if (typeof point !== 'object' || point.__type !== 'GeoPoint') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value'); - } else { - _node.default.GeoPoint._validate(point.latitude, point.longitude); - } - - return `(${point.longitude}, ${point.latitude})`; - }).join(', '); - patterns.push(`$${index}:name::point <@ $${index + 1}::polygon`); - values.push(fieldName, `(${points})`); - index += 2; - } - - if (fieldValue.$geoIntersects && fieldValue.$geoIntersects.$point) { - const point = fieldValue.$geoIntersects.$point; - - if (typeof point !== 'object' || point.__type !== 'GeoPoint') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); - } else { - _node.default.GeoPoint._validate(point.latitude, point.longitude); - } - - patterns.push(`$${index}:name::polygon @> $${index + 1}::point`); - values.push(fieldName, `(${point.longitude}, ${point.latitude})`); - index += 2; - } - - if (fieldValue.$regex) { - let regex = fieldValue.$regex; - let operator = '~'; - const opts = fieldValue.$options; - - if (opts) { - if (opts.indexOf('i') >= 0) { - operator = '~*'; - } - - if (opts.indexOf('x') >= 0) { - regex = removeWhiteSpace(regex); - } - } - - const name = transformDotField(fieldName); - regex = processRegexPattern(regex); - patterns.push(`$${index}:raw ${operator} '$${index + 1}:raw'`); - values.push(name, regex); - index += 2; - } - - if (fieldValue.__type === 'Pointer') { - if (isArrayField) { - patterns.push(`array_contains($${index}:name, $${index + 1})`); - values.push(fieldName, JSON.stringify([fieldValue])); - index += 2; - } else { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.objectId); - index += 2; - } - } - - if (fieldValue.__type === 'Date') { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.iso); - index += 2; - } - - if (fieldValue.__type === 'GeoPoint') { - patterns.push(`$${index}:name ~= POINT($${index + 1}, $${index + 2})`); - values.push(fieldName, fieldValue.longitude, fieldValue.latitude); - index += 3; - } - - if (fieldValue.__type === 'Polygon') { - const value = convertPolygonToSQL(fieldValue.coordinates); - patterns.push(`$${index}:name ~= $${index + 1}::polygon`); - values.push(fieldName, value); - index += 2; - } - - Object.keys(ParseToPosgresComparator).forEach(cmp => { - if (fieldValue[cmp] || fieldValue[cmp] === 0) { - const pgComparator = ParseToPosgresComparator[cmp]; - const postgresValue = toPostgresValue(fieldValue[cmp]); - let constraintFieldName; - - if (fieldName.indexOf('.') >= 0) { - let castType; - - switch (typeof postgresValue) { - case 'number': - castType = 'double precision'; - break; - - case 'boolean': - castType = 'boolean'; - break; - - default: - castType = undefined; - } - - constraintFieldName = castType ? `CAST ((${transformDotField(fieldName)}) AS ${castType})` : transformDotField(fieldName); - } else { - constraintFieldName = `$${index++}:name`; - values.push(fieldName); - } - - values.push(postgresValue); - patterns.push(`${constraintFieldName} ${pgComparator} $${index++}`); - } - }); - - if (initialPatternsLength === patterns.length) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support this query type yet ${JSON.stringify(fieldValue)}`); - } - } - - values = values.map(transformValue); - return { - pattern: patterns.join(' AND '), - values, - sorts - }; -}; - -class PostgresStorageAdapter { - // Private - constructor({ - uri, - collectionPrefix = '', - databaseOptions - }) { - this._collectionPrefix = collectionPrefix; - const { - client, - pgp - } = (0, _PostgresClient.createClient)(uri, databaseOptions); - this._client = client; - this._pgp = pgp; - this.canSortOnJoinTables = false; - } //Note that analyze=true will run the query, executing INSERTS, DELETES, etc. - - - createExplainableQuery(query, analyze = false) { - if (analyze) { - return 'EXPLAIN (ANALYZE, FORMAT JSON) ' + query; - } else { - return 'EXPLAIN (FORMAT JSON) ' + query; - } - } - - handleShutdown() { - if (!this._client) { - return; - } - - this._client.$pool.end(); - } - - async _ensureSchemaCollectionExists(conn) { - conn = conn || this._client; - await conn.none('CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )').catch(error => { - if (error.code === PostgresDuplicateRelationError || error.code === PostgresUniqueIndexViolationError || error.code === PostgresDuplicateObjectError) {// Table already exists, must have been created by a different request. Ignore error. - } else { - throw error; - } - }); - } - - async classExists(name) { - return this._client.one('SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)', [name], a => a.exists); - } - - async setClassLevelPermissions(className, CLPs) { - const self = this; - await this._client.task('set-class-level-permissions', async t => { - await self._ensureSchemaCollectionExists(t); - const values = [className, 'schema', 'classLevelPermissions', JSON.stringify(CLPs)]; - await t.none(`UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1`, values); - }); - } - - async setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields, conn) { - conn = conn || this._client; - const self = this; - - if (submittedIndexes === undefined) { - return Promise.resolve(); - } - - if (Object.keys(existingIndexes).length === 0) { - existingIndexes = { - _id_: { - _id: 1 - } - }; - } - - const deletedIndexes = []; - const insertedIndexes = []; - Object.keys(submittedIndexes).forEach(name => { - const field = submittedIndexes[name]; - - if (existingIndexes[name] && field.__op !== 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); - } - - if (!existingIndexes[name] && field.__op === 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); - } - - if (field.__op === 'Delete') { - deletedIndexes.push(name); - delete existingIndexes[name]; - } else { - Object.keys(field).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(fields, key)) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); - } - }); - existingIndexes[name] = field; - insertedIndexes.push({ - key: field, - name - }); - } - }); - await conn.tx('set-indexes-with-schema-format', async t => { - if (insertedIndexes.length > 0) { - await self.createIndexes(className, insertedIndexes, t); - } - - if (deletedIndexes.length > 0) { - await self.dropIndexes(className, deletedIndexes, t); - } - - await self._ensureSchemaCollectionExists(t); - await t.none('UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1', [className, 'schema', 'indexes', JSON.stringify(existingIndexes)]); - }); - } - - async createClass(className, schema, conn) { - conn = conn || this._client; - return conn.tx('create-class', async t => { - const q1 = this.createTable(className, schema, t); - const q2 = t.none('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($, $, true)', { - className, - schema - }); - const q3 = this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields, t); // TODO: The test should not verify the returned value, and then - // the method can be simplified, to avoid returning useless stuff. - - return t.batch([q1, q2, q3]); - }).then(() => { - return toParseSchema(schema); - }).catch(err => { - if (err.data[0].result.code === PostgresTransactionAbortedError) { - err = err.data[1].result; - } - - if (err.code === PostgresUniqueIndexViolationError && err.detail.includes(className)) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, `Class ${className} already exists.`); - } - - throw err; - }); - } // Just create a table, do not insert in schema - - - async createTable(className, schema, conn) { - conn = conn || this._client; - const self = this; - debug('createTable', className, schema); - const valuesArray = []; - const patternsArray = []; - const fields = Object.assign({}, schema.fields); - - if (className === '_User') { - fields._email_verify_token_expires_at = { - type: 'Date' - }; - fields._email_verify_token = { - type: 'String' - }; - fields._account_lockout_expires_at = { - type: 'Date' - }; - fields._failed_login_count = { - type: 'Number' - }; - fields._perishable_token = { - type: 'String' - }; - fields._perishable_token_expires_at = { - type: 'Date' - }; - fields._password_changed_at = { - type: 'Date' - }; - fields._password_history = { - type: 'Array' - }; - } - - let index = 2; - const relations = []; - Object.keys(fields).forEach(fieldName => { - const parseType = fields[fieldName]; // Skip when it's a relation - // We'll create the tables later - - if (parseType.type === 'Relation') { - relations.push(fieldName); - return; - } - - if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { - parseType.contents = { - type: 'String' - }; - } - - valuesArray.push(fieldName); - valuesArray.push(parseTypeToPostgresType(parseType)); - patternsArray.push(`$${index}:name $${index + 1}:raw`); - - if (fieldName === 'objectId') { - patternsArray.push(`PRIMARY KEY ($${index}:name)`); - } - - index = index + 2; - }); - const qs = `CREATE TABLE IF NOT EXISTS $1:name (${patternsArray.join()})`; - const values = [className, ...valuesArray]; - debug(qs, values); - return conn.task('create-table', async t => { - try { - await self._ensureSchemaCollectionExists(t); - await t.none(qs, values); - } catch (error) { - if (error.code !== PostgresDuplicateRelationError) { - throw error; - } // ELSE: Table already exists, must have been created by a different request. Ignore the error. - - } - - await t.tx('create-table-tx', tx => { - return tx.batch(relations.map(fieldName => { - return tx.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { - joinTable: `_Join:${fieldName}:${className}` - }); - })); - }); - }); - } - - async schemaUpgrade(className, schema, conn) { - debug('schemaUpgrade', { - className, - schema - }); - conn = conn || this._client; - const self = this; - await conn.tx('schema-upgrade', async t => { - const columns = await t.map('SELECT column_name FROM information_schema.columns WHERE table_name = $', { - className - }, a => a.column_name); - const newColumns = Object.keys(schema.fields).filter(item => columns.indexOf(item) === -1).map(fieldName => self.addFieldIfNotExists(className, fieldName, schema.fields[fieldName], t)); - await t.batch(newColumns); - }); - } - - async addFieldIfNotExists(className, fieldName, type, conn) { - // TODO: Must be revised for invalid logic... - debug('addFieldIfNotExists', { - className, - fieldName, - type - }); - conn = conn || this._client; - const self = this; - await conn.tx('add-field-if-not-exists', async t => { - if (type.type !== 'Relation') { - try { - await t.none('ALTER TABLE $ ADD COLUMN IF NOT EXISTS $ $', { - className, - fieldName, - postgresType: parseTypeToPostgresType(type) - }); - } catch (error) { - if (error.code === PostgresRelationDoesNotExistError) { - return self.createClass(className, { - fields: { - [fieldName]: type - } - }, t); - } - - if (error.code !== PostgresDuplicateColumnError) { - throw error; - } // Column already exists, created by other request. Carry on to see if it's the right type. - - } - } else { - await t.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { - joinTable: `_Join:${fieldName}:${className}` - }); - } - - const result = await t.any('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $ and ("schema"::json->\'fields\'->$) is not null', { - className, - fieldName - }); - - if (result[0]) { - throw 'Attempted to add a field that already exists'; - } else { - const path = `{fields,${fieldName}}`; - await t.none('UPDATE "_SCHEMA" SET "schema"=jsonb_set("schema", $, $) WHERE "className"=$', { - path, - type, - className - }); - } - }); - } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) - // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. - - - async deleteClass(className) { - const operations = [{ - query: `DROP TABLE IF EXISTS $1:name`, - values: [className] - }, { - query: `DELETE FROM "_SCHEMA" WHERE "className" = $1`, - values: [className] - }]; - return this._client.tx(t => t.none(this._pgp.helpers.concat(operations))).then(() => className.indexOf('_Join:') != 0); // resolves with false when _Join table - } // Delete all data known to this adapter. Used for testing. - - - async deleteAllClasses() { - const now = new Date().getTime(); - const helpers = this._pgp.helpers; - debug('deleteAllClasses'); - await this._client.task('delete-all-classes', async t => { - try { - const results = await t.any('SELECT * FROM "_SCHEMA"'); - const joins = results.reduce((list, schema) => { - return list.concat(joinTablesForSchema(schema.schema)); - }, []); - const classes = ['_SCHEMA', '_PushStatus', '_JobStatus', '_JobSchedule', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_Audience', '_Idempotency', ...results.map(result => result.className), ...joins]; - const queries = classes.map(className => ({ - query: 'DROP TABLE IF EXISTS $', - values: { - className - } - })); - await t.tx(tx => tx.none(helpers.concat(queries))); - } catch (error) { - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } // No _SCHEMA collection. Don't delete anything. - - } - }).then(() => { - debug(`deleteAllClasses done in ${new Date().getTime() - now}`); - }); - } // Remove the column and all the data. For Relations, the _Join collection is handled - // specially, this function does not delete _Join columns. It should, however, indicate - // that the relation fields does not exist anymore. In mongo, this means removing it from - // the _SCHEMA collection. There should be no actual data in the collection under the same name - // as the relation column, so it's fine to attempt to delete it. If the fields listed to be - // deleted do not exist, this function should return successfully anyways. Checking for - // attempts to delete non-existent fields is the responsibility of Parse Server. - // This function is not obligated to delete fields atomically. It is given the field - // names in a list so that databases that are capable of deleting fields atomically - // may do so. - // Returns a Promise. - - - async deleteFields(className, schema, fieldNames) { - debug('deleteFields', className, fieldNames); - fieldNames = fieldNames.reduce((list, fieldName) => { - const field = schema.fields[fieldName]; - - if (field.type !== 'Relation') { - list.push(fieldName); - } - - delete schema.fields[fieldName]; - return list; - }, []); - const values = [className, ...fieldNames]; - const columns = fieldNames.map((name, idx) => { - return `$${idx + 2}:name`; - }).join(', DROP COLUMN'); - await this._client.tx('delete-fields', async t => { - await t.none('UPDATE "_SCHEMA" SET "schema" = $ WHERE "className" = $', { - schema, - className - }); - - if (values.length > 1) { - await t.none(`ALTER TABLE $1:name DROP COLUMN IF EXISTS ${columns}`, values); - } - }); - } // Return a promise for all schemas known to this adapter, in Parse format. In case the - // schemas cannot be retrieved, returns a promise that rejects. Requirements for the - // rejection reason are TBD. - - - async getAllClasses() { - const self = this; - return this._client.task('get-all-classes', async t => { - await self._ensureSchemaCollectionExists(t); - return await t.map('SELECT * FROM "_SCHEMA"', null, row => toParseSchema(_objectSpread({ - className: row.className - }, row.schema))); - }); - } // Return a promise for the schema with the given name, in Parse format. If - // this adapter doesn't know about the schema, return a promise that rejects with - // undefined as the reason. - - - async getClass(className) { - debug('getClass', className); - return this._client.any('SELECT * FROM "_SCHEMA" WHERE "className" = $', { - className - }).then(result => { - if (result.length !== 1) { - throw undefined; - } - - return result[0].schema; - }).then(toParseSchema); - } // TODO: remove the mongo format dependency in the return value - - - async createObject(className, schema, object, transactionalSession) { - debug('createObject', className, object); - let columnsArray = []; - const valuesArray = []; - schema = toPostgresSchema(schema); - const geoPoints = {}; - object = handleDotFields(object); - validateKeys(object); - Object.keys(object).forEach(fieldName => { - if (object[fieldName] === null) { - return; - } - - var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch) { - var provider = authDataMatch[1]; - object['authData'] = object['authData'] || {}; - object['authData'][provider] = object[fieldName]; - delete object[fieldName]; - fieldName = 'authData'; - } - - columnsArray.push(fieldName); - - if (!schema.fields[fieldName] && className === '_User') { - if (fieldName === '_email_verify_token' || fieldName === '_failed_login_count' || fieldName === '_perishable_token' || fieldName === '_password_history') { - valuesArray.push(object[fieldName]); - } - - if (fieldName === '_email_verify_token_expires_at') { - if (object[fieldName]) { - valuesArray.push(object[fieldName].iso); - } else { - valuesArray.push(null); - } - } - - if (fieldName === '_account_lockout_expires_at' || fieldName === '_perishable_token_expires_at' || fieldName === '_password_changed_at') { - if (object[fieldName]) { - valuesArray.push(object[fieldName].iso); - } else { - valuesArray.push(null); - } - } - - return; - } - - switch (schema.fields[fieldName].type) { - case 'Date': - if (object[fieldName]) { - valuesArray.push(object[fieldName].iso); - } else { - valuesArray.push(null); - } - - break; - - case 'Pointer': - valuesArray.push(object[fieldName].objectId); - break; - - case 'Array': - if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { - valuesArray.push(object[fieldName]); - } else { - valuesArray.push(JSON.stringify(object[fieldName])); - } - - break; - - case 'Object': - case 'Bytes': - case 'String': - case 'Number': - case 'Boolean': - valuesArray.push(object[fieldName]); - break; - - case 'File': - valuesArray.push(object[fieldName].name); - break; - - case 'Polygon': - { - const value = convertPolygonToSQL(object[fieldName].coordinates); - valuesArray.push(value); - break; - } - - case 'GeoPoint': - // pop the point and process later - geoPoints[fieldName] = object[fieldName]; - columnsArray.pop(); - break; - - default: - throw `Type ${schema.fields[fieldName].type} not supported yet`; - } - }); - columnsArray = columnsArray.concat(Object.keys(geoPoints)); - const initialValues = valuesArray.map((val, index) => { - let termination = ''; - const fieldName = columnsArray[index]; - - if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { - termination = '::text[]'; - } else if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { - termination = '::jsonb'; - } - - return `$${index + 2 + columnsArray.length}${termination}`; - }); - const geoPointsInjects = Object.keys(geoPoints).map(key => { - const value = geoPoints[key]; - valuesArray.push(value.longitude, value.latitude); - const l = valuesArray.length + columnsArray.length; - return `POINT($${l}, $${l + 1})`; - }); - const columnsPattern = columnsArray.map((col, index) => `$${index + 2}:name`).join(); - const valuesPattern = initialValues.concat(geoPointsInjects).join(); - const qs = `INSERT INTO $1:name (${columnsPattern}) VALUES (${valuesPattern})`; - const values = [className, ...columnsArray, ...valuesArray]; - debug(qs, values); - const promise = (transactionalSession ? transactionalSession.t : this._client).none(qs, values).then(() => ({ - ops: [object] - })).catch(error => { - if (error.code === PostgresUniqueIndexViolationError) { - const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - err.underlyingError = error; - - if (error.constraint) { - const matches = error.constraint.match(/unique_([a-zA-Z]+)/); - - if (matches && Array.isArray(matches)) { - err.userInfo = { - duplicated_field: matches[1] - }; - } - } - - error = err; - } - - throw error; - }); - - if (transactionalSession) { - transactionalSession.batch.push(promise); - } - - return promise; - } // Remove all objects that match the given Parse Query. - // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. - // If there is some other error, reject with INTERNAL_SERVER_ERROR. - - - async deleteObjectsByQuery(className, schema, query, transactionalSession) { - debug('deleteObjectsByQuery', className, query); - const values = [className]; - const index = 2; - const where = buildWhereClause({ - schema, - index, - query, - caseInsensitive: false - }); - values.push(...where.values); - - if (Object.keys(query).length === 0) { - where.pattern = 'TRUE'; - } - - const qs = `WITH deleted AS (DELETE FROM $1:name WHERE ${where.pattern} RETURNING *) SELECT count(*) FROM deleted`; - debug(qs, values); - const promise = (transactionalSession ? transactionalSession.t : this._client).one(qs, values, a => +a.count).then(count => { - if (count === 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } else { - return count; - } - }).catch(error => { - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } // ELSE: Don't delete anything if doesn't exist - - }); - - if (transactionalSession) { - transactionalSession.batch.push(promise); - } - - return promise; - } // Return value not currently well specified. - - - async findOneAndUpdate(className, schema, query, update, transactionalSession) { - debug('findOneAndUpdate', className, query, update); - return this.updateObjectsByQuery(className, schema, query, update, transactionalSession).then(val => val[0]); - } // Apply the update to all objects that match the given Parse Query. - - - async updateObjectsByQuery(className, schema, query, update, transactionalSession) { - debug('updateObjectsByQuery', className, query, update); - const updatePatterns = []; - const values = [className]; - let index = 2; - schema = toPostgresSchema(schema); - - const originalUpdate = _objectSpread({}, update); // Set flag for dot notation fields - - - const dotNotationOptions = {}; - Object.keys(update).forEach(fieldName => { - if (fieldName.indexOf('.') > -1) { - const components = fieldName.split('.'); - const first = components.shift(); - dotNotationOptions[first] = true; - } else { - dotNotationOptions[fieldName] = false; - } - }); - update = handleDotFields(update); // Resolve authData first, - // So we don't end up with multiple key updates - - for (const fieldName in update) { - const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch) { - var provider = authDataMatch[1]; - const value = update[fieldName]; - delete update[fieldName]; - update['authData'] = update['authData'] || {}; - update['authData'][provider] = value; - } - } - - for (const fieldName in update) { - const fieldValue = update[fieldName]; // Drop any undefined values. - - if (typeof fieldValue === 'undefined') { - delete update[fieldName]; - } else if (fieldValue === null) { - updatePatterns.push(`$${index}:name = NULL`); - values.push(fieldName); - index += 1; - } else if (fieldName == 'authData') { - // This recursively sets the json_object - // Only 1 level deep - const generate = (jsonb, key, value) => { - return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`; - }; - - const lastKey = `$${index}:name`; - const fieldNameIndex = index; - index += 1; - values.push(fieldName); - const update = Object.keys(fieldValue).reduce((lastKey, key) => { - const str = generate(lastKey, `$${index}::text`, `$${index + 1}::jsonb`); - index += 2; - let value = fieldValue[key]; - - if (value) { - if (value.__op === 'Delete') { - value = null; - } else { - value = JSON.stringify(value); - } - } - - values.push(key, value); - return str; - }, lastKey); - updatePatterns.push(`$${fieldNameIndex}:name = ${update}`); - } else if (fieldValue.__op === 'Increment') { - updatePatterns.push(`$${index}:name = COALESCE($${index}:name, 0) + $${index + 1}`); - values.push(fieldName, fieldValue.amount); - index += 2; - } else if (fieldValue.__op === 'Add') { - updatePatterns.push(`$${index}:name = array_add(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); - values.push(fieldName, JSON.stringify(fieldValue.objects)); - index += 2; - } else if (fieldValue.__op === 'Delete') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, null); - index += 2; - } else if (fieldValue.__op === 'Remove') { - updatePatterns.push(`$${index}:name = array_remove(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); - values.push(fieldName, JSON.stringify(fieldValue.objects)); - index += 2; - } else if (fieldValue.__op === 'AddUnique') { - updatePatterns.push(`$${index}:name = array_add_unique(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); - values.push(fieldName, JSON.stringify(fieldValue.objects)); - index += 2; - } else if (fieldName === 'updatedAt') { - //TODO: stop special casing this. It should check for __type === 'Date' and use .iso - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'string') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'boolean') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (fieldValue.__type === 'Pointer') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.objectId); - index += 2; - } else if (fieldValue.__type === 'Date') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, toPostgresValue(fieldValue)); - index += 2; - } else if (fieldValue instanceof Date) { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (fieldValue.__type === 'File') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, toPostgresValue(fieldValue)); - index += 2; - } else if (fieldValue.__type === 'GeoPoint') { - updatePatterns.push(`$${index}:name = POINT($${index + 1}, $${index + 2})`); - values.push(fieldName, fieldValue.longitude, fieldValue.latitude); - index += 3; - } else if (fieldValue.__type === 'Polygon') { - const value = convertPolygonToSQL(fieldValue.coordinates); - updatePatterns.push(`$${index}:name = $${index + 1}::polygon`); - values.push(fieldName, value); - index += 2; - } else if (fieldValue.__type === 'Relation') {// noop - } else if (typeof fieldValue === 'number') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'object' && schema.fields[fieldName] && schema.fields[fieldName].type === 'Object') { - // Gather keys to increment - const keysToIncrement = Object.keys(originalUpdate).filter(k => { - // choose top level fields that have a delete operation set - // Note that Object.keys is iterating over the **original** update object - // and that some of the keys of the original update could be null or undefined: - // (See the above check `if (fieldValue === null || typeof fieldValue == "undefined")`) - const value = originalUpdate[k]; - return value && value.__op === 'Increment' && k.split('.').length === 2 && k.split('.')[0] === fieldName; - }).map(k => k.split('.')[1]); - let incrementPatterns = ''; - - if (keysToIncrement.length > 0) { - incrementPatterns = ' || ' + keysToIncrement.map(c => { - const amount = fieldValue[c].amount; - return `CONCAT('{"${c}":', COALESCE($${index}:name->>'${c}','0')::int + ${amount}, '}')::jsonb`; - }).join(' || '); // Strip the keys - - keysToIncrement.forEach(key => { - delete fieldValue[key]; - }); - } - - const keysToDelete = Object.keys(originalUpdate).filter(k => { - // choose top level fields that have a delete operation set. - const value = originalUpdate[k]; - return value && value.__op === 'Delete' && k.split('.').length === 2 && k.split('.')[0] === fieldName; - }).map(k => k.split('.')[1]); - const deletePatterns = keysToDelete.reduce((p, c, i) => { - return p + ` - '$${index + 1 + i}:value'`; - }, ''); // Override Object - - let updateObject = "'{}'::jsonb"; - - if (dotNotationOptions[fieldName]) { - // Merge Object - updateObject = `COALESCE($${index}:name, '{}'::jsonb)`; - } - - updatePatterns.push(`$${index}:name = (${updateObject} ${deletePatterns} ${incrementPatterns} || $${index + 1 + keysToDelete.length}::jsonb )`); - values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue)); - index += 2 + keysToDelete.length; - } else if (Array.isArray(fieldValue) && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { - const expectedType = parseTypeToPostgresType(schema.fields[fieldName]); - - if (expectedType === 'text[]') { - updatePatterns.push(`$${index}:name = $${index + 1}::text[]`); - values.push(fieldName, fieldValue); - index += 2; - } else { - updatePatterns.push(`$${index}:name = $${index + 1}::jsonb`); - values.push(fieldName, JSON.stringify(fieldValue)); - index += 2; - } - } else { - debug('Not supported update', fieldName, fieldValue); - return Promise.reject(new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support update ${JSON.stringify(fieldValue)} yet`)); - } - } - - const where = buildWhereClause({ - schema, - index, - query, - caseInsensitive: false - }); - values.push(...where.values); - const whereClause = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - const qs = `UPDATE $1:name SET ${updatePatterns.join()} ${whereClause} RETURNING *`; - debug('update: ', qs, values); - const promise = (transactionalSession ? transactionalSession.t : this._client).any(qs, values); - - if (transactionalSession) { - transactionalSession.batch.push(promise); - } - - return promise; - } // Hopefully, we can get rid of this. It's only used for config and hooks. - - - upsertOneObject(className, schema, query, update, transactionalSession) { - debug('upsertOneObject', { - className, - query, - update - }); - const createValue = Object.assign({}, query, update); - return this.createObject(className, schema, createValue, transactionalSession).catch(error => { - // ignore duplicate value errors as it's upsert - if (error.code !== _node.default.Error.DUPLICATE_VALUE) { - throw error; - } - - return this.findOneAndUpdate(className, schema, query, update, transactionalSession); - }); - } - - find(className, schema, query, { - skip, - limit, - sort, - keys, - caseInsensitive, - explain - }) { - debug('find', className, query, { - skip, - limit, - sort, - keys, - caseInsensitive, - explain - }); - const hasLimit = limit !== undefined; - const hasSkip = skip !== undefined; - let values = [className]; - const where = buildWhereClause({ - schema, - query, - index: 2, - caseInsensitive - }); - values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - const limitPattern = hasLimit ? `LIMIT $${values.length + 1}` : ''; - - if (hasLimit) { - values.push(limit); - } - - const skipPattern = hasSkip ? `OFFSET $${values.length + 1}` : ''; - - if (hasSkip) { - values.push(skip); - } - - let sortPattern = ''; - - if (sort) { - const sortCopy = sort; - const sorting = Object.keys(sort).map(key => { - const transformKey = transformDotFieldToComponents(key).join('->'); // Using $idx pattern gives: non-integer constant in ORDER BY - - if (sortCopy[key] === 1) { - return `${transformKey} ASC`; - } - - return `${transformKey} DESC`; - }).join(); - sortPattern = sort !== undefined && Object.keys(sort).length > 0 ? `ORDER BY ${sorting}` : ''; - } - - if (where.sorts && Object.keys(where.sorts).length > 0) { - sortPattern = `ORDER BY ${where.sorts.join()}`; - } - - let columns = '*'; - - if (keys) { - // Exclude empty keys - // Replace ACL by it's keys - keys = keys.reduce((memo, key) => { - if (key === 'ACL') { - memo.push('_rperm'); - memo.push('_wperm'); - } else if (key.length > 0) { - memo.push(key); - } - - return memo; - }, []); - columns = keys.map((key, index) => { - if (key === '$score') { - return `ts_rank_cd(to_tsvector($${2}, $${3}:name), to_tsquery($${4}, $${5}), 32) as score`; - } - - return `$${index + values.length + 1}:name`; - }).join(); - values = values.concat(keys); - } - - const originalQuery = `SELECT ${columns} FROM $1:name ${wherePattern} ${sortPattern} ${limitPattern} ${skipPattern}`; - const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; - debug(qs, values); - return this._client.any(qs, values).catch(error => { - // Query on non existing table, don't crash - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } - - return []; - }).then(results => { - if (explain) { - return results; - } - - return results.map(object => this.postgresObjectToParseObject(className, object, schema)); - }); - } // Converts from a postgres-format object to a REST-format object. - // Does not strip out anything based on a lack of authentication. - - - postgresObjectToParseObject(className, object, schema) { - Object.keys(schema.fields).forEach(fieldName => { - if (schema.fields[fieldName].type === 'Pointer' && object[fieldName]) { - object[fieldName] = { - objectId: object[fieldName], - __type: 'Pointer', - className: schema.fields[fieldName].targetClass - }; - } - - if (schema.fields[fieldName].type === 'Relation') { - object[fieldName] = { - __type: 'Relation', - className: schema.fields[fieldName].targetClass - }; - } - - if (object[fieldName] && schema.fields[fieldName].type === 'GeoPoint') { - object[fieldName] = { - __type: 'GeoPoint', - latitude: object[fieldName].y, - longitude: object[fieldName].x - }; - } - - if (object[fieldName] && schema.fields[fieldName].type === 'Polygon') { - let coords = object[fieldName]; - coords = coords.substr(2, coords.length - 4).split('),('); - coords = coords.map(point => { - return [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]; - }); - object[fieldName] = { - __type: 'Polygon', - coordinates: coords - }; - } - - if (object[fieldName] && schema.fields[fieldName].type === 'File') { - object[fieldName] = { - __type: 'File', - name: object[fieldName] - }; - } - }); //TODO: remove this reliance on the mongo format. DB adapter shouldn't know there is a difference between created at and any other date field. - - if (object.createdAt) { - object.createdAt = object.createdAt.toISOString(); - } - - if (object.updatedAt) { - object.updatedAt = object.updatedAt.toISOString(); - } - - if (object.expiresAt) { - object.expiresAt = { - __type: 'Date', - iso: object.expiresAt.toISOString() - }; - } - - if (object._email_verify_token_expires_at) { - object._email_verify_token_expires_at = { - __type: 'Date', - iso: object._email_verify_token_expires_at.toISOString() - }; - } - - if (object._account_lockout_expires_at) { - object._account_lockout_expires_at = { - __type: 'Date', - iso: object._account_lockout_expires_at.toISOString() - }; - } - - if (object._perishable_token_expires_at) { - object._perishable_token_expires_at = { - __type: 'Date', - iso: object._perishable_token_expires_at.toISOString() - }; - } - - if (object._password_changed_at) { - object._password_changed_at = { - __type: 'Date', - iso: object._password_changed_at.toISOString() - }; - } - - for (const fieldName in object) { - if (object[fieldName] === null) { - delete object[fieldName]; - } - - if (object[fieldName] instanceof Date) { - object[fieldName] = { - __type: 'Date', - iso: object[fieldName].toISOString() - }; - } - } - - return object; - } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't - // currently know which fields are nullable and which aren't, we ignore that criteria. - // As such, we shouldn't expose this function to users of parse until we have an out-of-band - // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, - // which is why we use sparse indexes. - - - async ensureUniqueness(className, schema, fieldNames) { - const constraintName = `${className}_unique_${fieldNames.sort().join('_')}`; - const constraintPatterns = fieldNames.map((fieldName, index) => `$${index + 3}:name`); - const qs = `CREATE UNIQUE INDEX IF NOT EXISTS $2:name ON $1:name(${constraintPatterns.join()})`; - return this._client.none(qs, [className, constraintName, ...fieldNames]).catch(error => { - if (error.code === PostgresDuplicateRelationError && error.message.includes(constraintName)) {// Index already exists. Ignore error. - } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(constraintName)) { - // Cast the error into the proper parse error - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - } else { - throw error; - } - }); - } // Executes a count. - - - async count(className, schema, query, readPreference, estimate = true) { - debug('count', className, query, readPreference, estimate); - const values = [className]; - const where = buildWhereClause({ - schema, - query, - index: 2, - caseInsensitive: false - }); - values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - let qs = ''; - - if (where.pattern.length > 0 || !estimate) { - qs = `SELECT count(*) FROM $1:name ${wherePattern}`; - } else { - qs = 'SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = $1'; - } - - return this._client.one(qs, values, a => { - if (a.approximate_row_count != null) { - return +a.approximate_row_count; - } else { - return +a.count; - } - }).catch(error => { - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } - - return 0; - }); - } - - async distinct(className, schema, query, fieldName) { - debug('distinct', className, query); - let field = fieldName; - let column = fieldName; - const isNested = fieldName.indexOf('.') >= 0; - - if (isNested) { - field = transformDotFieldToComponents(fieldName).join('->'); - column = fieldName.split('.')[0]; - } - - const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; - const isPointerField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; - const values = [field, column, className]; - const where = buildWhereClause({ - schema, - query, - index: 4, - caseInsensitive: false - }); - values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - const transformer = isArrayField ? 'jsonb_array_elements' : 'ON'; - let qs = `SELECT DISTINCT ${transformer}($1:name) $2:name FROM $3:name ${wherePattern}`; - - if (isNested) { - qs = `SELECT DISTINCT ${transformer}($1:raw) $2:raw FROM $3:name ${wherePattern}`; - } - - debug(qs, values); - return this._client.any(qs, values).catch(error => { - if (error.code === PostgresMissingColumnError) { - return []; - } - - throw error; - }).then(results => { - if (!isNested) { - results = results.filter(object => object[field] !== null); - return results.map(object => { - if (!isPointerField) { - return object[field]; - } - - return { - __type: 'Pointer', - className: schema.fields[fieldName].targetClass, - objectId: object[field] - }; - }); - } - - const child = fieldName.split('.')[1]; - return results.map(object => object[column][child]); - }).then(results => results.map(object => this.postgresObjectToParseObject(className, object, schema))); - } - - async aggregate(className, schema, pipeline, readPreference, hint, explain) { - debug('aggregate', className, pipeline, readPreference, hint, explain); - const values = [className]; - let index = 2; - let columns = []; - let countField = null; - let groupValues = null; - let wherePattern = ''; - let limitPattern = ''; - let skipPattern = ''; - let sortPattern = ''; - let groupPattern = ''; - - for (let i = 0; i < pipeline.length; i += 1) { - const stage = pipeline[i]; - - if (stage.$group) { - for (const field in stage.$group) { - const value = stage.$group[field]; - - if (value === null || value === undefined) { - continue; - } - - if (field === '_id' && typeof value === 'string' && value !== '') { - columns.push(`$${index}:name AS "objectId"`); - groupPattern = `GROUP BY $${index}:name`; - values.push(transformAggregateField(value)); - index += 1; - continue; - } - - if (field === '_id' && typeof value === 'object' && Object.keys(value).length !== 0) { - groupValues = value; - const groupByFields = []; - - for (const alias in value) { - if (typeof value[alias] === 'string' && value[alias]) { - const source = transformAggregateField(value[alias]); - - if (!groupByFields.includes(`"${source}"`)) { - groupByFields.push(`"${source}"`); - } - - values.push(source, alias); - columns.push(`$${index}:name AS $${index + 1}:name`); - index += 2; - } else { - const operation = Object.keys(value[alias])[0]; - const source = transformAggregateField(value[alias][operation]); - - if (mongoAggregateToPostgres[operation]) { - if (!groupByFields.includes(`"${source}"`)) { - groupByFields.push(`"${source}"`); - } - - columns.push(`EXTRACT(${mongoAggregateToPostgres[operation]} FROM $${index}:name AT TIME ZONE 'UTC') AS $${index + 1}:name`); - values.push(source, alias); - index += 2; - } - } - } - - groupPattern = `GROUP BY $${index}:raw`; - values.push(groupByFields.join()); - index += 1; - continue; - } - - if (typeof value === 'object') { - if (value.$sum) { - if (typeof value.$sum === 'string') { - columns.push(`SUM($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$sum), field); - index += 2; - } else { - countField = field; - columns.push(`COUNT(*) AS $${index}:name`); - values.push(field); - index += 1; - } - } - - if (value.$max) { - columns.push(`MAX($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$max), field); - index += 2; - } - - if (value.$min) { - columns.push(`MIN($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$min), field); - index += 2; - } - - if (value.$avg) { - columns.push(`AVG($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$avg), field); - index += 2; - } - } - } - } else { - columns.push('*'); - } - - if (stage.$project) { - if (columns.includes('*')) { - columns = []; - } - - for (const field in stage.$project) { - const value = stage.$project[field]; - - if (value === 1 || value === true) { - columns.push(`$${index}:name`); - values.push(field); - index += 1; - } - } - } - - if (stage.$match) { - const patterns = []; - const orOrAnd = Object.prototype.hasOwnProperty.call(stage.$match, '$or') ? ' OR ' : ' AND '; - - if (stage.$match.$or) { - const collapse = {}; - stage.$match.$or.forEach(element => { - for (const key in element) { - collapse[key] = element[key]; - } - }); - stage.$match = collapse; - } - - for (const field in stage.$match) { - const value = stage.$match[field]; - const matchPatterns = []; - Object.keys(ParseToPosgresComparator).forEach(cmp => { - if (value[cmp]) { - const pgComparator = ParseToPosgresComparator[cmp]; - matchPatterns.push(`$${index}:name ${pgComparator} $${index + 1}`); - values.push(field, toPostgresValue(value[cmp])); - index += 2; - } - }); - - if (matchPatterns.length > 0) { - patterns.push(`(${matchPatterns.join(' AND ')})`); - } - - if (schema.fields[field] && schema.fields[field].type && matchPatterns.length === 0) { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(field, value); - index += 2; - } - } - - wherePattern = patterns.length > 0 ? `WHERE ${patterns.join(` ${orOrAnd} `)}` : ''; - } - - if (stage.$limit) { - limitPattern = `LIMIT $${index}`; - values.push(stage.$limit); - index += 1; - } - - if (stage.$skip) { - skipPattern = `OFFSET $${index}`; - values.push(stage.$skip); - index += 1; - } - - if (stage.$sort) { - const sort = stage.$sort; - const keys = Object.keys(sort); - const sorting = keys.map(key => { - const transformer = sort[key] === 1 ? 'ASC' : 'DESC'; - const order = `$${index}:name ${transformer}`; - index += 1; - return order; - }).join(); - values.push(...keys); - sortPattern = sort !== undefined && sorting.length > 0 ? `ORDER BY ${sorting}` : ''; - } - } - - if (groupPattern) { - columns.forEach((e, i, a) => { - if (e && e.trim() === '*') { - a[i] = ''; - } - }); - } - - const originalQuery = `SELECT ${columns.filter(Boolean).join()} FROM $1:name ${wherePattern} ${skipPattern} ${groupPattern} ${sortPattern} ${limitPattern}`; - const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; - debug(qs, values); - return this._client.any(qs, values).then(a => { - if (explain) { - return a; - } - - const results = a.map(object => this.postgresObjectToParseObject(className, object, schema)); - results.forEach(result => { - if (!Object.prototype.hasOwnProperty.call(result, 'objectId')) { - result.objectId = null; - } - - if (groupValues) { - result.objectId = {}; - - for (const key in groupValues) { - result.objectId[key] = result[key]; - delete result[key]; - } - } - - if (countField) { - result[countField] = parseInt(result[countField], 10); - } - }); - return results; - }); - } - - async performInitialization({ - VolatileClassesSchemas - }) { - // TODO: This method needs to be rewritten to make proper use of connections (@vitaly-t) - debug('performInitialization'); - const promises = VolatileClassesSchemas.map(schema => { - return this.createTable(schema.className, schema).catch(err => { - if (err.code === PostgresDuplicateRelationError || err.code === _node.default.Error.INVALID_CLASS_NAME) { - return Promise.resolve(); - } - - throw err; - }).then(() => this.schemaUpgrade(schema.className, schema)); - }); - return Promise.all(promises).then(() => { - return this._client.tx('perform-initialization', t => { - return t.batch([t.none(_sql.default.misc.jsonObjectSetKeys), t.none(_sql.default.array.add), t.none(_sql.default.array.addUnique), t.none(_sql.default.array.remove), t.none(_sql.default.array.containsAll), t.none(_sql.default.array.containsAllRegex), t.none(_sql.default.array.contains)]); - }); - }).then(data => { - debug(`initializationDone in ${data.duration}`); - }).catch(error => { - /* eslint-disable no-console */ - console.error(error); - }); - } - - async createIndexes(className, indexes, conn) { - return (conn || this._client).tx(t => t.batch(indexes.map(i => { - return t.none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [i.name, className, i.key]); - }))); - } - - async createIndexesIfNeeded(className, fieldName, type, conn) { - await (conn || this._client).none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [fieldName, className, type]); - } - - async dropIndexes(className, indexes, conn) { - const queries = indexes.map(i => ({ - query: 'DROP INDEX $1:name', - values: i - })); - await (conn || this._client).tx(t => t.none(this._pgp.helpers.concat(queries))); - } - - async getIndexes(className) { - const qs = 'SELECT * FROM pg_indexes WHERE tablename = ${className}'; - return this._client.any(qs, { - className - }); - } - - async updateSchemaWithIndexes() { - return Promise.resolve(); - } // Used for testing purposes - - - async updateEstimatedCount(className) { - return this._client.none('ANALYZE $1:name', [className]); - } - - async createTransactionalSession() { - return new Promise(resolve => { - const transactionalSession = {}; - transactionalSession.result = this._client.tx(t => { - transactionalSession.t = t; - transactionalSession.promise = new Promise(resolve => { - transactionalSession.resolve = resolve; - }); - transactionalSession.batch = []; - resolve(transactionalSession); - return transactionalSession.promise; - }); - }); - } - - commitTransactionalSession(transactionalSession) { - transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); - return transactionalSession.result; - } - - abortTransactionalSession(transactionalSession) { - const result = transactionalSession.result.catch(); - transactionalSession.batch.push(Promise.reject()); - transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); - return result; - } - - async ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { - const conn = options.conn !== undefined ? options.conn : this._client; - const defaultIndexName = `parse_default_${fieldNames.sort().join('_')}`; - const indexNameOptions = indexName != null ? { - name: indexName - } : { - name: defaultIndexName - }; - const constraintPatterns = caseInsensitive ? fieldNames.map((fieldName, index) => `lower($${index + 3}:name) varchar_pattern_ops`) : fieldNames.map((fieldName, index) => `$${index + 3}:name`); - const qs = `CREATE INDEX IF NOT EXISTS $1:name ON $2:name (${constraintPatterns.join()})`; - await conn.none(qs, [indexNameOptions.name, className, ...fieldNames]).catch(error => { - if (error.code === PostgresDuplicateRelationError && error.message.includes(indexNameOptions.name)) {// Index already exists. Ignore error. - } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(indexNameOptions.name)) { - // Cast the error into the proper parse error - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - } else { - throw error; - } - }); - } - -} - -exports.PostgresStorageAdapter = PostgresStorageAdapter; - -function convertPolygonToSQL(polygon) { - if (polygon.length < 3) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `Polygon must have at least 3 values`); - } - - if (polygon[0][0] !== polygon[polygon.length - 1][0] || polygon[0][1] !== polygon[polygon.length - 1][1]) { - polygon.push(polygon[0]); - } - - const unique = polygon.filter((item, index, ar) => { - let foundIndex = -1; - - for (let i = 0; i < ar.length; i += 1) { - const pt = ar[i]; - - if (pt[0] === item[0] && pt[1] === item[1]) { - foundIndex = i; - break; - } - } - - return foundIndex === index; - }); - - if (unique.length < 3) { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); - } - - const points = polygon.map(point => { - _node.default.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); - - return `(${point[1]}, ${point[0]})`; - }).join(', '); - return `(${points})`; -} - -function removeWhiteSpace(regex) { - if (!regex.endsWith('\n')) { - regex += '\n'; - } // remove non escaped comments - - - return regex.replace(/([^\\])#.*\n/gim, '$1') // remove lines starting with a comment - .replace(/^#.*\n/gim, '') // remove non escaped whitespace - .replace(/([^\\])\s+/gim, '$1') // remove whitespace at the beginning of a line - .replace(/^\s+/, '').trim(); -} - -function processRegexPattern(s) { - if (s && s.startsWith('^')) { - // regex for startsWith - return '^' + literalizeRegexPart(s.slice(1)); - } else if (s && s.endsWith('$')) { - // regex for endsWith - return literalizeRegexPart(s.slice(0, s.length - 1)) + '$'; - } // regex for contains - - - return literalizeRegexPart(s); -} - -function isStartsWithRegex(value) { - if (!value || typeof value !== 'string' || !value.startsWith('^')) { - return false; - } - - const matches = value.match(/\^\\Q.*\\E/); - return !!matches; -} - -function isAllValuesRegexOrNone(values) { - if (!values || !Array.isArray(values) || values.length === 0) { - return true; - } - - const firstValuesIsRegex = isStartsWithRegex(values[0].$regex); - - if (values.length === 1) { - return firstValuesIsRegex; - } - - for (let i = 1, length = values.length; i < length; ++i) { - if (firstValuesIsRegex !== isStartsWithRegex(values[i].$regex)) { - return false; - } - } - - return true; -} - -function isAnyValueRegexStartsWith(values) { - return values.some(function (value) { - return isStartsWithRegex(value.$regex); - }); -} - -function createLiteralRegex(remaining) { - return remaining.split('').map(c => { - const regex = RegExp('[0-9 ]|\\p{L}', 'u'); // Support all unicode letter chars - - if (c.match(regex) !== null) { - // don't escape alphanumeric characters - return c; - } // escape everything else (single quotes with single quotes, everything else with a backslash) - - - return c === `'` ? `''` : `\\${c}`; - }).join(''); -} - -function literalizeRegexPart(s) { - const matcher1 = /\\Q((?!\\E).*)\\E$/; - const result1 = s.match(matcher1); - - if (result1 && result1.length > 1 && result1.index > -1) { - // process regex that has a beginning and an end specified for the literal text - const prefix = s.substr(0, result1.index); - const remaining = result1[1]; - return literalizeRegexPart(prefix) + createLiteralRegex(remaining); - } // process regex that has a beginning specified for the literal text - - - const matcher2 = /\\Q((?!\\E).*)$/; - const result2 = s.match(matcher2); - - if (result2 && result2.length > 1 && result2.index > -1) { - const prefix = s.substr(0, result2.index); - const remaining = result2[1]; - return literalizeRegexPart(prefix) + createLiteralRegex(remaining); - } // remove all instances of \Q and \E from the remaining text & escape single quotes - - - return s.replace(/([^\\])(\\E)/, '$1').replace(/([^\\])(\\Q)/, '$1').replace(/^\\E/, '').replace(/^\\Q/, '').replace(/([^'])'/, `$1''`).replace(/^'([^'])/, `''$1`); -} - -var GeoPointCoder = { - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; - } - -}; -var _default = PostgresStorageAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvciIsIlBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVPYmplY3RFcnJvciIsIlBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciIsIlBvc3RncmVzVHJhbnNhY3Rpb25BYm9ydGVkRXJyb3IiLCJsb2dnZXIiLCJyZXF1aXJlIiwiZGVidWciLCJhcmdzIiwiYXJndW1lbnRzIiwiY29uY2F0Iiwic2xpY2UiLCJsZW5ndGgiLCJsb2ciLCJnZXRMb2dnZXIiLCJhcHBseSIsInBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlIiwidHlwZSIsImNvbnRlbnRzIiwiSlNPTiIsInN0cmluZ2lmeSIsIlBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvciIsIiRndCIsIiRsdCIsIiRndGUiLCIkbHRlIiwibW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzIiwiJGRheU9mTW9udGgiLCIkZGF5T2ZXZWVrIiwiJGRheU9mWWVhciIsIiRpc29EYXlPZldlZWsiLCIkaXNvV2Vla1llYXIiLCIkaG91ciIsIiRtaW51dGUiLCIkc2Vjb25kIiwiJG1pbGxpc2Vjb25kIiwiJG1vbnRoIiwiJHdlZWsiLCIkeWVhciIsInRvUG9zdGdyZXNWYWx1ZSIsInZhbHVlIiwiX190eXBlIiwiaXNvIiwibmFtZSIsInRyYW5zZm9ybVZhbHVlIiwib2JqZWN0SWQiLCJlbXB0eUNMUFMiLCJPYmplY3QiLCJmcmVlemUiLCJmaW5kIiwiZ2V0IiwiY291bnQiLCJjcmVhdGUiLCJ1cGRhdGUiLCJkZWxldGUiLCJhZGRGaWVsZCIsInByb3RlY3RlZEZpZWxkcyIsImRlZmF1bHRDTFBTIiwidG9QYXJzZVNjaGVtYSIsInNjaGVtYSIsImNsYXNzTmFtZSIsImZpZWxkcyIsIl9oYXNoZWRfcGFzc3dvcmQiLCJfd3Blcm0iLCJfcnBlcm0iLCJjbHBzIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsInRvUG9zdGdyZXNTY2hlbWEiLCJfcGFzc3dvcmRfaGlzdG9yeSIsImhhbmRsZURvdEZpZWxkcyIsIm9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwiZmllbGROYW1lIiwiaW5kZXhPZiIsImNvbXBvbmVudHMiLCJzcGxpdCIsImZpcnN0Iiwic2hpZnQiLCJjdXJyZW50T2JqIiwibmV4dCIsIl9fb3AiLCJ1bmRlZmluZWQiLCJ0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyIsIm1hcCIsImNtcHQiLCJpbmRleCIsInRyYW5zZm9ybURvdEZpZWxkIiwiam9pbiIsInRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkIiwic3Vic3RyIiwidmFsaWRhdGVLZXlzIiwia2V5IiwiaW5jbHVkZXMiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9ORVNURURfS0VZIiwiam9pblRhYmxlc0ZvclNjaGVtYSIsImxpc3QiLCJmaWVsZCIsInB1c2giLCJidWlsZFdoZXJlQ2xhdXNlIiwicXVlcnkiLCJjYXNlSW5zZW5zaXRpdmUiLCJwYXR0ZXJucyIsInZhbHVlcyIsInNvcnRzIiwiaXNBcnJheUZpZWxkIiwiaW5pdGlhbFBhdHRlcm5zTGVuZ3RoIiwiZmllbGRWYWx1ZSIsIiRleGlzdHMiLCJhdXRoRGF0YU1hdGNoIiwibWF0Y2giLCIkaW4iLCIkcmVnZXgiLCJNQVhfSU5UX1BMVVNfT05FIiwiY2xhdXNlcyIsImNsYXVzZVZhbHVlcyIsInN1YlF1ZXJ5IiwiY2xhdXNlIiwicGF0dGVybiIsIm9yT3JBbmQiLCJub3QiLCIkbmUiLCJjb25zdHJhaW50RmllbGROYW1lIiwicG9pbnQiLCJsb25naXR1ZGUiLCJsYXRpdHVkZSIsIiRlcSIsImlzSW5Pck5pbiIsIkFycmF5IiwiaXNBcnJheSIsIiRuaW4iLCJpblBhdHRlcm5zIiwiYWxsb3dOdWxsIiwibGlzdEVsZW0iLCJsaXN0SW5kZXgiLCJjcmVhdGVDb25zdHJhaW50IiwiYmFzZUFycmF5Iiwibm90SW4iLCJfIiwiZmxhdE1hcCIsImVsdCIsIklOVkFMSURfSlNPTiIsIiRhbGwiLCJpc0FueVZhbHVlUmVnZXhTdGFydHNXaXRoIiwiaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSIsImkiLCJwcm9jZXNzUmVnZXhQYXR0ZXJuIiwic3Vic3RyaW5nIiwiJGNvbnRhaW5lZEJ5IiwiYXJyIiwiJHRleHQiLCJzZWFyY2giLCIkc2VhcmNoIiwibGFuZ3VhZ2UiLCIkdGVybSIsIiRsYW5ndWFnZSIsIiRjYXNlU2Vuc2l0aXZlIiwiJGRpYWNyaXRpY1NlbnNpdGl2ZSIsIiRuZWFyU3BoZXJlIiwiZGlzdGFuY2UiLCIkbWF4RGlzdGFuY2UiLCJkaXN0YW5jZUluS00iLCIkd2l0aGluIiwiJGJveCIsImJveCIsImxlZnQiLCJib3R0b20iLCJyaWdodCIsInRvcCIsIiRnZW9XaXRoaW4iLCIkY2VudGVyU3BoZXJlIiwiY2VudGVyU3BoZXJlIiwiR2VvUG9pbnQiLCJHZW9Qb2ludENvZGVyIiwiaXNWYWxpZEpTT04iLCJfdmFsaWRhdGUiLCJpc05hTiIsIiRwb2x5Z29uIiwicG9seWdvbiIsInBvaW50cyIsImNvb3JkaW5hdGVzIiwiJGdlb0ludGVyc2VjdHMiLCIkcG9pbnQiLCJyZWdleCIsIm9wZXJhdG9yIiwib3B0cyIsIiRvcHRpb25zIiwicmVtb3ZlV2hpdGVTcGFjZSIsImNvbnZlcnRQb2x5Z29uVG9TUUwiLCJjbXAiLCJwZ0NvbXBhcmF0b3IiLCJwb3N0Z3Jlc1ZhbHVlIiwiY2FzdFR5cGUiLCJPUEVSQVRJT05fRk9SQklEREVOIiwiUG9zdGdyZXNTdG9yYWdlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwidXJpIiwiY29sbGVjdGlvblByZWZpeCIsImRhdGFiYXNlT3B0aW9ucyIsIl9jb2xsZWN0aW9uUHJlZml4IiwiY2xpZW50IiwicGdwIiwiX2NsaWVudCIsIl9wZ3AiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiY3JlYXRlRXhwbGFpbmFibGVRdWVyeSIsImFuYWx5emUiLCJoYW5kbGVTaHV0ZG93biIsIiRwb29sIiwiZW5kIiwiX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHMiLCJjb25uIiwibm9uZSIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiY2xhc3NFeGlzdHMiLCJvbmUiLCJhIiwiZXhpc3RzIiwic2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiQ0xQcyIsInNlbGYiLCJ0YXNrIiwidCIsInNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0Iiwic3VibWl0dGVkSW5kZXhlcyIsImV4aXN0aW5nSW5kZXhlcyIsIlByb21pc2UiLCJyZXNvbHZlIiwiX2lkXyIsIl9pZCIsImRlbGV0ZWRJbmRleGVzIiwiaW5zZXJ0ZWRJbmRleGVzIiwiSU5WQUxJRF9RVUVSWSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR4IiwiY3JlYXRlSW5kZXhlcyIsImRyb3BJbmRleGVzIiwiY3JlYXRlQ2xhc3MiLCJxMSIsImNyZWF0ZVRhYmxlIiwicTIiLCJxMyIsImJhdGNoIiwidGhlbiIsImVyciIsImRhdGEiLCJyZXN1bHQiLCJkZXRhaWwiLCJEVVBMSUNBVEVfVkFMVUUiLCJ2YWx1ZXNBcnJheSIsInBhdHRlcm5zQXJyYXkiLCJhc3NpZ24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJfZW1haWxfdmVyaWZ5X3Rva2VuIiwiX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0IiwiX2ZhaWxlZF9sb2dpbl9jb3VudCIsIl9wZXJpc2hhYmxlX3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCIsIl9wYXNzd29yZF9jaGFuZ2VkX2F0IiwicmVsYXRpb25zIiwicGFyc2VUeXBlIiwicXMiLCJqb2luVGFibGUiLCJzY2hlbWFVcGdyYWRlIiwiY29sdW1ucyIsImNvbHVtbl9uYW1lIiwibmV3Q29sdW1ucyIsImZpbHRlciIsIml0ZW0iLCJhZGRGaWVsZElmTm90RXhpc3RzIiwicG9zdGdyZXNUeXBlIiwiYW55IiwicGF0aCIsImRlbGV0ZUNsYXNzIiwib3BlcmF0aW9ucyIsImhlbHBlcnMiLCJkZWxldGVBbGxDbGFzc2VzIiwibm93IiwiRGF0ZSIsImdldFRpbWUiLCJyZXN1bHRzIiwiam9pbnMiLCJyZWR1Y2UiLCJjbGFzc2VzIiwicXVlcmllcyIsImRlbGV0ZUZpZWxkcyIsImZpZWxkTmFtZXMiLCJpZHgiLCJnZXRBbGxDbGFzc2VzIiwicm93IiwiZ2V0Q2xhc3MiLCJjcmVhdGVPYmplY3QiLCJ0cmFuc2FjdGlvbmFsU2Vzc2lvbiIsImNvbHVtbnNBcnJheSIsImdlb1BvaW50cyIsInByb3ZpZGVyIiwicG9wIiwiaW5pdGlhbFZhbHVlcyIsInZhbCIsInRlcm1pbmF0aW9uIiwiZ2VvUG9pbnRzSW5qZWN0cyIsImwiLCJjb2x1bW5zUGF0dGVybiIsImNvbCIsInZhbHVlc1BhdHRlcm4iLCJwcm9taXNlIiwib3BzIiwidW5kZXJseWluZ0Vycm9yIiwiY29uc3RyYWludCIsIm1hdGNoZXMiLCJ1c2VySW5mbyIsImR1cGxpY2F0ZWRfZmllbGQiLCJkZWxldGVPYmplY3RzQnlRdWVyeSIsIndoZXJlIiwiT0JKRUNUX05PVF9GT1VORCIsImZpbmRPbmVBbmRVcGRhdGUiLCJ1cGRhdGVPYmplY3RzQnlRdWVyeSIsInVwZGF0ZVBhdHRlcm5zIiwib3JpZ2luYWxVcGRhdGUiLCJkb3ROb3RhdGlvbk9wdGlvbnMiLCJnZW5lcmF0ZSIsImpzb25iIiwibGFzdEtleSIsImZpZWxkTmFtZUluZGV4Iiwic3RyIiwiYW1vdW50Iiwib2JqZWN0cyIsImtleXNUb0luY3JlbWVudCIsImsiLCJpbmNyZW1lbnRQYXR0ZXJucyIsImMiLCJrZXlzVG9EZWxldGUiLCJkZWxldGVQYXR0ZXJucyIsInAiLCJ1cGRhdGVPYmplY3QiLCJleHBlY3RlZFR5cGUiLCJyZWplY3QiLCJ3aGVyZUNsYXVzZSIsInVwc2VydE9uZU9iamVjdCIsImNyZWF0ZVZhbHVlIiwic2tpcCIsImxpbWl0Iiwic29ydCIsImV4cGxhaW4iLCJoYXNMaW1pdCIsImhhc1NraXAiLCJ3aGVyZVBhdHRlcm4iLCJsaW1pdFBhdHRlcm4iLCJza2lwUGF0dGVybiIsInNvcnRQYXR0ZXJuIiwic29ydENvcHkiLCJzb3J0aW5nIiwidHJhbnNmb3JtS2V5IiwibWVtbyIsIm9yaWdpbmFsUXVlcnkiLCJwb3N0Z3Jlc09iamVjdFRvUGFyc2VPYmplY3QiLCJ0YXJnZXRDbGFzcyIsInkiLCJ4IiwiY29vcmRzIiwicGFyc2VGbG9hdCIsImNyZWF0ZWRBdCIsInRvSVNPU3RyaW5nIiwidXBkYXRlZEF0IiwiZXhwaXJlc0F0IiwiZW5zdXJlVW5pcXVlbmVzcyIsImNvbnN0cmFpbnROYW1lIiwiY29uc3RyYWludFBhdHRlcm5zIiwibWVzc2FnZSIsInJlYWRQcmVmZXJlbmNlIiwiZXN0aW1hdGUiLCJhcHByb3hpbWF0ZV9yb3dfY291bnQiLCJkaXN0aW5jdCIsImNvbHVtbiIsImlzTmVzdGVkIiwiaXNQb2ludGVyRmllbGQiLCJ0cmFuc2Zvcm1lciIsImNoaWxkIiwiYWdncmVnYXRlIiwicGlwZWxpbmUiLCJoaW50IiwiY291bnRGaWVsZCIsImdyb3VwVmFsdWVzIiwiZ3JvdXBQYXR0ZXJuIiwic3RhZ2UiLCIkZ3JvdXAiLCJncm91cEJ5RmllbGRzIiwiYWxpYXMiLCJzb3VyY2UiLCJvcGVyYXRpb24iLCIkc3VtIiwiJG1heCIsIiRtaW4iLCIkYXZnIiwiJHByb2plY3QiLCIkbWF0Y2giLCIkb3IiLCJjb2xsYXBzZSIsImVsZW1lbnQiLCJtYXRjaFBhdHRlcm5zIiwiJGxpbWl0IiwiJHNraXAiLCIkc29ydCIsIm9yZGVyIiwiZSIsInRyaW0iLCJCb29sZWFuIiwicGFyc2VJbnQiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCJWb2xhdGlsZUNsYXNzZXNTY2hlbWFzIiwicHJvbWlzZXMiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJhbGwiLCJzcWwiLCJtaXNjIiwianNvbk9iamVjdFNldEtleXMiLCJhcnJheSIsImFkZCIsImFkZFVuaXF1ZSIsInJlbW92ZSIsImNvbnRhaW5zQWxsIiwiY29udGFpbnNBbGxSZWdleCIsImNvbnRhaW5zIiwiZHVyYXRpb24iLCJjb25zb2xlIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZ2V0SW5kZXhlcyIsInVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzIiwidXBkYXRlRXN0aW1hdGVkQ291bnQiLCJjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwib3B0aW9ucyIsImRlZmF1bHRJbmRleE5hbWUiLCJpbmRleE5hbWVPcHRpb25zIiwidW5pcXVlIiwiYXIiLCJmb3VuZEluZGV4IiwicHQiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJlbmRzV2l0aCIsInJlcGxhY2UiLCJzIiwic3RhcnRzV2l0aCIsImxpdGVyYWxpemVSZWdleFBhcnQiLCJpc1N0YXJ0c1dpdGhSZWdleCIsImZpcnN0VmFsdWVzSXNSZWdleCIsInNvbWUiLCJjcmVhdGVMaXRlcmFsUmVnZXgiLCJyZW1haW5pbmciLCJSZWdFeHAiLCJtYXRjaGVyMSIsInJlc3VsdDEiLCJwcmVmaXgiLCJtYXRjaGVyMiIsInJlc3VsdDIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFFQTs7QUFFQTs7QUFDQTs7QUFpQkE7Ozs7Ozs7Ozs7QUFmQSxNQUFNQSxpQ0FBaUMsR0FBRyxPQUExQztBQUNBLE1BQU1DLDhCQUE4QixHQUFHLE9BQXZDO0FBQ0EsTUFBTUMsNEJBQTRCLEdBQUcsT0FBckM7QUFDQSxNQUFNQywwQkFBMEIsR0FBRyxPQUFuQztBQUNBLE1BQU1DLDRCQUE0QixHQUFHLE9BQXJDO0FBQ0EsTUFBTUMsaUNBQWlDLEdBQUcsT0FBMUM7QUFDQSxNQUFNQywrQkFBK0IsR0FBRyxPQUF4Qzs7QUFDQSxNQUFNQyxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxp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R1gsQ0FBQyxDQUFDeFcsTUFBRixDQUFTLENBQVQsRUFBWXFYLE9BQU8sQ0FBQ3pYLEtBQXBCLENBQWY7QUFDQSxVQUFNbVgsU0FBUyxHQUFHTSxPQUFPLENBQUMsQ0FBRCxDQUF6QjtBQUVBLFdBQU9YLG1CQUFtQixDQUFDUyxNQUFELENBQW5CLEdBQThCTCxrQkFBa0IsQ0FBQ0MsU0FBRCxDQUF2RDtBQUNELEdBbkJxQyxDQXFCdEM7OztBQUNBLFNBQU9QLENBQUMsQ0FDTEQsT0FESSxDQUNJLGNBREosRUFDb0IsSUFEcEIsRUFFSkEsT0FGSSxDQUVJLGNBRkosRUFFb0IsSUFGcEIsRUFHSkEsT0FISSxDQUdJLE1BSEosRUFHWSxFQUhaLEVBSUpBLE9BSkksQ0FJSSxNQUpKLEVBSVksRUFKWixFQUtKQSxPQUxJLENBS0ksU0FMSixFQUtnQixNQUxoQixFQU1KQSxPQU5JLENBTUksVUFOSixFQU1pQixNQU5qQixDQUFQO0FBT0Q7O0FBRUQsSUFBSWxSLGFBQWEsR0FBRztBQUNsQkMsRUFBQUEsV0FBVyxDQUFDekksS0FBRCxFQUFRO0FBQ2pCLFdBQ0UsT0FBT0EsS0FBUCxLQUFpQixRQUFqQixJQUE2QkEsS0FBSyxLQUFLLElBQXZDLElBQStDQSxLQUFLLENBQUNDLE1BQU4sS0FBaUIsVUFEbEU7QUFHRDs7QUFMaUIsQ0FBcEI7ZUFRZTRKLHNCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IGNyZWF0ZUNsaWVudCB9IGZyb20gJy4vUG9zdGdyZXNDbGllbnQnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgc3FsIGZyb20gJy4vc3FsJztcblxuY29uc3QgUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yID0gJzQyUDAxJztcbmNvbnN0IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciA9ICc0MlAwNyc7XG5jb25zdCBQb3N0Z3Jlc0R1cGxpY2F0ZUNvbHVtbkVycm9yID0gJzQyNzAxJztcbmNvbnN0IFBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yID0gJzQyNzAzJztcbmNvbnN0IFBvc3RncmVzRHVwbGljYXRlT2JqZWN0RXJyb3IgPSAnNDI3MTAnO1xuY29uc3QgUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yID0gJzIzNTA1JztcbmNvbnN0IFBvc3RncmVzVHJhbnNhY3Rpb25BYm9ydGVkRXJyb3IgPSAnMjVQMDInO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vLi4vbG9nZ2VyJyk7XG5cbmNvbnN0IGRlYnVnID0gZnVuY3Rpb24gKC4uLmFyZ3M6IGFueSkge1xuICBhcmdzID0gWydQRzogJyArIGFyZ3VtZW50c1swXV0uY29uY2F0KGFyZ3Muc2xpY2UoMSwgYXJncy5sZW5ndGgpKTtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmdldExvZ2dlcigpO1xuICBsb2cuZGVidWcuYXBwbHkobG9nLCBhcmdzKTtcbn07XG5cbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gZnJvbSAnLi4vU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHR5cGUgeyBTY2hlbWFUeXBlLCBRdWVyeVR5cGUsIFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcblxuY29uc3QgcGFyc2VUeXBlVG9Qb3N0Z3Jlc1R5cGUgPSB0eXBlID0+IHtcbiAgc3dpdGNoICh0eXBlLnR5cGUpIHtcbiAgICBjYXNlICdTdHJpbmcnOlxuICAgICAgcmV0dXJuICd0ZXh0JztcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiAndGltZXN0YW1wIHdpdGggdGltZSB6b25lJztcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuICdqc29uYic7XG4gICAgY2FzZSAnRmlsZSc6XG4gICAgICByZXR1cm4gJ3RleHQnO1xuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgIHJldHVybiAndGV4dCc7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiAnZG91YmxlIHByZWNpc2lvbic7XG4gICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgcmV0dXJuICdwb2ludCc7XG4gICAgY2FzZSAnQnl0ZXMnOlxuICAgICAgcmV0dXJuICdqc29uYic7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gJ3BvbHlnb24nO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIGlmICh0eXBlLmNvbnRlbnRzICYmIHR5cGUuY29udGVudHMudHlwZSA9PT0gJ1N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuICd0ZXh0W10nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICdqc29uYic7XG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IGBubyB0eXBlIGZvciAke0pTT04uc3RyaW5naWZ5KHR5cGUpfSB5ZXRgO1xuICB9XG59O1xuXG5jb25zdCBQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3IgPSB7XG4gICRndDogJz4nLFxuICAkbHQ6ICc8JyxcbiAgJGd0ZTogJz49JyxcbiAgJGx0ZTogJzw9Jyxcbn07XG5cbmNvbnN0IG1vbmdvQWdncmVnYXRlVG9Qb3N0Z3JlcyA9IHtcbiAgJGRheU9mTW9udGg6ICdEQVknLFxuICAkZGF5T2ZXZWVrOiAnRE9XJyxcbiAgJGRheU9mWWVhcjogJ0RPWScsXG4gICRpc29EYXlPZldlZWs6ICdJU09ET1cnLFxuICAkaXNvV2Vla1llYXI6ICdJU09ZRUFSJyxcbiAgJGhvdXI6ICdIT1VSJyxcbiAgJG1pbnV0ZTogJ01JTlVURScsXG4gICRzZWNvbmQ6ICdTRUNPTkQnLFxuICAkbWlsbGlzZWNvbmQ6ICdNSUxMSVNFQ09ORFMnLFxuICAkbW9udGg6ICdNT05USCcsXG4gICR3ZWVrOiAnV0VFSycsXG4gICR5ZWFyOiAnWUVBUicsXG59O1xuXG5jb25zdCB0b1Bvc3RncmVzVmFsdWUgPSB2YWx1ZSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnKSB7XG4gICAgICByZXR1cm4gdmFsdWUuaXNvO1xuICAgIH1cbiAgICBpZiAodmFsdWUuX190eXBlID09PSAnRmlsZScpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5uYW1lO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1WYWx1ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICByZXR1cm4gdmFsdWUub2JqZWN0SWQ7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuLy8gRHVwbGljYXRlIGZyb20gdGhlbiBtb25nbyBhZGFwdGVyLi4uXG5jb25zdCBlbXB0eUNMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDoge30sXG4gIGdldDoge30sXG4gIGNvdW50OiB7fSxcbiAgY3JlYXRlOiB7fSxcbiAgdXBkYXRlOiB7fSxcbiAgZGVsZXRlOiB7fSxcbiAgYWRkRmllbGQ6IHt9LFxuICBwcm90ZWN0ZWRGaWVsZHM6IHt9LFxufSk7XG5cbmNvbnN0IGRlZmF1bHRDTFBTID0gT2JqZWN0LmZyZWV6ZSh7XG4gIGZpbmQ6IHsgJyonOiB0cnVlIH0sXG4gIGdldDogeyAnKic6IHRydWUgfSxcbiAgY291bnQ6IHsgJyonOiB0cnVlIH0sXG4gIGNyZWF0ZTogeyAnKic6IHRydWUgfSxcbiAgdXBkYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICBkZWxldGU6IHsgJyonOiB0cnVlIH0sXG4gIGFkZEZpZWxkOiB7ICcqJzogdHJ1ZSB9LFxuICBwcm90ZWN0ZWRGaWVsZHM6IHsgJyonOiBbXSB9LFxufSk7XG5cbmNvbnN0IHRvUGFyc2VTY2hlbWEgPSBzY2hlbWEgPT4ge1xuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQ7XG4gIH1cbiAgaWYgKHNjaGVtYS5maWVsZHMpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICB9XG4gIGxldCBjbHBzID0gZGVmYXVsdENMUFM7XG4gIGlmIChzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zKSB7XG4gICAgY2xwcyA9IHsgLi4uZW1wdHlDTFBTLCAuLi5zY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zIH07XG4gIH1cbiAgbGV0IGluZGV4ZXMgPSB7fTtcbiAgaWYgKHNjaGVtYS5pbmRleGVzKSB7XG4gICAgaW5kZXhlcyA9IHsgLi4uc2NoZW1hLmluZGV4ZXMgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNsYXNzTmFtZTogc2NoZW1hLmNsYXNzTmFtZSxcbiAgICBmaWVsZHM6IHNjaGVtYS5maWVsZHMsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBjbHBzLFxuICAgIGluZGV4ZXMsXG4gIH07XG59O1xuXG5jb25zdCB0b1Bvc3RncmVzU2NoZW1hID0gc2NoZW1hID0+IHtcbiAgaWYgKCFzY2hlbWEpIHtcbiAgICByZXR1cm4gc2NoZW1hO1xuICB9XG4gIHNjaGVtYS5maWVsZHMgPSBzY2hlbWEuZmllbGRzIHx8IHt9O1xuICBzY2hlbWEuZmllbGRzLl93cGVybSA9IHsgdHlwZTogJ0FycmF5JywgY29udGVudHM6IHsgdHlwZTogJ1N0cmluZycgfSB9O1xuICBzY2hlbWEuZmllbGRzLl9ycGVybSA9IHsgdHlwZTogJ0FycmF5JywgY29udGVudHM6IHsgdHlwZTogJ1N0cmluZycgfSB9O1xuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZCA9IHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICBzY2hlbWEuZmllbGRzLl9wYXNzd29yZF9oaXN0b3J5ID0geyB0eXBlOiAnQXJyYXknIH07XG4gIH1cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbmNvbnN0IGhhbmRsZURvdEZpZWxkcyA9IG9iamVjdCA9PiB7XG4gIE9iamVjdC5rZXlzKG9iamVjdCkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID4gLTEpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBmaWVsZE5hbWUuc3BsaXQoJy4nKTtcbiAgICAgIGNvbnN0IGZpcnN0ID0gY29tcG9uZW50cy5zaGlmdCgpO1xuICAgICAgb2JqZWN0W2ZpcnN0XSA9IG9iamVjdFtmaXJzdF0gfHwge307XG4gICAgICBsZXQgY3VycmVudE9iaiA9IG9iamVjdFtmaXJzdF07XG4gICAgICBsZXQgbmV4dDtcbiAgICAgIGxldCB2YWx1ZSA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgICAgIHdoaWxlICgobmV4dCA9IGNvbXBvbmVudHMuc2hpZnQoKSkpIHtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgICAgICBjdXJyZW50T2JqW25leHRdID0gY3VycmVudE9ialtuZXh0XSB8fCB7fTtcbiAgICAgICAgaWYgKGNvbXBvbmVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgY3VycmVudE9ialtuZXh0XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRPYmogPSBjdXJyZW50T2JqW25leHRdO1xuICAgICAgfVxuICAgICAgZGVsZXRlIG9iamVjdFtmaWVsZE5hbWVdO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyA9IGZpZWxkTmFtZSA9PiB7XG4gIHJldHVybiBmaWVsZE5hbWUuc3BsaXQoJy4nKS5tYXAoKGNtcHQsIGluZGV4KSA9PiB7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gYFwiJHtjbXB0fVwiYDtcbiAgICB9XG4gICAgcmV0dXJuIGAnJHtjbXB0fSdgO1xuICB9KTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybURvdEZpZWxkID0gZmllbGROYW1lID0+IHtcbiAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPT09IC0xKSB7XG4gICAgcmV0dXJuIGBcIiR7ZmllbGROYW1lfVwiYDtcbiAgfVxuICBjb25zdCBjb21wb25lbnRzID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoZmllbGROYW1lKTtcbiAgbGV0IG5hbWUgPSBjb21wb25lbnRzLnNsaWNlKDAsIGNvbXBvbmVudHMubGVuZ3RoIC0gMSkuam9pbignLT4nKTtcbiAgbmFtZSArPSAnLT4+JyArIGNvbXBvbmVudHNbY29tcG9uZW50cy5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIG5hbWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1BZ2dyZWdhdGVGaWVsZCA9IGZpZWxkTmFtZSA9PiB7XG4gIGlmICh0eXBlb2YgZmllbGROYW1lICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmaWVsZE5hbWU7XG4gIH1cbiAgaWYgKGZpZWxkTmFtZSA9PT0gJyRfY3JlYXRlZF9hdCcpIHtcbiAgICByZXR1cm4gJ2NyZWF0ZWRBdCc7XG4gIH1cbiAgaWYgKGZpZWxkTmFtZSA9PT0gJyRfdXBkYXRlZF9hdCcpIHtcbiAgICByZXR1cm4gJ3VwZGF0ZWRBdCc7XG4gIH1cbiAgcmV0dXJuIGZpZWxkTmFtZS5zdWJzdHIoMSk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUtleXMgPSBvYmplY3QgPT4ge1xuICBpZiAodHlwZW9mIG9iamVjdCA9PSAnb2JqZWN0Jykge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKHR5cGVvZiBvYmplY3Rba2V5XSA9PSAnb2JqZWN0Jykge1xuICAgICAgICB2YWxpZGF0ZUtleXMob2JqZWN0W2tleV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LmluY2x1ZGVzKCckJykgfHwga2V5LmluY2x1ZGVzKCcuJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfTkVTVEVEX0tFWSxcbiAgICAgICAgICBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbi8vIFJldHVybnMgdGhlIGxpc3Qgb2Ygam9pbiB0YWJsZXMgb24gYSBzY2hlbWFcbmNvbnN0IGpvaW5UYWJsZXNGb3JTY2hlbWEgPSBzY2hlbWEgPT4ge1xuICBjb25zdCBsaXN0ID0gW107XG4gIGlmIChzY2hlbWEpIHtcbiAgICBPYmplY3Qua2V5cyhzY2hlbWEuZmllbGRzKS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGxpc3QucHVzaChgX0pvaW46JHtmaWVsZH06JHtzY2hlbWEuY2xhc3NOYW1lfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBsaXN0O1xufTtcblxuaW50ZXJmYWNlIFdoZXJlQ2xhdXNlIHtcbiAgcGF0dGVybjogc3RyaW5nO1xuICB2YWx1ZXM6IEFycmF5PGFueT47XG4gIHNvcnRzOiBBcnJheTxhbnk+O1xufVxuXG5jb25zdCBidWlsZFdoZXJlQ2xhdXNlID0gKHtcbiAgc2NoZW1hLFxuICBxdWVyeSxcbiAgaW5kZXgsXG4gIGNhc2VJbnNlbnNpdGl2ZSxcbn0pOiBXaGVyZUNsYXVzZSA9PiB7XG4gIGNvbnN0IHBhdHRlcm5zID0gW107XG4gIGxldCB2YWx1ZXMgPSBbXTtcbiAgY29uc3Qgc29ydHMgPSBbXTtcblxuICBzY2hlbWEgPSB0b1Bvc3RncmVzU2NoZW1hKHNjaGVtYSk7XG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgY29uc3QgaXNBcnJheUZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHMgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheSc7XG4gICAgY29uc3QgaW5pdGlhbFBhdHRlcm5zTGVuZ3RoID0gcGF0dGVybnMubGVuZ3RoO1xuICAgIGNvbnN0IGZpZWxkVmFsdWUgPSBxdWVyeVtmaWVsZE5hbWVdO1xuXG4gICAgLy8gbm90aGluZyBpbiB0aGUgc2NoZW1hLCBpdCdzIGdvbm5hIGJsb3cgdXBcbiAgICBpZiAoIXNjaGVtYS5maWVsZHNbZmllbGROYW1lXSkge1xuICAgICAgLy8gYXMgaXQgd29uJ3QgZXhpc3RcbiAgICAgIGlmIChmaWVsZFZhbHVlICYmIGZpZWxkVmFsdWUuJGV4aXN0cyA9PT0gZmFsc2UpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYXV0aERhdGFNYXRjaCA9IGZpZWxkTmFtZS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgIGlmIChhdXRoRGF0YU1hdGNoKSB7XG4gICAgICAvLyBUT0RPOiBIYW5kbGUgcXVlcnlpbmcgYnkgX2F1dGhfZGF0YV9wcm92aWRlciwgYXV0aERhdGEgaXMgc3RvcmVkIGluIGF1dGhEYXRhIGZpZWxkXG4gICAgICBjb250aW51ZTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgY2FzZUluc2Vuc2l0aXZlICYmXG4gICAgICAoZmllbGROYW1lID09PSAndXNlcm5hbWUnIHx8IGZpZWxkTmFtZSA9PT0gJ2VtYWlsJylcbiAgICApIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYExPV0VSKCQke2luZGV4fTpuYW1lKSA9IExPV0VSKCQke2luZGV4ICsgMX0pYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgbGV0IG5hbWUgPSB0cmFuc2Zvcm1Eb3RGaWVsZChmaWVsZE5hbWUpO1xuICAgICAgaWYgKGZpZWxkVmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9OnJhdyBJUyBOVUxMYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKG5hbWUpO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWVsZFZhbHVlLiRpbikge1xuICAgICAgICAgIG5hbWUgPSB0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyhmaWVsZE5hbWUpLmpvaW4oJy0+Jyk7XG4gICAgICAgICAgcGF0dGVybnMucHVzaChgKCQke2luZGV4fTpyYXcpOjpqc29uYiBAPiAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUuJGluKSk7XG4gICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLiRyZWdleCkge1xuICAgICAgICAgIC8vIEhhbmRsZSBsYXRlclxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpyYXcgPSAkJHtpbmRleCArIDF9Ojp0ZXh0YCk7XG4gICAgICAgICAgdmFsdWVzLnB1c2gobmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZSA9PT0gbnVsbCB8fCBmaWVsZFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgIC8vIENhbid0IGNhc3QgYm9vbGVhbiB0byBkb3VibGUgcHJlY2lzaW9uXG4gICAgICBpZiAoXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ051bWJlcidcbiAgICAgICkge1xuICAgICAgICAvLyBTaG91bGQgYWx3YXlzIHJldHVybiB6ZXJvIHJlc3VsdHNcbiAgICAgICAgY29uc3QgTUFYX0lOVF9QTFVTX09ORSA9IDkyMjMzNzIwMzY4NTQ3NzU4MDg7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgTUFYX0lOVF9QTFVTX09ORSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgfVxuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKFsnJG9yJywgJyRub3InLCAnJGFuZCddLmluY2x1ZGVzKGZpZWxkTmFtZSkpIHtcbiAgICAgIGNvbnN0IGNsYXVzZXMgPSBbXTtcbiAgICAgIGNvbnN0IGNsYXVzZVZhbHVlcyA9IFtdO1xuICAgICAgZmllbGRWYWx1ZS5mb3JFYWNoKHN1YlF1ZXJ5ID0+IHtcbiAgICAgICAgY29uc3QgY2xhdXNlID0gYnVpbGRXaGVyZUNsYXVzZSh7XG4gICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgIHF1ZXJ5OiBzdWJRdWVyeSxcbiAgICAgICAgICBpbmRleCxcbiAgICAgICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2xhdXNlLnBhdHRlcm4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNsYXVzZXMucHVzaChjbGF1c2UucGF0dGVybik7XG4gICAgICAgICAgY2xhdXNlVmFsdWVzLnB1c2goLi4uY2xhdXNlLnZhbHVlcyk7XG4gICAgICAgICAgaW5kZXggKz0gY2xhdXNlLnZhbHVlcy5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBvck9yQW5kID0gZmllbGROYW1lID09PSAnJGFuZCcgPyAnIEFORCAnIDogJyBPUiAnO1xuICAgICAgY29uc3Qgbm90ID0gZmllbGROYW1lID09PSAnJG5vcicgPyAnIE5PVCAnIDogJyc7XG5cbiAgICAgIHBhdHRlcm5zLnB1c2goYCR7bm90fSgke2NsYXVzZXMuam9pbihvck9yQW5kKX0pYCk7XG4gICAgICB2YWx1ZXMucHVzaCguLi5jbGF1c2VWYWx1ZXMpO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLiRuZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoaXNBcnJheUZpZWxkKSB7XG4gICAgICAgIGZpZWxkVmFsdWUuJG5lID0gSlNPTi5zdHJpbmdpZnkoW2ZpZWxkVmFsdWUuJG5lXSk7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYE5PVCBhcnJheV9jb250YWlucygkJHtpbmRleH06bmFtZSwgJCR7aW5kZXggKyAxfSlgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWVsZFZhbHVlLiRuZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5PVCBOVUxMYCk7XG4gICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGlmIG5vdCBudWxsLCB3ZSBuZWVkIHRvIG1hbnVhbGx5IGV4Y2x1ZGUgbnVsbFxuICAgICAgICAgIGlmIChmaWVsZFZhbHVlLiRuZS5fX3R5cGUgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgICAgIGAoJCR7aW5kZXh9Om5hbWUgPD4gUE9JTlQoJCR7aW5kZXggKyAxfSwgJCR7XG4gICAgICAgICAgICAgICAgaW5kZXggKyAyXG4gICAgICAgICAgICAgIH0pIE9SICQke2luZGV4fTpuYW1lIElTIE5VTEwpYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50RmllbGROYW1lID0gdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgICAgICAgICBgKCR7Y29uc3RyYWludEZpZWxkTmFtZX0gPD4gJCR7aW5kZXh9IE9SICR7Y29uc3RyYWludEZpZWxkTmFtZX0gSVMgTlVMTClgXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgICAgICAgIGAoJCR7aW5kZXh9Om5hbWUgPD4gJCR7aW5kZXggKyAxfSBPUiAkJHtpbmRleH06bmFtZSBJUyBOVUxMKWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmaWVsZFZhbHVlLiRuZS5fX3R5cGUgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBmaWVsZFZhbHVlLiRuZTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlKTtcbiAgICAgICAgaW5kZXggKz0gMztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IHN1cHBvcnQgYXJyYXlzXG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS4kbmUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZmllbGRWYWx1ZS4kZXEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGZpZWxkVmFsdWUuJGVxID09PSBudWxsKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZFZhbHVlLiRlcSk7XG4gICAgICAgICAgcGF0dGVybnMucHVzaChgJHt0cmFuc2Zvcm1Eb3RGaWVsZChmaWVsZE5hbWUpfSA9ICQke2luZGV4Kyt9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLiRlcSk7XG4gICAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBpc0luT3JOaW4gPVxuICAgICAgQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRpbikgfHwgQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRuaW4pO1xuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kaW4pICYmXG4gICAgICBpc0FycmF5RmllbGQgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5jb250ZW50cyAmJlxuICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLmNvbnRlbnRzLnR5cGUgPT09ICdTdHJpbmcnXG4gICAgKSB7XG4gICAgICBjb25zdCBpblBhdHRlcm5zID0gW107XG4gICAgICBsZXQgYWxsb3dOdWxsID0gZmFsc2U7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgZmllbGRWYWx1ZS4kaW4uZm9yRWFjaCgobGlzdEVsZW0sIGxpc3RJbmRleCkgPT4ge1xuICAgICAgICBpZiAobGlzdEVsZW0gPT09IG51bGwpIHtcbiAgICAgICAgICBhbGxvd051bGwgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGxpc3RFbGVtKTtcbiAgICAgICAgICBpblBhdHRlcm5zLnB1c2goYCQke2luZGV4ICsgMSArIGxpc3RJbmRleCAtIChhbGxvd051bGwgPyAxIDogMCl9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGFsbG93TnVsbCkge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAoJCR7aW5kZXh9Om5hbWUgSVMgTlVMTCBPUiAkJHtpbmRleH06bmFtZSAmJiBBUlJBWVske2luUGF0dGVybnMuam9pbigpfV0pYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgJiYgQVJSQVlbJHtpblBhdHRlcm5zLmpvaW4oKX1dYCk7XG4gICAgICB9XG4gICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgIH0gZWxzZSBpZiAoaXNJbk9yTmluKSB7XG4gICAgICB2YXIgY3JlYXRlQ29uc3RyYWludCA9IChiYXNlQXJyYXksIG5vdEluKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdCA9IG5vdEluID8gJyBOT1QgJyA6ICcnO1xuICAgICAgICBpZiAoYmFzZUFycmF5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpZiAoaXNBcnJheUZpZWxkKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgICAgICBgJHtub3R9IGFycmF5X2NvbnRhaW5zKCQke2luZGV4fTpuYW1lLCAkJHtpbmRleCArIDF9KWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGJhc2VBcnJheSkpO1xuICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSGFuZGxlIE5lc3RlZCBEb3QgTm90YXRpb24gQWJvdmVcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW5QYXR0ZXJucyA9IFtdO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICAgIGJhc2VBcnJheS5mb3JFYWNoKChsaXN0RWxlbSwgbGlzdEluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGlmIChsaXN0RWxlbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2gobGlzdEVsZW0pO1xuICAgICAgICAgICAgICAgIGluUGF0dGVybnMucHVzaChgJCR7aW5kZXggKyAxICsgbGlzdEluZGV4fWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lICR7bm90fSBJTiAoJHtpblBhdHRlcm5zLmpvaW4oKX0pYCk7XG4gICAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghbm90SW4pIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBIYW5kbGUgZW1wdHkgYXJyYXlcbiAgICAgICAgICBpZiAobm90SW4pIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAxJyk7IC8vIFJldHVybiBhbGwgdmFsdWVzXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAyJyk7IC8vIFJldHVybiBubyB2YWx1ZXNcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kaW4pIHtcbiAgICAgICAgY3JlYXRlQ29uc3RyYWludChcbiAgICAgICAgICBfLmZsYXRNYXAoZmllbGRWYWx1ZS4kaW4sIGVsdCA9PiBlbHQpLFxuICAgICAgICAgIGZhbHNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kbmluKSB7XG4gICAgICAgIGNyZWF0ZUNvbnN0cmFpbnQoXG4gICAgICAgICAgXy5mbGF0TWFwKGZpZWxkVmFsdWUuJG5pbiwgZWx0ID0+IGVsdCksXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUuJGluICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCAkaW4gdmFsdWUnKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlLiRuaW4gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkICRuaW4gdmFsdWUnKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRhbGwpICYmIGlzQXJyYXlGaWVsZCkge1xuICAgICAgaWYgKGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICBpZiAoIWlzQWxsVmFsdWVzUmVnZXhPck5vbmUoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICdBbGwgJGFsbCB2YWx1ZXMgbXVzdCBiZSBvZiByZWdleCB0eXBlIG9yIG5vbmU6ICcgKyBmaWVsZFZhbHVlLiRhbGxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZFZhbHVlLiRhbGwubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3NSZWdleFBhdHRlcm4oZmllbGRWYWx1ZS4kYWxsW2ldLiRyZWdleCk7XG4gICAgICAgICAgZmllbGRWYWx1ZS4kYWxsW2ldID0gdmFsdWUuc3Vic3RyaW5nKDEpICsgJyUnO1xuICAgICAgICB9XG4gICAgICAgIHBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgYGFycmF5X2NvbnRhaW5zX2FsbF9yZWdleCgkJHtpbmRleH06bmFtZSwgJCR7aW5kZXggKyAxfTo6anNvbmIpYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgICBgYXJyYXlfY29udGFpbnNfYWxsKCQke2luZGV4fTpuYW1lLCAkJHtpbmRleCArIDF9Ojpqc29uYilgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUuJGFsbCkpO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgaWYgKGZpZWxkVmFsdWUuJGFsbC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS4kYWxsWzBdLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGZpZWxkVmFsdWUuJGV4aXN0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChmaWVsZFZhbHVlLiRleGlzdHMpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgSVMgTk9UIE5VTExgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLiRjb250YWluZWRCeSkge1xuICAgICAgY29uc3QgYXJyID0gZmllbGRWYWx1ZS4kY29udGFpbmVkQnk7XG4gICAgICBpZiAoIShhcnIgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICBgYmFkICRjb250YWluZWRCeTogc2hvdWxkIGJlIGFuIGFycmF5YFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA8QCAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShhcnIpKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJHRleHQpIHtcbiAgICAgIGNvbnN0IHNlYXJjaCA9IGZpZWxkVmFsdWUuJHRleHQuJHNlYXJjaDtcbiAgICAgIGxldCBsYW5ndWFnZSA9ICdlbmdsaXNoJztcbiAgICAgIGlmICh0eXBlb2Ygc2VhcmNoICE9PSAnb2JqZWN0Jykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICRzZWFyY2gsIHNob3VsZCBiZSBvYmplY3RgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIXNlYXJjaC4kdGVybSB8fCB0eXBlb2Ygc2VhcmNoLiR0ZXJtICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICR0ZXJtLCBzaG91bGQgYmUgc3RyaW5nYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHNlYXJjaC4kbGFuZ3VhZ2UgJiYgdHlwZW9mIHNlYXJjaC4kbGFuZ3VhZ2UgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGxhbmd1YWdlLCBzaG91bGQgYmUgc3RyaW5nYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGxhbmd1YWdlKSB7XG4gICAgICAgIGxhbmd1YWdlID0gc2VhcmNoLiRsYW5ndWFnZTtcbiAgICAgIH1cbiAgICAgIGlmIChzZWFyY2guJGNhc2VTZW5zaXRpdmUgJiYgdHlwZW9mIHNlYXJjaC4kY2FzZVNlbnNpdGl2ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGNhc2VTZW5zaXRpdmUsIHNob3VsZCBiZSBib29sZWFuYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGNhc2VTZW5zaXRpdmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICBgYmFkICR0ZXh0OiAkY2FzZVNlbnNpdGl2ZSBub3Qgc3VwcG9ydGVkLCBwbGVhc2UgdXNlICRyZWdleCBvciBjcmVhdGUgYSBzZXBhcmF0ZSBsb3dlciBjYXNlIGNvbHVtbi5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICYmXG4gICAgICAgIHR5cGVvZiBzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZSAhPT0gJ2Jvb2xlYW4nXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICBgYmFkICR0ZXh0OiAkZGlhY3JpdGljU2Vuc2l0aXZlLCBzaG91bGQgYmUgYm9vbGVhbmBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRkaWFjcml0aWNTZW5zaXRpdmUgPT09IGZhbHNlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGRpYWNyaXRpY1NlbnNpdGl2ZSAtIGZhbHNlIG5vdCBzdXBwb3J0ZWQsIGluc3RhbGwgUG9zdGdyZXMgVW5hY2NlbnQgRXh0ZW5zaW9uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgYHRvX3RzdmVjdG9yKCQke2luZGV4fSwgJCR7aW5kZXggKyAxfTpuYW1lKSBAQCB0b190c3F1ZXJ5KCQke1xuICAgICAgICAgIGluZGV4ICsgMlxuICAgICAgICB9LCAkJHtpbmRleCArIDN9KWBcbiAgICAgICk7XG4gICAgICB2YWx1ZXMucHVzaChsYW5ndWFnZSwgZmllbGROYW1lLCBsYW5ndWFnZSwgc2VhcmNoLiR0ZXJtKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJG5lYXJTcGhlcmUpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gZmllbGRWYWx1ZS4kbmVhclNwaGVyZTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZmllbGRWYWx1ZS4kbWF4RGlzdGFuY2U7XG4gICAgICBjb25zdCBkaXN0YW5jZUluS00gPSBkaXN0YW5jZSAqIDYzNzEgKiAxMDAwO1xuICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgYFNUX0Rpc3RhbmNlU3BoZXJlKCQke2luZGV4fTpuYW1lOjpnZW9tZXRyeSwgUE9JTlQoJCR7aW5kZXggKyAxfSwgJCR7XG4gICAgICAgICAgaW5kZXggKyAyXG4gICAgICAgIH0pOjpnZW9tZXRyeSkgPD0gJCR7aW5kZXggKyAzfWBcbiAgICAgICk7XG4gICAgICBzb3J0cy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSBBU0NgXG4gICAgICApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlLCBkaXN0YW5jZUluS00pO1xuICAgICAgaW5kZXggKz0gNDtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kd2l0aGluICYmIGZpZWxkVmFsdWUuJHdpdGhpbi4kYm94KSB7XG4gICAgICBjb25zdCBib3ggPSBmaWVsZFZhbHVlLiR3aXRoaW4uJGJveDtcbiAgICAgIGNvbnN0IGxlZnQgPSBib3hbMF0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgYm90dG9tID0gYm94WzBdLmxhdGl0dWRlO1xuICAgICAgY29uc3QgcmlnaHQgPSBib3hbMV0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgdG9wID0gYm94WzFdLmxhdGl0dWRlO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6Ym94YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGAoKCR7bGVmdH0sICR7Ym90dG9tfSksICgke3JpZ2h0fSwgJHt0b3B9KSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJGNlbnRlclNwaGVyZSkge1xuICAgICAgY29uc3QgY2VudGVyU3BoZXJlID0gZmllbGRWYWx1ZS4kZ2VvV2l0aGluLiRjZW50ZXJTcGhlcmU7XG4gICAgICBpZiAoIShjZW50ZXJTcGhlcmUgaW5zdGFuY2VvZiBBcnJheSkgfHwgY2VudGVyU3BoZXJlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgc2hvdWxkIGJlIGFuIGFycmF5IG9mIFBhcnNlLkdlb1BvaW50IGFuZCBkaXN0YW5jZSdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEdldCBwb2ludCwgY29udmVydCB0byBnZW8gcG9pbnQgaWYgbmVjZXNzYXJ5IGFuZCB2YWxpZGF0ZVxuICAgICAgbGV0IHBvaW50ID0gY2VudGVyU3BoZXJlWzBdO1xuICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIHBvaW50ID0gbmV3IFBhcnNlLkdlb1BvaW50KHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICB9IGVsc2UgaWYgKCFHZW9Qb2ludENvZGVyLmlzVmFsaWRKU09OKHBvaW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBnZW8gcG9pbnQgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludC5sYXRpdHVkZSwgcG9pbnQubG9uZ2l0dWRlKTtcbiAgICAgIC8vIEdldCBkaXN0YW5jZSBhbmQgdmFsaWRhdGVcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gY2VudGVyU3BoZXJlWzFdO1xuICAgICAgaWYgKGlzTmFOKGRpc3RhbmNlKSB8fCBkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgZGlzdGFuY2UgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRpc3RhbmNlSW5LTSA9IGRpc3RhbmNlICogNjM3MSAqIDEwMDA7XG4gICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSA8PSAkJHtpbmRleCArIDN9YFxuICAgICAgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZSwgZGlzdGFuY2VJbktNKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb24pIHtcbiAgICAgIGNvbnN0IHBvbHlnb24gPSBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb247XG4gICAgICBsZXQgcG9pbnRzO1xuICAgICAgaWYgKHR5cGVvZiBwb2x5Z29uID09PSAnb2JqZWN0JyAmJiBwb2x5Z29uLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGlmICghcG9seWdvbi5jb29yZGluYXRlcyB8fCBwb2x5Z29uLmNvb3JkaW5hdGVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7IFBvbHlnb24uY29vcmRpbmF0ZXMgc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBsb24vbGF0IHBhaXJzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbi5jb29yZGluYXRlcztcbiAgICAgIH0gZWxzZSBpZiAocG9seWdvbiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgR2VvUG9pbnRzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgXCJiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGJlIFBvbHlnb24gb2JqZWN0IG9yIEFycmF5IG9mIFBhcnNlLkdlb1BvaW50J3NcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcG9pbnRzID0gcG9pbnRzXG4gICAgICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEFycmF5ICYmIHBvaW50Lmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICAgICAgICByZXR1cm4gYCgke3BvaW50WzBdfSwgJHtwb2ludFsxXX0pYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWA7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCcsICcpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6cG9seWdvbmApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBgKCR7cG9pbnRzfSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuICAgIGlmIChmaWVsZFZhbHVlLiRnZW9JbnRlcnNlY3RzICYmIGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50KSB7XG4gICAgICBjb25zdCBwb2ludCA9IGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50O1xuICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ2JhZCAkZ2VvSW50ZXJzZWN0IHZhbHVlOyAkcG9pbnQgc2hvdWxkIGJlIEdlb1BvaW50J1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgfVxuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWU6OnBvbHlnb24gQD4gJCR7aW5kZXggKyAxfTo6cG9pbnRgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWApO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kcmVnZXgpIHtcbiAgICAgIGxldCByZWdleCA9IGZpZWxkVmFsdWUuJHJlZ2V4O1xuICAgICAgbGV0IG9wZXJhdG9yID0gJ34nO1xuICAgICAgY29uc3Qgb3B0cyA9IGZpZWxkVmFsdWUuJG9wdGlvbnM7XG4gICAgICBpZiAob3B0cykge1xuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCdpJykgPj0gMCkge1xuICAgICAgICAgIG9wZXJhdG9yID0gJ34qJztcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCd4JykgPj0gMCkge1xuICAgICAgICAgIHJlZ2V4ID0gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbmFtZSA9IHRyYW5zZm9ybURvdEZpZWxkKGZpZWxkTmFtZSk7XG4gICAgICByZWdleCA9IHByb2Nlc3NSZWdleFBhdHRlcm4ocmVnZXgpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06cmF3ICR7b3BlcmF0b3J9ICckJHtpbmRleCArIDF9OnJhdydgKTtcbiAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIHJlZ2V4KTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIGlmIChpc0FycmF5RmllbGQpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoW2ZpZWxkVmFsdWVdKSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuaXNvKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtpbmRleCArIDJ9KWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmxvbmdpdHVkZSwgZmllbGRWYWx1ZS5sYXRpdHVkZSk7XG4gICAgICBpbmRleCArPSAzO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnZlcnRQb2x5Z29uVG9TUUwoZmllbGRWYWx1ZS5jb29yZGluYXRlcyk7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSAkJHtpbmRleCArIDF9Ojpwb2x5Z29uYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIHZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoUGFyc2VUb1Bvc2dyZXNDb21wYXJhdG9yKS5mb3JFYWNoKGNtcCA9PiB7XG4gICAgICBpZiAoZmllbGRWYWx1ZVtjbXBdIHx8IGZpZWxkVmFsdWVbY21wXSA9PT0gMCkge1xuICAgICAgICBjb25zdCBwZ0NvbXBhcmF0b3IgPSBQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3JbY21wXTtcbiAgICAgICAgY29uc3QgcG9zdGdyZXNWYWx1ZSA9IHRvUG9zdGdyZXNWYWx1ZShmaWVsZFZhbHVlW2NtcF0pO1xuICAgICAgICBsZXQgY29uc3RyYWludEZpZWxkTmFtZTtcbiAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgIGxldCBjYXN0VHlwZTtcbiAgICAgICAgICBzd2l0Y2ggKHR5cGVvZiBwb3N0Z3Jlc1ZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICAgICAgICBjYXN0VHlwZSA9ICdkb3VibGUgcHJlY2lzaW9uJztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSAnYm9vbGVhbic7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0cmFpbnRGaWVsZE5hbWUgPSBjYXN0VHlwZVxuICAgICAgICAgICAgPyBgQ0FTVCAoKCR7dHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKX0pIEFTICR7Y2FzdFR5cGV9KWBcbiAgICAgICAgICAgIDogdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdHJhaW50RmllbGROYW1lID0gYCQke2luZGV4Kyt9Om5hbWVgO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWVzLnB1c2gocG9zdGdyZXNWYWx1ZSk7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCR7Y29uc3RyYWludEZpZWxkTmFtZX0gJHtwZ0NvbXBhcmF0b3J9ICQke2luZGV4Kyt9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoaW5pdGlhbFBhdHRlcm5zTGVuZ3RoID09PSBwYXR0ZXJucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHF1ZXJ5IHR5cGUgeWV0ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgZmllbGRWYWx1ZVxuICAgICAgICApfWBcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHZhbHVlcyA9IHZhbHVlcy5tYXAodHJhbnNmb3JtVmFsdWUpO1xuICByZXR1cm4geyBwYXR0ZXJuOiBwYXR0ZXJucy5qb2luKCcgQU5EICcpLCB2YWx1ZXMsIHNvcnRzIH07XG59O1xuXG5leHBvcnQgY2xhc3MgUG9zdGdyZXNTdG9yYWdlQWRhcHRlciBpbXBsZW1lbnRzIFN0b3JhZ2VBZGFwdGVyIHtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcblxuICAvLyBQcml2YXRlXG4gIF9jb2xsZWN0aW9uUHJlZml4OiBzdHJpbmc7XG4gIF9jbGllbnQ6IGFueTtcbiAgX3BncDogYW55O1xuXG4gIGNvbnN0cnVjdG9yKHsgdXJpLCBjb2xsZWN0aW9uUHJlZml4ID0gJycsIGRhdGFiYXNlT3B0aW9ucyB9OiBhbnkpIHtcbiAgICB0aGlzLl9jb2xsZWN0aW9uUHJlZml4ID0gY29sbGVjdGlvblByZWZpeDtcbiAgICBjb25zdCB7IGNsaWVudCwgcGdwIH0gPSBjcmVhdGVDbGllbnQodXJpLCBkYXRhYmFzZU9wdGlvbnMpO1xuICAgIHRoaXMuX2NsaWVudCA9IGNsaWVudDtcbiAgICB0aGlzLl9wZ3AgPSBwZ3A7XG4gICAgdGhpcy5jYW5Tb3J0T25Kb2luVGFibGVzID0gZmFsc2U7XG4gIH1cblxuICAvL05vdGUgdGhhdCBhbmFseXplPXRydWUgd2lsbCBydW4gdGhlIHF1ZXJ5LCBleGVjdXRpbmcgSU5TRVJUUywgREVMRVRFUywgZXRjLlxuICBjcmVhdGVFeHBsYWluYWJsZVF1ZXJ5KHF1ZXJ5OiBzdHJpbmcsIGFuYWx5emU6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGlmIChhbmFseXplKSB7XG4gICAgICByZXR1cm4gJ0VYUExBSU4gKEFOQUxZWkUsIEZPUk1BVCBKU09OKSAnICsgcXVlcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnRVhQTEFJTiAoRk9STUFUIEpTT04pICcgKyBxdWVyeTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuX2NsaWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9jbGllbnQuJHBvb2wuZW5kKCk7XG4gIH1cblxuICBhc3luYyBfZW5zdXJlU2NoZW1hQ29sbGVjdGlvbkV4aXN0cyhjb25uOiBhbnkpIHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgYXdhaXQgY29ublxuICAgICAgLm5vbmUoXG4gICAgICAgICdDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyBcIl9TQ0hFTUFcIiAoIFwiY2xhc3NOYW1lXCIgdmFyQ2hhcigxMjApLCBcInNjaGVtYVwiIGpzb25iLCBcImlzUGFyc2VDbGFzc1wiIGJvb2wsIFBSSU1BUlkgS0VZIChcImNsYXNzTmFtZVwiKSApJ1xuICAgICAgKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciB8fFxuICAgICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciB8fFxuICAgICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlT2JqZWN0RXJyb3JcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gVGFibGUgYWxyZWFkeSBleGlzdHMsIG11c3QgaGF2ZSBiZWVuIGNyZWF0ZWQgYnkgYSBkaWZmZXJlbnQgcmVxdWVzdC4gSWdub3JlIGVycm9yLlxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNsYXNzRXhpc3RzKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQub25lKFxuICAgICAgJ1NFTEVDVCBFWElTVFMgKFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9uYW1lID0gJDEpJyxcbiAgICAgIFtuYW1lXSxcbiAgICAgIGEgPT4gYS5leGlzdHNcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgc2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nLCBDTFBzOiBhbnkpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBhd2FpdCB0aGlzLl9jbGllbnQudGFzaygnc2V0LWNsYXNzLWxldmVsLXBlcm1pc3Npb25zJywgYXN5bmMgdCA9PiB7XG4gICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgY29uc3QgdmFsdWVzID0gW1xuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICdzY2hlbWEnLFxuICAgICAgICAnY2xhc3NMZXZlbFBlcm1pc3Npb25zJyxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoQ0xQcyksXG4gICAgICBdO1xuICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICBgVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCAkMjpuYW1lID0ganNvbl9vYmplY3Rfc2V0X2tleSgkMjpuYW1lLCAkMzo6dGV4dCwgJDQ6Ompzb25iKSBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDFgLFxuICAgICAgICB2YWx1ZXNcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzdWJtaXR0ZWRJbmRleGVzOiBhbnksXG4gICAgZXhpc3RpbmdJbmRleGVzOiBhbnkgPSB7fSxcbiAgICBmaWVsZHM6IGFueSxcbiAgICBjb25uOiA/YW55XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBpZiAoc3VibWl0dGVkSW5kZXhlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhleGlzdGluZ0luZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdJbmRleGVzID0geyBfaWRfOiB7IF9pZDogMSB9IH07XG4gICAgfVxuICAgIGNvbnN0IGRlbGV0ZWRJbmRleGVzID0gW107XG4gICAgY29uc3QgaW5zZXJ0ZWRJbmRleGVzID0gW107XG4gICAgT2JqZWN0LmtleXMoc3VibWl0dGVkSW5kZXhlcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gc3VibWl0dGVkSW5kZXhlc1tuYW1lXTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgIGBJbmRleCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICBkZWxldGVkSW5kZXhlcy5wdXNoKG5hbWUpO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdJbmRleGVzW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmtleXMoZmllbGQpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmaWVsZHMsIGtleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICAgICAgYEZpZWxkICR7a2V5fSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGFkZCBpbmRleC5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGV4aXN0aW5nSW5kZXhlc1tuYW1lXSA9IGZpZWxkO1xuICAgICAgICBpbnNlcnRlZEluZGV4ZXMucHVzaCh7XG4gICAgICAgICAga2V5OiBmaWVsZCxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBhd2FpdCBjb25uLnR4KCdzZXQtaW5kZXhlcy13aXRoLXNjaGVtYS1mb3JtYXQnLCBhc3luYyB0ID0+IHtcbiAgICAgIGlmIChpbnNlcnRlZEluZGV4ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCBzZWxmLmNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lLCBpbnNlcnRlZEluZGV4ZXMsIHQpO1xuICAgICAgfVxuICAgICAgaWYgKGRlbGV0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgc2VsZi5kcm9wSW5kZXhlcyhjbGFzc05hbWUsIGRlbGV0ZWRJbmRleGVzLCB0KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNlbGYuX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHModCk7XG4gICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICdVUERBVEUgXCJfU0NIRU1BXCIgU0VUICQyOm5hbWUgPSBqc29uX29iamVjdF9zZXRfa2V5KCQyOm5hbWUsICQzOjp0ZXh0LCAkNDo6anNvbmIpIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkMScsXG4gICAgICAgIFtjbGFzc05hbWUsICdzY2hlbWEnLCAnaW5kZXhlcycsIEpTT04uc3RyaW5naWZ5KGV4aXN0aW5nSW5kZXhlcyldXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgY29ubjogP2FueSkge1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICByZXR1cm4gY29ublxuICAgICAgLnR4KCdjcmVhdGUtY2xhc3MnLCBhc3luYyB0ID0+IHtcbiAgICAgICAgY29uc3QgcTEgPSB0aGlzLmNyZWF0ZVRhYmxlKGNsYXNzTmFtZSwgc2NoZW1hLCB0KTtcbiAgICAgICAgY29uc3QgcTIgPSB0Lm5vbmUoXG4gICAgICAgICAgJ0lOU0VSVCBJTlRPIFwiX1NDSEVNQVwiIChcImNsYXNzTmFtZVwiLCBcInNjaGVtYVwiLCBcImlzUGFyc2VDbGFzc1wiKSBWQUxVRVMgKCQ8Y2xhc3NOYW1lPiwgJDxzY2hlbWE+LCB0cnVlKScsXG4gICAgICAgICAgeyBjbGFzc05hbWUsIHNjaGVtYSB9XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHEzID0gdGhpcy5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgc2NoZW1hLmluZGV4ZXMsXG4gICAgICAgICAge30sXG4gICAgICAgICAgc2NoZW1hLmZpZWxkcyxcbiAgICAgICAgICB0XG4gICAgICAgICk7XG4gICAgICAgIC8vIFRPRE86IFRoZSB0ZXN0IHNob3VsZCBub3QgdmVyaWZ5IHRoZSByZXR1cm5lZCB2YWx1ZSwgYW5kIHRoZW5cbiAgICAgICAgLy8gIHRoZSBtZXRob2QgY2FuIGJlIHNpbXBsaWZpZWQsIHRvIGF2b2lkIHJldHVybmluZyB1c2VsZXNzIHN0dWZmLlxuICAgICAgICByZXR1cm4gdC5iYXRjaChbcTEsIHEyLCBxM10pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRvUGFyc2VTY2hlbWEoc2NoZW1hKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgaWYgKGVyci5kYXRhWzBdLnJlc3VsdC5jb2RlID09PSBQb3N0Z3Jlc1RyYW5zYWN0aW9uQWJvcnRlZEVycm9yKSB7XG4gICAgICAgICAgZXJyID0gZXJyLmRhdGFbMV0ucmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlcnIuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yICYmXG4gICAgICAgICAgZXJyLmRldGFpbC5pbmNsdWRlcyhjbGFzc05hbWUpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgIGBDbGFzcyAke2NsYXNzTmFtZX0gYWxyZWFkeSBleGlzdHMuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBKdXN0IGNyZWF0ZSBhIHRhYmxlLCBkbyBub3QgaW5zZXJ0IGluIHNjaGVtYVxuICBhc3luYyBjcmVhdGVUYWJsZShjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBjb25uOiBhbnkpIHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgZGVidWcoJ2NyZWF0ZVRhYmxlJywgY2xhc3NOYW1lLCBzY2hlbWEpO1xuICAgIGNvbnN0IHZhbHVlc0FycmF5ID0gW107XG4gICAgY29uc3QgcGF0dGVybnNBcnJheSA9IFtdO1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5hc3NpZ24oe30sIHNjaGVtYS5maWVsZHMpO1xuICAgIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgIGZpZWxkcy5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSB7IHR5cGU6ICdEYXRlJyB9O1xuICAgICAgZmllbGRzLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gICAgICBmaWVsZHMuX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fZmFpbGVkX2xvZ2luX2NvdW50ID0geyB0eXBlOiAnTnVtYmVyJyB9O1xuICAgICAgZmllbGRzLl9wZXJpc2hhYmxlX3Rva2VuID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgICAgZmllbGRzLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSB7IHR5cGU6ICdEYXRlJyB9O1xuICAgICAgZmllbGRzLl9wYXNzd29yZF9jaGFuZ2VkX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fcGFzc3dvcmRfaGlzdG9yeSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuICAgIH1cbiAgICBsZXQgaW5kZXggPSAyO1xuICAgIGNvbnN0IHJlbGF0aW9ucyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKGZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgY29uc3QgcGFyc2VUeXBlID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAvLyBTa2lwIHdoZW4gaXQncyBhIHJlbGF0aW9uXG4gICAgICAvLyBXZSdsbCBjcmVhdGUgdGhlIHRhYmxlcyBsYXRlclxuICAgICAgaWYgKHBhcnNlVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIHJlbGF0aW9ucy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChbJ19ycGVybScsICdfd3Blcm0nXS5pbmRleE9mKGZpZWxkTmFtZSkgPj0gMCkge1xuICAgICAgICBwYXJzZVR5cGUuY29udGVudHMgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gICAgICB9XG4gICAgICB2YWx1ZXNBcnJheS5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICB2YWx1ZXNBcnJheS5wdXNoKHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHBhcnNlVHlwZSkpO1xuICAgICAgcGF0dGVybnNBcnJheS5wdXNoKGAkJHtpbmRleH06bmFtZSAkJHtpbmRleCArIDF9OnJhd2ApO1xuICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ29iamVjdElkJykge1xuICAgICAgICBwYXR0ZXJuc0FycmF5LnB1c2goYFBSSU1BUlkgS0VZICgkJHtpbmRleH06bmFtZSlgKTtcbiAgICAgIH1cbiAgICAgIGluZGV4ID0gaW5kZXggKyAyO1xuICAgIH0pO1xuICAgIGNvbnN0IHFzID0gYENSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICQxOm5hbWUgKCR7cGF0dGVybnNBcnJheS5qb2luKCl9KWA7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4udmFsdWVzQXJyYXldO1xuXG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgcmV0dXJuIGNvbm4udGFzaygnY3JlYXRlLXRhYmxlJywgYXN5bmMgdCA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgICBhd2FpdCB0Lm5vbmUocXMsIHZhbHVlcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRUxTRTogVGFibGUgYWxyZWFkeSBleGlzdHMsIG11c3QgaGF2ZSBiZWVuIGNyZWF0ZWQgYnkgYSBkaWZmZXJlbnQgcmVxdWVzdC4gSWdub3JlIHRoZSBlcnJvci5cbiAgICAgIH1cbiAgICAgIGF3YWl0IHQudHgoJ2NyZWF0ZS10YWJsZS10eCcsIHR4ID0+IHtcbiAgICAgICAgcmV0dXJuIHR4LmJhdGNoKFxuICAgICAgICAgIHJlbGF0aW9ucy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0eC5ub25lKFxuICAgICAgICAgICAgICAnQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgJDxqb2luVGFibGU6bmFtZT4gKFwicmVsYXRlZElkXCIgdmFyQ2hhcigxMjApLCBcIm93bmluZ0lkXCIgdmFyQ2hhcigxMjApLCBQUklNQVJZIEtFWShcInJlbGF0ZWRJZFwiLCBcIm93bmluZ0lkXCIpICknLFxuICAgICAgICAgICAgICB7IGpvaW5UYWJsZTogYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2NoZW1hVXBncmFkZShjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBjb25uOiBhbnkpIHtcbiAgICBkZWJ1Zygnc2NoZW1hVXBncmFkZScsIHsgY2xhc3NOYW1lLCBzY2hlbWEgfSk7XG4gICAgY29ubiA9IGNvbm4gfHwgdGhpcy5fY2xpZW50O1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgYXdhaXQgY29ubi50eCgnc2NoZW1hLXVwZ3JhZGUnLCBhc3luYyB0ID0+IHtcbiAgICAgIGNvbnN0IGNvbHVtbnMgPSBhd2FpdCB0Lm1hcChcbiAgICAgICAgJ1NFTEVDVCBjb2x1bW5fbmFtZSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIFdIRVJFIHRhYmxlX25hbWUgPSAkPGNsYXNzTmFtZT4nLFxuICAgICAgICB7IGNsYXNzTmFtZSB9LFxuICAgICAgICBhID0+IGEuY29sdW1uX25hbWVcbiAgICAgICk7XG4gICAgICBjb25zdCBuZXdDb2x1bW5zID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcylcbiAgICAgICAgLmZpbHRlcihpdGVtID0+IGNvbHVtbnMuaW5kZXhPZihpdGVtKSA9PT0gLTEpXG4gICAgICAgIC5tYXAoZmllbGROYW1lID0+XG4gICAgICAgICAgc2VsZi5hZGRGaWVsZElmTm90RXhpc3RzKFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLFxuICAgICAgICAgICAgdFxuICAgICAgICAgIClcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgdC5iYXRjaChuZXdDb2x1bW5zKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGFkZEZpZWxkSWZOb3RFeGlzdHMoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgdHlwZTogYW55LFxuICAgIGNvbm46IGFueVxuICApIHtcbiAgICAvLyBUT0RPOiBNdXN0IGJlIHJldmlzZWQgZm9yIGludmFsaWQgbG9naWMuLi5cbiAgICBkZWJ1ZygnYWRkRmllbGRJZk5vdEV4aXN0cycsIHsgY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUgfSk7XG4gICAgY29ubiA9IGNvbm4gfHwgdGhpcy5fY2xpZW50O1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGF3YWl0IGNvbm4udHgoJ2FkZC1maWVsZC1pZi1ub3QtZXhpc3RzJywgYXN5bmMgdCA9PiB7XG4gICAgICBpZiAodHlwZS50eXBlICE9PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAgICAgJ0FMVEVSIFRBQkxFICQ8Y2xhc3NOYW1lOm5hbWU+IEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyAkPGZpZWxkTmFtZTpuYW1lPiAkPHBvc3RncmVzVHlwZTpyYXc+JyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBmaWVsZE5hbWUsXG4gICAgICAgICAgICAgIHBvc3RncmVzVHlwZTogcGFyc2VUeXBlVG9Qb3N0Z3Jlc1R5cGUodHlwZSksXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5jcmVhdGVDbGFzcyhcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICB7IGZpZWxkczogeyBbZmllbGROYW1lXTogdHlwZSB9IH0sXG4gICAgICAgICAgICAgIHRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlcnJvci5jb2RlICE9PSBQb3N0Z3Jlc0R1cGxpY2F0ZUNvbHVtbkVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29sdW1uIGFscmVhZHkgZXhpc3RzLCBjcmVhdGVkIGJ5IG90aGVyIHJlcXVlc3QuIENhcnJ5IG9uIHRvIHNlZSBpZiBpdCdzIHRoZSByaWdodCB0eXBlLlxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICAgJ0NSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICQ8am9pblRhYmxlOm5hbWU+IChcInJlbGF0ZWRJZFwiIHZhckNoYXIoMTIwKSwgXCJvd25pbmdJZFwiIHZhckNoYXIoMTIwKSwgUFJJTUFSWSBLRVkoXCJyZWxhdGVkSWRcIiwgXCJvd25pbmdJZFwiKSApJyxcbiAgICAgICAgICB7IGpvaW5UYWJsZTogYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdC5hbnkoXG4gICAgICAgICdTRUxFQ1QgXCJzY2hlbWFcIiBGUk9NIFwiX1NDSEVNQVwiIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkPGNsYXNzTmFtZT4gYW5kIChcInNjaGVtYVwiOjpqc29uLT5cXCdmaWVsZHNcXCctPiQ8ZmllbGROYW1lPikgaXMgbm90IG51bGwnLFxuICAgICAgICB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH1cbiAgICAgICk7XG5cbiAgICAgIGlmIChyZXN1bHRbMF0pIHtcbiAgICAgICAgdGhyb3cgJ0F0dGVtcHRlZCB0byBhZGQgYSBmaWVsZCB0aGF0IGFscmVhZHkgZXhpc3RzJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBge2ZpZWxkcywke2ZpZWxkTmFtZX19YDtcbiAgICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAgICdVUERBVEUgXCJfU0NIRU1BXCIgU0VUIFwic2NoZW1hXCI9anNvbmJfc2V0KFwic2NoZW1hXCIsICQ8cGF0aD4sICQ8dHlwZT4pICBXSEVSRSBcImNsYXNzTmFtZVwiPSQ8Y2xhc3NOYW1lPicsXG4gICAgICAgICAgeyBwYXRoLCB0eXBlLCBjbGFzc05hbWUgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gRHJvcHMgYSBjb2xsZWN0aW9uLiBSZXNvbHZlcyB3aXRoIHRydWUgaWYgaXQgd2FzIGEgUGFyc2UgU2NoZW1hIChlZy4gX1VzZXIsIEN1c3RvbSwgZXRjLilcbiAgLy8gYW5kIHJlc29sdmVzIHdpdGggZmFsc2UgaWYgaXQgd2Fzbid0IChlZy4gYSBqb2luIHRhYmxlKS4gUmVqZWN0cyBpZiBkZWxldGlvbiB3YXMgaW1wb3NzaWJsZS5cbiAgYXN5bmMgZGVsZXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBvcGVyYXRpb25zID0gW1xuICAgICAgeyBxdWVyeTogYERST1AgVEFCTEUgSUYgRVhJU1RTICQxOm5hbWVgLCB2YWx1ZXM6IFtjbGFzc05hbWVdIH0sXG4gICAgICB7XG4gICAgICAgIHF1ZXJ5OiBgREVMRVRFIEZST00gXCJfU0NIRU1BXCIgV0hFUkUgXCJjbGFzc05hbWVcIiA9ICQxYCxcbiAgICAgICAgdmFsdWVzOiBbY2xhc3NOYW1lXSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAudHgodCA9PiB0Lm5vbmUodGhpcy5fcGdwLmhlbHBlcnMuY29uY2F0KG9wZXJhdGlvbnMpKSlcbiAgICAgIC50aGVuKCgpID0+IGNsYXNzTmFtZS5pbmRleE9mKCdfSm9pbjonKSAhPSAwKTsgLy8gcmVzb2x2ZXMgd2l0aCBmYWxzZSB3aGVuIF9Kb2luIHRhYmxlXG4gIH1cblxuICAvLyBEZWxldGUgYWxsIGRhdGEga25vd24gdG8gdGhpcyBhZGFwdGVyLiBVc2VkIGZvciB0ZXN0aW5nLlxuICBhc3luYyBkZWxldGVBbGxDbGFzc2VzKCkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGhlbHBlcnMgPSB0aGlzLl9wZ3AuaGVscGVycztcbiAgICBkZWJ1ZygnZGVsZXRlQWxsQ2xhc3NlcycpO1xuXG4gICAgYXdhaXQgdGhpcy5fY2xpZW50XG4gICAgICAudGFzaygnZGVsZXRlLWFsbC1jbGFzc2VzJywgYXN5bmMgdCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHQuYW55KCdTRUxFQ1QgKiBGUk9NIFwiX1NDSEVNQVwiJyk7XG4gICAgICAgICAgY29uc3Qgam9pbnMgPSByZXN1bHRzLnJlZHVjZSgobGlzdDogQXJyYXk8c3RyaW5nPiwgc2NoZW1hOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0LmNvbmNhdChqb2luVGFibGVzRm9yU2NoZW1hKHNjaGVtYS5zY2hlbWEpKTtcbiAgICAgICAgICB9LCBbXSk7XG4gICAgICAgICAgY29uc3QgY2xhc3NlcyA9IFtcbiAgICAgICAgICAgICdfU0NIRU1BJyxcbiAgICAgICAgICAgICdfUHVzaFN0YXR1cycsXG4gICAgICAgICAgICAnX0pvYlN0YXR1cycsXG4gICAgICAgICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgICAgICAgICdfSG9va3MnLFxuICAgICAgICAgICAgJ19HbG9iYWxDb25maWcnLFxuICAgICAgICAgICAgJ19HcmFwaFFMQ29uZmlnJyxcbiAgICAgICAgICAgICdfQXVkaWVuY2UnLFxuICAgICAgICAgICAgJ19JZGVtcG90ZW5jeScsXG4gICAgICAgICAgICAuLi5yZXN1bHRzLm1hcChyZXN1bHQgPT4gcmVzdWx0LmNsYXNzTmFtZSksXG4gICAgICAgICAgICAuLi5qb2lucyxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0IHF1ZXJpZXMgPSBjbGFzc2VzLm1hcChjbGFzc05hbWUgPT4gKHtcbiAgICAgICAgICAgIHF1ZXJ5OiAnRFJPUCBUQUJMRSBJRiBFWElTVFMgJDxjbGFzc05hbWU6bmFtZT4nLFxuICAgICAgICAgICAgdmFsdWVzOiB7IGNsYXNzTmFtZSB9LFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgICBhd2FpdCB0LnR4KHR4ID0+IHR4Lm5vbmUoaGVscGVycy5jb25jYXQocXVlcmllcykpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gTm8gX1NDSEVNQSBjb2xsZWN0aW9uLiBEb24ndCBkZWxldGUgYW55dGhpbmcuXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGRlYnVnKGBkZWxldGVBbGxDbGFzc2VzIGRvbmUgaW4gJHtuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIG5vd31gKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmVtb3ZlIHRoZSBjb2x1bW4gYW5kIGFsbCB0aGUgZGF0YS4gRm9yIFJlbGF0aW9ucywgdGhlIF9Kb2luIGNvbGxlY3Rpb24gaXMgaGFuZGxlZFxuICAvLyBzcGVjaWFsbHksIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgZGVsZXRlIF9Kb2luIGNvbHVtbnMuIEl0IHNob3VsZCwgaG93ZXZlciwgaW5kaWNhdGVcbiAgLy8gdGhhdCB0aGUgcmVsYXRpb24gZmllbGRzIGRvZXMgbm90IGV4aXN0IGFueW1vcmUuIEluIG1vbmdvLCB0aGlzIG1lYW5zIHJlbW92aW5nIGl0IGZyb21cbiAgLy8gdGhlIF9TQ0hFTUEgY29sbGVjdGlvbi4gIFRoZXJlIHNob3VsZCBiZSBubyBhY3R1YWwgZGF0YSBpbiB0aGUgY29sbGVjdGlvbiB1bmRlciB0aGUgc2FtZSBuYW1lXG4gIC8vIGFzIHRoZSByZWxhdGlvbiBjb2x1bW4sIHNvIGl0J3MgZmluZSB0byBhdHRlbXB0IHRvIGRlbGV0ZSBpdC4gSWYgdGhlIGZpZWxkcyBsaXN0ZWQgdG8gYmVcbiAgLy8gZGVsZXRlZCBkbyBub3QgZXhpc3QsIHRoaXMgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBzdWNjZXNzZnVsbHkgYW55d2F5cy4gQ2hlY2tpbmcgZm9yXG4gIC8vIGF0dGVtcHRzIHRvIGRlbGV0ZSBub24tZXhpc3RlbnQgZmllbGRzIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiBQYXJzZSBTZXJ2ZXIuXG5cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBub3Qgb2JsaWdhdGVkIHRvIGRlbGV0ZSBmaWVsZHMgYXRvbWljYWxseS4gSXQgaXMgZ2l2ZW4gdGhlIGZpZWxkXG4gIC8vIG5hbWVzIGluIGEgbGlzdCBzbyB0aGF0IGRhdGFiYXNlcyB0aGF0IGFyZSBjYXBhYmxlIG9mIGRlbGV0aW5nIGZpZWxkcyBhdG9taWNhbGx5XG4gIC8vIG1heSBkbyBzby5cblxuICAvLyBSZXR1cm5zIGEgUHJvbWlzZS5cbiAgYXN5bmMgZGVsZXRlRmllbGRzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBkZWJ1ZygnZGVsZXRlRmllbGRzJywgY2xhc3NOYW1lLCBmaWVsZE5hbWVzKTtcbiAgICBmaWVsZE5hbWVzID0gZmllbGROYW1lcy5yZWR1Y2UoKGxpc3Q6IEFycmF5PHN0cmluZz4sIGZpZWxkTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgIGlmIChmaWVsZC50eXBlICE9PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGxpc3QucHVzaChmaWVsZE5hbWUpO1xuICAgICAgfVxuICAgICAgZGVsZXRlIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IFtjbGFzc05hbWUsIC4uLmZpZWxkTmFtZXNdO1xuICAgIGNvbnN0IGNvbHVtbnMgPSBmaWVsZE5hbWVzXG4gICAgICAubWFwKChuYW1lLCBpZHgpID0+IHtcbiAgICAgICAgcmV0dXJuIGAkJHtpZHggKyAyfTpuYW1lYDtcbiAgICAgIH0pXG4gICAgICAuam9pbignLCBEUk9QIENPTFVNTicpO1xuXG4gICAgYXdhaXQgdGhpcy5fY2xpZW50LnR4KCdkZWxldGUtZmllbGRzJywgYXN5bmMgdCA9PiB7XG4gICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICdVUERBVEUgXCJfU0NIRU1BXCIgU0VUIFwic2NoZW1hXCIgPSAkPHNjaGVtYT4gV0hFUkUgXCJjbGFzc05hbWVcIiA9ICQ8Y2xhc3NOYW1lPicsXG4gICAgICAgIHsgc2NoZW1hLCBjbGFzc05hbWUgfVxuICAgICAgKTtcbiAgICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICAgYEFMVEVSIFRBQkxFICQxOm5hbWUgRFJPUCBDT0xVTU4gSUYgRVhJU1RTICR7Y29sdW1uc31gLFxuICAgICAgICAgIHZhbHVlc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJuIGEgcHJvbWlzZSBmb3IgYWxsIHNjaGVtYXMga25vd24gdG8gdGhpcyBhZGFwdGVyLCBpbiBQYXJzZSBmb3JtYXQuIEluIGNhc2UgdGhlXG4gIC8vIHNjaGVtYXMgY2Fubm90IGJlIHJldHJpZXZlZCwgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZWplY3RzLiBSZXF1aXJlbWVudHMgZm9yIHRoZVxuICAvLyByZWplY3Rpb24gcmVhc29uIGFyZSBUQkQuXG4gIGFzeW5jIGdldEFsbENsYXNzZXMoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC50YXNrKCdnZXQtYWxsLWNsYXNzZXMnLCBhc3luYyB0ID0+IHtcbiAgICAgIGF3YWl0IHNlbGYuX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHModCk7XG4gICAgICByZXR1cm4gYXdhaXQgdC5tYXAoJ1NFTEVDVCAqIEZST00gXCJfU0NIRU1BXCInLCBudWxsLCByb3cgPT5cbiAgICAgICAgdG9QYXJzZVNjaGVtYSh7IGNsYXNzTmFtZTogcm93LmNsYXNzTmFtZSwgLi4ucm93LnNjaGVtYSB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIHRoZSBzY2hlbWEgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgaW4gUGFyc2UgZm9ybWF0LiBJZlxuICAvLyB0aGlzIGFkYXB0ZXIgZG9lc24ndCBrbm93IGFib3V0IHRoZSBzY2hlbWEsIHJldHVybiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGhcbiAgLy8gdW5kZWZpbmVkIGFzIHRoZSByZWFzb24uXG4gIGFzeW5jIGdldENsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgZGVidWcoJ2dldENsYXNzJywgY2xhc3NOYW1lKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAuYW55KCdTRUxFQ1QgKiBGUk9NIFwiX1NDSEVNQVwiIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkPGNsYXNzTmFtZT4nLCB7XG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0WzBdLnNjaGVtYTtcbiAgICAgIH0pXG4gICAgICAudGhlbih0b1BhcnNlU2NoZW1hKTtcbiAgfVxuXG4gIC8vIFRPRE86IHJlbW92ZSB0aGUgbW9uZ28gZm9ybWF0IGRlcGVuZGVuY3kgaW4gdGhlIHJldHVybiB2YWx1ZVxuICBhc3luYyBjcmVhdGVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIG9iamVjdDogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCdjcmVhdGVPYmplY3QnLCBjbGFzc05hbWUsIG9iamVjdCk7XG4gICAgbGV0IGNvbHVtbnNBcnJheSA9IFtdO1xuICAgIGNvbnN0IHZhbHVlc0FycmF5ID0gW107XG4gICAgc2NoZW1hID0gdG9Qb3N0Z3Jlc1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGdlb1BvaW50cyA9IHt9O1xuXG4gICAgb2JqZWN0ID0gaGFuZGxlRG90RmllbGRzKG9iamVjdCk7XG5cbiAgICB2YWxpZGF0ZUtleXMob2JqZWN0KTtcblxuICAgIE9iamVjdC5rZXlzKG9iamVjdCkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBhdXRoRGF0YU1hdGNoID0gZmllbGROYW1lLm1hdGNoKC9eX2F1dGhfZGF0YV8oW2EtekEtWjAtOV9dKykkLyk7XG4gICAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgICB2YXIgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICBvYmplY3RbJ2F1dGhEYXRhJ10gPSBvYmplY3RbJ2F1dGhEYXRhJ10gfHwge307XG4gICAgICAgIG9iamVjdFsnYXV0aERhdGEnXVtwcm92aWRlcl0gPSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgICAgZGVsZXRlIG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICBmaWVsZE5hbWUgPSAnYXV0aERhdGEnO1xuICAgICAgfVxuXG4gICAgICBjb2x1bW5zQXJyYXkucHVzaChmaWVsZE5hbWUpO1xuICAgICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBmaWVsZE5hbWUgPT09ICdfZW1haWxfdmVyaWZ5X3Rva2VuJyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19mYWlsZWRfbG9naW5fY291bnQnIHx8XG4gICAgICAgICAgZmllbGROYW1lID09PSAnX3BlcmlzaGFibGVfdG9rZW4nIHx8XG4gICAgICAgICAgZmllbGROYW1lID09PSAnX3Bhc3N3b3JkX2hpc3RvcnknXG4gICAgICAgICkge1xuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCcpIHtcbiAgICAgICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0uaXNvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZmllbGROYW1lID09PSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnIHx8XG4gICAgICAgICAgZmllbGROYW1lID09PSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSkge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5pc28pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG51bGwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSkge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5pc28pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG51bGwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5vYmplY3RJZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgICAgICBpZiAoWydfcnBlcm0nLCAnX3dwZXJtJ10uaW5kZXhPZihmaWVsZE5hbWUpID49IDApIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKEpTT04uc3RyaW5naWZ5KG9iamVjdFtmaWVsZE5hbWVdKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdPYmplY3QnOlxuICAgICAgICBjYXNlICdCeXRlcyc6XG4gICAgICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICAgIGNhc2UgJ051bWJlcic6XG4gICAgICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdGaWxlJzpcbiAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdLm5hbWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdQb2x5Z29uJzoge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gY29udmVydFBvbHlnb25Ub1NRTChvYmplY3RbZmllbGROYW1lXS5jb29yZGluYXRlcyk7XG4gICAgICAgICAgdmFsdWVzQXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgICAgIC8vIHBvcCB0aGUgcG9pbnQgYW5kIHByb2Nlc3MgbGF0ZXJcbiAgICAgICAgICBnZW9Qb2ludHNbZmllbGROYW1lXSA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICAgIGNvbHVtbnNBcnJheS5wb3AoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBgVHlwZSAke3NjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlfSBub3Qgc3VwcG9ydGVkIHlldGA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb2x1bW5zQXJyYXkgPSBjb2x1bW5zQXJyYXkuY29uY2F0KE9iamVjdC5rZXlzKGdlb1BvaW50cykpO1xuICAgIGNvbnN0IGluaXRpYWxWYWx1ZXMgPSB2YWx1ZXNBcnJheS5tYXAoKHZhbCwgaW5kZXgpID0+IHtcbiAgICAgIGxldCB0ZXJtaW5hdGlvbiA9ICcnO1xuICAgICAgY29uc3QgZmllbGROYW1lID0gY29sdW1uc0FycmF5W2luZGV4XTtcbiAgICAgIGlmIChbJ19ycGVybScsICdfd3Blcm0nXS5pbmRleE9mKGZpZWxkTmFtZSkgPj0gMCkge1xuICAgICAgICB0ZXJtaW5hdGlvbiA9ICc6OnRleHRbXSc7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheSdcbiAgICAgICkge1xuICAgICAgICB0ZXJtaW5hdGlvbiA9ICc6Ompzb25iJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBgJCR7aW5kZXggKyAyICsgY29sdW1uc0FycmF5Lmxlbmd0aH0ke3Rlcm1pbmF0aW9ufWA7XG4gICAgfSk7XG4gICAgY29uc3QgZ2VvUG9pbnRzSW5qZWN0cyA9IE9iamVjdC5rZXlzKGdlb1BvaW50cykubWFwKGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdlb1BvaW50c1trZXldO1xuICAgICAgdmFsdWVzQXJyYXkucHVzaCh2YWx1ZS5sb25naXR1ZGUsIHZhbHVlLmxhdGl0dWRlKTtcbiAgICAgIGNvbnN0IGwgPSB2YWx1ZXNBcnJheS5sZW5ndGggKyBjb2x1bW5zQXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGBQT0lOVCgkJHtsfSwgJCR7bCArIDF9KWA7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjb2x1bW5zUGF0dGVybiA9IGNvbHVtbnNBcnJheVxuICAgICAgLm1hcCgoY29sLCBpbmRleCkgPT4gYCQke2luZGV4ICsgMn06bmFtZWApXG4gICAgICAuam9pbigpO1xuICAgIGNvbnN0IHZhbHVlc1BhdHRlcm4gPSBpbml0aWFsVmFsdWVzLmNvbmNhdChnZW9Qb2ludHNJbmplY3RzKS5qb2luKCk7XG5cbiAgICBjb25zdCBxcyA9IGBJTlNFUlQgSU5UTyAkMTpuYW1lICgke2NvbHVtbnNQYXR0ZXJufSkgVkFMVUVTICgke3ZhbHVlc1BhdHRlcm59KWA7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4uY29sdW1uc0FycmF5LCAuLi52YWx1ZXNBcnJheV07XG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgPyB0cmFuc2FjdGlvbmFsU2Vzc2lvbi50XG4gICAgICA6IHRoaXMuX2NsaWVudFxuICAgIClcbiAgICAgIC5ub25lKHFzLCB2YWx1ZXMpXG4gICAgICAudGhlbigoKSA9PiAoeyBvcHM6IFtvYmplY3RdIH0pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvcikge1xuICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgZXJyLnVuZGVybHlpbmdFcnJvciA9IGVycm9yO1xuICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50KSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gZXJyb3IuY29uc3RyYWludC5tYXRjaCgvdW5pcXVlXyhbYS16QS1aXSspLyk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBBcnJheS5pc0FycmF5KG1hdGNoZXMpKSB7XG4gICAgICAgICAgICAgIGVyci51c2VySW5mbyA9IHsgZHVwbGljYXRlZF9maWVsZDogbWF0Y2hlc1sxXSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBlcnJvciA9IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICAgIGlmICh0cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChwcm9taXNlKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICAvLyBSZW1vdmUgYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIC8vIElmIG5vIG9iamVjdHMgbWF0Y2gsIHJlamVjdCB3aXRoIE9CSkVDVF9OT1RfRk9VTkQuIElmIG9iamVjdHMgYXJlIGZvdW5kIGFuZCBkZWxldGVkLCByZXNvbHZlIHdpdGggdW5kZWZpbmVkLlxuICAvLyBJZiB0aGVyZSBpcyBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBJTlRFUk5BTF9TRVJWRVJfRVJST1IuXG4gIGFzeW5jIGRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCdkZWxldGVPYmplY3RzQnlRdWVyeScsIGNsYXNzTmFtZSwgcXVlcnkpO1xuICAgIGNvbnN0IHZhbHVlcyA9IFtjbGFzc05hbWVdO1xuICAgIGNvbnN0IGluZGV4ID0gMjtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgaW5kZXgsXG4gICAgICBxdWVyeSxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcbiAgICBpZiAoT2JqZWN0LmtleXMocXVlcnkpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgd2hlcmUucGF0dGVybiA9ICdUUlVFJztcbiAgICB9XG4gICAgY29uc3QgcXMgPSBgV0lUSCBkZWxldGVkIEFTIChERUxFVEUgRlJPTSAkMTpuYW1lIFdIRVJFICR7d2hlcmUucGF0dGVybn0gUkVUVVJOSU5HICopIFNFTEVDVCBjb3VudCgqKSBGUk9NIGRlbGV0ZWRgO1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIGNvbnN0IHByb21pc2UgPSAodHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgID8gdHJhbnNhY3Rpb25hbFNlc3Npb24udFxuICAgICAgOiB0aGlzLl9jbGllbnRcbiAgICApXG4gICAgICAub25lKHFzLCB2YWx1ZXMsIGEgPT4gK2EuY291bnQpXG4gICAgICAudGhlbihjb3VudCA9PiB7XG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAnT2JqZWN0IG5vdCBmb3VuZC4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRUxTRTogRG9uJ3QgZGVsZXRlIGFueXRoaW5nIGlmIGRvZXNuJ3QgZXhpc3RcbiAgICAgIH0pO1xuICAgIGlmICh0cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChwcm9taXNlKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cbiAgLy8gUmV0dXJuIHZhbHVlIG5vdCBjdXJyZW50bHkgd2VsbCBzcGVjaWZpZWQuXG4gIGFzeW5jIGZpbmRPbmVBbmRVcGRhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBkZWJ1ZygnZmluZE9uZUFuZFVwZGF0ZScsIGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT2JqZWN0c0J5UXVlcnkoXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBzY2hlbWEsXG4gICAgICBxdWVyeSxcbiAgICAgIHVwZGF0ZSxcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgKS50aGVuKHZhbCA9PiB2YWxbMF0pO1xuICB9XG5cbiAgLy8gQXBwbHkgdGhlIHVwZGF0ZSB0byBhbGwgb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBnaXZlbiBQYXJzZSBRdWVyeS5cbiAgYXN5bmMgdXBkYXRlT2JqZWN0c0J5UXVlcnkoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKTogUHJvbWlzZTxbYW55XT4ge1xuICAgIGRlYnVnKCd1cGRhdGVPYmplY3RzQnlRdWVyeScsIGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSk7XG4gICAgY29uc3QgdXBkYXRlUGF0dGVybnMgPSBbXTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBsZXQgaW5kZXggPSAyO1xuICAgIHNjaGVtYSA9IHRvUG9zdGdyZXNTY2hlbWEoc2NoZW1hKTtcblxuICAgIGNvbnN0IG9yaWdpbmFsVXBkYXRlID0geyAuLi51cGRhdGUgfTtcblxuICAgIC8vIFNldCBmbGFnIGZvciBkb3Qgbm90YXRpb24gZmllbGRzXG4gICAgY29uc3QgZG90Tm90YXRpb25PcHRpb25zID0ge307XG4gICAgT2JqZWN0LmtleXModXBkYXRlKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA+IC0xKSB7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBmaWVsZE5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgY29uc3QgZmlyc3QgPSBjb21wb25lbnRzLnNoaWZ0KCk7XG4gICAgICAgIGRvdE5vdGF0aW9uT3B0aW9uc1tmaXJzdF0gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG90Tm90YXRpb25PcHRpb25zW2ZpZWxkTmFtZV0gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB1cGRhdGUgPSBoYW5kbGVEb3RGaWVsZHModXBkYXRlKTtcbiAgICAvLyBSZXNvbHZlIGF1dGhEYXRhIGZpcnN0LFxuICAgIC8vIFNvIHdlIGRvbid0IGVuZCB1cCB3aXRoIG11bHRpcGxlIGtleSB1cGRhdGVzXG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gdXBkYXRlKSB7XG4gICAgICBjb25zdCBhdXRoRGF0YU1hdGNoID0gZmllbGROYW1lLm1hdGNoKC9eX2F1dGhfZGF0YV8oW2EtekEtWjAtOV9dKykkLyk7XG4gICAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgICB2YXIgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgICBkZWxldGUgdXBkYXRlW2ZpZWxkTmFtZV07XG4gICAgICAgIHVwZGF0ZVsnYXV0aERhdGEnXSA9IHVwZGF0ZVsnYXV0aERhdGEnXSB8fCB7fTtcbiAgICAgICAgdXBkYXRlWydhdXRoRGF0YSddW3Byb3ZpZGVyXSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHVwZGF0ZSkge1xuICAgICAgY29uc3QgZmllbGRWYWx1ZSA9IHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgLy8gRHJvcCBhbnkgdW5kZWZpbmVkIHZhbHVlcy5cbiAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZGVsZXRlIHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gTlVMTGApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZE5hbWUgPT0gJ2F1dGhEYXRhJykge1xuICAgICAgICAvLyBUaGlzIHJlY3Vyc2l2ZWx5IHNldHMgdGhlIGpzb25fb2JqZWN0XG4gICAgICAgIC8vIE9ubHkgMSBsZXZlbCBkZWVwXG4gICAgICAgIGNvbnN0IGdlbmVyYXRlID0gKGpzb25iOiBzdHJpbmcsIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGBqc29uX29iamVjdF9zZXRfa2V5KENPQUxFU0NFKCR7anNvbmJ9LCAne30nOjpqc29uYiksICR7a2V5fSwgJHt2YWx1ZX0pOjpqc29uYmA7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGxhc3RLZXkgPSBgJCR7aW5kZXh9Om5hbWVgO1xuICAgICAgICBjb25zdCBmaWVsZE5hbWVJbmRleCA9IGluZGV4O1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICBjb25zdCB1cGRhdGUgPSBPYmplY3Qua2V5cyhmaWVsZFZhbHVlKS5yZWR1Y2UoXG4gICAgICAgICAgKGxhc3RLZXk6IHN0cmluZywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IGdlbmVyYXRlKFxuICAgICAgICAgICAgICBsYXN0S2V5LFxuICAgICAgICAgICAgICBgJCR7aW5kZXh9Ojp0ZXh0YCxcbiAgICAgICAgICAgICAgYCQke2luZGV4ICsgMX06Ompzb25iYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBmaWVsZFZhbHVlW2tleV07XG4gICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgaWYgKHZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYXN0S2V5XG4gICAgICAgICk7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2ZpZWxkTmFtZUluZGV4fTpuYW1lID0gJHt1cGRhdGV9YCk7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX19vcCA9PT0gJ0luY3JlbWVudCcpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChcbiAgICAgICAgICBgJCR7aW5kZXh9Om5hbWUgPSBDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgMCkgKyAkJHtpbmRleCArIDF9YFxuICAgICAgICApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuYW1vdW50KTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnQWRkJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9IGFycmF5X2FkZChDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ1tdJzo6anNvbmIpLCAkJHtcbiAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgIH06Ompzb25iKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLm9iamVjdHMpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBudWxsKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnUmVtb3ZlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9IGFycmF5X3JlbW92ZShDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ1tdJzo6anNvbmIpLCAkJHtcbiAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgIH06Ompzb25iKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLm9iamVjdHMpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnQWRkVW5pcXVlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9IGFycmF5X2FkZF91bmlxdWUoQ09BTEVTQ0UoJCR7aW5kZXh9Om5hbWUsICdbXSc6Ompzb25iKSwgJCR7XG4gICAgICAgICAgICBpbmRleCArIDFcbiAgICAgICAgICB9Ojpqc29uYilgXG4gICAgICAgICk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZS5vYmplY3RzKSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkTmFtZSA9PT0gJ3VwZGF0ZWRBdCcpIHtcbiAgICAgICAgLy9UT0RPOiBzdG9wIHNwZWNpYWwgY2FzaW5nIHRoaXMuIEl0IHNob3VsZCBjaGVjayBmb3IgX190eXBlID09PSAnRGF0ZScgYW5kIHVzZSAuaXNvXG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS5vYmplY3RJZCk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnRGF0ZScpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgdG9Qb3N0Z3Jlc1ZhbHVlKGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnRmlsZScpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgdG9Qb3N0Z3Jlc1ZhbHVlKGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChcbiAgICAgICAgICBgJCR7aW5kZXh9Om5hbWUgPSBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtpbmRleCArIDJ9KWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmxvbmdpdHVkZSwgZmllbGRWYWx1ZS5sYXRpdHVkZSk7XG4gICAgICAgIGluZGV4ICs9IDM7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBjb252ZXJ0UG9seWdvblRvU1FMKGZpZWxkVmFsdWUuY29vcmRpbmF0ZXMpO1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX06OnBvbHlnb25gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCB2YWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIC8vIG5vb3BcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIGZpZWxkVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ09iamVjdCdcbiAgICAgICkge1xuICAgICAgICAvLyBHYXRoZXIga2V5cyB0byBpbmNyZW1lbnRcbiAgICAgICAgY29uc3Qga2V5c1RvSW5jcmVtZW50ID0gT2JqZWN0LmtleXMob3JpZ2luYWxVcGRhdGUpXG4gICAgICAgICAgLmZpbHRlcihrID0+IHtcbiAgICAgICAgICAgIC8vIGNob29zZSB0b3AgbGV2ZWwgZmllbGRzIHRoYXQgaGF2ZSBhIGRlbGV0ZSBvcGVyYXRpb24gc2V0XG4gICAgICAgICAgICAvLyBOb3RlIHRoYXQgT2JqZWN0LmtleXMgaXMgaXRlcmF0aW5nIG92ZXIgdGhlICoqb3JpZ2luYWwqKiB1cGRhdGUgb2JqZWN0XG4gICAgICAgICAgICAvLyBhbmQgdGhhdCBzb21lIG9mIHRoZSBrZXlzIG9mIHRoZSBvcmlnaW5hbCB1cGRhdGUgY291bGQgYmUgbnVsbCBvciB1bmRlZmluZWQ6XG4gICAgICAgICAgICAvLyAoU2VlIHRoZSBhYm92ZSBjaGVjayBgaWYgKGZpZWxkVmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIGZpZWxkVmFsdWUgPT0gXCJ1bmRlZmluZWRcIilgKVxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBvcmlnaW5hbFVwZGF0ZVtrXTtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIHZhbHVlICYmXG4gICAgICAgICAgICAgIHZhbHVlLl9fb3AgPT09ICdJbmNyZW1lbnQnICYmXG4gICAgICAgICAgICAgIGsuc3BsaXQoJy4nKS5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgICAgICAgay5zcGxpdCgnLicpWzBdID09PSBmaWVsZE5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAubWFwKGsgPT4gay5zcGxpdCgnLicpWzFdKTtcblxuICAgICAgICBsZXQgaW5jcmVtZW50UGF0dGVybnMgPSAnJztcbiAgICAgICAgaWYgKGtleXNUb0luY3JlbWVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaW5jcmVtZW50UGF0dGVybnMgPVxuICAgICAgICAgICAgJyB8fCAnICtcbiAgICAgICAgICAgIGtleXNUb0luY3JlbWVudFxuICAgICAgICAgICAgICAubWFwKGMgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IGZpZWxkVmFsdWVbY10uYW1vdW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBgQ09OQ0FUKCd7XCIke2N9XCI6JywgQ09BTEVTQ0UoJCR7aW5kZXh9Om5hbWUtPj4nJHtjfScsJzAnKTo6aW50ICsgJHthbW91bnR9LCAnfScpOjpqc29uYmA7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5qb2luKCcgfHwgJyk7XG4gICAgICAgICAgLy8gU3RyaXAgdGhlIGtleXNcbiAgICAgICAgICBrZXlzVG9JbmNyZW1lbnQuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgZGVsZXRlIGZpZWxkVmFsdWVba2V5XTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGtleXNUb0RlbGV0ZTogQXJyYXk8c3RyaW5nPiA9IE9iamVjdC5rZXlzKG9yaWdpbmFsVXBkYXRlKVxuICAgICAgICAgIC5maWx0ZXIoayA9PiB7XG4gICAgICAgICAgICAvLyBjaG9vc2UgdG9wIGxldmVsIGZpZWxkcyB0aGF0IGhhdmUgYSBkZWxldGUgb3BlcmF0aW9uIHNldC5cbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gb3JpZ2luYWxVcGRhdGVba107XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICB2YWx1ZSAmJlxuICAgICAgICAgICAgICB2YWx1ZS5fX29wID09PSAnRGVsZXRlJyAmJlxuICAgICAgICAgICAgICBrLnNwbGl0KCcuJykubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICAgIGsuc3BsaXQoJy4nKVswXSA9PT0gZmllbGROYW1lXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLm1hcChrID0+IGsuc3BsaXQoJy4nKVsxXSk7XG5cbiAgICAgICAgY29uc3QgZGVsZXRlUGF0dGVybnMgPSBrZXlzVG9EZWxldGUucmVkdWNlKFxuICAgICAgICAgIChwOiBzdHJpbmcsIGM6IHN0cmluZywgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcCArIGAgLSAnJCR7aW5kZXggKyAxICsgaX06dmFsdWUnYDtcbiAgICAgICAgICB9LFxuICAgICAgICAgICcnXG4gICAgICAgICk7XG4gICAgICAgIC8vIE92ZXJyaWRlIE9iamVjdFxuICAgICAgICBsZXQgdXBkYXRlT2JqZWN0ID0gXCIne30nOjpqc29uYlwiO1xuXG4gICAgICAgIGlmIChkb3ROb3RhdGlvbk9wdGlvbnNbZmllbGROYW1lXSkge1xuICAgICAgICAgIC8vIE1lcmdlIE9iamVjdFxuICAgICAgICAgIHVwZGF0ZU9iamVjdCA9IGBDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ3t9Jzo6anNvbmIpYDtcbiAgICAgICAgfVxuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9ICgke3VwZGF0ZU9iamVjdH0gJHtkZWxldGVQYXR0ZXJuc30gJHtpbmNyZW1lbnRQYXR0ZXJuc30gfHwgJCR7XG4gICAgICAgICAgICBpbmRleCArIDEgKyBrZXlzVG9EZWxldGUubGVuZ3RoXG4gICAgICAgICAgfTo6anNvbmIgKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCAuLi5rZXlzVG9EZWxldGUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMiArIGtleXNUb0RlbGV0ZS5sZW5ndGg7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUpICYmXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0FycmF5J1xuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSk7XG4gICAgICAgIGlmIChleHBlY3RlZFR5cGUgPT09ICd0ZXh0W10nKSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojp0ZXh0W11gKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZSkpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnKCdOb3Qgc3VwcG9ydGVkIHVwZGF0ZScsIGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB1cGRhdGUgJHtKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlKX0geWV0YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgaW5kZXgsXG4gICAgICBxdWVyeSxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlQ2xhdXNlID1cbiAgICAgIHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IHFzID0gYFVQREFURSAkMTpuYW1lIFNFVCAke3VwZGF0ZVBhdHRlcm5zLmpvaW4oKX0gJHt3aGVyZUNsYXVzZX0gUkVUVVJOSU5HICpgO1xuICAgIGRlYnVnKCd1cGRhdGU6ICcsIHFzLCB2YWx1ZXMpO1xuICAgIGNvbnN0IHByb21pc2UgPSAodHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgID8gdHJhbnNhY3Rpb25hbFNlc3Npb24udFxuICAgICAgOiB0aGlzLl9jbGllbnRcbiAgICApLmFueShxcywgdmFsdWVzKTtcbiAgICBpZiAodHJhbnNhY3Rpb25hbFNlc3Npb24pIHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLmJhdGNoLnB1c2gocHJvbWlzZSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5LCB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGlzLiBJdCdzIG9ubHkgdXNlZCBmb3IgY29uZmlnIGFuZCBob29rcy5cbiAgdXBzZXJ0T25lT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCd1cHNlcnRPbmVPYmplY3QnLCB7IGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSB9KTtcbiAgICBjb25zdCBjcmVhdGVWYWx1ZSA9IE9iamVjdC5hc3NpZ24oe30sIHF1ZXJ5LCB1cGRhdGUpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZU9iamVjdChcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHNjaGVtYSxcbiAgICAgIGNyZWF0ZVZhbHVlLFxuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICApLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIC8vIGlnbm9yZSBkdXBsaWNhdGUgdmFsdWUgZXJyb3JzIGFzIGl0J3MgdXBzZXJ0XG4gICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZmluZE9uZUFuZFVwZGF0ZShcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBzY2hlbWEsXG4gICAgICAgIHF1ZXJ5LFxuICAgICAgICB1cGRhdGUsXG4gICAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCBjYXNlSW5zZW5zaXRpdmUsIGV4cGxhaW4gfTogUXVlcnlPcHRpb25zXG4gICkge1xuICAgIGRlYnVnKCdmaW5kJywgY2xhc3NOYW1lLCBxdWVyeSwge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgc29ydCxcbiAgICAgIGtleXMsXG4gICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICBleHBsYWluLFxuICAgIH0pO1xuICAgIGNvbnN0IGhhc0xpbWl0ID0gbGltaXQgIT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBoYXNTa2lwID0gc2tpcCAhPT0gdW5kZWZpbmVkO1xuICAgIGxldCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogMixcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICB9KTtcbiAgICB2YWx1ZXMucHVzaCguLi53aGVyZS52YWx1ZXMpO1xuXG4gICAgY29uc3Qgd2hlcmVQYXR0ZXJuID1cbiAgICAgIHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IGxpbWl0UGF0dGVybiA9IGhhc0xpbWl0ID8gYExJTUlUICQke3ZhbHVlcy5sZW5ndGggKyAxfWAgOiAnJztcbiAgICBpZiAoaGFzTGltaXQpIHtcbiAgICAgIHZhbHVlcy5wdXNoKGxpbWl0KTtcbiAgICB9XG4gICAgY29uc3Qgc2tpcFBhdHRlcm4gPSBoYXNTa2lwID8gYE9GRlNFVCAkJHt2YWx1ZXMubGVuZ3RoICsgMX1gIDogJyc7XG4gICAgaWYgKGhhc1NraXApIHtcbiAgICAgIHZhbHVlcy5wdXNoKHNraXApO1xuICAgIH1cblxuICAgIGxldCBzb3J0UGF0dGVybiA9ICcnO1xuICAgIGlmIChzb3J0KSB7XG4gICAgICBjb25zdCBzb3J0Q29weTogYW55ID0gc29ydDtcbiAgICAgIGNvbnN0IHNvcnRpbmcgPSBPYmplY3Qua2V5cyhzb3J0KVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtS2V5ID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoa2V5KS5qb2luKCctPicpO1xuICAgICAgICAgIC8vIFVzaW5nICRpZHggcGF0dGVybiBnaXZlczogIG5vbi1pbnRlZ2VyIGNvbnN0YW50IGluIE9SREVSIEJZXG4gICAgICAgICAgaWYgKHNvcnRDb3B5W2tleV0gPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IEFTQ2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IERFU0NgO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbigpO1xuICAgICAgc29ydFBhdHRlcm4gPVxuICAgICAgICBzb3J0ICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LmtleXMoc29ydCkubGVuZ3RoID4gMFxuICAgICAgICAgID8gYE9SREVSIEJZICR7c29ydGluZ31gXG4gICAgICAgICAgOiAnJztcbiAgICB9XG4gICAgaWYgKHdoZXJlLnNvcnRzICYmIE9iamVjdC5rZXlzKCh3aGVyZS5zb3J0czogYW55KSkubGVuZ3RoID4gMCkge1xuICAgICAgc29ydFBhdHRlcm4gPSBgT1JERVIgQlkgJHt3aGVyZS5zb3J0cy5qb2luKCl9YDtcbiAgICB9XG5cbiAgICBsZXQgY29sdW1ucyA9ICcqJztcbiAgICBpZiAoa2V5cykge1xuICAgICAgLy8gRXhjbHVkZSBlbXB0eSBrZXlzXG4gICAgICAvLyBSZXBsYWNlIEFDTCBieSBpdCdzIGtleXNcbiAgICAgIGtleXMgPSBrZXlzLnJlZHVjZSgobWVtbywga2V5KSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09ICdBQ0wnKSB7XG4gICAgICAgICAgbWVtby5wdXNoKCdfcnBlcm0nKTtcbiAgICAgICAgICBtZW1vLnB1c2goJ193cGVybScpO1xuICAgICAgICB9IGVsc2UgaWYgKGtleS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbWVtby5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9LCBbXSk7XG4gICAgICBjb2x1bW5zID0ga2V5c1xuICAgICAgICAubWFwKChrZXksIGluZGV4KSA9PiB7XG4gICAgICAgICAgaWYgKGtleSA9PT0gJyRzY29yZScpIHtcbiAgICAgICAgICAgIHJldHVybiBgdHNfcmFua19jZCh0b190c3ZlY3RvcigkJHsyfSwgJCR7M306bmFtZSksIHRvX3RzcXVlcnkoJCR7NH0sICQkezV9KSwgMzIpIGFzIHNjb3JlYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGAkJHtpbmRleCArIHZhbHVlcy5sZW5ndGggKyAxfTpuYW1lYDtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oKTtcbiAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoa2V5cyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JpZ2luYWxRdWVyeSA9IGBTRUxFQ1QgJHtjb2x1bW5zfSBGUk9NICQxOm5hbWUgJHt3aGVyZVBhdHRlcm59ICR7c29ydFBhdHRlcm59ICR7bGltaXRQYXR0ZXJufSAke3NraXBQYXR0ZXJufWA7XG4gICAgY29uc3QgcXMgPSBleHBsYWluXG4gICAgICA/IHRoaXMuY3JlYXRlRXhwbGFpbmFibGVRdWVyeShvcmlnaW5hbFF1ZXJ5KVxuICAgICAgOiBvcmlnaW5hbFF1ZXJ5O1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5hbnkocXMsIHZhbHVlcylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFF1ZXJ5IG9uIG5vbiBleGlzdGluZyB0YWJsZSwgZG9uJ3QgY3Jhc2hcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+XG4gICAgICAgICAgdGhpcy5wb3N0Z3Jlc09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gQ29udmVydHMgZnJvbSBhIHBvc3RncmVzLWZvcm1hdCBvYmplY3QgdG8gYSBSRVNULWZvcm1hdCBvYmplY3QuXG4gIC8vIERvZXMgbm90IHN0cmlwIG91dCBhbnl0aGluZyBiYXNlZCBvbiBhIGxhY2sgb2YgYXV0aGVudGljYXRpb24uXG4gIHBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHNjaGVtYTogYW55KSB7XG4gICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicgJiYgb2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdFtmaWVsZE5hbWVdLFxuICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnRhcmdldENsYXNzLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50YXJnZXRDbGFzcyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBvYmplY3RbZmllbGROYW1lXSA9IHtcbiAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgbGF0aXR1ZGU6IG9iamVjdFtmaWVsZE5hbWVdLnksXG4gICAgICAgICAgbG9uZ2l0dWRlOiBvYmplY3RbZmllbGROYW1lXS54LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgbGV0IGNvb3JkcyA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICBjb29yZHMgPSBjb29yZHMuc3Vic3RyKDIsIGNvb3Jkcy5sZW5ndGggLSA0KS5zcGxpdCgnKSwoJyk7XG4gICAgICAgIGNvb3JkcyA9IGNvb3Jkcy5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBwYXJzZUZsb2F0KHBvaW50LnNwbGl0KCcsJylbMV0pLFxuICAgICAgICAgICAgcGFyc2VGbG9hdChwb2ludC5zcGxpdCgnLCcpWzBdKSxcbiAgICAgICAgICBdO1xuICAgICAgICB9KTtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgICAgICAgY29vcmRpbmF0ZXM6IGNvb3JkcyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0ZpbGUnKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ0ZpbGUnLFxuICAgICAgICAgIG5hbWU6IG9iamVjdFtmaWVsZE5hbWVdLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vVE9ETzogcmVtb3ZlIHRoaXMgcmVsaWFuY2Ugb24gdGhlIG1vbmdvIGZvcm1hdC4gREIgYWRhcHRlciBzaG91bGRuJ3Qga25vdyB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiBjcmVhdGVkIGF0IGFuZCBhbnkgb3RoZXIgZGF0ZSBmaWVsZC5cbiAgICBpZiAob2JqZWN0LmNyZWF0ZWRBdCkge1xuICAgICAgb2JqZWN0LmNyZWF0ZWRBdCA9IG9iamVjdC5jcmVhdGVkQXQudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC51cGRhdGVkQXQpIHtcbiAgICAgIG9iamVjdC51cGRhdGVkQXQgPSBvYmplY3QudXBkYXRlZEF0LnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChvYmplY3QuZXhwaXJlc0F0KSB7XG4gICAgICBvYmplY3QuZXhwaXJlc0F0ID0ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBvYmplY3QuZXhwaXJlc0F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAob2JqZWN0Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCkge1xuICAgICAgb2JqZWN0Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdC50b0lTT1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQpIHtcbiAgICAgIG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQudG9JU09TdHJpbmcoKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChvYmplY3QuX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCkge1xuICAgICAgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAob2JqZWN0Ll9wYXNzd29yZF9jaGFuZ2VkX2F0KSB7XG4gICAgICBvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5fcGFzc3dvcmRfY2hhbmdlZF9hdC50b0lTT1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICAgIGlzbzogb2JqZWN0W2ZpZWxkTmFtZV0udG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgdW5pcXVlIGluZGV4LiBVbmlxdWUgaW5kZXhlcyBvbiBudWxsYWJsZSBmaWVsZHMgYXJlIG5vdCBhbGxvd2VkLiBTaW5jZSB3ZSBkb24ndFxuICAvLyBjdXJyZW50bHkga25vdyB3aGljaCBmaWVsZHMgYXJlIG51bGxhYmxlIGFuZCB3aGljaCBhcmVuJ3QsIHdlIGlnbm9yZSB0aGF0IGNyaXRlcmlhLlxuICAvLyBBcyBzdWNoLCB3ZSBzaG91bGRuJ3QgZXhwb3NlIHRoaXMgZnVuY3Rpb24gdG8gdXNlcnMgb2YgcGFyc2UgdW50aWwgd2UgaGF2ZSBhbiBvdXQtb2YtYmFuZFxuICAvLyBXYXkgb2YgZGV0ZXJtaW5pbmcgaWYgYSBmaWVsZCBpcyBudWxsYWJsZS4gVW5kZWZpbmVkIGRvZXNuJ3QgY291bnQgYWdhaW5zdCB1bmlxdWVuZXNzLFxuICAvLyB3aGljaCBpcyB3aHkgd2UgdXNlIHNwYXJzZSBpbmRleGVzLlxuICBhc3luYyBlbnN1cmVVbmlxdWVuZXNzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXVxuICApIHtcbiAgICBjb25zdCBjb25zdHJhaW50TmFtZSA9IGAke2NsYXNzTmFtZX1fdW5pcXVlXyR7ZmllbGROYW1lcy5zb3J0KCkuam9pbignXycpfWA7XG4gICAgY29uc3QgY29uc3RyYWludFBhdHRlcm5zID0gZmllbGROYW1lcy5tYXAoXG4gICAgICAoZmllbGROYW1lLCBpbmRleCkgPT4gYCQke2luZGV4ICsgM306bmFtZWBcbiAgICApO1xuICAgIGNvbnN0IHFzID0gYENSRUFURSBVTklRVUUgSU5ERVggSUYgTk9UIEVYSVNUUyAkMjpuYW1lIE9OICQxOm5hbWUoJHtjb25zdHJhaW50UGF0dGVybnMuam9pbigpfSlgO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5ub25lKHFzLCBbY2xhc3NOYW1lLCBjb25zdHJhaW50TmFtZSwgLi4uZmllbGROYW1lc10pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yICYmXG4gICAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhjb25zdHJhaW50TmFtZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gSW5kZXggYWxyZWFkeSBleGlzdHMuIElnbm9yZSBlcnJvci5cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBlcnJvci5jb2RlID09PSBQb3N0Z3Jlc1VuaXF1ZUluZGV4VmlvbGF0aW9uRXJyb3IgJiZcbiAgICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGNvbnN0cmFpbnROYW1lKVxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBDYXN0IHRoZSBlcnJvciBpbnRvIHRoZSBwcm9wZXIgcGFyc2UgZXJyb3JcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIEV4ZWN1dGVzIGEgY291bnQuXG4gIGFzeW5jIGNvdW50KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHJlYWRQcmVmZXJlbmNlPzogc3RyaW5nLFxuICAgIGVzdGltYXRlPzogYm9vbGVhbiA9IHRydWVcbiAgKSB7XG4gICAgZGVidWcoJ2NvdW50JywgY2xhc3NOYW1lLCBxdWVyeSwgcmVhZFByZWZlcmVuY2UsIGVzdGltYXRlKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogMixcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9XG4gICAgICB3aGVyZS5wYXR0ZXJuLmxlbmd0aCA+IDAgPyBgV0hFUkUgJHt3aGVyZS5wYXR0ZXJufWAgOiAnJztcbiAgICBsZXQgcXMgPSAnJztcblxuICAgIGlmICh3aGVyZS5wYXR0ZXJuLmxlbmd0aCA+IDAgfHwgIWVzdGltYXRlKSB7XG4gICAgICBxcyA9IGBTRUxFQ1QgY291bnQoKikgRlJPTSAkMTpuYW1lICR7d2hlcmVQYXR0ZXJufWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHFzID1cbiAgICAgICAgJ1NFTEVDVCByZWx0dXBsZXMgQVMgYXBwcm94aW1hdGVfcm93X2NvdW50IEZST00gcGdfY2xhc3MgV0hFUkUgcmVsbmFtZSA9ICQxJztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAub25lKHFzLCB2YWx1ZXMsIGEgPT4ge1xuICAgICAgICBpZiAoYS5hcHByb3hpbWF0ZV9yb3dfY291bnQgIT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiArYS5hcHByb3hpbWF0ZV9yb3dfY291bnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICthLmNvdW50O1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBkaXN0aW5jdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICBmaWVsZE5hbWU6IHN0cmluZ1xuICApIHtcbiAgICBkZWJ1ZygnZGlzdGluY3QnLCBjbGFzc05hbWUsIHF1ZXJ5KTtcbiAgICBsZXQgZmllbGQgPSBmaWVsZE5hbWU7XG4gICAgbGV0IGNvbHVtbiA9IGZpZWxkTmFtZTtcbiAgICBjb25zdCBpc05lc3RlZCA9IGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMDtcbiAgICBpZiAoaXNOZXN0ZWQpIHtcbiAgICAgIGZpZWxkID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoZmllbGROYW1lKS5qb2luKCctPicpO1xuICAgICAgY29sdW1uID0gZmllbGROYW1lLnNwbGl0KCcuJylbMF07XG4gICAgfVxuICAgIGNvbnN0IGlzQXJyYXlGaWVsZCA9XG4gICAgICBzY2hlbWEuZmllbGRzICYmXG4gICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnQXJyYXknO1xuICAgIGNvbnN0IGlzUG9pbnRlckZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHMgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB2YWx1ZXMgPSBbZmllbGQsIGNvbHVtbiwgY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogNCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9XG4gICAgICB3aGVyZS5wYXR0ZXJuLmxlbmd0aCA+IDAgPyBgV0hFUkUgJHt3aGVyZS5wYXR0ZXJufWAgOiAnJztcbiAgICBjb25zdCB0cmFuc2Zvcm1lciA9IGlzQXJyYXlGaWVsZCA/ICdqc29uYl9hcnJheV9lbGVtZW50cycgOiAnT04nO1xuICAgIGxldCBxcyA9IGBTRUxFQ1QgRElTVElOQ1QgJHt0cmFuc2Zvcm1lcn0oJDE6bmFtZSkgJDI6bmFtZSBGUk9NICQzOm5hbWUgJHt3aGVyZVBhdHRlcm59YDtcbiAgICBpZiAoaXNOZXN0ZWQpIHtcbiAgICAgIHFzID0gYFNFTEVDVCBESVNUSU5DVCAke3RyYW5zZm9ybWVyfSgkMTpyYXcpICQyOnJhdyBGUk9NICQzOm5hbWUgJHt3aGVyZVBhdHRlcm59YDtcbiAgICB9XG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudFxuICAgICAgLmFueShxcywgdmFsdWVzKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAoIWlzTmVzdGVkKSB7XG4gICAgICAgICAgcmVzdWx0cyA9IHJlc3VsdHMuZmlsdGVyKG9iamVjdCA9PiBvYmplY3RbZmllbGRdICE9PSBudWxsKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICAgIGlmICghaXNQb2ludGVyRmllbGQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdFtmaWVsZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICAgICAgY2xhc3NOYW1lOiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgIG9iamVjdElkOiBvYmplY3RbZmllbGRdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGlsZCA9IGZpZWxkTmFtZS5zcGxpdCgnLicpWzFdO1xuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+IG9iamVjdFtjb2x1bW5dW2NoaWxkXSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PlxuICAgICAgICByZXN1bHRzLm1hcChvYmplY3QgPT5cbiAgICAgICAgICB0aGlzLnBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKVxuICAgICAgICApXG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgYWdncmVnYXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogYW55LFxuICAgIHBpcGVsaW5lOiBhbnksXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgaGludDogP21peGVkLFxuICAgIGV4cGxhaW4/OiBib29sZWFuXG4gICkge1xuICAgIGRlYnVnKCdhZ2dyZWdhdGUnLCBjbGFzc05hbWUsIHBpcGVsaW5lLCByZWFkUHJlZmVyZW5jZSwgaGludCwgZXhwbGFpbik7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZV07XG4gICAgbGV0IGluZGV4OiBudW1iZXIgPSAyO1xuICAgIGxldCBjb2x1bW5zOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBjb3VudEZpZWxkID0gbnVsbDtcbiAgICBsZXQgZ3JvdXBWYWx1ZXMgPSBudWxsO1xuICAgIGxldCB3aGVyZVBhdHRlcm4gPSAnJztcbiAgICBsZXQgbGltaXRQYXR0ZXJuID0gJyc7XG4gICAgbGV0IHNraXBQYXR0ZXJuID0gJyc7XG4gICAgbGV0IHNvcnRQYXR0ZXJuID0gJyc7XG4gICAgbGV0IGdyb3VwUGF0dGVybiA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGlwZWxpbmUubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IHN0YWdlID0gcGlwZWxpbmVbaV07XG4gICAgICBpZiAoc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdGFnZS4kZ3JvdXBbZmllbGRdO1xuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZpZWxkID09PSAnX2lkJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlICE9PSAnJykge1xuICAgICAgICAgICAgY29sdW1ucy5wdXNoKGAkJHtpbmRleH06bmFtZSBBUyBcIm9iamVjdElkXCJgKTtcbiAgICAgICAgICAgIGdyb3VwUGF0dGVybiA9IGBHUk9VUCBCWSAkJHtpbmRleH06bmFtZWA7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaCh0cmFuc2Zvcm1BZ2dyZWdhdGVGaWVsZCh2YWx1ZSkpO1xuICAgICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBmaWVsZCA9PT0gJ19pZCcgJiZcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGggIT09IDBcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGdyb3VwVmFsdWVzID0gdmFsdWU7XG4gICAgICAgICAgICBjb25zdCBncm91cEJ5RmllbGRzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFsaWFzIGluIHZhbHVlKSB7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWVbYWxpYXNdID09PSAnc3RyaW5nJyAmJiB2YWx1ZVthbGlhc10pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSB0cmFuc2Zvcm1BZ2dyZWdhdGVGaWVsZCh2YWx1ZVthbGlhc10pO1xuICAgICAgICAgICAgICAgIGlmICghZ3JvdXBCeUZpZWxkcy5pbmNsdWRlcyhgXCIke3NvdXJjZX1cImApKSB7XG4gICAgICAgICAgICAgICAgICBncm91cEJ5RmllbGRzLnB1c2goYFwiJHtzb3VyY2V9XCJgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goc291cmNlLCBhbGlhcyk7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGAkJHtpbmRleH06bmFtZSBBUyAkJHtpbmRleCArIDF9Om5hbWVgKTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IE9iamVjdC5rZXlzKHZhbHVlW2FsaWFzXSlbMF07XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gdHJhbnNmb3JtQWdncmVnYXRlRmllbGQodmFsdWVbYWxpYXNdW29wZXJhdGlvbl0pO1xuICAgICAgICAgICAgICAgIGlmIChtb25nb0FnZ3JlZ2F0ZVRvUG9zdGdyZXNbb3BlcmF0aW9uXSkge1xuICAgICAgICAgICAgICAgICAgaWYgKCFncm91cEJ5RmllbGRzLmluY2x1ZGVzKGBcIiR7c291cmNlfVwiYCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBCeUZpZWxkcy5wdXNoKGBcIiR7c291cmNlfVwiYCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIGBFWFRSQUNUKCR7XG4gICAgICAgICAgICAgICAgICAgICAgbW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzW29wZXJhdGlvbl1cbiAgICAgICAgICAgICAgICAgICAgfSBGUk9NICQke2luZGV4fTpuYW1lIEFUIFRJTUUgWk9ORSAnVVRDJykgQVMgJCR7XG4gICAgICAgICAgICAgICAgICAgICAgaW5kZXggKyAxXG4gICAgICAgICAgICAgICAgICAgIH06bmFtZWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChzb3VyY2UsIGFsaWFzKTtcbiAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBncm91cFBhdHRlcm4gPSBgR1JPVVAgQlkgJCR7aW5kZXh9OnJhd2A7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChncm91cEJ5RmllbGRzLmpvaW4oKSk7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUuJHN1bSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlLiRzdW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBTVU0oJCR7aW5kZXh9Om5hbWUpIEFTICQke2luZGV4ICsgMX06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRzdW0pLCBmaWVsZCk7XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudEZpZWxkID0gZmllbGQ7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBDT1VOVCgqKSBBUyAkJHtpbmRleH06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1heCkge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1BWCgkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtYXgpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1pbikge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1JTigkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtaW4pLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJGF2Zykge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYEFWRygkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRhdmcpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW5zLnB1c2goJyonKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBpZiAoY29sdW1ucy5pbmNsdWRlcygnKicpKSB7XG4gICAgICAgICAgY29sdW1ucyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJHByb2plY3QpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHN0YWdlLiRwcm9qZWN0W2ZpZWxkXTtcbiAgICAgICAgICBpZiAodmFsdWUgPT09IDEgfHwgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbHVtbnMucHVzaChgJCR7aW5kZXh9Om5hbWVgKTtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5zID0gW107XG4gICAgICAgIGNvbnN0IG9yT3JBbmQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoXG4gICAgICAgICAgc3RhZ2UuJG1hdGNoLFxuICAgICAgICAgICckb3InXG4gICAgICAgIClcbiAgICAgICAgICA/ICcgT1IgJ1xuICAgICAgICAgIDogJyBBTkQgJztcblxuICAgICAgICBpZiAoc3RhZ2UuJG1hdGNoLiRvcikge1xuICAgICAgICAgIGNvbnN0IGNvbGxhcHNlID0ge307XG4gICAgICAgICAgc3RhZ2UuJG1hdGNoLiRvci5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZWxlbWVudCkge1xuICAgICAgICAgICAgICBjb2xsYXBzZVtrZXldID0gZWxlbWVudFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YWdlLiRtYXRjaCA9IGNvbGxhcHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdGFnZS4kbWF0Y2hbZmllbGRdO1xuICAgICAgICAgIGNvbnN0IG1hdGNoUGF0dGVybnMgPSBbXTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3IpLmZvckVhY2goY21wID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZVtjbXBdKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHBnQ29tcGFyYXRvciA9IFBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvcltjbXBdO1xuICAgICAgICAgICAgICBtYXRjaFBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgICAgICAgYCQke2luZGV4fTpuYW1lICR7cGdDb21wYXJhdG9yfSAkJHtpbmRleCArIDF9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZCwgdG9Qb3N0Z3Jlc1ZhbHVlKHZhbHVlW2NtcF0pKTtcbiAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAobWF0Y2hQYXR0ZXJucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAoJHttYXRjaFBhdHRlcm5zLmpvaW4oJyBBTkQgJyl9KWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJlxuICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSAmJlxuICAgICAgICAgICAgbWF0Y2hQYXR0ZXJucy5sZW5ndGggPT09IDBcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZmllbGQsIHZhbHVlKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHdoZXJlUGF0dGVybiA9XG4gICAgICAgICAgcGF0dGVybnMubGVuZ3RoID4gMCA/IGBXSEVSRSAke3BhdHRlcm5zLmpvaW4oYCAke29yT3JBbmR9IGApfWAgOiAnJztcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kbGltaXQpIHtcbiAgICAgICAgbGltaXRQYXR0ZXJuID0gYExJTUlUICQke2luZGV4fWA7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0YWdlLiRsaW1pdCk7XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJHNraXApIHtcbiAgICAgICAgc2tpcFBhdHRlcm4gPSBgT0ZGU0VUICQke2luZGV4fWA7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0YWdlLiRza2lwKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kc29ydCkge1xuICAgICAgICBjb25zdCBzb3J0ID0gc3RhZ2UuJHNvcnQ7XG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhzb3J0KTtcbiAgICAgICAgY29uc3Qgc29ydGluZyA9IGtleXNcbiAgICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lciA9IHNvcnRba2V5XSA9PT0gMSA/ICdBU0MnIDogJ0RFU0MnO1xuICAgICAgICAgICAgY29uc3Qgb3JkZXIgPSBgJCR7aW5kZXh9Om5hbWUgJHt0cmFuc2Zvcm1lcn1gO1xuICAgICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICAgIHJldHVybiBvcmRlcjtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5qb2luKCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKC4uLmtleXMpO1xuICAgICAgICBzb3J0UGF0dGVybiA9XG4gICAgICAgICAgc29ydCAhPT0gdW5kZWZpbmVkICYmIHNvcnRpbmcubGVuZ3RoID4gMCA/IGBPUkRFUiBCWSAke3NvcnRpbmd9YCA6ICcnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChncm91cFBhdHRlcm4pIHtcbiAgICAgIGNvbHVtbnMuZm9yRWFjaCgoZSwgaSwgYSkgPT4ge1xuICAgICAgICBpZiAoZSAmJiBlLnRyaW0oKSA9PT0gJyonKSB7XG4gICAgICAgICAgYVtpXSA9ICcnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFF1ZXJ5ID0gYFNFTEVDVCAke2NvbHVtbnNcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKCl9IEZST00gJDE6bmFtZSAke3doZXJlUGF0dGVybn0gJHtza2lwUGF0dGVybn0gJHtncm91cFBhdHRlcm59ICR7c29ydFBhdHRlcm59ICR7bGltaXRQYXR0ZXJufWA7XG4gICAgY29uc3QgcXMgPSBleHBsYWluXG4gICAgICA/IHRoaXMuY3JlYXRlRXhwbGFpbmFibGVRdWVyeShvcmlnaW5hbFF1ZXJ5KVxuICAgICAgOiBvcmlnaW5hbFF1ZXJ5O1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQuYW55KHFzLCB2YWx1ZXMpLnRoZW4oYSA9PiB7XG4gICAgICBpZiAoZXhwbGFpbikge1xuICAgICAgICByZXR1cm4gYTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhLm1hcChvYmplY3QgPT5cbiAgICAgICAgdGhpcy5wb3N0Z3Jlc09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSlcbiAgICAgICk7XG4gICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCAnb2JqZWN0SWQnKSkge1xuICAgICAgICAgIHJlc3VsdC5vYmplY3RJZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdyb3VwVmFsdWVzKSB7XG4gICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0ge307XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZ3JvdXBWYWx1ZXMpIHtcbiAgICAgICAgICAgIHJlc3VsdC5vYmplY3RJZFtrZXldID0gcmVzdWx0W2tleV07XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0W2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb3VudEZpZWxkKSB7XG4gICAgICAgICAgcmVzdWx0W2NvdW50RmllbGRdID0gcGFyc2VJbnQocmVzdWx0W2NvdW50RmllbGRdLCAxMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBwZXJmb3JtSW5pdGlhbGl6YXRpb24oeyBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzIH06IGFueSkge1xuICAgIC8vIFRPRE86IFRoaXMgbWV0aG9kIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB0byBtYWtlIHByb3BlciB1c2Ugb2YgY29ubmVjdGlvbnMgKEB2aXRhbHktdClcbiAgICBkZWJ1ZygncGVyZm9ybUluaXRpYWxpemF0aW9uJyk7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzLm1hcChzY2hlbWEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVGFibGUoc2NoZW1hLmNsYXNzTmFtZSwgc2NoZW1hKVxuICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBlcnIuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIHx8XG4gICAgICAgICAgICBlcnIuY29kZSA9PT0gUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5zY2hlbWFVcGdyYWRlKHNjaGVtYS5jbGFzc05hbWUsIHNjaGVtYSkpO1xuICAgIH0pO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcylcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudC50eCgncGVyZm9ybS1pbml0aWFsaXphdGlvbicsIHQgPT4ge1xuICAgICAgICAgIHJldHVybiB0LmJhdGNoKFtcbiAgICAgICAgICAgIHQubm9uZShzcWwubWlzYy5qc29uT2JqZWN0U2V0S2V5cyksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmFkZCksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmFkZFVuaXF1ZSksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LnJlbW92ZSksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zQWxsKSxcbiAgICAgICAgICAgIHQubm9uZShzcWwuYXJyYXkuY29udGFpbnNBbGxSZWdleCksXG4gICAgICAgICAgICB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zKSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgIGRlYnVnKGBpbml0aWFsaXphdGlvbkRvbmUgaW4gJHtkYXRhLmR1cmF0aW9ufWApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4ZXMoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgaW5kZXhlczogYW55LFxuICAgIGNvbm46ID9hbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIChjb25uIHx8IHRoaXMuX2NsaWVudCkudHgodCA9PlxuICAgICAgdC5iYXRjaChcbiAgICAgICAgaW5kZXhlcy5tYXAoaSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHQubm9uZSgnQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgJDE6bmFtZSBPTiAkMjpuYW1lICgkMzpuYW1lKScsIFtcbiAgICAgICAgICAgIGkubmFtZSxcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIGkua2V5LFxuICAgICAgICAgIF0pO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVJbmRleGVzSWZOZWVkZWQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgdHlwZTogYW55LFxuICAgIGNvbm46ID9hbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgKFxuICAgICAgY29ubiB8fCB0aGlzLl9jbGllbnRcbiAgICApLm5vbmUoJ0NSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTICQxOm5hbWUgT04gJDI6bmFtZSAoJDM6bmFtZSknLCBbXG4gICAgICBmaWVsZE5hbWUsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0eXBlLFxuICAgIF0pO1xuICB9XG5cbiAgYXN5bmMgZHJvcEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4ZXM6IGFueSwgY29ubjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcXVlcmllcyA9IGluZGV4ZXMubWFwKGkgPT4gKHtcbiAgICAgIHF1ZXJ5OiAnRFJPUCBJTkRFWCAkMTpuYW1lJyxcbiAgICAgIHZhbHVlczogaSxcbiAgICB9KSk7XG4gICAgYXdhaXQgKGNvbm4gfHwgdGhpcy5fY2xpZW50KS50eCh0ID0+XG4gICAgICB0Lm5vbmUodGhpcy5fcGdwLmhlbHBlcnMuY29uY2F0KHF1ZXJpZXMpKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcXMgPSAnU0VMRUNUICogRlJPTSBwZ19pbmRleGVzIFdIRVJFIHRhYmxlbmFtZSA9ICR7Y2xhc3NOYW1lfSc7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5hbnkocXMsIHsgY2xhc3NOYW1lIH0pO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlU2NoZW1hV2l0aEluZGV4ZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gVXNlZCBmb3IgdGVzdGluZyBwdXJwb3Nlc1xuICBhc3luYyB1cGRhdGVFc3RpbWF0ZWRDb3VudChjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQubm9uZSgnQU5BTFlaRSAkMTpuYW1lJywgW2NsYXNzTmFtZV0pO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbmFsU2Vzc2lvbiA9IHt9O1xuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0ID0gdGhpcy5fY2xpZW50LnR4KHQgPT4ge1xuICAgICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi50ID0gdDtcbiAgICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucHJvbWlzZSA9IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICB9KTtcbiAgICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2ggPSBbXTtcbiAgICAgICAgcmVzb2x2ZSh0cmFuc2FjdGlvbmFsU2Vzc2lvbik7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5wcm9taXNlO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2Vzc2lvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzb2x2ZShcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQuYmF0Y2godHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gpXG4gICAgKTtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0O1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2Vzc2lvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0LmNhdGNoKCk7XG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChQcm9taXNlLnJlamVjdCgpKTtcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXNvbHZlKFxuICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24udC5iYXRjaCh0cmFuc2FjdGlvbmFsU2Vzc2lvbi5iYXRjaClcbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBlbnN1cmVJbmRleChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgZmllbGROYW1lczogc3RyaW5nW10sXG4gICAgaW5kZXhOYW1lOiA/c3RyaW5nLFxuICAgIGNhc2VJbnNlbnNpdGl2ZTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIG9wdGlvbnM/OiBPYmplY3QgPSB7fVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGNvbm4gPSBvcHRpb25zLmNvbm4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29ubiA6IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBkZWZhdWx0SW5kZXhOYW1lID0gYHBhcnNlX2RlZmF1bHRfJHtmaWVsZE5hbWVzLnNvcnQoKS5qb2luKCdfJyl9YDtcbiAgICBjb25zdCBpbmRleE5hbWVPcHRpb25zOiBPYmplY3QgPVxuICAgICAgaW5kZXhOYW1lICE9IG51bGwgPyB7IG5hbWU6IGluZGV4TmFtZSB9IDogeyBuYW1lOiBkZWZhdWx0SW5kZXhOYW1lIH07XG4gICAgY29uc3QgY29uc3RyYWludFBhdHRlcm5zID0gY2FzZUluc2Vuc2l0aXZlXG4gICAgICA/IGZpZWxkTmFtZXMubWFwKFxuICAgICAgICAoZmllbGROYW1lLCBpbmRleCkgPT4gYGxvd2VyKCQke2luZGV4ICsgM306bmFtZSkgdmFyY2hhcl9wYXR0ZXJuX29wc2BcbiAgICAgIClcbiAgICAgIDogZmllbGROYW1lcy5tYXAoKGZpZWxkTmFtZSwgaW5kZXgpID0+IGAkJHtpbmRleCArIDN9Om5hbWVgKTtcbiAgICBjb25zdCBxcyA9IGBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyAkMTpuYW1lIE9OICQyOm5hbWUgKCR7Y29uc3RyYWludFBhdHRlcm5zLmpvaW4oKX0pYDtcbiAgICBhd2FpdCBjb25uXG4gICAgICAubm9uZShxcywgW2luZGV4TmFtZU9wdGlvbnMubmFtZSwgY2xhc3NOYW1lLCAuLi5maWVsZE5hbWVzXSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlcnJvci5jb2RlID09PSBQb3N0Z3Jlc0R1cGxpY2F0ZVJlbGF0aW9uRXJyb3IgJiZcbiAgICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGluZGV4TmFtZU9wdGlvbnMubmFtZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gSW5kZXggYWxyZWFkeSBleGlzdHMuIElnbm9yZSBlcnJvci5cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBlcnJvci5jb2RlID09PSBQb3N0Z3Jlc1VuaXF1ZUluZGV4VmlvbGF0aW9uRXJyb3IgJiZcbiAgICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGluZGV4TmFtZU9wdGlvbnMubmFtZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gQ2FzdCB0aGUgZXJyb3IgaW50byB0aGUgcHJvcGVyIHBhcnNlIGVycm9yXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ0EgZHVwbGljYXRlIHZhbHVlIGZvciBhIGZpZWxkIHdpdGggdW5pcXVlIHZhbHVlcyB3YXMgcHJvdmlkZWQnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydFBvbHlnb25Ub1NRTChwb2x5Z29uKSB7XG4gIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgUG9seWdvbiBtdXN0IGhhdmUgYXQgbGVhc3QgMyB2YWx1ZXNgXG4gICAgKTtcbiAgfVxuICBpZiAoXG4gICAgcG9seWdvblswXVswXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzBdIHx8XG4gICAgcG9seWdvblswXVsxXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzFdXG4gICkge1xuICAgIHBvbHlnb24ucHVzaChwb2x5Z29uWzBdKTtcbiAgfVxuICBjb25zdCB1bmlxdWUgPSBwb2x5Z29uLmZpbHRlcigoaXRlbSwgaW5kZXgsIGFyKSA9PiB7XG4gICAgbGV0IGZvdW5kSW5kZXggPSAtMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBwdCA9IGFyW2ldO1xuICAgICAgaWYgKHB0WzBdID09PSBpdGVtWzBdICYmIHB0WzFdID09PSBpdGVtWzFdKSB7XG4gICAgICAgIGZvdW5kSW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kSW5kZXggPT09IGluZGV4O1xuICB9KTtcbiAgaWYgKHVuaXF1ZS5sZW5ndGggPCAzKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgJ0dlb0pTT046IExvb3AgbXVzdCBoYXZlIGF0IGxlYXN0IDMgZGlmZmVyZW50IHZlcnRpY2VzJ1xuICAgICk7XG4gIH1cbiAgY29uc3QgcG9pbnRzID0gcG9seWdvblxuICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBhcnNlRmxvYXQocG9pbnRbMV0pLCBwYXJzZUZsb2F0KHBvaW50WzBdKSk7XG4gICAgICByZXR1cm4gYCgke3BvaW50WzFdfSwgJHtwb2ludFswXX0pYDtcbiAgICB9KVxuICAgIC5qb2luKCcsICcpO1xuICByZXR1cm4gYCgke3BvaW50c30pYDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCkge1xuICBpZiAoIXJlZ2V4LmVuZHNXaXRoKCdcXG4nKSkge1xuICAgIHJlZ2V4ICs9ICdcXG4nO1xuICB9XG5cbiAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIGNvbW1lbnRzXG4gIHJldHVybiAoXG4gICAgcmVnZXhcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSkjLipcXG4vZ2ltLCAnJDEnKVxuICAgICAgLy8gcmVtb3ZlIGxpbmVzIHN0YXJ0aW5nIHdpdGggYSBjb21tZW50XG4gICAgICAucmVwbGFjZSgvXiMuKlxcbi9naW0sICcnKVxuICAgICAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIHdoaXRlc3BhY2VcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSlcXHMrL2dpbSwgJyQxJylcbiAgICAgIC8vIHJlbW92ZSB3aGl0ZXNwYWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBsaW5lXG4gICAgICAucmVwbGFjZSgvXlxccysvLCAnJylcbiAgICAgIC50cmltKClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1JlZ2V4UGF0dGVybihzKSB7XG4gIGlmIChzICYmIHMuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgLy8gcmVnZXggZm9yIHN0YXJ0c1dpdGhcbiAgICByZXR1cm4gJ14nICsgbGl0ZXJhbGl6ZVJlZ2V4UGFydChzLnNsaWNlKDEpKTtcbiAgfSBlbHNlIGlmIChzICYmIHMuZW5kc1dpdGgoJyQnKSkge1xuICAgIC8vIHJlZ2V4IGZvciBlbmRzV2l0aFxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHMuc2xpY2UoMCwgcy5sZW5ndGggLSAxKSkgKyAnJCc7XG4gIH1cblxuICAvLyByZWdleCBmb3IgY29udGFpbnNcbiAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocyk7XG59XG5cbmZ1bmN0aW9uIGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCAhdmFsdWUuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IHZhbHVlLm1hdGNoKC9cXF5cXFxcUS4qXFxcXEUvKTtcbiAgcmV0dXJuICEhbWF0Y2hlcztcbn1cblxuZnVuY3Rpb24gaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSh2YWx1ZXMpIHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0uJHJlZ2V4KTtcbiAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZmlyc3RWYWx1ZXNJc1JlZ2V4O1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDEsIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmIChmaXJzdFZhbHVlc0lzUmVnZXggIT09IGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlc1tpXS4kcmVnZXgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgodmFsdWVzKSB7XG4gIHJldHVybiB2YWx1ZXMuc29tZShmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNTdGFydHNXaXRoUmVnZXgodmFsdWUuJHJlZ2V4KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpIHtcbiAgcmV0dXJuIHJlbWFpbmluZ1xuICAgIC5zcGxpdCgnJylcbiAgICAubWFwKGMgPT4ge1xuICAgICAgY29uc3QgcmVnZXggPSBSZWdFeHAoJ1swLTkgXXxcXFxccHtMfScsICd1Jyk7IC8vIFN1cHBvcnQgYWxsIHVuaWNvZGUgbGV0dGVyIGNoYXJzXG4gICAgICBpZiAoYy5tYXRjaChyZWdleCkgIT09IG51bGwpIHtcbiAgICAgICAgLy8gZG9uJ3QgZXNjYXBlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzXG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfVxuICAgICAgLy8gZXNjYXBlIGV2ZXJ5dGhpbmcgZWxzZSAoc2luZ2xlIHF1b3RlcyB3aXRoIHNpbmdsZSBxdW90ZXMsIGV2ZXJ5dGhpbmcgZWxzZSB3aXRoIGEgYmFja3NsYXNoKVxuICAgICAgcmV0dXJuIGMgPT09IGAnYCA/IGAnJ2AgOiBgXFxcXCR7Y31gO1xuICAgIH0pXG4gICAgLmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBsaXRlcmFsaXplUmVnZXhQYXJ0KHM6IHN0cmluZykge1xuICBjb25zdCBtYXRjaGVyMSA9IC9cXFxcUSgoPyFcXFxcRSkuKilcXFxcRSQvO1xuICBjb25zdCByZXN1bHQxOiBhbnkgPSBzLm1hdGNoKG1hdGNoZXIxKTtcbiAgaWYgKHJlc3VsdDEgJiYgcmVzdWx0MS5sZW5ndGggPiAxICYmIHJlc3VsdDEuaW5kZXggPiAtMSkge1xuICAgIC8vIHByb2Nlc3MgcmVnZXggdGhhdCBoYXMgYSBiZWdpbm5pbmcgYW5kIGFuIGVuZCBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgICBjb25zdCBwcmVmaXggPSBzLnN1YnN0cigwLCByZXN1bHQxLmluZGV4KTtcbiAgICBjb25zdCByZW1haW5pbmcgPSByZXN1bHQxWzFdO1xuXG4gICAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocHJlZml4KSArIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpO1xuICB9XG5cbiAgLy8gcHJvY2VzcyByZWdleCB0aGF0IGhhcyBhIGJlZ2lubmluZyBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgY29uc3QgbWF0Y2hlcjIgPSAvXFxcXFEoKD8hXFxcXEUpLiopJC87XG4gIGNvbnN0IHJlc3VsdDI6IGFueSA9IHMubWF0Y2gobWF0Y2hlcjIpO1xuICBpZiAocmVzdWx0MiAmJiByZXN1bHQyLmxlbmd0aCA+IDEgJiYgcmVzdWx0Mi5pbmRleCA+IC0xKSB7XG4gICAgY29uc3QgcHJlZml4ID0gcy5zdWJzdHIoMCwgcmVzdWx0Mi5pbmRleCk7XG4gICAgY29uc3QgcmVtYWluaW5nID0gcmVzdWx0MlsxXTtcblxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHByZWZpeCkgKyBjcmVhdGVMaXRlcmFsUmVnZXgocmVtYWluaW5nKTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBhbGwgaW5zdGFuY2VzIG9mIFxcUSBhbmQgXFxFIGZyb20gdGhlIHJlbWFpbmluZyB0ZXh0ICYgZXNjYXBlIHNpbmdsZSBxdW90ZXNcbiAgcmV0dXJuIHNcbiAgICAucmVwbGFjZSgvKFteXFxcXF0pKFxcXFxFKS8sICckMScpXG4gICAgLnJlcGxhY2UoLyhbXlxcXFxdKShcXFxcUSkvLCAnJDEnKVxuICAgIC5yZXBsYWNlKC9eXFxcXEUvLCAnJylcbiAgICAucmVwbGFjZSgvXlxcXFxRLywgJycpXG4gICAgLnJlcGxhY2UoLyhbXiddKScvLCBgJDEnJ2ApXG4gICAgLnJlcGxhY2UoL14nKFteJ10pLywgYCcnJDFgKTtcbn1cblxudmFyIEdlb1BvaW50Q29kZXIgPSB7XG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnXG4gICAgKTtcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFBvc3RncmVzU3RvcmFnZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql b/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql deleted file mode 100644 index aad90d45f5..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_add_unique( - "array" jsonb, - "values" jsonb -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT array_to_json(ARRAY(SELECT DISTINCT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT DISTINCT jsonb_array_elements("values")))))::jsonb; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/add.sql b/lib/Adapters/Storage/Postgres/sql/array/add.sql deleted file mode 100644 index a0b5859908..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/add.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_add( - "array" jsonb, - "values" jsonb -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT array_to_json(ARRAY(SELECT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT jsonb_array_elements("values")))))::jsonb; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql deleted file mode 100644 index 7ca5853a9f..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE OR REPLACE FUNCTION array_contains_all_regex( - "array" jsonb, - "values" jsonb -) - RETURNS boolean - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT CASE - WHEN 0 = jsonb_array_length("values") THEN true = false - ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt LIKE ANY (SELECT jsonb_array_elements_text("values"))) as RES) - END; -$function$; \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql deleted file mode 100644 index 8db1ca0e7b..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE OR REPLACE FUNCTION array_contains_all( - "array" jsonb, - "values" jsonb -) - RETURNS boolean - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT CASE - WHEN 0 = jsonb_array_length("values") THEN true = false - ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt IN (SELECT jsonb_array_elements_text("values"))) as RES) - END; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains.sql b/lib/Adapters/Storage/Postgres/sql/array/contains.sql deleted file mode 100644 index f7c458782e..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/contains.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_contains( - "array" jsonb, - "values" jsonb -) - RETURNS boolean - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT RES.CNT >= 1 FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements("array") as elt WHERE elt IN (SELECT jsonb_array_elements("values"))) as RES; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/remove.sql b/lib/Adapters/Storage/Postgres/sql/array/remove.sql deleted file mode 100644 index 52895d2f46..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/remove.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_remove( - "array" jsonb, - "values" jsonb -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT array_to_json(ARRAY(SELECT * FROM jsonb_array_elements("array") as elt WHERE elt NOT IN (SELECT * FROM (SELECT jsonb_array_elements("values")) AS sub)))::jsonb; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/index.js b/lib/Adapters/Storage/Postgres/sql/index.js deleted file mode 100644 index 2fc76f3ab1..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/index.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -var QueryFile = require('pg-promise').QueryFile; - -var path = require('path'); - -module.exports = { - array: { - add: sql('array/add.sql'), - addUnique: sql('array/add-unique.sql'), - contains: sql('array/contains.sql'), - containsAll: sql('array/contains-all.sql'), - containsAllRegex: sql('array/contains-all-regex.sql'), - remove: sql('array/remove.sql') - }, - misc: { - jsonObjectSetKeys: sql('misc/json-object-set-keys.sql') - } -}; /////////////////////////////////////////////// -// Helper for linking to external query files; - -function sql(file) { - var fullPath = path.join(__dirname, file); // generating full path; - - var qf = new QueryFile(fullPath, { - minify: true - }); - - if (qf.error) { - throw qf.error; - } - - return qf; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL3NxbC9pbmRleC5qcyJdLCJuYW1lcyI6WyJRdWVyeUZpbGUiLCJyZXF1aXJlIiwicGF0aCIsIm1vZHVsZSIsImV4cG9ydHMiLCJhcnJheSIsImFkZCIsInNxbCIsImFkZFVuaXF1ZSIsImNvbnRhaW5zIiwiY29udGFpbnNBbGwiLCJjb250YWluc0FsbFJlZ2V4IiwicmVtb3ZlIiwibWlzYyIsImpzb25PYmplY3RTZXRLZXlzIiwiZmlsZSIsImZ1bGxQYXRoIiwiam9pbiIsIl9fZGlybmFtZSIsInFmIiwibWluaWZ5IiwiZXJyb3IiXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBLElBQUlBLFNBQVMsR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsU0FBdEM7O0FBQ0EsSUFBSUUsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFsQjs7QUFFQUUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZDLEVBQUFBLEtBQUssRUFBRTtBQUNMQyxJQUFBQSxHQUFHLEVBQUVDLEdBQUcsQ0FBQyxlQUFELENBREg7QUFFTEMsSUFBQUEsU0FBUyxFQUFFRCxHQUFHLENBQUMsc0JBQUQsQ0FGVDtBQUdMRSxJQUFBQSxRQUFRLEVBQUVGLEdBQUcsQ0FBQyxvQkFBRCxDQUhSO0FBSUxHLElBQUFBLFdBQVcsRUFBRUgsR0FBRyxDQUFDLHdCQUFELENBSlg7QUFLTEksSUFBQUEsZ0JBQWdCLEVBQUVKLEdBQUcsQ0FBQyw4QkFBRCxDQUxoQjtBQU1MSyxJQUFBQSxNQUFNLEVBQUVMLEdBQUcsQ0FBQyxrQkFBRDtBQU5OLEdBRFE7QUFTZk0sRUFBQUEsSUFBSSxFQUFFO0FBQ0pDLElBQUFBLGlCQUFpQixFQUFFUCxHQUFHLENBQUMsK0JBQUQ7QUFEbEI7QUFUUyxDQUFqQixDLENBY0E7QUFDQTs7QUFDQSxTQUFTQSxHQUFULENBQWFRLElBQWIsRUFBbUI7QUFDakIsTUFBSUMsUUFBUSxHQUFHZCxJQUFJLENBQUNlLElBQUwsQ0FBVUMsU0FBVixFQUFxQkgsSUFBckIsQ0FBZixDQURpQixDQUMwQjs7QUFFM0MsTUFBSUksRUFBRSxHQUFHLElBQUluQixTQUFKLENBQWNnQixRQUFkLEVBQXdCO0FBQUVJLElBQUFBLE1BQU0sRUFBRTtBQUFWLEdBQXhCLENBQVQ7O0FBRUEsTUFBSUQsRUFBRSxDQUFDRSxLQUFQLEVBQWM7QUFDWixVQUFNRixFQUFFLENBQUNFLEtBQVQ7QUFDRDs7QUFFRCxTQUFPRixFQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBRdWVyeUZpbGUgPSByZXF1aXJlKCdwZy1wcm9taXNlJykuUXVlcnlGaWxlO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhcnJheToge1xuICAgIGFkZDogc3FsKCdhcnJheS9hZGQuc3FsJyksXG4gICAgYWRkVW5pcXVlOiBzcWwoJ2FycmF5L2FkZC11bmlxdWUuc3FsJyksXG4gICAgY29udGFpbnM6IHNxbCgnYXJyYXkvY29udGFpbnMuc3FsJyksXG4gICAgY29udGFpbnNBbGw6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLnNxbCcpLFxuICAgIGNvbnRhaW5zQWxsUmVnZXg6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLXJlZ2V4LnNxbCcpLFxuICAgIHJlbW92ZTogc3FsKCdhcnJheS9yZW1vdmUuc3FsJyksXG4gIH0sXG4gIG1pc2M6IHtcbiAgICBqc29uT2JqZWN0U2V0S2V5czogc3FsKCdtaXNjL2pzb24tb2JqZWN0LXNldC1rZXlzLnNxbCcpLFxuICB9LFxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEhlbHBlciBmb3IgbGlua2luZyB0byBleHRlcm5hbCBxdWVyeSBmaWxlcztcbmZ1bmN0aW9uIHNxbChmaWxlKSB7XG4gIHZhciBmdWxsUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsIGZpbGUpOyAvLyBnZW5lcmF0aW5nIGZ1bGwgcGF0aDtcblxuICB2YXIgcWYgPSBuZXcgUXVlcnlGaWxlKGZ1bGxQYXRoLCB7IG1pbmlmeTogdHJ1ZSB9KTtcblxuICBpZiAocWYuZXJyb3IpIHtcbiAgICB0aHJvdyBxZi5lcnJvcjtcbiAgfVxuXG4gIHJldHVybiBxZjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql b/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql deleted file mode 100644 index eb28b36928..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql +++ /dev/null @@ -1,19 +0,0 @@ --- Function to set a key on a nested JSON document - -CREATE OR REPLACE FUNCTION json_object_set_key( - "json" jsonb, - key_to_set TEXT, - value_to_set anyelement -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ -SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::jsonb - FROM (SELECT * - FROM jsonb_each("json") - WHERE key <> key_to_set - UNION ALL - SELECT key_to_set, to_json("value_to_set")::jsonb) AS fields -$function$; diff --git a/lib/Adapters/Storage/StorageAdapter.js b/lib/Adapters/Storage/StorageAdapter.js deleted file mode 100644 index 4310b4ffac..0000000000 --- a/lib/Adapters/Storage/StorageAdapter.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSAdapter.js b/lib/Adapters/WebSocketServer/WSAdapter.js deleted file mode 100644 index a586fbcd8a..0000000000 --- a/lib/Adapters/WebSocketServer/WSAdapter.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.WSAdapter = void 0; - -var _WSSAdapter = require("./WSSAdapter"); - -/*eslint no-unused-vars: "off"*/ -const WebSocketServer = require('ws').Server; -/** - * Wrapper for ws node module - */ - - -class WSAdapter extends _WSSAdapter.WSSAdapter { - constructor(options) { - super(options); - this.options = options; - } - - onListen() {} - - onConnection(ws) {} - - onError(error) {} - - start() { - const wss = new WebSocketServer({ - server: this.options.server - }); - wss.on('listening', this.onListen); - wss.on('connection', this.onConnection); - wss.on('error', this.onError); - } - - close() {} - -} - -exports.WSAdapter = WSAdapter; -var _default = WSAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIldlYlNvY2tldFNlcnZlciIsInJlcXVpcmUiLCJTZXJ2ZXIiLCJXU0FkYXB0ZXIiLCJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uRXJyb3IiLCJlcnJvciIsInN0YXJ0Iiwid3NzIiwic2VydmVyIiwib24iLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQURBO0FBRUEsTUFBTUEsZUFBZSxHQUFHQyxPQUFPLENBQUMsSUFBRCxDQUFQLENBQWNDLE1BQXRDO0FBRUE7Ozs7O0FBR08sTUFBTUMsU0FBTixTQUF3QkMsc0JBQXhCLENBQW1DO0FBQ3hDQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBZTtBQUN4QixVQUFNQSxPQUFOO0FBQ0EsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRURDLEVBQUFBLFFBQVEsR0FBRyxDQUFFOztBQUNiQyxFQUFBQSxZQUFZLENBQUNDLEVBQUQsRUFBSyxDQUFFOztBQUNuQkMsRUFBQUEsT0FBTyxDQUFDQyxLQUFELEVBQVEsQ0FBRTs7QUFDakJDLEVBQUFBLEtBQUssR0FBRztBQUNOLFVBQU1DLEdBQUcsR0FBRyxJQUFJYixlQUFKLENBQW9CO0FBQUVjLE1BQUFBLE1BQU0sRUFBRSxLQUFLUixPQUFMLENBQWFRO0FBQXZCLEtBQXBCLENBQVo7QUFDQUQsSUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sV0FBUCxFQUFvQixLQUFLUixRQUF6QjtBQUNBTSxJQUFBQSxHQUFHLENBQUNFLEVBQUosQ0FBTyxZQUFQLEVBQXFCLEtBQUtQLFlBQTFCO0FBQ0FLLElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE9BQVAsRUFBZ0IsS0FBS0wsT0FBckI7QUFDRDs7QUFDRE0sRUFBQUEsS0FBSyxHQUFHLENBQUU7O0FBZjhCOzs7ZUFrQjNCYixTIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuaW1wb3J0IHsgV1NTQWRhcHRlciB9IGZyb20gJy4vV1NTQWRhcHRlcic7XG5jb25zdCBXZWJTb2NrZXRTZXJ2ZXIgPSByZXF1aXJlKCd3cycpLlNlcnZlcjtcblxuLyoqXG4gKiBXcmFwcGVyIGZvciB3cyBub2RlIG1vZHVsZVxuICovXG5leHBvcnQgY2xhc3MgV1NBZGFwdGVyIGV4dGVuZHMgV1NTQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IGFueSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBvbkxpc3RlbigpIHt9XG4gIG9uQ29ubmVjdGlvbih3cykge31cbiAgb25FcnJvcihlcnJvcikge31cbiAgc3RhcnQoKSB7XG4gICAgY29uc3Qgd3NzID0gbmV3IFdlYlNvY2tldFNlcnZlcih7IHNlcnZlcjogdGhpcy5vcHRpb25zLnNlcnZlciB9KTtcbiAgICB3c3Mub24oJ2xpc3RlbmluZycsIHRoaXMub25MaXN0ZW4pO1xuICAgIHdzcy5vbignY29ubmVjdGlvbicsIHRoaXMub25Db25uZWN0aW9uKTtcbiAgICB3c3Mub24oJ2Vycm9yJywgdGhpcy5vbkVycm9yKTtcbiAgfVxuICBjbG9zZSgpIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFdTQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSSAdapter.js b/lib/Adapters/WebSocketServer/WSSAdapter.js deleted file mode 100644 index d3a836e02d..0000000000 --- a/lib/Adapters/WebSocketServer/WSSAdapter.js +++ /dev/null @@ -1,74 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.WSSAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ -// WebSocketServer Adapter -// -// Adapter classes must implement the following functions: -// * onListen() -// * onConnection(ws) -// * onError(error) -// * start() -// * close() -// -// Default is WSAdapter. The above functions will be binded. - -/** - * @module Adapters - */ - -/** - * @interface WSSAdapter - */ -class WSSAdapter { - /** - * @param {Object} options - {http.Server|https.Server} server - */ - constructor(options) { - this.onListen = () => {}; - - this.onConnection = () => {}; - - this.onError = () => {}; - } // /** - // * Emitted when the underlying server has been bound. - // */ - // onListen() {} - // /** - // * Emitted when the handshake is complete. - // * - // * @param {WebSocket} ws - RFC 6455 WebSocket. - // */ - // onConnection(ws) {} - // /** - // * Emitted when error event is called. - // * - // * @param {Error} error - WebSocketServer error - // */ - // onError(error) {} - - /** - * Initialize Connection. - * - * @param {Object} options - */ - - - start(options) {} - /** - * Closes server. - */ - - - close() {} - -} - -exports.WSSAdapter = WSSAdapter; -var _default = WSSAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJvbkVycm9yIiwic3RhcnQiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7QUFHQTs7O0FBR08sTUFBTUEsVUFBTixDQUFpQjtBQUN0Qjs7O0FBR0FDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVO0FBQ25CLFNBQUtDLFFBQUwsR0FBZ0IsTUFBTSxDQUFFLENBQXhCOztBQUNBLFNBQUtDLFlBQUwsR0FBb0IsTUFBTSxDQUFFLENBQTVCOztBQUNBLFNBQUtDLE9BQUwsR0FBZSxNQUFNLENBQUUsQ0FBdkI7QUFDRCxHQVJxQixDQVV0QjtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQUtBQyxFQUFBQSxLQUFLLENBQUNKLE9BQUQsRUFBVSxDQUFFO0FBRWpCOzs7OztBQUdBSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF2Q1k7OztlQTBDVFAsVSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8vIFdlYlNvY2tldFNlcnZlciBBZGFwdGVyXG4vL1xuLy8gQWRhcHRlciBjbGFzc2VzIG11c3QgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuLy8gKiBvbkxpc3RlbigpXG4vLyAqIG9uQ29ubmVjdGlvbih3cylcbi8vICogb25FcnJvcihlcnJvcilcbi8vICogc3RhcnQoKVxuLy8gKiBjbG9zZSgpXG4vL1xuLy8gRGVmYXVsdCBpcyBXU0FkYXB0ZXIuIFRoZSBhYm92ZSBmdW5jdGlvbnMgd2lsbCBiZSBiaW5kZWQuXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgV1NTQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgV1NTQWRhcHRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIHtodHRwLlNlcnZlcnxodHRwcy5TZXJ2ZXJ9IHNlcnZlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHRoaXMub25MaXN0ZW4gPSAoKSA9PiB7fTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbiA9ICgpID0+IHt9O1xuICAgIHRoaXMub25FcnJvciA9ICgpID0+IHt9O1xuICB9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgdW5kZXJseWluZyBzZXJ2ZXIgaGFzIGJlZW4gYm91bmQuXG4gIC8vICAqL1xuICAvLyBvbkxpc3RlbigpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgaGFuZHNoYWtlIGlzIGNvbXBsZXRlLlxuICAvLyAgKlxuICAvLyAgKiBAcGFyYW0ge1dlYlNvY2tldH0gd3MgLSBSRkMgNjQ1NSBXZWJTb2NrZXQuXG4gIC8vICAqL1xuICAvLyBvbkNvbm5lY3Rpb24od3MpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiBlcnJvciBldmVudCBpcyBjYWxsZWQuXG4gIC8vICAqXG4gIC8vICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gV2ViU29ja2V0U2VydmVyIGVycm9yXG4gIC8vICAqL1xuICAvLyBvbkVycm9yKGVycm9yKSB7fVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIENvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqL1xuICBzdGFydChvcHRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgc2VydmVyLlxuICAgKi9cbiAgY2xvc2UoKSB7fVxufVxuXG5leHBvcnQgZGVmYXVsdCBXU1NBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Auth.js b/lib/Auth.js deleted file mode 100644 index 7fe33b66de..0000000000 --- a/lib/Auth.js +++ /dev/null @@ -1,373 +0,0 @@ -"use strict"; - -const cryptoUtils = require('./cryptoUtils'); - -const RestQuery = require('./RestQuery'); - -const Parse = require('parse/node'); // An Auth object tells you who is requesting something and whether -// the master key was used. -// userObject is a Parse.User and can be null if there's no user. - - -function Auth({ - config, - cacheController = undefined, - isMaster = false, - isReadOnly = false, - user, - installationId -}) { - this.config = config; - this.cacheController = cacheController || config && config.cacheController; - this.installationId = installationId; - this.isMaster = isMaster; - this.user = user; - this.isReadOnly = isReadOnly; // Assuming a users roles won't change during a single request, we'll - // only load them once. - - this.userRoles = []; - this.fetchedRoles = false; - this.rolePromise = null; -} // Whether this auth could possibly modify the given user id. -// It still could be forbidden via ACLs even if this returns true. - - -Auth.prototype.isUnauthenticated = function () { - if (this.isMaster) { - return false; - } - - if (this.user) { - return false; - } - - return true; -}; // A helper to get a master-level Auth object - - -function master(config) { - return new Auth({ - config, - isMaster: true - }); -} // A helper to get a master-level Auth object - - -function readOnly(config) { - return new Auth({ - config, - isMaster: true, - isReadOnly: true - }); -} // A helper to get a nobody-level Auth object - - -function nobody(config) { - return new Auth({ - config, - isMaster: false - }); -} // Returns a promise that resolves to an Auth object - - -const getAuthForSessionToken = async function ({ - config, - cacheController, - sessionToken, - installationId -}) { - cacheController = cacheController || config && config.cacheController; - - if (cacheController) { - const userJSON = await cacheController.user.get(sessionToken); - - if (userJSON) { - const cachedUser = Parse.Object.fromJSON(userJSON); - return Promise.resolve(new Auth({ - config, - cacheController, - isMaster: false, - installationId, - user: cachedUser - })); - } - } - - let results; - - if (config) { - const restOptions = { - limit: 1, - include: 'user' - }; - const query = new RestQuery(config, master(config), '_Session', { - sessionToken - }, restOptions); - results = (await query.execute()).results; - } else { - results = (await new Parse.Query(Parse.Session).limit(1).include('user').equalTo('sessionToken', sessionToken).find({ - useMasterKey: true - })).map(obj => obj.toJSON()); - } - - if (results.length !== 1 || !results[0]['user']) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - const now = new Date(), - expiresAt = results[0].expiresAt ? new Date(results[0].expiresAt.iso) : undefined; - - if (expiresAt < now) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.'); - } - - const obj = results[0]['user']; - delete obj.password; - obj['className'] = '_User'; - obj['sessionToken'] = sessionToken; - - if (cacheController) { - cacheController.user.put(sessionToken, obj); - } - - const userObject = Parse.Object.fromJSON(obj); - return new Auth({ - config, - cacheController, - isMaster: false, - installationId, - user: userObject - }); -}; - -var getAuthForLegacySessionToken = function ({ - config, - sessionToken, - installationId -}) { - var restOptions = { - limit: 1 - }; - var query = new RestQuery(config, master(config), '_User', { - sessionToken - }, restOptions); - return query.execute().then(response => { - var results = response.results; - - if (results.length !== 1) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token'); - } - - const obj = results[0]; - obj.className = '_User'; - const userObject = Parse.Object.fromJSON(obj); - return new Auth({ - config, - isMaster: false, - installationId, - user: userObject - }); - }); -}; // Returns a promise that resolves to an array of role names - - -Auth.prototype.getUserRoles = function () { - if (this.isMaster || !this.user) { - return Promise.resolve([]); - } - - if (this.fetchedRoles) { - return Promise.resolve(this.userRoles); - } - - if (this.rolePromise) { - return this.rolePromise; - } - - this.rolePromise = this._loadRoles(); - return this.rolePromise; -}; - -Auth.prototype.getRolesForUser = async function () { - //Stack all Parse.Role - const results = []; - - if (this.config) { - const restWhere = { - users: { - __type: 'Pointer', - className: '_User', - objectId: this.user.id - } - }; - await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); - } else { - await new Parse.Query(Parse.Role).equalTo('users', this.user).each(result => results.push(result.toJSON()), { - useMasterKey: true - }); - } - - return results; -}; // Iterates through the role tree and compiles a user's roles - - -Auth.prototype._loadRoles = async function () { - if (this.cacheController) { - const cachedRoles = await this.cacheController.role.get(this.user.id); - - if (cachedRoles != null) { - this.fetchedRoles = true; - this.userRoles = cachedRoles; - return cachedRoles; - } - } // First get the role ids this user is directly a member of - - - const results = await this.getRolesForUser(); - - if (!results.length) { - this.userRoles = []; - this.fetchedRoles = true; - this.rolePromise = null; - this.cacheRoles(); - return this.userRoles; - } - - const rolesMap = results.reduce((m, r) => { - m.names.push(r.name); - m.ids.push(r.objectId); - return m; - }, { - ids: [], - names: [] - }); // run the recursive finding - - const roleNames = await this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names); - this.userRoles = roleNames.map(r => { - return 'role:' + r; - }); - this.fetchedRoles = true; - this.rolePromise = null; - this.cacheRoles(); - return this.userRoles; -}; - -Auth.prototype.cacheRoles = function () { - if (!this.cacheController) { - return false; - } - - this.cacheController.role.put(this.user.id, Array(...this.userRoles)); - return true; -}; - -Auth.prototype.getRolesByIds = async function (ins) { - const results = []; // Build an OR query across all parentRoles - - if (!this.config) { - await new Parse.Query(Parse.Role).containedIn('roles', ins.map(id => { - const role = new Parse.Object(Parse.Role); - role.id = id; - return role; - })).each(result => results.push(result.toJSON()), { - useMasterKey: true - }); - } else { - const roles = ins.map(id => { - return { - __type: 'Pointer', - className: '_Role', - objectId: id - }; - }); - const restWhere = { - roles: { - $in: roles - } - }; - await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); - } - - return results; -}; // Given a list of roleIds, find all the parent roles, returns a promise with all names - - -Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], queriedRoles = {}) { - const ins = roleIDs.filter(roleID => { - const wasQueried = queriedRoles[roleID] !== true; - queriedRoles[roleID] = true; - return wasQueried; - }); // all roles are accounted for, return the names - - if (ins.length == 0) { - return Promise.resolve([...new Set(names)]); - } - - return this.getRolesByIds(ins).then(results => { - // Nothing found - if (!results.length) { - return Promise.resolve(names); - } // Map the results with all Ids and names - - - const resultMap = results.reduce((memo, role) => { - memo.names.push(role.name); - memo.ids.push(role.objectId); - return memo; - }, { - ids: [], - names: [] - }); // store the new found names - - names = names.concat(resultMap.names); // find the next ones, circular roles will be cut - - return this._getAllRolesNamesForRoleIds(resultMap.ids, names, queriedRoles); - }).then(names => { - return Promise.resolve([...new Set(names)]); - }); -}; - -const createSession = function (config, { - userId, - createdWith, - installationId, - additionalSessionData -}) { - const token = 'r:' + cryptoUtils.newToken(); - const expiresAt = config.generateSessionExpiresAt(); - const sessionData = { - sessionToken: token, - user: { - __type: 'Pointer', - className: '_User', - objectId: userId - }, - createdWith, - restricted: false, - expiresAt: Parse._encode(expiresAt) - }; - - if (installationId) { - sessionData.installationId = installationId; - } - - Object.assign(sessionData, additionalSessionData); // We need to import RestWrite at this point for the cyclic dependency it has to it - - const RestWrite = require('./RestWrite'); - - return { - sessionData, - createSession: () => new RestWrite(config, master(config), '_Session', null, sessionData).execute() - }; -}; - -module.exports = { - Auth, - master, - nobody, - readOnly, - getAuthForSessionToken, - getAuthForLegacySessionToken, - createSession -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BdXRoLmpzIl0sIm5hbWVzIjpbImNyeXB0b1V0aWxzIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlBhcnNlIiwiQXV0aCIsImNvbmZpZyIsImNhY2hlQ29udHJvbGxlciIsInVuZGVmaW5lZCIsImlzTWFzdGVyIiwiaXNSZWFkT25seSIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsInVzZXJSb2xlcyIsImZldGNoZWRSb2xlcyIsInJvbGVQcm9taXNlIiwicHJvdG90eXBlIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJtYXN0ZXIiLCJyZWFkT25seSIsIm5vYm9keSIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJzZXNzaW9uVG9rZW4iLCJ1c2VySlNPTiIsImdldCIsImNhY2hlZFVzZXIiLCJPYmplY3QiLCJmcm9tSlNPTiIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0cyIsInJlc3RPcHRpb25zIiwibGltaXQiLCJpbmNsdWRlIiwicXVlcnkiLCJleGVjdXRlIiwiUXVlcnkiLCJTZXNzaW9uIiwiZXF1YWxUbyIsImZpbmQiLCJ1c2VNYXN0ZXJLZXkiLCJtYXAiLCJvYmoiLCJ0b0pTT04iLCJsZW5ndGgiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIm5vdyIsIkRhdGUiLCJleHBpcmVzQXQiLCJpc28iLCJwYXNzd29yZCIsInB1dCIsInVzZXJPYmplY3QiLCJnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiY2xhc3NOYW1lIiwiZ2V0VXNlclJvbGVzIiwiX2xvYWRSb2xlcyIsImdldFJvbGVzRm9yVXNlciIsInJlc3RXaGVyZSIsInVzZXJzIiwiX190eXBlIiwib2JqZWN0SWQiLCJpZCIsImVhY2giLCJyZXN1bHQiLCJwdXNoIiwiUm9sZSIsImNhY2hlZFJvbGVzIiwicm9sZSIsImNhY2hlUm9sZXMiLCJyb2xlc01hcCIsInJlZHVjZSIsIm0iLCJyIiwibmFtZXMiLCJuYW1lIiwiaWRzIiwicm9sZU5hbWVzIiwiX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzIiwiQXJyYXkiLCJnZXRSb2xlc0J5SWRzIiwiaW5zIiwiY29udGFpbmVkSW4iLCJyb2xlcyIsIiRpbiIsInJvbGVJRHMiLCJxdWVyaWVkUm9sZXMiLCJmaWx0ZXIiLCJyb2xlSUQiLCJ3YXNRdWVyaWVkIiwiU2V0IiwicmVzdWx0TWFwIiwibWVtbyIsImNvbmNhdCIsImNyZWF0ZVNlc3Npb24iLCJ1c2VySWQiLCJjcmVhdGVkV2l0aCIsImFkZGl0aW9uYWxTZXNzaW9uRGF0YSIsInRva2VuIiwibmV3VG9rZW4iLCJnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQiLCJzZXNzaW9uRGF0YSIsInJlc3RyaWN0ZWQiLCJfZW5jb2RlIiwiYXNzaWduIiwiUmVzdFdyaXRlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFNQSxXQUFXLEdBQUdDLE9BQU8sQ0FBQyxlQUFELENBQTNCOztBQUNBLE1BQU1DLFNBQVMsR0FBR0QsT0FBTyxDQUFDLGFBQUQsQ0FBekI7O0FBQ0EsTUFBTUUsS0FBSyxHQUFHRixPQUFPLENBQUMsWUFBRCxDQUFyQixDLENBRUE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTRyxJQUFULENBQWM7QUFDWkMsRUFBQUEsTUFEWTtBQUVaQyxFQUFBQSxlQUFlLEdBQUdDLFNBRk47QUFHWkMsRUFBQUEsUUFBUSxHQUFHLEtBSEM7QUFJWkMsRUFBQUEsVUFBVSxHQUFHLEtBSkQ7QUFLWkMsRUFBQUEsSUFMWTtBQU1aQyxFQUFBQTtBQU5ZLENBQWQsRUFPRztBQUNELE9BQUtOLE1BQUwsR0FBY0EsTUFBZDtBQUNBLE9BQUtDLGVBQUwsR0FBdUJBLGVBQWUsSUFBS0QsTUFBTSxJQUFJQSxNQUFNLENBQUNDLGVBQTVEO0FBQ0EsT0FBS0ssY0FBTCxHQUFzQkEsY0FBdEI7QUFDQSxPQUFLSCxRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLE9BQUtFLElBQUwsR0FBWUEsSUFBWjtBQUNBLE9BQUtELFVBQUwsR0FBa0JB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LGNBQUosRUFBb0I7QUFDbEI0RixJQUFBQSxXQUFXLENBQUM1RixjQUFaLEdBQTZCQSxjQUE3QjtBQUNEOztBQUVEYyxFQUFBQSxNQUFNLENBQUNpRixNQUFQLENBQWNILFdBQWQsRUFBMkJKLHFCQUEzQixFQW5CQSxDQW9CQTs7QUFDQSxRQUFNUSxTQUFTLEdBQUcxRyxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFFQSxTQUFPO0FBQ0xzRyxJQUFBQSxXQURLO0FBRUxQLElBQUFBLGFBQWEsRUFBRSxNQUNiLElBQUlXLFNBQUosQ0FBY3RHLE1BQWQsRUFBc0JZLE1BQU0sQ0FBQ1osTUFBRCxDQUE1QixFQUFzQyxVQUF0QyxFQUFrRCxJQUFsRCxFQUF3RGtHLFdBQXhELEVBQXFFckUsT0FBckU7QUFIRyxHQUFQO0FBS0QsQ0EvQkQ7O0FBaUNBMEUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Z6RyxFQUFBQSxJQURlO0FBRWZhLEVBQUFBLE1BRmU7QUFHZkUsRUFBQUEsTUFIZTtBQUlmRCxFQUFBQSxRQUplO0FBS2ZFLEVBQUFBLHNCQUxlO0FBTWZpQyxFQUFBQSw0QkFOZTtBQU9mMkMsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xuY29uc3QgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi9SZXN0UXVlcnknKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuXG4vLyBBbiBBdXRoIG9iamVjdCB0ZWxscyB5b3Ugd2hvIGlzIHJlcXVlc3Rpbmcgc29tZXRoaW5nIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbi8vIHVzZXJPYmplY3QgaXMgYSBQYXJzZS5Vc2VyIGFuZCBjYW4gYmUgbnVsbCBpZiB0aGVyZSdzIG5vIHVzZXIuXG5mdW5jdGlvbiBBdXRoKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIgPSB1bmRlZmluZWQsXG4gIGlzTWFzdGVyID0gZmFsc2UsXG4gIGlzUmVhZE9ubHkgPSBmYWxzZSxcbiAgdXNlcixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gIHRoaXMuaXNNYXN0ZXIgPSBpc01hc3RlcjtcbiAgdGhpcy51c2VyID0gdXNlcjtcbiAgdGhpcy5pc1JlYWRPbmx5ID0gaXNSZWFkT25seTtcblxuICAvLyBBc3N1bWluZyBhIHVzZXJzIHJvbGVzIHdvbid0IGNoYW5nZSBkdXJpbmcgYSBzaW5nbGUgcmVxdWVzdCwgd2UnbGxcbiAgLy8gb25seSBsb2FkIHRoZW0gb25jZS5cbiAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSBmYWxzZTtcbiAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgdGhpcyBhdXRoIGNvdWxkIHBvc3NpYmx5IG1vZGlmeSB0aGUgZ2l2ZW4gdXNlciBpZC5cbi8vIEl0IHN0aWxsIGNvdWxkIGJlIGZvcmJpZGRlbiB2aWEgQUNMcyBldmVuIGlmIHRoaXMgcmV0dXJucyB0cnVlLlxuQXV0aC5wcm90b3R5cGUuaXNVbmF1dGhlbnRpY2F0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBtYXN0ZXItbGV2ZWwgQXV0aCBvYmplY3RcbmZ1bmN0aW9uIG1hc3Rlcihjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiByZWFkT25seShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSwgaXNSZWFkT25seTogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbm9ib2R5LWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBub2JvZHkoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IGZhbHNlIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEF1dGggb2JqZWN0XG5jb25zdCBnZXRBdXRoRm9yU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIsXG4gIHNlc3Npb25Ub2tlbixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIGNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICBpZiAoY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgdXNlckpTT04gPSBhd2FpdCBjYWNoZUNvbnRyb2xsZXIudXNlci5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlckpTT04pIHtcbiAgICAgIGNvbnN0IGNhY2hlZFVzZXIgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04odXNlckpTT04pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IEF1dGgoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHVzZXI6IGNhY2hlZFVzZXIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGxldCByZXN1bHRzO1xuICBpZiAoY29uZmlnKSB7XG4gICAgY29uc3QgcmVzdE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMSxcbiAgICAgIGluY2x1ZGU6ICd1c2VyJyxcbiAgICB9O1xuXG4gICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIHsgc2Vzc2lvblRva2VuIH0sIHJlc3RPcHRpb25zKTtcbiAgICByZXN1bHRzID0gKGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKSkucmVzdWx0cztcbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzID0gKFxuICAgICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlNlc3Npb24pXG4gICAgICAgIC5saW1pdCgxKVxuICAgICAgICAuaW5jbHVkZSgndXNlcicpXG4gICAgICAgIC5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pXG4gICAgICAgIC5maW5kKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pXG4gICAgKS5tYXAob2JqID0+IG9iai50b0pTT04oKSk7XG4gIH1cblxuICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEgfHwgIXJlc3VsdHNbMF1bJ3VzZXInXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfVxuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLFxuICAgIGV4cGlyZXNBdCA9IHJlc3VsdHNbMF0uZXhwaXJlc0F0ID8gbmV3IERhdGUocmVzdWx0c1swXS5leHBpcmVzQXQuaXNvKSA6IHVuZGVmaW5lZDtcbiAgaWYgKGV4cGlyZXNBdCA8IG5vdykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdTZXNzaW9uIHRva2VuIGlzIGV4cGlyZWQuJyk7XG4gIH1cbiAgY29uc3Qgb2JqID0gcmVzdWx0c1swXVsndXNlciddO1xuICBkZWxldGUgb2JqLnBhc3N3b3JkO1xuICBvYmpbJ2NsYXNzTmFtZSddID0gJ19Vc2VyJztcbiAgb2JqWydzZXNzaW9uVG9rZW4nXSA9IHNlc3Npb25Ub2tlbjtcbiAgaWYgKGNhY2hlQ29udHJvbGxlcikge1xuICAgIGNhY2hlQ29udHJvbGxlci51c2VyLnB1dChzZXNzaW9uVG9rZW4sIG9iaik7XG4gIH1cbiAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICByZXR1cm4gbmV3IEF1dGgoe1xuICAgIGNvbmZpZyxcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIGluc3RhbGxhdGlvbklkLFxuICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gIH0pO1xufTtcblxudmFyIGdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4gPSBmdW5jdGlvbiAoeyBjb25maWcsIHNlc3Npb25Ub2tlbiwgaW5zdGFsbGF0aW9uSWQgfSkge1xuICB2YXIgcmVzdE9wdGlvbnMgPSB7XG4gICAgbGltaXQ6IDEsXG4gIH07XG4gIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBtYXN0ZXIoY29uZmlnKSwgJ19Vc2VyJywgeyBzZXNzaW9uVG9rZW4gfSwgcmVzdE9wdGlvbnMpO1xuICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHZhciByZXN1bHRzID0gcmVzcG9uc2UucmVzdWx0cztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdpbnZhbGlkIGxlZ2FjeSBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IG9iaiA9IHJlc3VsdHNbMF07XG4gICAgb2JqLmNsYXNzTmFtZSA9ICdfVXNlcic7XG4gICAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICAgIHJldHVybiBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByb2xlIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5nZXRVc2VyUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyIHx8ICF0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfVxuICBpZiAodGhpcy5mZXRjaGVkUm9sZXMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMudXNlclJvbGVzKTtcbiAgfVxuICBpZiAodGhpcy5yb2xlUHJvbWlzZSkge1xuICAgIHJldHVybiB0aGlzLnJvbGVQcm9taXNlO1xuICB9XG4gIHRoaXMucm9sZVByb21pc2UgPSB0aGlzLl9sb2FkUm9sZXMoKTtcbiAgcmV0dXJuIHRoaXMucm9sZVByb21pc2U7XG59O1xuXG5BdXRoLnByb3RvdHlwZS5nZXRSb2xlc0ZvclVzZXIgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gIC8vU3RhY2sgYWxsIFBhcnNlLlJvbGVcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICBpZiAodGhpcy5jb25maWcpIHtcbiAgICBjb25zdCByZXN0V2hlcmUgPSB7XG4gICAgICB1c2Vyczoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy51c2VyLmlkLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGF3YWl0IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIG1hc3Rlcih0aGlzLmNvbmZpZyksICdfUm9sZScsIHJlc3RXaGVyZSwge30pLmVhY2gocmVzdWx0ID0+XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuZXF1YWxUbygndXNlcnMnLCB0aGlzLnVzZXIpXG4gICAgICAuZWFjaChyZXN1bHQgPT4gcmVzdWx0cy5wdXNoKHJlc3VsdC50b0pTT04oKSksIHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gSXRlcmF0ZXMgdGhyb3VnaCB0aGUgcm9sZSB0cmVlIGFuZCBjb21waWxlcyBhIHVzZXIncyByb2xlc1xuQXV0aC5wcm90b3R5cGUuX2xvYWRSb2xlcyA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY2FjaGVkUm9sZXMgPSBhd2FpdCB0aGlzLmNhY2hlQ29udHJvbGxlci5yb2xlLmdldCh0aGlzLnVzZXIuaWQpO1xuICAgIGlmIChjYWNoZWRSb2xlcyAhPSBudWxsKSB7XG4gICAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgICB0aGlzLnVzZXJSb2xlcyA9IGNhY2hlZFJvbGVzO1xuICAgICAgcmV0dXJuIGNhY2hlZFJvbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpcnN0IGdldCB0aGUgcm9sZSBpZHMgdGhpcyB1c2VyIGlzIGRpcmVjdGx5IGEgbWVtYmVyIG9mXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmdldFJvbGVzRm9yVXNlcigpO1xuICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG5cbiAgICB0aGlzLmNhY2hlUm9sZXMoKTtcbiAgICByZXR1cm4gdGhpcy51c2VyUm9sZXM7XG4gIH1cblxuICBjb25zdCByb2xlc01hcCA9IHJlc3VsdHMucmVkdWNlKFxuICAgIChtLCByKSA9PiB7XG4gICAgICBtLm5hbWVzLnB1c2goci5uYW1lKTtcbiAgICAgIG0uaWRzLnB1c2goci5vYmplY3RJZCk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9LFxuICAgIHsgaWRzOiBbXSwgbmFtZXM6IFtdIH1cbiAgKTtcblxuICAvLyBydW4gdGhlIHJlY3Vyc2l2ZSBmaW5kaW5nXG4gIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJvbGVzTWFwLmlkcywgcm9sZXNNYXAubmFtZXMpO1xuICB0aGlzLnVzZXJSb2xlcyA9IHJvbGVOYW1lcy5tYXAociA9PiB7XG4gICAgcmV0dXJuICdyb2xlOicgKyByO1xuICB9KTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbiAgdGhpcy5jYWNoZVJvbGVzKCk7XG4gIHJldHVybiB0aGlzLnVzZXJSb2xlcztcbn07XG5cbkF1dGgucHJvdG90eXBlLmNhY2hlUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jYWNoZUNvbnRyb2xsZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdGhpcy5jYWNoZUNvbnRyb2xsZXIucm9sZS5wdXQodGhpcy51c2VyLmlkLCBBcnJheSguLi50aGlzLnVzZXJSb2xlcykpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmdldFJvbGVzQnlJZHMgPSBhc3luYyBmdW5jdGlvbiAoaW5zKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgLy8gQnVpbGQgYW4gT1IgcXVlcnkgYWNyb3NzIGFsbCBwYXJlbnRSb2xlc1xuICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuY29udGFpbmVkSW4oXG4gICAgICAgICdyb2xlcycsXG4gICAgICAgIGlucy5tYXAoaWQgPT4ge1xuICAgICAgICAgIGNvbnN0IHJvbGUgPSBuZXcgUGFyc2UuT2JqZWN0KFBhcnNlLlJvbGUpO1xuICAgICAgICAgIHJvbGUuaWQgPSBpZDtcbiAgICAgICAgICByZXR1cm4gcm9sZTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0LnRvSlNPTigpKSwgeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgcm9sZXMgPSBpbnMubWFwKGlkID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfUm9sZScsXG4gICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgcmVzdFdoZXJlID0geyByb2xlczogeyAkaW46IHJvbGVzIH0gfTtcbiAgICBhd2FpdCBuZXcgUmVzdFF1ZXJ5KHRoaXMuY29uZmlnLCBtYXN0ZXIodGhpcy5jb25maWcpLCAnX1JvbGUnLCByZXN0V2hlcmUsIHt9KS5lYWNoKHJlc3VsdCA9PlxuICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdClcbiAgICApO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gR2l2ZW4gYSBsaXN0IG9mIHJvbGVJZHMsIGZpbmQgYWxsIHRoZSBwYXJlbnQgcm9sZXMsIHJldHVybnMgYSBwcm9taXNlIHdpdGggYWxsIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMgPSBmdW5jdGlvbiAocm9sZUlEcywgbmFtZXMgPSBbXSwgcXVlcmllZFJvbGVzID0ge30pIHtcbiAgY29uc3QgaW5zID0gcm9sZUlEcy5maWx0ZXIocm9sZUlEID0+IHtcbiAgICBjb25zdCB3YXNRdWVyaWVkID0gcXVlcmllZFJvbGVzW3JvbGVJRF0gIT09IHRydWU7XG4gICAgcXVlcmllZFJvbGVzW3JvbGVJRF0gPSB0cnVlO1xuICAgIHJldHVybiB3YXNRdWVyaWVkO1xuICB9KTtcblxuICAvLyBhbGwgcm9sZXMgYXJlIGFjY291bnRlZCBmb3IsIHJldHVybiB0aGUgbmFtZXNcbiAgaWYgKGlucy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoWy4uLm5ldyBTZXQobmFtZXMpXSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5nZXRSb2xlc0J5SWRzKGlucylcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIC8vIE5vdGhpbmcgZm91bmRcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuYW1lcyk7XG4gICAgICB9XG4gICAgICAvLyBNYXAgdGhlIHJlc3VsdHMgd2l0aCBhbGwgSWRzIGFuZCBuYW1lc1xuICAgICAgY29uc3QgcmVzdWx0TWFwID0gcmVzdWx0cy5yZWR1Y2UoXG4gICAgICAgIChtZW1vLCByb2xlKSA9PiB7XG4gICAgICAgICAgbWVtby5uYW1lcy5wdXNoKHJvbGUubmFtZSk7XG4gICAgICAgICAgbWVtby5pZHMucHVzaChyb2xlLm9iamVjdElkKTtcbiAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgfSxcbiAgICAgICAgeyBpZHM6IFtdLCBuYW1lczogW10gfVxuICAgICAgKTtcbiAgICAgIC8vIHN0b3JlIHRoZSBuZXcgZm91bmQgbmFtZXNcbiAgICAgIG5hbWVzID0gbmFtZXMuY29uY2F0KHJlc3VsdE1hcC5uYW1lcyk7XG4gICAgICAvLyBmaW5kIHRoZSBuZXh0IG9uZXMsIGNpcmN1bGFyIHJvbGVzIHdpbGwgYmUgY3V0XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMocmVzdWx0TWFwLmlkcywgbmFtZXMsIHF1ZXJpZWRSb2xlcyk7XG4gICAgfSlcbiAgICAudGhlbihuYW1lcyA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFsuLi5uZXcgU2V0KG5hbWVzKV0pO1xuICAgIH0pO1xufTtcblxuY29uc3QgY3JlYXRlU2Vzc2lvbiA9IGZ1bmN0aW9uIChcbiAgY29uZmlnLFxuICB7IHVzZXJJZCwgY3JlYXRlZFdpdGgsIGluc3RhbGxhdGlvbklkLCBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEgfVxuKSB7XG4gIGNvbnN0IHRva2VuID0gJ3I6JyArIGNyeXB0b1V0aWxzLm5ld1Rva2VuKCk7XG4gIGNvbnN0IGV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKTtcbiAgY29uc3Qgc2Vzc2lvbkRhdGEgPSB7XG4gICAgc2Vzc2lvblRva2VuOiB0b2tlbixcbiAgICB1c2VyOiB7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgIG9iamVjdElkOiB1c2VySWQsXG4gICAgfSxcbiAgICBjcmVhdGVkV2l0aCxcbiAgICByZXN0cmljdGVkOiBmYWxzZSxcbiAgICBleHBpcmVzQXQ6IFBhcnNlLl9lbmNvZGUoZXhwaXJlc0F0KSxcbiAgfTtcblxuICBpZiAoaW5zdGFsbGF0aW9uSWQpIHtcbiAgICBzZXNzaW9uRGF0YS5pbnN0YWxsYXRpb25JZCA9IGluc3RhbGxhdGlvbklkO1xuICB9XG5cbiAgT2JqZWN0LmFzc2lnbihzZXNzaW9uRGF0YSwgYWRkaXRpb25hbFNlc3Npb25EYXRhKTtcbiAgLy8gV2UgbmVlZCB0byBpbXBvcnQgUmVzdFdyaXRlIGF0IHRoaXMgcG9pbnQgZm9yIHRoZSBjeWNsaWMgZGVwZW5kZW5jeSBpdCBoYXMgdG8gaXRcbiAgY29uc3QgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcblxuICByZXR1cm4ge1xuICAgIHNlc3Npb25EYXRhLFxuICAgIGNyZWF0ZVNlc3Npb246ICgpID0+XG4gICAgICBuZXcgUmVzdFdyaXRlKGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIG51bGwsIHNlc3Npb25EYXRhKS5leGVjdXRlKCksXG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQXV0aCxcbiAgbWFzdGVyLFxuICBub2JvZHksXG4gIHJlYWRPbmx5LFxuICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLFxuICBnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuLFxuICBjcmVhdGVTZXNzaW9uLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/ClientSDK.js b/lib/ClientSDK.js deleted file mode 100644 index ed5cf3beab..0000000000 --- a/lib/ClientSDK.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -var semver = require('semver'); - -function compatible(compatibleSDK) { - return function (clientSDK) { - if (typeof clientSDK === 'string') { - clientSDK = fromString(clientSDK); - } // REST API, or custom SDK - - - if (!clientSDK) { - return true; - } - - const clientVersion = clientSDK.version; - const compatiblityVersion = compatibleSDK[clientSDK.sdk]; - return semver.satisfies(clientVersion, compatiblityVersion); - }; -} - -function supportsForwardDelete(clientSDK) { - return compatible({ - js: '>=1.9.0' - })(clientSDK); -} - -function fromString(version) { - const versionRE = /([-a-zA-Z]+)([0-9\.]+)/; - const match = version.toLowerCase().match(versionRE); - - if (match && match.length === 3) { - return { - sdk: match[1], - version: match[2] - }; - } - - return undefined; -} - -module.exports = { - compatible, - supportsForwardDelete, - fromString -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9DbGllbnRTREsuanMiXSwibmFtZXMiOlsic2VtdmVyIiwicmVxdWlyZSIsImNvbXBhdGlibGUiLCJjb21wYXRpYmxlU0RLIiwiY2xpZW50U0RLIiwiZnJvbVN0cmluZyIsImNsaWVudFZlcnNpb24iLCJ2ZXJzaW9uIiwiY29tcGF0aWJsaXR5VmVyc2lvbiIsInNkayIsInNhdGlzZmllcyIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImpzIiwidmVyc2lvblJFIiwibWF0Y2giLCJ0b0xvd2VyQ2FzZSIsImxlbmd0aCIsInVuZGVmaW5lZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBSUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsUUFBRCxDQUFwQjs7QUFFQSxTQUFTQyxVQUFULENBQW9CQyxhQUFwQixFQUFtQztBQUNqQyxTQUFPLFVBQVVDLFNBQVYsRUFBcUI7QUFDMUIsUUFBSSxPQUFPQSxTQUFQLEtBQXFCLFFBQXpCLEVBQW1DO0FBQ2pDQSxNQUFBQSxTQUFTLEdBQUdDLFVBQVUsQ0FBQ0QsU0FBRCxDQUF0QjtBQUNELEtBSHlCLENBSTFCOzs7QUFDQSxRQUFJLENBQUNBLFNBQUwsRUFBZ0I7QUFDZCxhQUFPLElBQVA7QUFDRDs7QUFDRCxVQUFNRSxhQUFhLEdBQUdGLFNBQVMsQ0FBQ0csT0FBaEM7QUFDQSxVQUFNQyxtQkFBbUIsR0FBR0wsYUFBYSxDQUFDQyxTQUFTLENBQUNLLEdBQVgsQ0FBekM7QUFDQSxXQUFPVCxNQUFNLENBQUNVLFNBQVAsQ0FBaUJKLGFBQWpCLEVBQWdDRSxtQkFBaEMsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTRyxxQkFBVCxDQUErQlAsU0FBL0IsRUFBMEM7QUFDeEMsU0FBT0YsVUFBVSxDQUFDO0FBQ2hCVSxJQUFBQSxFQUFFLEVBQUU7QUFEWSxHQUFELENBQVYsQ0FFSlIsU0FGSSxDQUFQO0FBR0Q7O0FBRUQsU0FBU0MsVUFBVCxDQUFvQkUsT0FBcEIsRUFBNkI7QUFDM0IsUUFBTU0sU0FBUyxHQUFHLHdCQUFsQjtBQUNBLFFBQU1DLEtBQUssR0FBR1AsT0FBTyxDQUFDUSxXQUFSLEdBQXNCRCxLQUF0QixDQUE0QkQsU0FBNUIsQ0FBZDs7QUFDQSxNQUFJQyxLQUFLLElBQUlBLEtBQUssQ0FBQ0UsTUFBTixLQUFpQixDQUE5QixFQUFpQztBQUMvQixXQUFPO0FBQ0xQLE1BQUFBLEdBQUcsRUFBRUssS0FBSyxDQUFDLENBQUQsQ0FETDtBQUVMUCxNQUFBQSxPQUFPLEVBQUVPLEtBQUssQ0FBQyxDQUFEO0FBRlQsS0FBUDtBQUlEOztBQUNELFNBQU9HLFNBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZqQixFQUFBQSxVQURlO0FBRWZTLEVBQUFBLHFCQUZlO0FBR2ZOLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgc2VtdmVyID0gcmVxdWlyZSgnc2VtdmVyJyk7XG5cbmZ1bmN0aW9uIGNvbXBhdGlibGUoY29tcGF0aWJsZVNESykge1xuICByZXR1cm4gZnVuY3Rpb24gKGNsaWVudFNESykge1xuICAgIGlmICh0eXBlb2YgY2xpZW50U0RLID09PSAnc3RyaW5nJykge1xuICAgICAgY2xpZW50U0RLID0gZnJvbVN0cmluZyhjbGllbnRTREspO1xuICAgIH1cbiAgICAvLyBSRVNUIEFQSSwgb3IgY3VzdG9tIFNES1xuICAgIGlmICghY2xpZW50U0RLKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50VmVyc2lvbiA9IGNsaWVudFNESy52ZXJzaW9uO1xuICAgIGNvbnN0IGNvbXBhdGlibGl0eVZlcnNpb24gPSBjb21wYXRpYmxlU0RLW2NsaWVudFNESy5zZGtdO1xuICAgIHJldHVybiBzZW12ZXIuc2F0aXNmaWVzKGNsaWVudFZlcnNpb24sIGNvbXBhdGlibGl0eVZlcnNpb24pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c0ZvcndhcmREZWxldGUoY2xpZW50U0RLKSB7XG4gIHJldHVybiBjb21wYXRpYmxlKHtcbiAgICBqczogJz49MS45LjAnLFxuICB9KShjbGllbnRTREspO1xufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHZlcnNpb24pIHtcbiAgY29uc3QgdmVyc2lvblJFID0gLyhbLWEtekEtWl0rKShbMC05XFwuXSspLztcbiAgY29uc3QgbWF0Y2ggPSB2ZXJzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2godmVyc2lvblJFKTtcbiAgaWYgKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA9PT0gMykge1xuICAgIHJldHVybiB7XG4gICAgICBzZGs6IG1hdGNoWzFdLFxuICAgICAgdmVyc2lvbjogbWF0Y2hbMl0sXG4gICAgfTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tcGF0aWJsZSxcbiAgc3VwcG9ydHNGb3J3YXJkRGVsZXRlLFxuICBmcm9tU3RyaW5nLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Config.js b/lib/Config.js deleted file mode 100644 index 9efd47eaec..0000000000 --- a/lib/Config.js +++ /dev/null @@ -1,348 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.Config = void 0; - -var _cache = _interopRequireDefault(require("./cache")); - -var _SchemaCache = _interopRequireDefault(require("./Controllers/SchemaCache")); - -var _DatabaseController = _interopRequireDefault(require("./Controllers/DatabaseController")); - -var _net = _interopRequireDefault(require("net")); - -var _Definitions = require("./Options/Definitions"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// A Config object provides information about how a specific app is -// configured. -// mount is the URL for the root of the API; includes http, domain, etc. -function removeTrailingSlash(str) { - if (!str) { - return str; - } - - if (str.endsWith('/')) { - str = str.substr(0, str.length - 1); - } - - return str; -} - -class Config { - static get(applicationId, mount) { - const cacheInfo = _cache.default.get(applicationId); - - if (!cacheInfo) { - return; - } - - const config = new Config(); - config.applicationId = applicationId; - Object.keys(cacheInfo).forEach(key => { - if (key == 'databaseController') { - const schemaCache = new _SchemaCache.default(cacheInfo.cacheController, cacheInfo.schemaCacheTTL, cacheInfo.enableSingleSchemaCache); - config.database = new _DatabaseController.default(cacheInfo.databaseController.adapter, schemaCache); - } else { - config[key] = cacheInfo[key]; - } - }); - config.mount = removeTrailingSlash(mount); - config.generateSessionExpiresAt = config.generateSessionExpiresAt.bind(config); - config.generateEmailVerifyTokenExpiresAt = config.generateEmailVerifyTokenExpiresAt.bind(config); - return config; - } - - static put(serverConfiguration) { - Config.validate(serverConfiguration); - - _cache.default.put(serverConfiguration.appId, serverConfiguration); - - Config.setupPasswordValidator(serverConfiguration.passwordPolicy); - return serverConfiguration; - } - - static validate({ - verifyUserEmails, - userController, - appName, - publicServerURL, - revokeSessionOnPasswordReset, - expireInactiveSessions, - sessionLength, - maxLimit, - emailVerifyTokenValidityDuration, - accountLockout, - passwordPolicy, - masterKeyIps, - masterKey, - readOnlyMasterKey, - allowHeaders, - idempotencyOptions - }) { - if (masterKey === readOnlyMasterKey) { - throw new Error('masterKey and readOnlyMasterKey should be different'); - } - - const emailAdapter = userController.adapter; - - if (verifyUserEmails) { - this.validateEmailConfiguration({ - emailAdapter, - appName, - publicServerURL, - emailVerifyTokenValidityDuration - }); - } - - this.validateAccountLockoutPolicy(accountLockout); - this.validatePasswordPolicy(passwordPolicy); - - if (typeof revokeSessionOnPasswordReset !== 'boolean') { - throw 'revokeSessionOnPasswordReset must be a boolean value'; - } - - if (publicServerURL) { - if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) { - throw 'publicServerURL should be a valid HTTPS URL starting with https://'; - } - } - - this.validateSessionConfiguration(sessionLength, expireInactiveSessions); - this.validateMasterKeyIps(masterKeyIps); - this.validateMaxLimit(maxLimit); - this.validateAllowHeaders(allowHeaders); - this.validateIdempotencyOptions(idempotencyOptions); - } - - static validateIdempotencyOptions(idempotencyOptions) { - if (!idempotencyOptions) { - return; - } - - if (idempotencyOptions.ttl === undefined) { - idempotencyOptions.ttl = _Definitions.IdempotencyOptions.ttl.default; - } else if (!isNaN(idempotencyOptions.ttl) && idempotencyOptions.ttl <= 0) { - throw 'idempotency TTL value must be greater than 0 seconds'; - } else if (isNaN(idempotencyOptions.ttl)) { - throw 'idempotency TTL value must be a number'; - } - - if (!idempotencyOptions.paths) { - idempotencyOptions.paths = _Definitions.IdempotencyOptions.paths.default; - } else if (!(idempotencyOptions.paths instanceof Array)) { - throw 'idempotency paths must be of an array of strings'; - } - } - - static validateAccountLockoutPolicy(accountLockout) { - if (accountLockout) { - if (typeof accountLockout.duration !== 'number' || accountLockout.duration <= 0 || accountLockout.duration > 99999) { - throw 'Account lockout duration should be greater than 0 and less than 100000'; - } - - if (!Number.isInteger(accountLockout.threshold) || accountLockout.threshold < 1 || accountLockout.threshold > 999) { - throw 'Account lockout threshold should be an integer greater than 0 and less than 1000'; - } - } - } - - static validatePasswordPolicy(passwordPolicy) { - if (passwordPolicy) { - if (passwordPolicy.maxPasswordAge !== undefined && (typeof passwordPolicy.maxPasswordAge !== 'number' || passwordPolicy.maxPasswordAge < 0)) { - throw 'passwordPolicy.maxPasswordAge must be a positive number'; - } - - if (passwordPolicy.resetTokenValidityDuration !== undefined && (typeof passwordPolicy.resetTokenValidityDuration !== 'number' || passwordPolicy.resetTokenValidityDuration <= 0)) { - throw 'passwordPolicy.resetTokenValidityDuration must be a positive number'; - } - - if (passwordPolicy.validatorPattern) { - if (typeof passwordPolicy.validatorPattern === 'string') { - passwordPolicy.validatorPattern = new RegExp(passwordPolicy.validatorPattern); - } else if (!(passwordPolicy.validatorPattern instanceof RegExp)) { - throw 'passwordPolicy.validatorPattern must be a regex string or RegExp object.'; - } - } - - if (passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') { - throw 'passwordPolicy.validatorCallback must be a function.'; - } - - if (passwordPolicy.doNotAllowUsername && typeof passwordPolicy.doNotAllowUsername !== 'boolean') { - throw 'passwordPolicy.doNotAllowUsername must be a boolean value.'; - } - - if (passwordPolicy.maxPasswordHistory && (!Number.isInteger(passwordPolicy.maxPasswordHistory) || passwordPolicy.maxPasswordHistory <= 0 || passwordPolicy.maxPasswordHistory > 20)) { - throw 'passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20'; - } - } - } // if the passwordPolicy.validatorPattern is configured then setup a callback to process the pattern - - - static setupPasswordValidator(passwordPolicy) { - if (passwordPolicy && passwordPolicy.validatorPattern) { - passwordPolicy.patternValidator = value => { - return passwordPolicy.validatorPattern.test(value); - }; - } - } - - static validateEmailConfiguration({ - emailAdapter, - appName, - publicServerURL, - emailVerifyTokenValidityDuration - }) { - if (!emailAdapter) { - throw 'An emailAdapter is required for e-mail verification and password resets.'; - } - - if (typeof appName !== 'string') { - throw 'An app name is required for e-mail verification and password resets.'; - } - - if (typeof publicServerURL !== 'string') { - throw 'A public server url is required for e-mail verification and password resets.'; - } - - if (emailVerifyTokenValidityDuration) { - if (isNaN(emailVerifyTokenValidityDuration)) { - throw 'Email verify token validity duration must be a valid number.'; - } else if (emailVerifyTokenValidityDuration <= 0) { - throw 'Email verify token validity duration must be a value greater than 0.'; - } - } - } - - static validateMasterKeyIps(masterKeyIps) { - for (const ip of masterKeyIps) { - if (!_net.default.isIP(ip)) { - throw `Invalid ip in masterKeyIps: ${ip}`; - } - } - } - - get mount() { - var mount = this._mount; - - if (this.publicServerURL) { - mount = this.publicServerURL; - } - - return mount; - } - - set mount(newValue) { - this._mount = newValue; - } - - static validateSessionConfiguration(sessionLength, expireInactiveSessions) { - if (expireInactiveSessions) { - if (isNaN(sessionLength)) { - throw 'Session length must be a valid number.'; - } else if (sessionLength <= 0) { - throw 'Session length must be a value greater than 0.'; - } - } - } - - static validateMaxLimit(maxLimit) { - if (maxLimit <= 0) { - throw 'Max limit must be a value greater than 0.'; - } - } - - static validateAllowHeaders(allowHeaders) { - if (![null, undefined].includes(allowHeaders)) { - if (Array.isArray(allowHeaders)) { - allowHeaders.forEach(header => { - if (typeof header !== 'string') { - throw 'Allow headers must only contain strings'; - } else if (!header.trim().length) { - throw 'Allow headers must not contain empty strings'; - } - }); - } else { - throw 'Allow headers must be an array'; - } - } - } - - generateEmailVerifyTokenExpiresAt() { - if (!this.verifyUserEmails || !this.emailVerifyTokenValidityDuration) { - return undefined; - } - - var now = new Date(); - return new Date(now.getTime() + this.emailVerifyTokenValidityDuration * 1000); - } - - generatePasswordResetTokenExpiresAt() { - if (!this.passwordPolicy || !this.passwordPolicy.resetTokenValidityDuration) { - return undefined; - } - - const now = new Date(); - return new Date(now.getTime() + this.passwordPolicy.resetTokenValidityDuration * 1000); - } - - generateSessionExpiresAt() { - if (!this.expireInactiveSessions) { - return undefined; - } - - var now = new Date(); - return new Date(now.getTime() + this.sessionLength * 1000); - } - - get invalidLinkURL() { - return this.customPages.invalidLink || `${this.publicServerURL}/apps/invalid_link.html`; - } - - get invalidVerificationLinkURL() { - return this.customPages.invalidVerificationLink || `${this.publicServerURL}/apps/invalid_verification_link.html`; - } - - get linkSendSuccessURL() { - return this.customPages.linkSendSuccess || `${this.publicServerURL}/apps/link_send_success.html`; - } - - get linkSendFailURL() { - return this.customPages.linkSendFail || `${this.publicServerURL}/apps/link_send_fail.html`; - } - - get verifyEmailSuccessURL() { - return this.customPages.verifyEmailSuccess || `${this.publicServerURL}/apps/verify_email_success.html`; - } - - get choosePasswordURL() { - return this.customPages.choosePassword || `${this.publicServerURL}/apps/choose_password`; - } - - get requestResetPasswordURL() { - return `${this.publicServerURL}/apps/${this.applicationId}/request_password_reset`; - } - - get passwordResetSuccessURL() { - return this.customPages.passwordResetSuccess || `${this.publicServerURL}/apps/password_reset_success.html`; - } - - get parseFrameURL() { - return this.customPages.parseFrameURL; - } - - get verifyEmailURL() { - return `${this.publicServerURL}/apps/${this.applicationId}/verify_email`; - } - -} - -exports.Config = Config; -var _default = Config; -exports.default = _default; -module.exports = Config; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db25maWcuanMiXSwibmFtZXMiOlsicmVtb3ZlVHJhaWxpbmdTbGFzaCIsInN0ciIsImVuZHNXaXRoIiwic3Vic3RyIiwibGVuZ3RoIiwiQ29uZmlnIiwiZ2V0IiwiYXBwbGljYXRpb25JZCIsIm1vdW50IiwiY2FjaGVJbmZvIiwiQXBwQ2FjaGUiLCJjb25maWciLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsInNjaGVtYUNhY2hlIiwiU2NoZW1hQ2FjaGUiLCJjYWNoZUNvbnRyb2xsZXIiLCJzY2hlbWFDYWNoZVRUTCIsImVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIiwiZGF0YWJhc2UiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0IiwiYmluZCIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInB1dCIsInNlcnZlckNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZSIsImFwcElkIiwic2V0dXBQYXNzd29yZFZhbGlkYXRvciIsInBhc3N3b3JkUG9saWN5IiwidmVyaWZ5VXNlckVtYWlscyIsInVzZXJDb250cm9sbGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwic2Vzc2lvbkxlbmd0aCIsIm1heExpbWl0IiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJhY2NvdW50TG9ja291dCIsIm1hc3RlcktleUlwcyIsIm1hc3RlcktleSIsInJlYWRPbmx5TWFzdGVyS2V5IiwiYWxsb3dIZWFkZXJzIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwiRXJyb3IiLCJlbWFpbEFkYXB0ZXIiLCJ2YWxpZGF0ZUVtYWlsQ29uZmlndXJhdGlvbiIsInZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3kiLCJ2YWxpZGF0ZVBhc3N3b3JkUG9saWN5Iiwic3RhcnRzV2l0aCIsInZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZU1hc3RlcktleUlwcyIsInZhbGlkYXRlTWF4TGltaXQiLCJ2YWxpZGF0ZUFsbG93SGVhZGVycyIsInZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zIiwidHRsIiwidW5kZWZpbmVkIiwiSWRlbXBvdGVuY3lPcHRpb25zIiwiZGVmYXVsdCIsImlzTmFOIiwicGF0aHMiLCJBcnJheSIsImR1cmF0aW9uIiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwidGhyZXNob2xkIiwibWF4UGFzc3dvcmRBZ2UiLCJyZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiIsInZhbGlkYXRvclBhdHRlcm4iLCJSZWdFeHAiLCJ2YWxpZGF0b3JDYWxsYmFjayIsImRvTm90QWxsb3dVc2VybmFtZSIsIm1heFBhc3N3b3JkSGlzdG9yeSIsInBhdHRlcm5WYWxpZGF0b3IiLCJ2YWx1ZSIsInRlc3QiLCJpcCIsIm5ldCIsImlzSVAiLCJfbW91bnQiLCJuZXdWYWx1ZSIsImluY2x1ZGVzIiwiaXNBcnJheSIsImhlYWRlciIsInRyaW0iLCJub3ciLCJEYXRlIiwiZ2V0VGltZSIsImdlbmVyYXRlUGFzc3dvcmRSZXNldFRva2VuRXhwaXJlc0F0IiwiaW52YWxpZExpbmtVUkwiLCJjdXN0b21QYWdlcyIsImludmFsaWRMaW5rIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGluayIsImxpbmtTZW5kU3VjY2Vzc1VSTCIsImxpbmtTZW5kU3VjY2VzcyIsImxpbmtTZW5kRmFpbFVSTCIsImxpbmtTZW5kRmFpbCIsInZlcmlmeUVtYWlsU3VjY2Vzc1VSTCIsInZlcmlmeUVtYWlsU3VjY2VzcyIsImNob29zZVBhc3N3b3JkVVJMIiwiY2hvb3NlUGFzc3dvcmQiLCJyZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwicGFzc3dvcmRSZXNldFN1Y2Nl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ZUFBZ0Isc0NBRjFCO0FBSUQ7O0FBRUQsTUFBSThELGtCQUFKLEdBQXlCO0FBQ3ZCLFdBQ0UsS0FBS0osV0FBTCxDQUFpQkssZUFBakIsSUFBcUMsR0FBRSxLQUFLL0QsZUFBZ0IsOEJBRDlEO0FBR0Q7O0FBRUQsTUFBSWdFLGVBQUosR0FBc0I7QUFDcEIsV0FBTyxLQUFLTixXQUFMLENBQWlCTyxZQUFqQixJQUFrQyxHQUFFLEtBQUtqRSxlQUFnQiwyQkFBaEU7QUFDRDs7QUFFRCxNQUFJa0UscUJBQUosR0FBNEI7QUFDMUIsV0FDRSxLQUFLUixXQUFMLENBQWlCUyxrQkFBakIsSUFDQyxHQUFFLEtBQUtuRSxlQUFnQixpQ0FGMUI7QUFJRDs7QUFFRCxNQUFJb0UsaUJBQUosR0FBd0I7QUFDdEIsV0FBTyxLQUFLVixXQUFMLENBQWlCVyxjQUFqQixJQUFvQyxHQUFFLEtBQUtyRSxlQUFnQix1QkFBbEU7QUFDRDs7QUFFRCxNQUFJc0UsdUJBQUosR0FBOEI7QUFDNUIsV0FBUSxHQUFFLEtBQUt0RSxlQUFnQixTQUFRLEtBQUs5QixhQUFjLHlCQUExRDtBQUNEOztBQUVELE1BQUlxRyx1QkFBSixHQUE4QjtBQUM1QixXQUNFLEtBQUtiLFdBQUwsQ0FBaUJjLG9CQUFqQixJQUNDLEdBQUUsS0FBS3hFLGVBQWdCLG1DQUYxQjtBQUlEOztBQUVELE1BQUl5RSxhQUFKLEdBQW9CO0FBQ2xCLFdBQU8sS0FBS2YsV0FBTCxDQUFpQmUsYUFBeEI7QUFDRDs7QUFFRCxNQUFJQyxjQUFKLEdBQXFCO0FBQ25CLFdBQVEsR0FBRSxLQUFLMUUsZUFBZ0IsU0FBUSxLQUFLOUIsYUFBYyxlQUExRDtBQUNEOztBQTdVaUI7OztlQWdWTEYsTTs7QUFDZjJHLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjVHLE1BQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBDb25maWcgb2JqZWN0IHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGhvdyBhIHNwZWNpZmljIGFwcCBpc1xuLy8gY29uZmlndXJlZC5cbi8vIG1vdW50IGlzIHRoZSBVUkwgZm9yIHRoZSByb290IG9mIHRoZSBBUEk7IGluY2x1ZGVzIGh0dHAsIGRvbWFpbiwgZXRjLlxuXG5pbXBvcnQgQXBwQ2FjaGUgZnJvbSAnLi9jYWNoZSc7XG5pbXBvcnQgU2NoZW1hQ2FjaGUgZnJvbSAnLi9Db250cm9sbGVycy9TY2hlbWFDYWNoZSc7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4vQ29udHJvbGxlcnMvRGF0YWJhc2VDb250cm9sbGVyJztcbmltcG9ydCBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCB7IElkZW1wb3RlbmN5T3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucy9EZWZpbml0aW9ucyc7XG5cbmZ1bmN0aW9uIHJlbW92ZVRyYWlsaW5nU2xhc2goc3RyKSB7XG4gIGlmICghc3RyKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuICBpZiAoc3RyLmVuZHNXaXRoKCcvJykpIHtcbiAgICBzdHIgPSBzdHIuc3Vic3RyKDAsIHN0ci5sZW5ndGggLSAxKTtcbiAgfVxuICByZXR1cm4gc3RyO1xufVxuXG5leHBvcnQgY2xhc3MgQ29uZmlnIHtcbiAgc3RhdGljIGdldChhcHBsaWNhdGlvbklkOiBzdHJpbmcsIG1vdW50OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjYWNoZUluZm8gPSBBcHBDYWNoZS5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCFjYWNoZUluZm8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnID0gbmV3IENvbmZpZygpO1xuICAgIGNvbmZpZy5hcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZDtcbiAgICBPYmplY3Qua2V5cyhjYWNoZUluZm8pLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmIChrZXkgPT0gJ2RhdGFiYXNlQ29udHJvbGxlcicpIHtcbiAgICAgICAgY29uc3Qgc2NoZW1hQ2FjaGUgPSBuZXcgU2NoZW1hQ2FjaGUoXG4gICAgICAgICAgY2FjaGVJbmZvLmNhY2hlQ29udHJvbGxlcixcbiAgICAgICAgICBjYWNoZUluZm8uc2NoZW1hQ2FjaGVUVEwsXG4gICAgICAgICAgY2FjaGVJbmZvLmVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlXG4gICAgICAgICk7XG4gICAgICAgIGNvbmZpZy5kYXRhYmFzZSA9IG5ldyBEYXRhYmFzZUNvbnRyb2xsZXIoY2FjaGVJbmZvLmRhdGFiYXNlQ29udHJvbGxlci5hZGFwdGVyLCBzY2hlbWFDYWNoZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25maWdba2V5XSA9IGNhY2hlSW5mb1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbmZpZy5tb3VudCA9IHJlbW92ZVRyYWlsaW5nU2xhc2gobW91bnQpO1xuICAgIGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQgPSBjb25maWcuZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0LmJpbmQoY29uZmlnKTtcbiAgICBjb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0ID0gY29uZmlnLmdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdC5iaW5kKFxuICAgICAgY29uZmlnXG4gICAgKTtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgc3RhdGljIHB1dChzZXJ2ZXJDb25maWd1cmF0aW9uKSB7XG4gICAgQ29uZmlnLnZhbGlkYXRlKHNlcnZlckNvbmZpZ3VyYXRpb24pO1xuICAgIEFwcENhY2hlLnB1dChzZXJ2ZXJDb25maWd1cmF0aW9uLmFwcElkLCBzZXJ2ZXJDb25maWd1cmF0aW9uKTtcbiAgICBDb25maWcuc2V0dXBQYXNzd29yZFZhbGlkYXRvcihzZXJ2ZXJDb25maWd1cmF0aW9uLnBhc3N3b3JkUG9saWN5KTtcbiAgICByZXR1cm4gc2VydmVyQ29uZmlndXJhdGlvbjtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZSh7XG4gICAgdmVyaWZ5VXNlckVtYWlscyxcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0LFxuICAgIGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMsXG4gICAgc2Vzc2lvbkxlbmd0aCxcbiAgICBtYXhMaW1pdCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICBhY2NvdW50TG9ja291dCxcbiAgICBwYXNzd29yZFBvbGljeSxcbiAgICBtYXN0ZXJLZXlJcHMsXG4gICAgbWFzdGVyS2V5LFxuICAgIHJlYWRPbmx5TWFzdGVyS2V5LFxuICAgIGFsbG93SGVhZGVycyxcbiAgICBpZGVtcG90ZW5jeU9wdGlvbnMsXG4gIH0pIHtcbiAgICBpZiAobWFzdGVyS2V5ID09PSByZWFkT25seU1hc3RlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtYXN0ZXJLZXkgYW5kIHJlYWRPbmx5TWFzdGVyS2V5IHNob3VsZCBiZSBkaWZmZXJlbnQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbWFpbEFkYXB0ZXIgPSB1c2VyQ29udHJvbGxlci5hZGFwdGVyO1xuICAgIGlmICh2ZXJpZnlVc2VyRW1haWxzKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtcbiAgICAgICAgZW1haWxBZGFwdGVyLFxuICAgICAgICBhcHBOYW1lLFxuICAgICAgICBwdWJsaWNTZXJ2ZXJVUkwsXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy52YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5KGFjY291bnRMb2Nrb3V0KTtcblxuICAgIHRoaXMudmFsaWRhdGVQYXNzd29yZFBvbGljeShwYXNzd29yZFBvbGljeSk7XG5cbiAgICBpZiAodHlwZW9mIHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ3Jldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUnO1xuICAgIH1cblxuICAgIGlmIChwdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgIGlmICghcHVibGljU2VydmVyVVJMLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSAmJiAhcHVibGljU2VydmVyVVJMLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICAgICAgdGhyb3cgJ3B1YmxpY1NlcnZlclVSTCBzaG91bGQgYmUgYSB2YWxpZCBIVFRQUyBVUkwgc3RhcnRpbmcgd2l0aCBodHRwczovLyc7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbihzZXNzaW9uTGVuZ3RoLCBleHBpcmVJbmFjdGl2ZVNlc3Npb25zKTtcbiAgICB0aGlzLnZhbGlkYXRlTWFzdGVyS2V5SXBzKG1hc3RlcktleUlwcyk7XG4gICAgdGhpcy52YWxpZGF0ZU1heExpbWl0KG1heExpbWl0KTtcbiAgICB0aGlzLnZhbGlkYXRlQWxsb3dIZWFkZXJzKGFsbG93SGVhZGVycyk7XG4gICAgdGhpcy52YWxpZGF0ZUlkZW1wb3RlbmN5T3B0aW9ucyhpZGVtcG90ZW5jeU9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zKGlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIGlmICghaWRlbXBvdGVuY3lPcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpZGVtcG90ZW5jeU9wdGlvbnMudHRsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy50dGwgPSBJZGVtcG90ZW5jeU9wdGlvbnMudHRsLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNOYU4oaWRlbXBvdGVuY3lPcHRpb25zLnR0bCkgJiYgaWRlbXBvdGVuY3lPcHRpb25zLnR0bCA8PSAwKSB7XG4gICAgICB0aHJvdyAnaWRlbXBvdGVuY3kgVFRMIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgc2Vjb25kcyc7XG4gICAgfSBlbHNlIGlmIChpc05hTihpZGVtcG90ZW5jeU9wdGlvbnMudHRsKSkge1xuICAgICAgdGhyb3cgJ2lkZW1wb3RlbmN5IFRUTCB2YWx1ZSBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9XG4gICAgaWYgKCFpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy5wYXRocyA9IElkZW1wb3RlbmN5T3B0aW9ucy5wYXRocy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIShpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgIHRocm93ICdpZGVtcG90ZW5jeSBwYXRocyBtdXN0IGJlIG9mIGFuIGFycmF5IG9mIHN0cmluZ3MnO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5KGFjY291bnRMb2Nrb3V0KSB7XG4gICAgaWYgKGFjY291bnRMb2Nrb3V0KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBhY2NvdW50TG9ja291dC5kdXJhdGlvbiAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gPD0gMCB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC5kdXJhdGlvbiA+IDk5OTk5XG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ0FjY291bnQgbG9ja291dCBkdXJhdGlvbiBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAxMDAwMDAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFOdW1iZXIuaXNJbnRlZ2VyKGFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCkgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQudGhyZXNob2xkIDwgMSB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC50aHJlc2hvbGQgPiA5OTlcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAnQWNjb3VudCBsb2Nrb3V0IHRocmVzaG9sZCBzaG91bGQgYmUgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDEwMDAnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVBhc3N3b3JkUG9saWN5KHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHR5cGVvZiBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSAhPT0gJ251bWJlcicgfHwgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgPCAwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gIT09ICdudW1iZXInIHx8XG4gICAgICAgICAgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gPD0gMClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcic7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKTtcbiAgICAgICAgfSBlbHNlIGlmICghKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApKSB7XG4gICAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gbXVzdCBiZSBhIHJlZ2V4IHN0cmluZyBvciBSZWdFeHAgb2JqZWN0Lic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayAmJlxuICAgICAgICB0eXBlb2YgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgIT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uLic7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcGFzc3dvcmRQb2xpY3kuZG9Ob3RBbGxvd1VzZXJuYW1lICYmXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgIT09ICdib29sZWFuJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgJiZcbiAgICAgICAgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSkgfHxcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgPD0gMCB8fFxuICAgICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSA+IDIwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgbXVzdCBiZSBhbiBpbnRlZ2VyIHJhbmdpbmcgMCAtIDIwJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpcyBjb25maWd1cmVkIHRoZW4gc2V0dXAgYSBjYWxsYmFjayB0byBwcm9jZXNzIHRoZSBwYXR0ZXJuXG4gIHN0YXRpYyBzZXR1cFBhc3N3b3JkVmFsaWRhdG9yKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5ICYmIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgIHBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgPSB2YWx1ZSA9PiB7XG4gICAgICAgIHJldHVybiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuLnRlc3QodmFsdWUpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgIGVtYWlsQWRhcHRlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgfSkge1xuICAgIGlmICghZW1haWxBZGFwdGVyKSB7XG4gICAgICB0aHJvdyAnQW4gZW1haWxBZGFwdGVyIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBhcHBOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgJ0FuIGFwcCBuYW1lIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwdWJsaWNTZXJ2ZXJVUkwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyAnQSBwdWJsaWMgc2VydmVyIHVybCBpcyByZXF1aXJlZCBmb3IgZS1tYWlsIHZlcmlmaWNhdGlvbiBhbmQgcGFzc3dvcmQgcmVzZXRzLic7XG4gICAgfVxuICAgIGlmIChlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgaWYgKGlzTmFOKGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSkge1xuICAgICAgICB0aHJvdyAnRW1haWwgdmVyaWZ5IHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uIG11c3QgYmUgYSB2YWxpZCBudW1iZXIuJztcbiAgICAgIH0gZWxzZSBpZiAoZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gPD0gMCkge1xuICAgICAgICB0aHJvdyAnRW1haWwgdmVyaWZ5IHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uIG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gMC4nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZU1hc3RlcktleUlwcyhtYXN0ZXJLZXlJcHMpIHtcbiAgICBmb3IgKGNvbnN0IGlwIG9mIG1hc3RlcktleUlwcykge1xuICAgICAgaWYgKCFuZXQuaXNJUChpcCkpIHtcbiAgICAgICAgdGhyb3cgYEludmFsaWQgaXAgaW4gbWFzdGVyS2V5SXBzOiAke2lwfWA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IG1vdW50KCkge1xuICAgIHZhciBtb3VudCA9IHRoaXMuX21vdW50O1xuICAgIGlmICh0aGlzLnB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgbW91bnQgPSB0aGlzLnB1YmxpY1NlcnZlclVSTDtcbiAgICB9XG4gICAgcmV0dXJuIG1vdW50O1xuICB9XG5cbiAgc2V0IG1vdW50KG5ld1ZhbHVlKSB7XG4gICAgdGhpcy5fbW91bnQgPSBuZXdWYWx1ZTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVNlc3Npb25Db25maWd1cmF0aW9uKHNlc3Npb25MZW5ndGgsIGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICBpZiAoZXhwaXJlSW5hY3RpdmVTZXNzaW9ucykge1xuICAgICAgaWYgKGlzTmFOKHNlc3Npb25MZW5ndGgpKSB7XG4gICAgICAgIHRocm93ICdTZXNzaW9uIGxlbmd0aCBtdXN0IGJlIGEgdmFsaWQgbnVtYmVyLic7XG4gICAgICB9IGVsc2UgaWYgKHNlc3Npb25MZW5ndGggPD0gMCkge1xuICAgICAgICB0aHJvdyAnU2Vzc2lvbiBsZW5ndGggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlTWF4TGltaXQobWF4TGltaXQpIHtcbiAgICBpZiAobWF4TGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgJ01heCBsaW1pdCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIDAuJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVBbGxvd0hlYWRlcnMoYWxsb3dIZWFkZXJzKSB7XG4gICAgaWYgKCFbbnVsbCwgdW5kZWZpbmVkXS5pbmNsdWRlcyhhbGxvd0hlYWRlcnMpKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhbGxvd0hlYWRlcnMpKSB7XG4gICAgICAgIGFsbG93SGVhZGVycy5mb3JFYWNoKGhlYWRlciA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyAnQWxsb3cgaGVhZGVycyBtdXN0IG9ubHkgY29udGFpbiBzdHJpbmdzJztcbiAgICAgICAgICB9IGVsc2UgaWYgKCFoZWFkZXIudHJpbSgpLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBub3QgY29udGFpbiBlbXB0eSBzdHJpbmdzJztcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBiZSBhbiBhcnJheSc7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KCkge1xuICAgIGlmICghdGhpcy52ZXJpZnlVc2VyRW1haWxzIHx8ICF0aGlzLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gbmV3IERhdGUobm93LmdldFRpbWUoKSArIHRoaXMuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gKiAxMDAwKTtcbiAgfVxuXG4gIGdlbmVyYXRlUGFzc3dvcmRSZXNldFRva2VuRXhwaXJlc0F0KCkge1xuICAgIGlmICghdGhpcy5wYXNzd29yZFBvbGljeSB8fCAhdGhpcy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gbmV3IERhdGUobm93LmdldFRpbWUoKSArIHRoaXMucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gKiAxMDAwKTtcbiAgfVxuXG4gIGdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdCgpIHtcbiAgICBpZiAoIXRoaXMuZXhwaXJlSW5hY3RpdmVTZXNzaW9ucykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLnNlc3Npb25MZW5ndGggKiAxMDAwKTtcbiAgfVxuXG4gIGdldCBpbnZhbGlkTGlua1VSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5pbnZhbGlkTGluayB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9pbnZhbGlkX2xpbmsuaHRtbGA7XG4gIH1cblxuICBnZXQgaW52YWxpZFZlcmlmaWNhdGlvbkxpbmtVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMuaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2ludmFsaWRfdmVyaWZpY2F0aW9uX2xpbmsuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IGxpbmtTZW5kU3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy5saW5rU2VuZFN1Y2Nlc3MgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvbGlua19zZW5kX3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IGxpbmtTZW5kRmFpbFVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5saW5rU2VuZEZhaWwgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvbGlua19zZW5kX2ZhaWwuaHRtbGA7XG4gIH1cblxuICBnZXQgdmVyaWZ5RW1haWxTdWNjZXNzVVJMKCkge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmN1c3RvbVBhZ2VzLnZlcmlmeUVtYWlsU3VjY2VzcyB8fFxuICAgICAgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvdmVyaWZ5X2VtYWlsX3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IGNob29zZVBhc3N3b3JkVVJMKCkge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVBhZ2VzLmNob29zZVBhc3N3b3JkIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2Nob29zZV9wYXNzd29yZGA7XG4gIH1cblxuICBnZXQgcmVxdWVzdFJlc2V0UGFzc3dvcmRVUkwoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzLyR7dGhpcy5hcHBsaWNhdGlvbklkfS9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0YDtcbiAgfVxuXG4gIGdldCBwYXNzd29yZFJlc2V0U3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy5wYXNzd29yZFJlc2V0U3VjY2VzcyB8fFxuICAgICAgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvcGFzc3dvcmRfcmVzZXRfc3VjY2Vzcy5odG1sYFxuICAgICk7XG4gIH1cblxuICBnZXQgcGFyc2VGcmFtZVVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5wYXJzZUZyYW1lVVJMO1xuICB9XG5cbiAgZ2V0IHZlcmlmeUVtYWlsVVJMKCkge1xuICAgIHJldHVybiBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy8ke3RoaXMuYXBwbGljYXRpb25JZH0vdmVyaWZ5X2VtYWlsYDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb25maWc7XG5tb2R1bGUuZXhwb3J0cyA9IENvbmZpZztcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/AdaptableController.js b/lib/Controllers/AdaptableController.js deleted file mode 100644 index 520cd57406..0000000000 --- a/lib/Controllers/AdaptableController.js +++ /dev/null @@ -1,88 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AdaptableController = void 0; - -var _Config = _interopRequireDefault(require("../Config")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/* -AdaptableController.js - -AdaptableController is the base class for all controllers -that support adapter, -The super class takes care of creating the right instance for the adapter -based on the parameters passed - - */ -// _adapter is private, use Symbol -var _adapter = Symbol(); - -class AdaptableController { - constructor(adapter, appId, options) { - this.options = options; - this.appId = appId; - this.adapter = adapter; - } - - set adapter(adapter) { - this.validateAdapter(adapter); - this[_adapter] = adapter; - } - - get adapter() { - return this[_adapter]; - } - - get config() { - return _Config.default.get(this.appId); - } - - expectedAdapterType() { - throw new Error('Subclasses should implement expectedAdapterType()'); - } - - validateAdapter(adapter) { - AdaptableController.validateAdapter(adapter, this); - } - - static validateAdapter(adapter, self, ExpectedType) { - if (!adapter) { - throw new Error(this.constructor.name + ' requires an adapter'); - } - - const Type = ExpectedType || self.expectedAdapterType(); // Allow skipping for testing - - if (!Type) { - return; - } // Makes sure the prototype matches - - - const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => { - const adapterType = typeof adapter[key]; - const expectedType = typeof Type.prototype[key]; - - if (adapterType !== expectedType) { - obj[key] = { - expected: expectedType, - actual: adapterType - }; - } - - return obj; - }, {}); - - if (Object.keys(mismatches).length > 0) { - throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches); - } - } - -} - -exports.AdaptableController = AdaptableController; -var _default = AdaptableController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIl9hZGFwdGVyIiwiU3ltYm9sIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsImNvbmZpZyIsIkNvbmZpZyIsImdldCIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJFcnJvciIsInNlbGYiLCJFeHBlY3RlZFR5cGUiLCJuYW1lIiwiVHlwZSIsIm1pc21hdGNoZXMiLCJPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwicHJvdG90eXBlIiwicmVkdWNlIiwib2JqIiwia2V5IiwiYWRhcHRlclR5cGUiLCJleHBlY3RlZFR5cGUiLCJleHBlY3RlZCIsImFjdHVhbCIsImtleXMiLCJsZW5ndGgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFZQTs7OztBQVpBOzs7Ozs7Ozs7QUFVQTtBQUNBLElBQUlBLFFBQVEsR0FBR0MsTUFBTSxFQUFyQjs7QUFHTyxNQUFNQyxtQkFBTixDQUEwQjtBQUMvQkMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQWpCLEVBQTBCO0FBQ25DLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNBLFNBQUtELEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtELE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVELE1BQUlBLE9BQUosQ0FBWUEsT0FBWixFQUFxQjtBQUNuQixTQUFLRyxlQUFMLENBQXFCSCxPQUFyQjtBQUNBLFNBQUtKLFFBQUwsSUFBaUJJLE9BQWpCO0FBQ0Q7O0FBRUQsTUFBSUEsT0FBSixHQUFjO0FBQ1osV0FBTyxLQUFLSixRQUFMLENBQVA7QUFDRDs7QUFFRCxNQUFJUSxNQUFKLEdBQWE7QUFDWCxXQUFPQyxnQkFBT0MsR0FBUCxDQUFXLEtBQUtMLEtBQWhCLENBQVA7QUFDRDs7QUFFRE0sRUFBQUEsbUJBQW1CLEdBQUc7QUFDcEIsVUFBTSxJQUFJQyxLQUFKLENBQVUsbURBQVYsQ0FBTjtBQUNEOztBQUVETCxFQUFBQSxlQUFlLENBQUNILE9BQUQsRUFBVTtBQUN2QkYsSUFBQUEsbUJBQW1CLENBQUNLLGVBQXBCLENBQW9DSCxPQUFwQyxFQUE2QyxJQUE3QztBQUNEOztBQUVELFNBQU9HLGVBQVAsQ0FBdUJILE9BQXZCLEVBQWdDUyxJQUFoQyxFQUFzQ0MsWUFBdEMsRUFBb0Q7QUFDbEQsUUFBSSxDQUFDVixPQUFMLEVBQWM7QUFDWixZQUFNLElBQUlRLEtBQUosQ0FBVSxLQUFLVCxXQUFMLENBQWlCWSxJQUFqQixHQUF3QixzQkFBbEMsQ0FBTjtBQUNEOztBQUVELFVBQU1DLElBQUksR0FBR0YsWUFBWSxJQUFJRCxJQUFJLENBQUNGLG1CQUFMLEVBQTdCLENBTGtELENBTWxEOztBQUNBLFFBQUksQ0FBQ0ssSUFBTCxFQUFXO0FBQ1Q7QUFDRCxLQVRpRCxDQVdsRDs7O0FBQ0EsVUFBTUMsVUFBVSxHQUFHQyxNQUFNLENBQUNDLG1CQUFQLENBQTJCSCxJQUFJLENBQUNJLFNBQWhDLEVBQTJDQyxNQUEzQyxDQUFrRCxDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUNqRixZQUFNQyxXQUFXLEdBQUcsT0FBT3BCLE9BQU8sQ0FBQ21CLEdBQUQsQ0FBbEM7QUFDQSxZQUFNRSxZQUFZLEdBQUcsT0FBT1QsSUFBSSxDQUFDSSxTQUFMLENBQWVHLEdBQWYsQ0FBNUI7O0FBQ0EsVUFBSUMsV0FBVyxLQUFLQyxZQUFwQixFQUFrQztBQUNoQ0gsUUFBQUEsR0FBRyxDQUFDQyxHQUFELENBQUgsR0FBVztBQUNURyxVQUFBQSxRQUFRLEVBQUVELFlBREQ7QUFFVEUsVUFBQUEsTUFBTSxFQUFFSDtBQUZDLFNBQVg7QUFJRDs7QUFDRCxhQUFPRixHQUFQO0FBQ0QsS0FWa0IsRUFVaEIsRUFWZ0IsQ0FBbkI7O0FBWUEsUUFBSUosTUFBTSxDQUFDVSxJQUFQLENBQVlYLFVBQVosRUFBd0JZLE1BQXhCLEdBQWlDLENBQXJDLEVBQXdDO0FBQ3RDLFlBQU0sSUFBSWpCLEtBQUosQ0FBVSxrREFBVixFQUE4RFIsT0FBOUQsRUFBdUVhLFVBQXZFLENBQU47QUFDRDtBQUNGOztBQXZEOEI7OztlQTBEbEJmLG1CIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkFkYXB0YWJsZUNvbnRyb2xsZXIuanNcblxuQWRhcHRhYmxlQ29udHJvbGxlciBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsIGNvbnRyb2xsZXJzXG50aGF0IHN1cHBvcnQgYWRhcHRlcixcblRoZSBzdXBlciBjbGFzcyB0YWtlcyBjYXJlIG9mIGNyZWF0aW5nIHRoZSByaWdodCBpbnN0YW5jZSBmb3IgdGhlIGFkYXB0ZXJcbmJhc2VkIG9uIHRoZSBwYXJhbWV0ZXJzIHBhc3NlZFxuXG4gKi9cblxuLy8gX2FkYXB0ZXIgaXMgcHJpdmF0ZSwgdXNlIFN5bWJvbFxudmFyIF9hZGFwdGVyID0gU3ltYm9sKCk7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuYXBwSWQgPSBhcHBJZDtcbiAgICB0aGlzLmFkYXB0ZXIgPSBhZGFwdGVyO1xuICB9XG5cbiAgc2V0IGFkYXB0ZXIoYWRhcHRlcikge1xuICAgIHRoaXMudmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpO1xuICAgIHRoaXNbX2FkYXB0ZXJdID0gYWRhcHRlcjtcbiAgfVxuXG4gIGdldCBhZGFwdGVyKCkge1xuICAgIHJldHVybiB0aGlzW19hZGFwdGVyXTtcbiAgfVxuXG4gIGdldCBjb25maWcoKSB7XG4gICAgcmV0dXJuIENvbmZpZy5nZXQodGhpcy5hcHBJZCk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3ViY2xhc3NlcyBzaG91bGQgaW1wbGVtZW50IGV4cGVjdGVkQWRhcHRlclR5cGUoKScpO1xuICB9XG5cbiAgdmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpIHtcbiAgICBBZGFwdGFibGVDb250cm9sbGVyLnZhbGlkYXRlQWRhcHRlcihhZGFwdGVyLCB0aGlzKTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlciwgc2VsZiwgRXhwZWN0ZWRUeXBlKSB7XG4gICAgaWYgKCFhZGFwdGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgJyByZXF1aXJlcyBhbiBhZGFwdGVyJyk7XG4gICAgfVxuXG4gICAgY29uc3QgVHlwZSA9IEV4cGVjdGVkVHlwZSB8fCBzZWxmLmV4cGVjdGVkQWRhcHRlclR5cGUoKTtcbiAgICAvLyBBbGxvdyBza2lwcGluZyBmb3IgdGVzdGluZ1xuICAgIGlmICghVHlwZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE1ha2VzIHN1cmUgdGhlIHByb3RvdHlwZSBtYXRjaGVzXG4gICAgY29uc3QgbWlzbWF0Y2hlcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFR5cGUucHJvdG90eXBlKS5yZWR1Y2UoKG9iaiwga2V5KSA9PiB7XG4gICAgICBjb25zdCBhZGFwdGVyVHlwZSA9IHR5cGVvZiBhZGFwdGVyW2tleV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0eXBlb2YgVHlwZS5wcm90b3R5cGVba2V5XTtcbiAgICAgIGlmIChhZGFwdGVyVHlwZSAhPT0gZXhwZWN0ZWRUeXBlKSB7XG4gICAgICAgIG9ialtrZXldID0ge1xuICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZFR5cGUsXG4gICAgICAgICAgYWN0dWFsOiBhZGFwdGVyVHlwZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfSwge30pO1xuXG4gICAgaWYgKE9iamVjdC5rZXlzKG1pc21hdGNoZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkFkYXB0ZXIgcHJvdG90eXBlIGRvbid0IG1hdGNoIGV4cGVjdGVkIHByb3RvdHlwZVwiLCBhZGFwdGVyLCBtaXNtYXRjaGVzKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQWRhcHRhYmxlQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/AnalyticsController.js b/lib/Controllers/AnalyticsController.js deleted file mode 100644 index 1416558aca..0000000000 --- a/lib/Controllers/AnalyticsController.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AnalyticsController = void 0; - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class AnalyticsController extends _AdaptableController.default { - appOpened(req) { - return Promise.resolve().then(() => { - return this.adapter.appOpened(req.body, req); - }).then(response => { - return { - response: response || {} - }; - }).catch(() => { - return { - response: {} - }; - }); - } - - trackEvent(req) { - return Promise.resolve().then(() => { - return this.adapter.trackEvent(req.params.eventName, req.body, req); - }).then(response => { - return { - response: response || {} - }; - }).catch(() => { - return { - response: {} - }; - }); - } - - expectedAdapterType() { - return _AnalyticsAdapter.AnalyticsAdapter; - } - -} - -exports.AnalyticsController = AnalyticsController; -var _default = AnalyticsController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BbmFseXRpY3NDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiYXBwT3BlbmVkIiwicmVxIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiYWRhcHRlciIsImJvZHkiLCJyZXNwb25zZSIsImNhdGNoIiwidHJhY2tFdmVudCIsInBhcmFtcyIsImV2ZW50TmFtZSIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJBbmFseXRpY3NBZGFwdGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxNQUFNQSxtQkFBTixTQUFrQ0MsNEJBQWxDLENBQXNEO0FBQzNEQyxFQUFBQSxTQUFTLENBQUNDLEdBQUQsRUFBTTtBQUNiLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixHQUNKQyxJQURJLENBQ0MsTUFBTTtBQUNWLGFBQU8sS0FBS0MsT0FBTCxDQUFhTCxTQUFiLENBQXVCQyxHQUFHLENBQUNLLElBQTNCLEVBQWlDTCxHQUFqQyxDQUFQO0FBQ0QsS0FISSxFQUlKRyxJQUpJLENBSUNHLFFBQVEsSUFBSTtBQUNoQixhQUFPO0FBQUVBLFFBQUFBLFFBQVEsRUFBRUEsUUFBUSxJQUFJO0FBQXhCLE9BQVA7QUFDRCxLQU5JLEVBT0pDLEtBUEksQ0FPRSxNQUFNO0FBQ1gsYUFBTztBQUFFRCxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQO0FBQ0QsS0FUSSxDQUFQO0FBVUQ7O0FBRURFLEVBQUFBLFVBQVUsQ0FBQ1IsR0FBRCxFQUFNO0FBQ2QsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBTyxLQUFLQyxPQUFMLENBQWFJLFVBQWIsQ0FBd0JSLEdBQUcsQ0FBQ1MsTUFBSixDQUFXQyxTQUFuQyxFQUE4Q1YsR0FBRyxDQUFDSyxJQUFsRCxFQUF3REwsR0FBeEQsQ0FBUDtBQUNELEtBSEksRUFJSkcsSUFKSSxDQUlDRyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBLFFBQVEsSUFBSTtBQUF4QixPQUFQO0FBQ0QsS0FOSSxFQU9KQyxLQVBJLENBT0UsTUFBTTtBQUNYLGFBQU87QUFBRUQsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVEksQ0FBUDtBQVVEOztBQUVESyxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixXQUFPQyxrQ0FBUDtBQUNEOztBQTdCMEQ7OztlQWdDOUNmLG1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IEFuYWx5dGljc0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlcic7XG5cbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGFwcE9wZW5lZChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hcHBPcGVuZWQocmVxLmJvZHksIHJlcSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfHwge30gfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgdHJhY2tFdmVudChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci50cmFja0V2ZW50KHJlcS5wYXJhbXMuZXZlbnROYW1lLCByZXEuYm9keSwgcmVxKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB8fCB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBBbmFseXRpY3NBZGFwdGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuYWx5dGljc0NvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/CacheController.js b/lib/Controllers/CacheController.js deleted file mode 100644 index 9feaa778f9..0000000000 --- a/lib/Controllers/CacheController.js +++ /dev/null @@ -1,92 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.CacheController = exports.SubCache = void 0; - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _CacheAdapter = _interopRequireDefault(require("../Adapters/Cache/CacheAdapter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const KEY_SEPARATOR_CHAR = ':'; - -function joinKeys(...keys) { - return keys.join(KEY_SEPARATOR_CHAR); -} -/** - * Prefix all calls to the cache via a prefix string, useful when grouping Cache by object type. - * - * eg "Role" or "Session" - */ - - -class SubCache { - constructor(prefix, cacheController, ttl) { - this.prefix = prefix; - this.cache = cacheController; - this.ttl = ttl; - } - - get(key) { - const cacheKey = joinKeys(this.prefix, key); - return this.cache.get(cacheKey); - } - - put(key, value, ttl) { - const cacheKey = joinKeys(this.prefix, key); - return this.cache.put(cacheKey, value, ttl); - } - - del(key) { - const cacheKey = joinKeys(this.prefix, key); - return this.cache.del(cacheKey); - } - - clear() { - return this.cache.clear(); - } - -} - -exports.SubCache = SubCache; - -class CacheController extends _AdaptableController.default { - constructor(adapter, appId, options = {}) { - super(adapter, appId, options); - this.role = new SubCache('role', this); - this.user = new SubCache('user', this); - this.graphQL = new SubCache('graphQL', this); - } - - get(key) { - const cacheKey = joinKeys(this.appId, key); - return this.adapter.get(cacheKey).then(null, () => Promise.resolve(null)); - } - - put(key, value, ttl) { - const cacheKey = joinKeys(this.appId, key); - return this.adapter.put(cacheKey, value, ttl); - } - - del(key) { - const cacheKey = joinKeys(this.appId, key); - return this.adapter.del(cacheKey); - } - - clear() { - return this.adapter.clear(); - } - - expectedAdapterType() { - return _CacheAdapter.default; - } - -} - -exports.CacheController = CacheController; -var _default = CacheController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9DYWNoZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiS0VZX1NFUEFSQVRPUl9DSEFSIiwiam9pbktleXMiLCJrZXlzIiwiam9pbiIsIlN1YkNhY2hlIiwiY29uc3RydWN0b3IiLCJwcmVmaXgiLCJjYWNoZUNvbnRyb2xsZXIiLCJ0dGwiLCJjYWNoZSIsImdldCIsImtleSIsImNhY2hlS2V5IiwicHV0IiwidmFsdWUiLCJkZWwiLCJjbGVhciIsIkNhY2hlQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwicm9sZSIsInVzZXIiLCJncmFwaFFMIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkNhY2hlQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRUEsTUFBTUEsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRUEsU0FBU0MsUUFBVCxDQUFrQixHQUFHQyxJQUFyQixFQUEyQjtBQUN6QixTQUFPQSxJQUFJLENBQUNDLElBQUwsQ0FBVUgsa0JBQVYsQ0FBUDtBQUNEO0FBRUQ7Ozs7Ozs7QUFLTyxNQUFNSSxRQUFOLENBQWU7QUFDcEJDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFTQyxlQUFULEVBQTBCQyxHQUExQixFQUErQjtBQUN4QyxTQUFLRixNQUFMLEdBQWNBLE1BQWQ7QUFDQSxTQUFLRyxLQUFMLEdBQWFGLGVBQWI7QUFDQSxTQUFLQyxHQUFMLEdBQVdBLEdBQVg7QUFDRDs7QUFFREUsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU07QUFDUCxVQUFNQyxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLSyxNQUFOLEVBQWNLLEdBQWQsQ0FBekI7QUFDQSxXQUFPLEtBQUtGLEtBQUwsQ0FBV0MsR0FBWCxDQUFlRSxRQUFmLENBQVA7QUFDRDs7QUFFREMsRUFBQUEsR0FBRyxDQUFDRixHQUFELEVBQU1HLEtBQU4sRUFBYU4sR0FBYixFQUFrQjtBQUNuQixVQUFNSSxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLSyxNQUFOLEVBQWNLLEdBQWQsQ0FBekI7QUFDQSxXQUFPLEtBQUtGLEtBQUwsQ0FBV0ksR0FBWCxDQUFlRCxRQUFmLEVBQXlCRSxLQUF6QixFQUFnQ04sR0FBaEMsQ0FBUDtBQUNEOztBQUVETyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTTtBQUNQLFVBQU1DLFFBQVEsR0FBR1gsUUFBUSxDQUFDLEtBQUtLLE1BQU4sRUFBY0ssR0FBZCxDQUF6QjtBQUNBLFdBQU8sS0FBS0YsS0FBTCxDQUFXTSxHQUFYLENBQWVILFFBQWYsQ0FBUDtBQUNEOztBQUVESSxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtQLEtBQUwsQ0FBV08sS0FBWCxFQUFQO0FBQ0Q7O0FBeEJtQjs7OztBQTJCZixNQUFNQyxlQUFOLFNBQThCQyw0QkFBOUIsQ0FBa0Q7QUFDdkRiLEVBQUFBLFdBQVcsQ0FBQ2MsT0FBRCxFQUFVQyxLQUFWLEVBQWlCQyxPQUFPLEdBQUcsRUFBM0IsRUFBK0I7QUFDeEMsVUFBTUYsT0FBTixFQUFlQyxLQUFmLEVBQXNCQyxPQUF0QjtBQUVBLFNBQUtDLElBQUwsR0FBWSxJQUFJbEIsUUFBSixDQUFhLE1BQWIsRUFBcUIsSUFBckIsQ0FBWjtBQUNBLFNBQUttQixJQUFMLEdBQVksSUFBSW5CLFFBQUosQ0FBYSxNQUFiLEVBQXFCLElBQXJCLENBQVo7QUFDQSxTQUFLb0IsT0FBTCxHQUFlLElBQUlwQixRQUFKLENBQWEsU0FBYixFQUF3QixJQUF4QixDQUFmO0FBQ0Q7O0FBRURNLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS21CLEtBQU4sRUFBYVQsR0FBYixDQUF6QjtBQUNBLFdBQU8sS0FBS1EsT0FBTCxDQUFhVCxHQUFiLENBQWlCRSxRQUFqQixFQUEyQmEsSUFBM0IsQ0FBZ0MsSUFBaEMsRUFBc0MsTUFBTUMsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQTVDLENBQVA7QUFDRDs7QUFFRGQsRUFBQUEsR0FBRyxDQUFDRixHQUFELEVBQU1HLEtBQU4sRUFBYU4sR0FBYixFQUFrQjtBQUNuQixVQUFNSSxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLbUIsS0FBTixFQUFhVCxHQUFiLENBQXpCO0FBQ0EsV0FBTyxLQUFLUSxPQUFMLENBQWFOLEdBQWIsQ0FBaUJELFFBQWpCLEVBQTJCRSxLQUEzQixFQUFrQ04sR0FBbEMsQ0FBUDtBQUNEOztBQUVETyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTTtBQUNQLFVBQU1DLFFBQVEsR0FBR1gsUUFBUSxDQUFDLEtBQUttQixLQUFOLEVBQWFULEdBQWIsQ0FBekI7QUFDQSxXQUFPLEtBQUtRLE9BQUwsQ0FBYUosR0FBYixDQUFpQkgsUUFBakIsQ0FBUDtBQUNEOztBQUVESSxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtHLE9BQUwsQ0FBYUgsS0FBYixFQUFQO0FBQ0Q7O0FBRURZLEVBQUFBLG1CQUFtQixHQUFHO0FBQ3BCLFdBQU9DLHFCQUFQO0FBQ0Q7O0FBOUJzRDs7O2VBaUMxQ1osZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgQ2FjaGVBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0NhY2hlL0NhY2hlQWRhcHRlcic7XG5cbmNvbnN0IEtFWV9TRVBBUkFUT1JfQ0hBUiA9ICc6JztcblxuZnVuY3Rpb24gam9pbktleXMoLi4ua2V5cykge1xuICByZXR1cm4ga2V5cy5qb2luKEtFWV9TRVBBUkFUT1JfQ0hBUik7XG59XG5cbi8qKlxuICogUHJlZml4IGFsbCBjYWxscyB0byB0aGUgY2FjaGUgdmlhIGEgcHJlZml4IHN0cmluZywgdXNlZnVsIHdoZW4gZ3JvdXBpbmcgQ2FjaGUgYnkgb2JqZWN0IHR5cGUuXG4gKlxuICogZWcgXCJSb2xlXCIgb3IgXCJTZXNzaW9uXCJcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YkNhY2hlIHtcbiAgY29uc3RydWN0b3IocHJlZml4LCBjYWNoZUNvbnRyb2xsZXIsIHR0bCkge1xuICAgIHRoaXMucHJlZml4ID0gcHJlZml4O1xuICAgIHRoaXMuY2FjaGUgPSBjYWNoZUNvbnRyb2xsZXI7XG4gICAgdGhpcy50dGwgPSB0dGw7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBqb2luS2V5cyh0aGlzLnByZWZpeCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXQoY2FjaGVLZXkpO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5wcmVmaXgsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUucHV0KGNhY2hlS2V5LCB2YWx1ZSwgdHRsKTtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMucHJlZml4LCBrZXkpO1xuICAgIHJldHVybiB0aGlzLmNhY2hlLmRlbChjYWNoZUtleSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5jbGVhcigpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBDYWNoZUNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcblxuICAgIHRoaXMucm9sZSA9IG5ldyBTdWJDYWNoZSgncm9sZScsIHRoaXMpO1xuICAgIHRoaXMudXNlciA9IG5ldyBTdWJDYWNoZSgndXNlcicsIHRoaXMpO1xuICAgIHRoaXMuZ3JhcGhRTCA9IG5ldyBTdWJDYWNoZSgnZ3JhcGhRTCcsIHRoaXMpO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5hcHBJZCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmdldChjYWNoZUtleSkudGhlbihudWxsLCAoKSA9PiBQcm9taXNlLnJlc29sdmUobnVsbCkpO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5hcHBJZCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnB1dChjYWNoZUtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBqb2luS2V5cyh0aGlzLmFwcElkLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGVsKGNhY2hlS2V5KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY2xlYXIoKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIENhY2hlQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYWNoZUNvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/DatabaseController.js b/lib/Controllers/DatabaseController.js deleted file mode 100644 index aa1087cfd4..0000000000 --- a/lib/Controllers/DatabaseController.js +++ /dev/null @@ -1,1485 +0,0 @@ -"use strict"; - -var _node = require("parse/node"); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _intersect = _interopRequireDefault(require("intersect")); - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -var _logger = _interopRequireDefault(require("../logger")); - -var SchemaController = _interopRequireWildcard(require("./SchemaController")); - -var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); - -var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function addWriteACL(query, acl) { - const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_wperm' query, we don't allow client queries on that, no need to $and - - - newQuery._wperm = { - $in: [null, ...acl] - }; - return newQuery; -} - -function addReadACL(query, acl) { - const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_rperm' query, we don't allow client queries on that, no need to $and - - - newQuery._rperm = { - $in: [null, '*', ...acl] - }; - return newQuery; -} // Transforms a REST API formatted ACL object to our two-field mongo format. - - -const transformObjectACL = (_ref) => { - let { - ACL - } = _ref, - result = _objectWithoutProperties(_ref, ["ACL"]); - - if (!ACL) { - return result; - } - - result._wperm = []; - result._rperm = []; - - for (const entry in ACL) { - if (ACL[entry].read) { - result._rperm.push(entry); - } - - if (ACL[entry].write) { - result._wperm.push(entry); - } - } - - return result; -}; - -const specialQuerykeys = ['$and', '$or', '$nor', '_rperm', '_wperm', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count']; - -const isSpecialQueryKey = key => { - return specialQuerykeys.indexOf(key) >= 0; -}; - -const validateQuery = query => { - if (query.ACL) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Cannot query on ACL.'); - } - - if (query.$or) { - if (query.$or instanceof Array) { - query.$or.forEach(validateQuery); - } else { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.'); - } - } - - if (query.$and) { - if (query.$and instanceof Array) { - query.$and.forEach(validateQuery); - } else { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $and format - use an array value.'); - } - } - - if (query.$nor) { - if (query.$nor instanceof Array && query.$nor.length > 0) { - query.$nor.forEach(validateQuery); - } else { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $nor format - use an array of at least 1 value.'); - } - } - - Object.keys(query).forEach(key => { - if (query && query[key] && query[key].$regex) { - if (typeof query[key].$options === 'string') { - if (!query[key].$options.match(/^[imxs]+$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, `Bad $options value for query: ${query[key].$options}`); - } - } - } - - if (!isSpecialQueryKey(key) && !key.match(/^[a-zA-Z][a-zA-Z0-9_\.]*$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid key name: ${key}`); - } - }); -}; // Filters out any data that shouldn't be on this REST-formatted object. - - -const filterSensitiveData = (isMaster, aclGroup, auth, operation, schema, className, protectedFields, object) => { - let userId = null; - if (auth && auth.user) userId = auth.user.id; // replace protectedFields when using pointer-permissions - - const perms = schema.getClassLevelPermissions(className); - - if (perms) { - const isReadOperation = ['get', 'find'].indexOf(operation) > -1; - - if (isReadOperation && perms.protectedFields) { - // extract protectedFields added with the pointer-permission prefix - const protectedFieldsPointerPerm = Object.keys(perms.protectedFields).filter(key => key.startsWith('userField:')).map(key => { - return { - key: key.substring(10), - value: perms.protectedFields[key] - }; - }); - const newProtectedFields = []; - let overrideProtectedFields = false; // check if the object grants the current user access based on the extracted fields - - protectedFieldsPointerPerm.forEach(pointerPerm => { - let pointerPermIncludesUser = false; - const readUserFieldValue = object[pointerPerm.key]; - - if (readUserFieldValue) { - if (Array.isArray(readUserFieldValue)) { - pointerPermIncludesUser = readUserFieldValue.some(user => user.objectId && user.objectId === userId); - } else { - pointerPermIncludesUser = readUserFieldValue.objectId && readUserFieldValue.objectId === userId; - } - } - - if (pointerPermIncludesUser) { - overrideProtectedFields = true; - newProtectedFields.push(pointerPerm.value); - } - }); // if at least one pointer-permission affected the current user - // intersect vs protectedFields from previous stage (@see addProtectedFields) - // Sets theory (intersections): A x (B x C) == (A x B) x C - - if (overrideProtectedFields && protectedFields) { - newProtectedFields.push(protectedFields); - } // intersect all sets of protectedFields - - - newProtectedFields.forEach(fields => { - if (fields) { - // if there're no protctedFields by other criteria ( id / role / auth) - // then we must intersect each set (per userField) - if (!protectedFields) { - protectedFields = fields; - } else { - protectedFields = protectedFields.filter(v => fields.includes(v)); - } - } - }); - } - } - - const isUserClass = className === '_User'; - /* special treat for the user class: don't filter protectedFields if currently loggedin user is - the retrieved user */ - - if (!(isUserClass && userId && object.objectId === userId)) { - protectedFields && protectedFields.forEach(k => delete object[k]); // fields not requested by client (excluded), - //but were needed to apply protecttedFields - - perms.protectedFields && perms.protectedFields.temporaryKeys && perms.protectedFields.temporaryKeys.forEach(k => delete object[k]); - } - - if (!isUserClass) { - return object; - } - - object.password = object._hashed_password; - delete object._hashed_password; - delete object.sessionToken; - - if (isMaster) { - return object; - } - - delete object._email_verify_token; - delete object._perishable_token; - delete object._perishable_token_expires_at; - delete object._tombstone; - delete object._email_verify_token_expires_at; - delete object._failed_login_count; - delete object._account_lockout_expires_at; - delete object._password_changed_at; - delete object._password_history; - - if (aclGroup.indexOf(object.objectId) > -1) { - return object; - } - - delete object.authData; - return object; -}; - -// Runs an update on the database. -// Returns a promise for an object with the new values for field -// modifications that don't know their results ahead of time, like -// 'increment'. -// Options: -// acl: a list of strings. If the object to be updated has an ACL, -// one of the provided strings must provide the caller with -// write permissions. -const specialKeysForUpdate = ['_hashed_password', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count', '_perishable_token_expires_at', '_password_changed_at', '_password_history']; - -const isSpecialUpdateKey = key => { - return specialKeysForUpdate.indexOf(key) >= 0; -}; - -function expandResultOnKeyPath(object, key, value) { - if (key.indexOf('.') < 0) { - object[key] = value[key]; - return object; - } - - const path = key.split('.'); - const firstKey = path[0]; - const nextPath = path.slice(1).join('.'); - object[firstKey] = expandResultOnKeyPath(object[firstKey] || {}, nextPath, value[firstKey]); - delete object[key]; - return object; -} - -function sanitizeDatabaseResult(originalObject, result) { - const response = {}; - - if (!result) { - return Promise.resolve(response); - } - - Object.keys(originalObject).forEach(key => { - const keyUpdate = originalObject[key]; // determine if that was an op - - if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op && ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) { - // only valid ops that produce an actionable result - // the op may have happend on a keypath - expandResultOnKeyPath(response, key, result); - } - }); - return Promise.resolve(response); -} - -function joinTableName(className, key) { - return `_Join:${key}:${className}`; -} - -const flattenUpdateOperatorsForCreate = object => { - for (const key in object) { - if (object[key] && object[key].__op) { - switch (object[key].__op) { - case 'Increment': - if (typeof object[key].amount !== 'number') { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = object[key].amount; - break; - - case 'Add': - if (!(object[key].objects instanceof Array)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = object[key].objects; - break; - - case 'AddUnique': - if (!(object[key].objects instanceof Array)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = object[key].objects; - break; - - case 'Remove': - if (!(object[key].objects instanceof Array)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = []; - break; - - case 'Delete': - delete object[key]; - break; - - default: - throw new _node.Parse.Error(_node.Parse.Error.COMMAND_UNAVAILABLE, `The ${object[key].__op} operator is not supported yet.`); - } - } - } -}; - -const transformAuthData = (className, object, schema) => { - if (object.authData && className === '_User') { - Object.keys(object.authData).forEach(provider => { - const providerData = object.authData[provider]; - const fieldName = `_auth_data_${provider}`; - - if (providerData == null) { - object[fieldName] = { - __op: 'Delete' - }; - } else { - object[fieldName] = providerData; - schema.fields[fieldName] = { - type: 'Object' - }; - } - }); - delete object.authData; - } -}; // Transforms a Database format ACL to a REST API format ACL - - -const untransformObjectACL = (_ref2) => { - let { - _rperm, - _wperm - } = _ref2, - output = _objectWithoutProperties(_ref2, ["_rperm", "_wperm"]); - - if (_rperm || _wperm) { - output.ACL = {}; - - (_rperm || []).forEach(entry => { - if (!output.ACL[entry]) { - output.ACL[entry] = { - read: true - }; - } else { - output.ACL[entry]['read'] = true; - } - }); - - (_wperm || []).forEach(entry => { - if (!output.ACL[entry]) { - output.ACL[entry] = { - write: true - }; - } else { - output.ACL[entry]['write'] = true; - } - }); - } - - return output; -}; -/** - * When querying, the fieldName may be compound, extract the root fieldName - * `temperature.celsius` becomes `temperature` - * @param {string} fieldName that may be a compound field name - * @returns {string} the root name of the field - */ - - -const getRootFieldName = fieldName => { - return fieldName.split('.')[0]; -}; - -const relationSchema = { - fields: { - relatedId: { - type: 'String' - }, - owningId: { - type: 'String' - } - } -}; - -class DatabaseController { - constructor(adapter, schemaCache) { - this.adapter = adapter; - this.schemaCache = schemaCache; // We don't want a mutable this.schema, because then you could have - // one request that uses different schemas for different parts of - // it. Instead, use loadSchema to get a schema. - - this.schemaPromise = null; - this._transactionalSession = null; - } - - collectionExists(className) { - return this.adapter.classExists(className); - } - - purgeCollection(className) { - return this.loadSchema().then(schemaController => schemaController.getOneSchema(className)).then(schema => this.adapter.deleteObjectsByQuery(className, schema, {})); - } - - validateClassName(className) { - if (!SchemaController.classNameIsValid(className)) { - return Promise.reject(new _node.Parse.Error(_node.Parse.Error.INVALID_CLASS_NAME, 'invalid className: ' + className)); - } - - return Promise.resolve(); - } // Returns a promise for a schemaController. - - - loadSchema(options = { - clearCache: false - }) { - if (this.schemaPromise != null) { - return this.schemaPromise; - } - - this.schemaPromise = SchemaController.load(this.adapter, this.schemaCache, options); - this.schemaPromise.then(() => delete this.schemaPromise, () => delete this.schemaPromise); - return this.loadSchema(options); - } - - loadSchemaIfNeeded(schemaController, options = { - clearCache: false - }) { - return schemaController ? Promise.resolve(schemaController) : this.loadSchema(options); - } // Returns a promise for the classname that is related to the given - // classname through the key. - // TODO: make this not in the DatabaseController interface - - - redirectClassNameForKey(className, key) { - return this.loadSchema().then(schema => { - var t = schema.getExpectedType(className, key); - - if (t != null && typeof t !== 'string' && t.type === 'Relation') { - return t.targetClass; - } - - return className; - }); - } // Uses the schema to validate the object (REST API format). - // Returns a promise that resolves to the new schema. - // This does not update this.schema, because in a situation like a - // batch request, that could confuse other users of the schema. - - - validateObject(className, object, query, runOptions) { - let schema; - const acl = runOptions.acl; - const isMaster = acl === undefined; - var aclGroup = acl || []; - return this.loadSchema().then(s => { - schema = s; - - if (isMaster) { - return Promise.resolve(); - } - - return this.canAddField(schema, className, object, aclGroup, runOptions); - }).then(() => { - return schema.validateObject(className, object, query); - }); - } - - update(className, query, update, { - acl, - many, - upsert, - addsField - } = {}, skipSanitization = false, validateOnly = false, validSchemaController) { - const originalQuery = query; - const originalUpdate = update; // Make a copy of the object, so we don't mutate the incoming data. - - update = (0, _deepcopy.default)(update); - var relationUpdates = []; - var isMaster = acl === undefined; - var aclGroup = acl || []; - return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'update')).then(() => { - relationUpdates = this.collectRelationUpdates(className, originalQuery.objectId, update); - - if (!isMaster) { - query = this.addPointerPermissions(schemaController, className, 'update', query, aclGroup); - - if (addsField) { - query = { - $and: [query, this.addPointerPermissions(schemaController, className, 'addField', query, aclGroup)] - }; - } - } - - if (!query) { - return Promise.resolve(); - } - - if (acl) { - query = addWriteACL(query, acl); - } - - validateQuery(query); - return schemaController.getOneSchema(className, true).catch(error => { - // If the schema doesn't exist, pretend it exists with no fields. This behavior - // will likely need revisiting. - if (error === undefined) { - return { - fields: {} - }; - } - - throw error; - }).then(schema => { - Object.keys(update).forEach(fieldName => { - if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); - } - - const rootFieldName = getRootFieldName(fieldName); - - if (!SchemaController.fieldNameIsValid(rootFieldName) && !isSpecialUpdateKey(rootFieldName)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); - } - }); - - for (const updateOperation in update) { - if (update[updateOperation] && typeof update[updateOperation] === 'object' && Object.keys(update[updateOperation]).some(innerKey => innerKey.includes('$') || innerKey.includes('.'))) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } - } - - update = transformObjectACL(update); - transformAuthData(className, update, schema); - - if (validateOnly) { - return this.adapter.find(className, schema, query, {}).then(result => { - if (!result || !result.length) { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - return {}; - }); - } - - if (many) { - return this.adapter.updateObjectsByQuery(className, schema, query, update, this._transactionalSession); - } else if (upsert) { - return this.adapter.upsertOneObject(className, schema, query, update, this._transactionalSession); - } else { - return this.adapter.findOneAndUpdate(className, schema, query, update, this._transactionalSession); - } - }); - }).then(result => { - if (!result) { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - if (validateOnly) { - return result; - } - - return this.handleRelationUpdates(className, originalQuery.objectId, update, relationUpdates).then(() => { - return result; - }); - }).then(result => { - if (skipSanitization) { - return Promise.resolve(result); - } - - return sanitizeDatabaseResult(originalUpdate, result); - }); - }); - } // Collect all relation-updating operations from a REST-format update. - // Returns a list of all relation updates to perform - // This mutates update. - - - collectRelationUpdates(className, objectId, update) { - var ops = []; - var deleteMe = []; - objectId = update.objectId || objectId; - - var process = (op, key) => { - if (!op) { - return; - } - - if (op.__op == 'AddRelation') { - ops.push({ - key, - op - }); - deleteMe.push(key); - } - - if (op.__op == 'RemoveRelation') { - ops.push({ - key, - op - }); - deleteMe.push(key); - } - - if (op.__op == 'Batch') { - for (var x of op.ops) { - process(x, key); - } - } - }; - - for (const key in update) { - process(update[key], key); - } - - for (const key of deleteMe) { - delete update[key]; - } - - return ops; - } // Processes relation-updating operations from a REST-format update. - // Returns a promise that resolves when all updates have been performed - - - handleRelationUpdates(className, objectId, update, ops) { - var pending = []; - objectId = update.objectId || objectId; - ops.forEach(({ - key, - op - }) => { - if (!op) { - return; - } - - if (op.__op == 'AddRelation') { - for (const object of op.objects) { - pending.push(this.addRelation(key, className, objectId, object.objectId)); - } - } - - if (op.__op == 'RemoveRelation') { - for (const object of op.objects) { - pending.push(this.removeRelation(key, className, objectId, object.objectId)); - } - } - }); - return Promise.all(pending); - } // Adds a relation. - // Returns a promise that resolves successfully iff the add was successful. - - - addRelation(key, fromClassName, fromId, toId) { - const doc = { - relatedId: toId, - owningId: fromId - }; - return this.adapter.upsertOneObject(`_Join:${key}:${fromClassName}`, relationSchema, doc, doc, this._transactionalSession); - } // Removes a relation. - // Returns a promise that resolves successfully iff the remove was - // successful. - - - removeRelation(key, fromClassName, fromId, toId) { - var doc = { - relatedId: toId, - owningId: fromId - }; - return this.adapter.deleteObjectsByQuery(`_Join:${key}:${fromClassName}`, relationSchema, doc, this._transactionalSession).catch(error => { - // We don't care if they try to delete a non-existent relation. - if (error.code == _node.Parse.Error.OBJECT_NOT_FOUND) { - return; - } - - throw error; - }); - } // Removes objects matches this query from the database. - // Returns a promise that resolves successfully iff the object was - // deleted. - // Options: - // acl: a list of strings. If the object to be updated has an ACL, - // one of the provided strings must provide the caller with - // write permissions. - - - destroy(className, query, { - acl - } = {}, validSchemaController) { - const isMaster = acl === undefined; - const aclGroup = acl || []; - return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'delete')).then(() => { - if (!isMaster) { - query = this.addPointerPermissions(schemaController, className, 'delete', query, aclGroup); - - if (!query) { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - } // delete by query - - - if (acl) { - query = addWriteACL(query, acl); - } - - validateQuery(query); - return schemaController.getOneSchema(className).catch(error => { - // If the schema doesn't exist, pretend it exists with no fields. This behavior - // will likely need revisiting. - if (error === undefined) { - return { - fields: {} - }; - } - - throw error; - }).then(parseFormatSchema => this.adapter.deleteObjectsByQuery(className, parseFormatSchema, query, this._transactionalSession)).catch(error => { - // When deleting sessions while changing passwords, don't throw an error if they don't have any sessions. - if (className === '_Session' && error.code === _node.Parse.Error.OBJECT_NOT_FOUND) { - return Promise.resolve({}); - } - - throw error; - }); - }); - }); - } // Inserts an object into the database. - // Returns a promise that resolves successfully iff the object saved. - - - create(className, object, { - acl - } = {}, validateOnly = false, validSchemaController) { - // Make a copy of the object, so we don't mutate the incoming data. - const originalObject = object; - object = transformObjectACL(object); - object.createdAt = { - iso: object.createdAt, - __type: 'Date' - }; - object.updatedAt = { - iso: object.updatedAt, - __type: 'Date' - }; - var isMaster = acl === undefined; - var aclGroup = acl || []; - const relationUpdates = this.collectRelationUpdates(className, null, object); - return this.validateClassName(className).then(() => this.loadSchemaIfNeeded(validSchemaController)).then(schemaController => { - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'create')).then(() => schemaController.enforceClassExists(className)).then(() => schemaController.getOneSchema(className, true)).then(schema => { - transformAuthData(className, object, schema); - flattenUpdateOperatorsForCreate(object); - - if (validateOnly) { - return {}; - } - - return this.adapter.createObject(className, SchemaController.convertSchemaToAdapterSchema(schema), object, this._transactionalSession); - }).then(result => { - if (validateOnly) { - return originalObject; - } - - return this.handleRelationUpdates(className, object.objectId, object, relationUpdates).then(() => { - return sanitizeDatabaseResult(originalObject, result.ops[0]); - }); - }); - }); - } - - canAddField(schema, className, object, aclGroup, runOptions) { - const classSchema = schema.schemaData[className]; - - if (!classSchema) { - return Promise.resolve(); - } - - const fields = Object.keys(object); - const schemaFields = Object.keys(classSchema.fields); - const newKeys = fields.filter(field => { - // Skip fields that are unset - if (object[field] && object[field].__op && object[field].__op === 'Delete') { - return false; - } - - return schemaFields.indexOf(field) < 0; - }); - - if (newKeys.length > 0) { - // adds a marker that new field is being adding during update - runOptions.addsField = true; - const action = runOptions.action; - return schema.validatePermission(className, aclGroup, 'addField', action); - } - - return Promise.resolve(); - } // Won't delete collections in the system namespace - - /** - * Delete all classes and clears the schema cache - * - * @param {boolean} fast set to true if it's ok to just delete rows and not indexes - * @returns {Promise} when the deletions completes - */ - - - deleteEverything(fast = false) { - this.schemaPromise = null; - return Promise.all([this.adapter.deleteAllClasses(fast), this.schemaCache.clear()]); - } // Returns a promise for a list of related ids given an owning id. - // className here is the owning className. - - - relatedIds(className, key, owningId, queryOptions) { - const { - skip, - limit, - sort - } = queryOptions; - const findOptions = {}; - - if (sort && sort.createdAt && this.adapter.canSortOnJoinTables) { - findOptions.sort = { - _id: sort.createdAt - }; - findOptions.limit = limit; - findOptions.skip = skip; - queryOptions.skip = 0; - } - - return this.adapter.find(joinTableName(className, key), relationSchema, { - owningId - }, findOptions).then(results => results.map(result => result.relatedId)); - } // Returns a promise for a list of owning ids given some related ids. - // className here is the owning className. - - - owningIds(className, key, relatedIds) { - return this.adapter.find(joinTableName(className, key), relationSchema, { - relatedId: { - $in: relatedIds - } - }, { - keys: ['owningId'] - }).then(results => results.map(result => result.owningId)); - } // Modifies query so that it no longer has $in on relation fields, or - // equal-to-pointer constraints on relation fields. - // Returns a promise that resolves when query is mutated - - - reduceInRelation(className, query, schema) { - // Search for an in-relation or equal-to-relation - // Make it sequential for now, not sure of paralleization side effects - if (query['$or']) { - const ors = query['$or']; - return Promise.all(ors.map((aQuery, index) => { - return this.reduceInRelation(className, aQuery, schema).then(aQuery => { - query['$or'][index] = aQuery; - }); - })).then(() => { - return Promise.resolve(query); - }); - } - - const promises = Object.keys(query).map(key => { - const t = schema.getExpectedType(className, key); - - if (!t || t.type !== 'Relation') { - return Promise.resolve(query); - } - - let queries = null; - - if (query[key] && (query[key]['$in'] || query[key]['$ne'] || query[key]['$nin'] || query[key].__type == 'Pointer')) { - // Build the list of queries - queries = Object.keys(query[key]).map(constraintKey => { - let relatedIds; - let isNegation = false; - - if (constraintKey === 'objectId') { - relatedIds = [query[key].objectId]; - } else if (constraintKey == '$in') { - relatedIds = query[key]['$in'].map(r => r.objectId); - } else if (constraintKey == '$nin') { - isNegation = true; - relatedIds = query[key]['$nin'].map(r => r.objectId); - } else if (constraintKey == '$ne') { - isNegation = true; - relatedIds = [query[key]['$ne'].objectId]; - } else { - return; - } - - return { - isNegation, - relatedIds - }; - }); - } else { - queries = [{ - isNegation: false, - relatedIds: [] - }]; - } // remove the current queryKey as we don,t need it anymore - - - delete query[key]; // execute each query independently to build the list of - // $in / $nin - - const promises = queries.map(q => { - if (!q) { - return Promise.resolve(); - } - - return this.owningIds(className, key, q.relatedIds).then(ids => { - if (q.isNegation) { - this.addNotInObjectIdsIds(ids, query); - } else { - this.addInObjectIdsIds(ids, query); - } - - return Promise.resolve(); - }); - }); - return Promise.all(promises).then(() => { - return Promise.resolve(); - }); - }); - return Promise.all(promises).then(() => { - return Promise.resolve(query); - }); - } // Modifies query so that it no longer has $relatedTo - // Returns a promise that resolves when query is mutated - - - reduceRelationKeys(className, query, queryOptions) { - if (query['$or']) { - return Promise.all(query['$or'].map(aQuery => { - return this.reduceRelationKeys(className, aQuery, queryOptions); - })); - } - - var relatedTo = query['$relatedTo']; - - if (relatedTo) { - return this.relatedIds(relatedTo.object.className, relatedTo.key, relatedTo.object.objectId, queryOptions).then(ids => { - delete query['$relatedTo']; - this.addInObjectIdsIds(ids, query); - return this.reduceRelationKeys(className, query, queryOptions); - }).then(() => {}); - } - } - - addInObjectIdsIds(ids = null, query) { - const idsFromString = typeof query.objectId === 'string' ? [query.objectId] : null; - const idsFromEq = query.objectId && query.objectId['$eq'] ? [query.objectId['$eq']] : null; - const idsFromIn = query.objectId && query.objectId['$in'] ? query.objectId['$in'] : null; // -disable-next - - const allIds = [idsFromString, idsFromEq, idsFromIn, ids].filter(list => list !== null); - const totalLength = allIds.reduce((memo, list) => memo + list.length, 0); - let idsIntersection = []; - - if (totalLength > 125) { - idsIntersection = _intersect.default.big(allIds); - } else { - idsIntersection = (0, _intersect.default)(allIds); - } // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. - - - if (!('objectId' in query)) { - query.objectId = { - $in: undefined - }; - } else if (typeof query.objectId === 'string') { - query.objectId = { - $in: undefined, - $eq: query.objectId - }; - } - - query.objectId['$in'] = idsIntersection; - return query; - } - - addNotInObjectIdsIds(ids = [], query) { - const idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : []; - let allIds = [...idsFromNin, ...ids].filter(list => list !== null); // make a set and spread to remove duplicates - - allIds = [...new Set(allIds)]; // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. - - if (!('objectId' in query)) { - query.objectId = { - $nin: undefined - }; - } else if (typeof query.objectId === 'string') { - query.objectId = { - $nin: undefined, - $eq: query.objectId - }; - } - - query.objectId['$nin'] = allIds; - return query; - } // Runs a query on the database. - // Returns a promise that resolves to a list of items. - // Options: - // skip number of results to skip. - // limit limit to this number of results. - // sort an object where keys are the fields to sort by. - // the value is +1 for ascending, -1 for descending. - // count run a count instead of returning results. - // acl restrict this operation with an ACL for the provided array - // of user objectIds and roles. acl: null means no user. - // when this field is not present, don't do anything regarding ACLs. - // caseInsensitive make string comparisons case insensitive - // TODO: make userIds not needed here. The db adapter shouldn't know - // anything about users, ideally. Then, improve the format of the ACL - // arg to work like the others. - - - find(className, query, { - skip, - limit, - acl, - sort = {}, - count, - keys, - op, - distinct, - pipeline, - readPreference, - hint, - caseInsensitive = false, - explain - } = {}, auth = {}, validSchemaController) { - const isMaster = acl === undefined; - const aclGroup = acl || []; - op = op || (typeof query.objectId == 'string' && Object.keys(query).length === 1 ? 'get' : 'find'); // Count operation if counting - - op = count === true ? 'count' : op; - let classExists = true; - return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { - //Allow volatile classes if querying with Master (for _PushStatus) - //TODO: Move volatile classes concept into mongo adapter, postgres adapter shouldn't care - //that api.parse.com breaks when _PushStatus exists in mongo. - return schemaController.getOneSchema(className, isMaster).catch(error => { - // Behavior for non-existent classes is kinda weird on Parse.com. Probably doesn't matter too much. - // For now, pretend the class exists but has no objects, - if (error === undefined) { - classExists = false; - return { - fields: {} - }; - } - - throw error; - }).then(schema => { - // Parse.com treats queries on _created_at and _updated_at as if they were queries on createdAt and updatedAt, - // so duplicate that behavior here. If both are specified, the correct behavior to match Parse.com is to - // use the one that appears first in the sort list. - if (sort._created_at) { - sort.createdAt = sort._created_at; - delete sort._created_at; - } - - if (sort._updated_at) { - sort.updatedAt = sort._updated_at; - delete sort._updated_at; - } - - const queryOptions = { - skip, - limit, - sort, - keys, - readPreference, - hint, - caseInsensitive, - explain - }; - Object.keys(sort).forEach(fieldName => { - if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Cannot sort by ${fieldName}`); - } - - const rootFieldName = getRootFieldName(fieldName); - - if (!SchemaController.fieldNameIsValid(rootFieldName)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); - } - }); - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, op)).then(() => this.reduceRelationKeys(className, query, queryOptions)).then(() => this.reduceInRelation(className, query, schemaController)).then(() => { - let protectedFields; - - if (!isMaster) { - query = this.addPointerPermissions(schemaController, className, op, query, aclGroup); - /* Don't use projections to optimize the protectedFields since the protectedFields - based on pointer-permissions are determined after querying. The filtering can - overwrite the protected fields. */ - - protectedFields = this.addProtectedFields(schemaController, className, query, aclGroup, auth, queryOptions); - } - - if (!query) { - if (op === 'get') { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } else { - return []; - } - } - - if (!isMaster) { - if (op === 'update' || op === 'delete') { - query = addWriteACL(query, aclGroup); - } else { - query = addReadACL(query, aclGroup); - } - } - - validateQuery(query); - - if (count) { - if (!classExists) { - return 0; - } else { - return this.adapter.count(className, schema, query, readPreference, undefined, hint); - } - } else if (distinct) { - if (!classExists) { - return []; - } else { - return this.adapter.distinct(className, schema, query, distinct); - } - } else if (pipeline) { - if (!classExists) { - return []; - } else { - return this.adapter.aggregate(className, schema, pipeline, readPreference, hint, explain); - } - } else if (explain) { - return this.adapter.find(className, schema, query, queryOptions); - } else { - return this.adapter.find(className, schema, query, queryOptions).then(objects => objects.map(object => { - object = untransformObjectACL(object); - return filterSensitiveData(isMaster, aclGroup, auth, op, schemaController, className, protectedFields, object); - })).catch(error => { - throw new _node.Parse.Error(_node.Parse.Error.INTERNAL_SERVER_ERROR, error); - }); - } - }); - }); - }); - } - - deleteSchema(className) { - return this.loadSchema({ - clearCache: true - }).then(schemaController => schemaController.getOneSchema(className, true)).catch(error => { - if (error === undefined) { - return { - fields: {} - }; - } else { - throw error; - } - }).then(schema => { - return this.collectionExists(className).then(() => this.adapter.count(className, { - fields: {} - }, null, '', false)).then(count => { - if (count > 0) { - throw new _node.Parse.Error(255, `Class ${className} is not empty, contains ${count} objects, cannot drop schema.`); - } - - return this.adapter.deleteClass(className); - }).then(wasParseCollection => { - if (wasParseCollection) { - const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); - return Promise.all(relationFieldNames.map(name => this.adapter.deleteClass(joinTableName(className, name)))).then(() => { - return; - }); - } else { - return Promise.resolve(); - } - }); - }); - } // Constraints query using CLP's pointer permissions (PP) if any. - // 1. Etract the user id from caller's ACLgroup; - // 2. Exctract a list of field names that are PP for target collection and operation; - // 3. Constraint the original query so that each PP field must - // point to caller's id (or contain it in case of PP field being an array) - - - addPointerPermissions(schema, className, operation, query, aclGroup = []) { - // Check if class has public permission for operation - // If the BaseCLP pass, let go through - if (schema.testPermissionsForClassName(className, aclGroup, operation)) { - return query; - } - - const perms = schema.getClassLevelPermissions(className); - const userACL = aclGroup.filter(acl => { - return acl.indexOf('role:') != 0 && acl != '*'; - }); - const groupKey = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; - const permFields = []; - - if (perms[operation] && perms[operation].pointerFields) { - permFields.push(...perms[operation].pointerFields); - } - - if (perms[groupKey]) { - for (const field of perms[groupKey]) { - if (!permFields.includes(field)) { - permFields.push(field); - } - } - } // the ACL should have exactly 1 user - - - if (permFields.length > 0) { - // the ACL should have exactly 1 user - // No user set return undefined - // If the length is > 1, that means we didn't de-dupe users correctly - if (userACL.length != 1) { - return; - } - - const userId = userACL[0]; - const userPointer = { - __type: 'Pointer', - className: '_User', - objectId: userId - }; - const queries = permFields.map(key => { - const fieldDescriptor = schema.getExpectedType(className, key); - const fieldType = fieldDescriptor && typeof fieldDescriptor === 'object' && Object.prototype.hasOwnProperty.call(fieldDescriptor, 'type') ? fieldDescriptor.type : null; - let queryClause; - - if (fieldType === 'Pointer') { - // constraint for single pointer setup - queryClause = { - [key]: userPointer - }; - } else if (fieldType === 'Array') { - // constraint for users-array setup - queryClause = { - [key]: { - $all: [userPointer] - } - }; - } else if (fieldType === 'Object') { - // constraint for object setup - queryClause = { - [key]: userPointer - }; - } else { - // This means that there is a CLP field of an unexpected type. This condition should not happen, which is - // why is being treated as an error. - throw Error(`An unexpected condition occurred when resolving pointer permissions: ${className} ${key}`); - } // if we already have a constraint on the key, use the $and - - - if (Object.prototype.hasOwnProperty.call(query, key)) { - return { - $and: [queryClause, query] - }; - } // otherwise just add the constaint - - - return Object.assign({}, query, queryClause); - }); - return queries.length === 1 ? queries[0] : { - $or: queries - }; - } else { - return query; - } - } - - addProtectedFields(schema, className, query = {}, aclGroup = [], auth = {}, queryOptions = {}) { - const perms = schema.getClassLevelPermissions(className); - if (!perms) return null; - const protectedFields = perms.protectedFields; - if (!protectedFields) return null; - if (aclGroup.indexOf(query.objectId) > -1) return null; // for queries where "keys" are set and do not include all 'userField':{field}, - // we have to transparently include it, and then remove before returning to client - // Because if such key not projected the permission won't be enforced properly - // PS this is called when 'excludeKeys' already reduced to 'keys' - - const preserveKeys = queryOptions.keys; // these are keys that need to be included only - // to be able to apply protectedFields by pointer - // and then unset before returning to client (later in filterSensitiveFields) - - const serverOnlyKeys = []; - const authenticated = auth.user; // map to allow check without array search - - const roles = (auth.userRoles || []).reduce((acc, r) => { - acc[r] = protectedFields[r]; - return acc; - }, {}); // array of sets of protected fields. separate item for each applicable criteria - - const protectedKeysSets = []; - - for (const key in protectedFields) { - // skip userFields - if (key.startsWith('userField:')) { - if (preserveKeys) { - const fieldName = key.substring(10); - - if (!preserveKeys.includes(fieldName)) { - // 1. put it there temporarily - queryOptions.keys && queryOptions.keys.push(fieldName); // 2. preserve it delete later - - serverOnlyKeys.push(fieldName); - } - } - - continue; - } // add public tier - - - if (key === '*') { - protectedKeysSets.push(protectedFields[key]); - continue; - } - - if (authenticated) { - if (key === 'authenticated') { - // for logged in users - protectedKeysSets.push(protectedFields[key]); - continue; - } - - if (roles[key] && key.startsWith('role:')) { - // add applicable roles - protectedKeysSets.push(roles[key]); - } - } - } // check if there's a rule for current user's id - - - if (authenticated) { - const userId = auth.user.id; - - if (perms.protectedFields[userId]) { - protectedKeysSets.push(perms.protectedFields[userId]); - } - } // preserve fields to be removed before sending response to client - - - if (serverOnlyKeys.length > 0) { - perms.protectedFields.temporaryKeys = serverOnlyKeys; - } - - let protectedKeys = protectedKeysSets.reduce((acc, next) => { - if (next) { - acc.push(...next); - } - - return acc; - }, []); // intersect all sets of protectedFields - - protectedKeysSets.forEach(fields => { - if (fields) { - protectedKeys = protectedKeys.filter(v => fields.includes(v)); - } - }); - return protectedKeys; - } - - createTransactionalSession() { - return this.adapter.createTransactionalSession().then(transactionalSession => { - this._transactionalSession = transactionalSession; - }); - } - - commitTransactionalSession() { - if (!this._transactionalSession) { - throw new Error('There is no transactional session to commit'); - } - - return this.adapter.commitTransactionalSession(this._transactionalSession).then(() => { - this._transactionalSession = null; - }); - } - - abortTransactionalSession() { - if (!this._transactionalSession) { - throw new Error('There is no transactional session to abort'); - } - - return this.adapter.abortTransactionalSession(this._transactionalSession).then(() => { - this._transactionalSession = null; - }); - } // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to - // have a Parse app without it having a _User collection. - - - performInitialization() { - const requiredUserFields = { - fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._User) - }; - const requiredRoleFields = { - fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Role) - }; - const requiredIdempotencyFields = { - fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Idempotency) - }; - const userClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_User')); - const roleClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_Role')); - const idempotencyClassPromise = this.adapter instanceof _MongoStorageAdapter.default ? this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')) : Promise.resolve(); - const usernameUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['username'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for usernames: ', error); - - throw error; - }); - const usernameCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)).catch(error => { - _logger.default.warn('Unable to create case insensitive username index: ', error); - - throw error; - }); - const emailUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['email'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for user email addresses: ', error); - - throw error; - }); - const emailCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true)).catch(error => { - _logger.default.warn('Unable to create case insensitive email index: ', error); - - throw error; - }); - const roleUniqueness = roleClassPromise.then(() => this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for role name: ', error); - - throw error; - }); - const idempotencyRequestIdIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureUniqueness('_Idempotency', requiredIdempotencyFields, ['reqId'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for idempotency request ID: ', error); - - throw error; - }) : Promise.resolve(); - const idempotencyExpireIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureIndex('_Idempotency', requiredIdempotencyFields, ['expire'], 'ttl', false, { - ttl: 0 - })).catch(error => { - _logger.default.warn('Unable to create TTL index for idempotency expire date: ', error); - - throw error; - }) : Promise.resolve(); - const indexPromise = this.adapter.updateSchemaWithIndexes(); // Create tables for volatile classes - - const adapterInit = this.adapter.performInitialization({ - VolatileClassesSchemas: SchemaController.VolatileClassesSchemas - }); - return Promise.all([usernameUniqueness, usernameCaseInsensitiveIndex, emailUniqueness, emailCaseInsensitiveIndex, roleUniqueness, idempotencyRequestIdIndex, idempotencyExpireIndex, adapterInit, indexPromise]); - } - -} - -module.exports = DatabaseController; // Expose validateQuery for tests - -module.exports._validateQuery = validateQuery; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9EYXRhYmFzZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiYWRkV3JpdGVBQ0wiLCJxdWVyeSIsImFjbCIsIm5ld1F1ZXJ5IiwiXyIsImNsb25lRGVlcCIsIl93cGVybSIsIiRpbiIsImFkZFJlYWRBQ0wiLCJfcnBlcm0iLCJ0cmFuc2Zvcm1PYmplY3RBQ0wiLCJBQ0wiLCJyZXN1bHQiLCJlbnRyeSIsInJlYWQiLCJwdXNoIiwid3JpdGUiLCJzcGVjaWFsUXVlcnlrZXlzIiwiaXNTcGVjaWFsUXVlcnlLZXkiLCJrZXkiLCJpbmRleE9mIiwidmFsaWRhdGVRdWVyeSIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1FVRVJZIiwiJG9yIiwiQXJyYXkiLCJmb3JFYWNoIiwiJGFuZCIsIiRub3IiLCJsZW5ndGgiLCJPYmplY3QiLCJrZXlzIiwiJHJlZ2V4IiwiJG9wdGlvbnMiLCJtYXRjaCIsIklOVkFMSURfS0VZX05BTUUiLCJmaWx0ZXJTZW5zaXRpdmVEYXRhIiwiaXNNYXN0ZXIiLCJhY2xHcm91cCIsImF1dGgiLCJvcGVyYXRpb24iLCJzY2hlbWEiLCJjbGFzc05hbWUiLCJwcm90ZWN0ZWRGaWVsZHMiLCJvYmplY3QiLCJ1c2VySWQiLCJ1c2VyIiwiaWQiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlzUmVhZE9wZXJhdGlvbiIsInByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtIiwiZmlsdGVyIiwic3RhcnRzV2l0aCIsIm1hcCIsInN1YnN0cmluZyIsInZhbHVlIiwibmV3UHJvdGVjdGVkRmllbGRzIiwib3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMiLCJwb2ludGVyUGVybSIsInBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyIiwicmVhZFVzZXJGaWVsZFZhbHVlIiwiaXNBcnJheSIsInNvbWUiLCJvYmplY3RJZCIsImZpZWxkcyIsInYiLCJpbmNsdWRlcyIsImlzVXNlckNsYXNzIiwiayIsInRlbXBvcmFyeUtleXMiLCJwYXNzd29yZCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJzZXNzaW9uVG9rZW4iLCJfZW1haWxfdmVyaWZ5X3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX3RvbWJzdG9uZSIsIl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCIsIl9mYWlsZWRfbG9naW5fY291bnQiLCJfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsIl9wYXNzd29yZF9oaXN0b3J5IiwiYXV0aERhdGEiLCJzcGVjaWFsS2V5c0ZvclVwZGF0ZSIsImlzU3BlY2lhbFVwZGF0ZUtleSIsImV4cGFuZFJlc3VsdE9uS2V5UGF0aCIsInBhdGgiLCJzcGxpdCIsImZpcnN0S2V5IiwibmV4dFBhdGgiLCJzbGljZSIsImpvaW4iLCJzYW5pdGl6ZURhdGFiYXNlUmVzdWx0Iiwib3JpZ2luYWxPYmplY3QiLCJyZXNwb25zZSIsIlByb21pc2UiLCJyZXNvbHZlIiwia2V5VXBkYXRlIiwiX19vcCIsImpvaW5UYWJsZU5hbWUiLCJmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlIiwiYW1vdW50IiwiSU5WQUxJRF9KU09OIiwib2JqZWN0cyIsIkNPTU1BTkRfVU5BVkFJTEFCTEUiLCJ0cmFuc2Zvcm1BdXRoRGF0YSIsInByb3ZpZGVyIiwicHJvdmlkZXJEYXRhIiwiZmllbGROYW1lIiwidHlwZSIsInVudHJhbnNmb3JtT2JqZWN0QUNMIiwib3V0cHV0IiwiZ2V0Um9vdEZpZWxkTmFtZSIsInJlbGF0aW9uU2NoZW1hIiwicmVsYXRlZElkIiwib3duaW5nSWQiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJzY2hlbWFDYWNoZSIsInNjaGVtYVByb21pc2UiLCJfdHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb2xsZWN0aW9uRXhpc3RzIiwiY2xhc3NFeGlzdHMiLCJwdXJnZUNvbGxlY3Rpb24iLCJsb2FkU2NoZW1hIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRPbmVTY2hlbWEiLCJkZWxldGVPYmplY3RzQnlRdWVyeSIsInZhbGlkYXRlQ2xhc3NOYW1lIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZUlzVmFsaWQiLCJyZWplY3QiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJvcHRpb25zIiwiY2xlYXJDYWNoZSIsImxvYWQiLCJsb2FkU2NoZW1hSWZOZWVkZWQiLCJyZWRpcmVjdENsYXNzTmFtZUZvcktleSIsInQiLCJnZXRFeHBlY3RlZFR5cGUiLCJ0YXJnZXRDbGFzcyIsInZhbGlkYXRlT2JqZWN0IiwicnVuT3B0aW9ucyIsInVuZGVmaW5lZCIsInMiLCJjYW5BZGRGaWVsZCIsInVwZGF0ZSIsIm1hbnkiLCJ1cHNlcnQiLCJhZGRzRmllbGQiLCJza2lwU2FuaXRpemF0aW9uIiwidmFsaWRhdGVPbmx5IiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwib3JpZ2luYWxRdWVyeSIsIm9yaWdpbmFsVXBkYXRlIiwicmVsYXRpb25VcGRhdGVzIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiY29sbGVjdFJlbGF0aW9uVXBkYXRlcyIsImFkZFBvaW50ZXJQZXJtaXNzaW9ucyIsImNhdGNoIiwiZXJyb3IiLCJyb290RmllbGROYW1lIiwiZmllbGROYW1lSXNWYWxpZCIsInVwZGF0ZU9wZXJhdGlvbiIsImlubmVyS2V5IiwiSU5WQUxJRF9ORVNURURfS0VZIiwiZmluZCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1cGRhdGVPYmplY3RzQnlRdWVyeSIsInVwc2VydE9uZU9iamVjdCIsImZpbmRPbmVBbmRVcGRhdGUiLCJoYW5kbGVSZWxhdGlvblVwZGF0ZXMiLCJvcHMiLCJkZWxldGVNZSIsInByb2Nlc3MiLCJvcCIsIngiLCJwZW5kaW5nIiwiYWRkUmVsYXRpb24iLCJyZW1vdmVSZWxhdGlvbiIsImFsbCIsImZyb21DbGFzc05hbWUiLCJmcm9tSWQiLCJ0b0lkIiwiZG9jIiwiY29kZSIsImRlc3Ryb3kiLCJwYXJzZUZvcm1hdFNjaGVtYSIsImNyZWF0ZSIsImNyZWF0ZWRBdCIsImlzbyIsIl9fdHlwZSIsInVwZGF0ZWRBdCIsImVuZm9yY2VDbGFzc0V4aXN0cyIsImNyZWF0ZU9iamVjdCIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJjbGFzc1NjaGVtYSIsInNjaGVtYURhdGEiLCJzY2hlbWFGaWVsZHMiLCJuZXdLZXlzIiwiZmllbGQiLCJhY3Rpb24iLCJkZWxldGVFdmVyeXRoaW5nIiwiZmFzdCIsImRlbGV0ZUFsbENsYXNzZXMiLCJjbGVhciIsInJlbGF0ZWRJZHMiLCJxdWVyeU9wdGlvbnMiLCJza2lwIiwibGltaXQiLCJzb3J0IiwiZmluZE9wdGlvbnMiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiX2lkIiwicmVzdWx0cyIsIm93bmluZ0lkcyIsInJlZHVjZUluUmVsYXRpb24iLCJvcnMiLCJhUXVlcnkiLCJpbmRleCIsInByb21pc2VzIiwicXVlcmllcyIsImNvbnN0cmFpbnRLZXkiLCJpc05lZ2F0aW9uIiwiciIsInEiLCJpZHMiLCJhZGROb3RJbk9iamVjdElkc0lkcyIsImFkZEluT2JqZWN0SWRzSWRzIiwicmVkdWNlUmVsYXRpb25LZXlzIiwicmVsYXRlZFRvIiwiaWRzRnJvbVN0cmluZyIsImlkc0Zyb21FcSIsImlkc0Zyb21JbiIsImFsbElkcyIsImxpc3QiLCJ0b3RhbExlbmd0aCIsInJlZHVjZSIsIm1lbW8iLCJpZHNJbnRlcnNlY3Rpb24iLCJpbnRlcnNlY3QiLCJiaWciLCIkZXEiLCJpZHNGcm9tTmluIiwiU2V0IiwiJG5pbiIsImNvdW50IiwiZGlzdGluY3QiLCJwaXBlbGluZSIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCJfY3JlYXRlZF9hdCIsIl91cGRhdGVkX2F0IiwiYWRkUHJvdGVjdGVkRmllbGRzIiwiYWdncmVnYXRlIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiZGVsZXRlU2NoZW1hIiwiZGVsZXRlQ2xhc3MiLCJ3YXNQYXJzZUNvbGxlY3Rpb24iLCJyZWxhdGlvbkZpZWxkTmFtZXMiLCJuYW1lIiwidGVzdFBlcm1pc3Npb25zRm9yQ2xhc3NOYW1lIiwidXNlckFDTCIsImdyb3VwS2V5IiwicGVybUZpZWxkcyIsInBvaW50ZXJGaWVsZHMiLCJ1c2VyUG9pbnRlciIsImZpZWxkRGVzY3JpcHRvciIsImZpZWxkVHlwZSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInF1ZXJ5Q2xhdXNlIiwiJGFsbCIsImFzc2lnbiIsInByZXNlcnZlS2V5cyIsInNlcnZlck9ubHlLZXlzIiwiYXV0aGVudGljYXRlZCIsInJvbGVzIiwidXNlclJvbGVzIiwiYWNjIiwicHJvdGVjdGVkS2V5c1NldHMiLCJwcm90ZWN0ZWRLZXlzIiwibmV4dCIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCJyZXF1aXJlZFVzZXJGaWVsZHMiLCJkZWZhdWx0Q29sdW1ucyIsIl9EZWZhdWx0IiwiX1VzZXIiLCJyZXF1aXJlZFJvbGVGaWVsZHMiLCJfUm9sZSIsInJlcXVpcmVkSWRlbXBvdGVuY3lGaWVsZHMiLCJfSWRlbXBvdGVuY3kiLCJ1c2VyQ2xhc3NQcm9taXNlIiwicm9sZUNsYXNzUHJvbWlzZSIsImlkZW1wb3RlbmN5Q2xhc3NQcm9taXNlIiwiTW9uZ29TdG9yYWdlQWRhcHRlciIsInVzZXJuYW1lVW5pcXVlbmVzcyIsImVuc3VyZVVuaXF1ZW5lc3MiLCJsb2dnZXIiLCJ3YXJuIiwidXNlcm5hbWVDYXNlSW5zZW5zaXRpdmVJbmRleCIsImVuc3VyZUluZGV4IiwiZW1haWxVbmlxdWVuZXNzIiwiZW1haWxDYXNlSW5zZW5zaXRpdmVJbmRleCIsInJvbGVVbmlxdWVuZXNzIiwiaWRlbXBvdGVuY3lSZXF1ZXN0SWRJbmRleCIsImlkZW1wb3RlbmN5RXhwaXJlSW5kZXgiLCJ0dGwiLCJpbmRleFByb21pc2UiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsImFkYXB0ZXJJbml0IiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsIm1vZHVsZSIsImV4cG9ydHMiLCJfdmFsaWRhdGVRdWVyeSJdLCJtYXBwaW5ncyI6Ijs7QUFLQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUEyTkE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXhOQSxTQUFTQSxXQUFULENBQXFCQyxLQUFyQixFQUE0QkMsR0FBNUIsRUFBaUM7QUFDL0IsUUFBTUMsUUFBUSxHQUFHQyxnQkFBRUMsU0FBRixDQUFZSixLQUFaLENBQWpCLENBRCtCLENBRS9COzs7QUFDQUUsRUFBQUEsUUFBUSxDQUFDRyxNQUFULEdBQWtCO0FBQUVDLElBQUFBLEdBQUcsRUFBRSxDQUFDLElBQUQsRUFBTyxHQUFHTCxHQUFWO0FBQVAsR0FBbEI7QUFDQSxTQUFPQyxRQUFQO0FBQ0Q7O0FBRUQsU0FBU0ssVUFBVCxDQUFvQlAsS0FBcEIsRUFBMkJDLEdBQTNCLEVBQWdDO0FBQzlCLFFBQU1DLFFBQVEsR0FBR0MsZ0JBQUVDLFNBQUYsQ0FBWUosS0FBWixDQUFqQixDQUQ4QixDQUU5Qjs7O0FBQ0FFLEVBQUFBLFFBQVEsQ0FBQ00sTUFBVCxHQUFrQjtBQUFFRixJQUFBQSxHQUFHLEVBQUUsQ0FBQyxJQUFELEVBQU8sR0FBUCxFQUFZLEdBQUdMLEdBQWY7QUFBUCxHQUFsQjtBQUNBLFNBQU9DLFFBQVA7QUFDRCxDLENBRUQ7OztBQUNBLE1BQU1PLGtCQUFrQixHQUFHLFVBQXdCO0FBQUEsTUFBdkI7QUFBRUMsSUFBQUE7QUFBRixHQUF1QjtBQUFBLE1BQWJDLE1BQWE7O0FBQ2pELE1BQUksQ0FBQ0QsR0FBTCxFQUFVO0FBQ1IsV0FBT0MsTUFBUDtBQUNEOztBQUVEQSxFQUFBQSxNQUFNLENBQUNOLE1BQVAsR0FBZ0IsRUFBaEI7QUFDQU0sRUFBQUEsTUFBTSxDQUFDSCxN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QUFMLENBQWF3TSx1QkFBYixFQUFyQixDQTdHc0IsQ0ErR3RCOztBQUNBLFVBQU1DLFdBQVcsR0FBRyxLQUFLek0sT0FBTCxDQUFhOEsscUJBQWIsQ0FBbUM7QUFDckQ0QixNQUFBQSxzQkFBc0IsRUFBRTdMLGdCQUFnQixDQUFDNkw7QUFEWSxLQUFuQyxDQUFwQjtBQUdBLFdBQU9qTyxPQUFPLENBQUN1RixHQUFSLENBQVksQ0FDakIySCxrQkFEaUIsRUFFakJJLDRCQUZpQixFQUdqQkUsZUFIaUIsRUFJakJDLHlCQUppQixFQUtqQkMsY0FMaUIsRUFNakJDLHlCQU5pQixFQU9qQkMsc0JBUGlCLEVBUWpCSSxXQVJpQixFQVNqQkYsWUFUaUIsQ0FBWixDQUFQO0FBV0Q7O0FBM3lDc0I7O0FBZ3pDekJJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjlNLGtCQUFqQixDLENBQ0E7O0FBQ0E2TSxNQUFNLENBQUNDLE9BQVAsQ0FBZUMsY0FBZixHQUFnQ2hULGFBQWhDIiwic291cmNlc0NvbnRlbnQiOlsi77u/Ly8gQGZsb3dcbi8vIEEgZGF0YWJhc2UgYWRhcHRlciB0aGF0IHdvcmtzIHdpdGggZGF0YSBleHBvcnRlZCBmcm9tIHRoZSBob3N0ZWRcbi8vIFBhcnNlIGRhdGFiYXNlLlxuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBpbnRlcnNlY3QgZnJvbSAnaW50ZXJzZWN0Jztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IGRlZXBjb3B5IGZyb20gJ2RlZXBjb3B5JztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCAqIGFzIFNjaGVtYUNvbnRyb2xsZXIgZnJvbSAnLi9TY2hlbWFDb250cm9sbGVyJztcbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7IFF1ZXJ5T3B0aW9ucywgRnVsbFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuXG5mdW5jdGlvbiBhZGRXcml0ZUFDTChxdWVyeSwgYWNsKSB7XG4gIGNvbnN0IG5ld1F1ZXJ5ID0gXy5jbG9uZURlZXAocXVlcnkpO1xuICAvL0Nhbid0IGJlIGFueSBleGlzdGluZyAnX3dwZXJtJyBxdWVyeSwgd2UgZG9uJ3QgYWxsb3cgY2xpZW50IHF1ZXJpZXMgb24gdGhhdCwgbm8gbmVlZCB0byAkYW5kXG4gIG5ld1F1ZXJ5Ll93cGVybSA9IHsgJGluOiBbbnVsbCwgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbmZ1bmN0aW9uIGFkZFJlYWRBQ0wocXVlcnksIGFjbCkge1xuICBjb25zdCBuZXdRdWVyeSA9IF8uY2xvbmVEZWVwKHF1ZXJ5KTtcbiAgLy9DYW4ndCBiZSBhbnkgZXhpc3RpbmcgJ19ycGVybScgcXVlcnksIHdlIGRvbid0IGFsbG93IGNsaWVudCBxdWVyaWVzIG9uIHRoYXQsIG5vIG5lZWQgdG8gJGFuZFxuICBuZXdRdWVyeS5fcnBlcm0gPSB7ICRpbjogW251bGwsICcqJywgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbi8vIFRyYW5zZm9ybXMgYSBSRVNUIEFQSSBmb3JtYXR0ZWQgQUNMIG9iamVjdCB0byBvdXIgdHdvLWZpZWxkIG1vbmdvIGZvcm1hdC5cbmNvbnN0IHRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IEFDTCwgLi4ucmVzdWx0IH0pID0+IHtcbiAgaWYgKCFBQ0wpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcmVzdWx0Ll93cGVybSA9IFtdO1xuICByZXN1bHQuX3JwZXJtID0gW107XG5cbiAgZm9yIChjb25zdCBlbnRyeSBpbiBBQ0wpIHtcbiAgICBpZiAoQUNMW2VudHJ5XS5yZWFkKSB7XG4gICAgICByZXN1bHQuX3JwZXJtLnB1c2goZW50cnkpO1xuICAgIH1cbiAgICBpZiAoQUNMW2VudHJ5XS53cml0ZSkge1xuICAgICAgcmVzdWx0Ll93cGVybS5wdXNoKGVudHJ5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbnN0IHNwZWNpYWxRdWVyeWtleXMgPSBbXG4gICckYW5kJyxcbiAgJyRvcicsXG4gICckbm9yJyxcbiAgJ19ycGVybScsXG4gICdfd3Blcm0nLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuXTtcblxuY29uc3QgaXNTcGVjaWFsUXVlcnlLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbFF1ZXJ5a2V5cy5pbmRleE9mKGtleSkgPj0gMDtcbn07XG5cbmNvbnN0IHZhbGlkYXRlUXVlcnkgPSAocXVlcnk6IGFueSk6IHZvaWQgPT4ge1xuICBpZiAocXVlcnkuQUNMKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdDYW5ub3QgcXVlcnkgb24gQUNMLicpO1xuICB9XG5cbiAgaWYgKHF1ZXJ5LiRvcikge1xuICAgIGlmIChxdWVyeS4kb3IgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcXVlcnkuJG9yLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRvciBmb3JtYXQgLSB1c2UgYW4gYXJyYXkgdmFsdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXJ5LiRhbmQpIHtcbiAgICBpZiAocXVlcnkuJGFuZCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBxdWVyeS4kYW5kLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRhbmQgZm9ybWF0IC0gdXNlIGFuIGFycmF5IHZhbHVlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChxdWVyeS4kbm9yKSB7XG4gICAgaWYgKHF1ZXJ5LiRub3IgaW5zdGFuY2VvZiBBcnJheSAmJiBxdWVyeS4kbm9yLmxlbmd0aCA+IDApIHtcbiAgICAgIHF1ZXJ5LiRub3IuZm9yRWFjaCh2YWxpZGF0ZVF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnQmFkICRub3IgZm9ybWF0IC0gdXNlIGFuIGFycmF5IG9mIGF0IGxlYXN0IDEgdmFsdWUuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGlmIChxdWVyeSAmJiBxdWVyeVtrZXldICYmIHF1ZXJ5W2tleV0uJHJlZ2V4KSB7XG4gICAgICBpZiAodHlwZW9mIHF1ZXJ5W2tleV0uJG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICghcXVlcnlba2V5XS4kb3B0aW9ucy5tYXRjaCgvXltpbXhzXSskLykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgICAgYEJhZCAkb3B0aW9ucyB2YWx1ZSBmb3IgcXVlcnk6ICR7cXVlcnlba2V5XS4kb3B0aW9uc31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWlzU3BlY2lhbFF1ZXJ5S2V5KGtleSkgJiYgIWtleS5tYXRjaCgvXlthLXpBLVpdW2EtekEtWjAtOV9cXC5dKiQvKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGtleSBuYW1lOiAke2tleX1gKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLy8gRmlsdGVycyBvdXQgYW55IGRhdGEgdGhhdCBzaG91bGRuJ3QgYmUgb24gdGhpcyBSRVNULWZvcm1hdHRlZCBvYmplY3QuXG5jb25zdCBmaWx0ZXJTZW5zaXRpdmVEYXRhID0gKFxuICBpc01hc3RlcjogYm9vbGVhbixcbiAgYWNsR3JvdXA6IGFueVtdLFxuICBhdXRoOiBhbnksXG4gIG9wZXJhdGlvbjogYW55LFxuICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gIHByb3RlY3RlZEZpZWxkczogbnVsbCB8IEFycmF5PGFueT4sXG4gIG9iamVjdDogYW55XG4pID0+IHtcbiAgbGV0IHVzZXJJZCA9IG51bGw7XG4gIGlmIChhdXRoICYmIGF1dGgudXNlcikgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuXG4gIC8vIHJlcGxhY2UgcHJvdGVjdGVkRmllbGRzIHdoZW4gdXNpbmcgcG9pbnRlci1wZXJtaXNzaW9uc1xuICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgaWYgKHBlcm1zKSB7XG4gICAgY29uc3QgaXNSZWFkT3BlcmF0aW9uID0gWydnZXQnLCAnZmluZCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xO1xuXG4gICAgaWYgKGlzUmVhZE9wZXJhdGlvbiAmJiBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgIC8vIGV4dHJhY3QgcHJvdGVjdGVkRmllbGRzIGFkZGVkIHdpdGggdGhlIHBvaW50ZXItcGVybWlzc2lvbiBwcmVmaXhcbiAgICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtID0gT2JqZWN0LmtleXMocGVybXMucHJvdGVjdGVkRmllbGRzKVxuICAgICAgICAuZmlsdGVyKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgndXNlckZpZWxkOicpKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsga2V5OiBrZXkuc3Vic3RyaW5nKDEwKSwgdmFsdWU6IHBlcm1zLnByb3RlY3RlZEZpZWxkc1trZXldIH07XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBuZXdQcm90ZWN0ZWRGaWVsZHM6IEFycmF5PHN0cmluZz5bXSA9IFtdO1xuICAgICAgbGV0IG92ZXJyaWRlUHJvdGVjdGVkRmllbGRzID0gZmFsc2U7XG5cbiAgICAgIC8vIGNoZWNrIGlmIHRoZSBvYmplY3QgZ3JhbnRzIHRoZSBjdXJyZW50IHVzZXIgYWNjZXNzIGJhc2VkIG9uIHRoZSBleHRyYWN0ZWQgZmllbGRzXG4gICAgICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUGVybS5mb3JFYWNoKHBvaW50ZXJQZXJtID0+IHtcbiAgICAgICAgbGV0IHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHJlYWRVc2VyRmllbGRWYWx1ZSA9IG9iamVjdFtwb2ludGVyUGVybS5rZXldO1xuICAgICAgICBpZiAocmVhZFVzZXJGaWVsZFZhbHVlKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVhZFVzZXJGaWVsZFZhbHVlKSkge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPSByZWFkVXNlckZpZWxkVmFsdWUuc29tZShcbiAgICAgICAgICAgICAgdXNlciA9PiB1c2VyLm9iamVjdElkICYmIHVzZXIub2JqZWN0SWQgPT09IHVzZXJJZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPVxuICAgICAgICAgICAgICByZWFkVXNlckZpZWxkVmFsdWUub2JqZWN0SWQgJiYgcmVhZFVzZXJGaWVsZFZhbHVlLm9iamVjdElkID09PSB1c2VySWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyKSB7XG4gICAgICAgICAgb3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMgPSB0cnVlO1xuICAgICAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5wdXNoKHBvaW50ZXJQZXJtLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIGlmIGF0IGxlYXN0IG9uZSBwb2ludGVyLXBlcm1pc3Npb24gYWZmZWN0ZWQgdGhlIGN1cnJlbnQgdXNlclxuICAgICAgLy8gaW50ZXJzZWN0IHZzIHByb3RlY3RlZEZpZWxkcyBmcm9tIHByZXZpb3VzIHN0YWdlIChAc2VlIGFkZFByb3RlY3RlZEZpZWxkcylcbiAgICAgIC8vIFNldHMgdGhlb3J5IChpbnRlcnNlY3Rpb25zKTogQSB4IChCIHggQykgPT0gKEEgeCBCKSB4IENcbiAgICAgIGlmIChvdmVycmlkZVByb3RlY3RlZEZpZWxkcyAmJiBwcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgICAgbmV3UHJvdGVjdGVkRmllbGRzLnB1c2gocHJvdGVjdGVkRmllbGRzKTtcbiAgICAgIH1cbiAgICAgIC8vIGludGVyc2VjdCBhbGwgc2V0cyBvZiBwcm90ZWN0ZWRGaWVsZHNcbiAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGZpZWxkcyA9PiB7XG4gICAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSdyZSBubyBwcm90Y3RlZEZpZWxkcyBieSBvdGhlciBjcml0ZXJpYSAoIGlkIC8gcm9sZSAvIGF1dGgpXG4gICAgICAgICAgLy8gdGhlbiB3ZSBtdXN0IGludGVyc2VjdCBlYWNoIHNldCAocGVyIHVzZXJGaWVsZClcbiAgICAgICAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzID0gZmllbGRzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHMuZmlsdGVyKHYgPT4gZmllbGRzLmluY2x1ZGVzKHYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGlzVXNlckNsYXNzID0gY2xhc3NOYW1lID09PSAnX1VzZXInO1xuXG4gIC8qIHNwZWNpYWwgdHJlYXQgZm9yIHRoZSB1c2VyIGNsYXNzOiBkb24ndCBmaWx0ZXIgcHJvdGVjdGVkRmllbGRzIGlmIGN1cnJlbnRseSBsb2dnZWRpbiB1c2VyIGlzXG4gIHRoZSByZXRyaWV2ZWQgdXNlciAqL1xuICBpZiAoIShpc1VzZXJDbGFzcyAmJiB1c2VySWQgJiYgb2JqZWN0Lm9iamVjdElkID09PSB1c2VySWQpKSB7XG4gICAgcHJvdGVjdGVkRmllbGRzICYmIHByb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGsgPT4gZGVsZXRlIG9iamVjdFtrXSk7XG5cbiAgICAvLyBmaWVsZHMgbm90IHJlcXVlc3RlZCBieSBjbGllbnQgKGV4Y2x1ZGVkKSxcbiAgICAvL2J1dCB3ZXJlIG5lZWRlZCB0byBhcHBseSBwcm90ZWN0dGVkRmllbGRzXG4gICAgcGVybXMucHJvdGVjdGVkRmllbGRzICYmXG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyAmJlxuICAgICAgcGVybXMucHJvdGVjdGVkRmllbGRzLnRlbXBvcmFyeUtleXMuZm9yRWFjaChrID0+IGRlbGV0ZSBvYmplY3Rba10pO1xuICB9XG5cbiAgaWYgKCFpc1VzZXJDbGFzcykge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICBvYmplY3QucGFzc3dvcmQgPSBvYmplY3QuX2hhc2hlZF9wYXNzd29yZDtcbiAgZGVsZXRlIG9iamVjdC5faGFzaGVkX3Bhc3N3b3JkO1xuXG4gIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuXG4gIGlmIChpc01hc3Rlcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3RvbWJzdG9uZTtcbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX2ZhaWxlZF9sb2dpbl9jb3VudDtcbiAgZGVsZXRlIG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2hpc3Rvcnk7XG5cbiAgaWYgKGFjbEdyb3VwLmluZGV4T2Yob2JqZWN0Lm9iamVjdElkKSA+IC0xKSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuaW1wb3J0IHR5cGUgeyBMb2FkU2NoZW1hT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcblxuLy8gUnVucyBhbiB1cGRhdGUgb24gdGhlIGRhdGFiYXNlLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGFuIG9iamVjdCB3aXRoIHRoZSBuZXcgdmFsdWVzIGZvciBmaWVsZFxuLy8gbW9kaWZpY2F0aW9ucyB0aGF0IGRvbid0IGtub3cgdGhlaXIgcmVzdWx0cyBhaGVhZCBvZiB0aW1lLCBsaWtlXG4vLyAnaW5jcmVtZW50Jy5cbi8vIE9wdGlvbnM6XG4vLyAgIGFjbDogIGEgbGlzdCBvZiBzdHJpbmdzLiBJZiB0aGUgb2JqZWN0IHRvIGJlIHVwZGF0ZWQgaGFzIGFuIEFDTCxcbi8vICAgICAgICAgb25lIG9mIHRoZSBwcm92aWRlZCBzdHJpbmdzIG11c3QgcHJvdmlkZSB0aGUgY2FsbGVyIHdpdGhcbi8vICAgICAgICAgd3JpdGUgcGVybWlzc2lvbnMuXG5jb25zdCBzcGVjaWFsS2V5c0ZvclVwZGF0ZSA9IFtcbiAgJ19oYXNoZWRfcGFzc3dvcmQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCcsXG4gICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsXG4gICdfcGFzc3dvcmRfaGlzdG9yeScsXG5dO1xuXG5jb25zdCBpc1NwZWNpYWxVcGRhdGVLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbEtleXNGb3JVcGRhdGUuaW5kZXhPZihrZXkpID49IDA7XG59O1xuXG5mdW5jdGlvbiBleHBhbmRSZXN1bHRPbktleVBhdGgob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkuaW5kZXhPZignLicpIDwgMCkge1xuICAgIG9iamVjdFtrZXldID0gdmFsdWVba2V5XTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG4gIGNvbnN0IHBhdGggPSBrZXkuc3BsaXQoJy4nKTtcbiAgY29uc3QgZmlyc3RLZXkgPSBwYXRoWzBdO1xuICBjb25zdCBuZXh0UGF0aCA9IHBhdGguc2xpY2UoMSkuam9pbignLicpO1xuICBvYmplY3RbZmlyc3RLZXldID0gZXhwYW5kUmVzdWx0T25LZXlQYXRoKG9iamVjdFtmaXJzdEtleV0gfHwge30sIG5leHRQYXRoLCB2YWx1ZVtmaXJzdEtleV0pO1xuICBkZWxldGUgb2JqZWN0W2tleV07XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbmZ1bmN0aW9uIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxPYmplY3QsIHJlc3VsdCk6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0ge307XG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XG4gIH1cbiAgT2JqZWN0LmtleXMob3JpZ2luYWxPYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICBjb25zdCBrZXlVcGRhdGUgPSBvcmlnaW5hbE9iamVjdFtrZXldO1xuICAgIC8vIGRldGVybWluZSBpZiB0aGF0IHdhcyBhbiBvcFxuICAgIGlmIChcbiAgICAgIGtleVVwZGF0ZSAmJlxuICAgICAgdHlwZW9mIGtleVVwZGF0ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIGtleVVwZGF0ZS5fX29wICYmXG4gICAgICBbJ0FkZCcsICdBZGRVbmlxdWUnLCAnUmVtb3ZlJywgJ0luY3JlbWVudCddLmluZGV4T2Yoa2V5VXBkYXRlLl9fb3ApID4gLTFcbiAgICApIHtcbiAgICAgIC8vIG9ubHkgdmFsaWQgb3BzIHRoYXQgcHJvZHVjZSBhbiBhY3Rpb25hYmxlIHJlc3VsdFxuICAgICAgLy8gdGhlIG9wIG1heSBoYXZlIGhhcHBlbmQgb24gYSBrZXlwYXRoXG4gICAgICBleHBhbmRSZXN1bHRPbktleVBhdGgocmVzcG9uc2UsIGtleSwgcmVzdWx0KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcbn1cblxuZnVuY3Rpb24gam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSkge1xuICByZXR1cm4gYF9Kb2luOiR7a2V5fToke2NsYXNzTmFtZX1gO1xufVxuXG5jb25zdCBmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlID0gb2JqZWN0ID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdFtrZXldICYmIG9iamVjdFtrZXldLl9fb3ApIHtcbiAgICAgIHN3aXRjaCAob2JqZWN0W2tleV0uX19vcCkge1xuICAgICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0W2tleV0uYW1vdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5hbW91bnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICAgICAgaWYgKCEob2JqZWN0W2tleV0ub2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5vYmplY3RzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgICAgIGlmICghKG9iamVjdFtrZXldLm9iamVjdHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdvYmplY3RzIHRvIGFkZCBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdFtrZXldID0gb2JqZWN0W2tleV0ub2JqZWN0cztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgICBpZiAoIShvYmplY3Rba2V5XS5vYmplY3RzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnb2JqZWN0cyB0byBhZGQgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICAgIGRlbGV0ZSBvYmplY3Rba2V5XTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5DT01NQU5EX1VOQVZBSUxBQkxFLFxuICAgICAgICAgICAgYFRoZSAke29iamVjdFtrZXldLl9fb3B9IG9wZXJhdG9yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LmBcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuY29uc3QgdHJhbnNmb3JtQXV0aERhdGEgPSAoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkgPT4ge1xuICBpZiAob2JqZWN0LmF1dGhEYXRhICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIE9iamVjdC5rZXlzKG9iamVjdC5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICBjb25zdCBwcm92aWRlckRhdGEgPSBvYmplY3QuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgY29uc3QgZmllbGROYW1lID0gYF9hdXRoX2RhdGFfJHtwcm92aWRlcn1gO1xuICAgICAgaWYgKHByb3ZpZGVyRGF0YSA9PSBudWxsKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fb3A6ICdEZWxldGUnLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSBwcm92aWRlckRhdGE7XG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSA9IHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICB9XG59O1xuLy8gVHJhbnNmb3JtcyBhIERhdGFiYXNlIGZvcm1hdCBBQ0wgdG8gYSBSRVNUIEFQSSBmb3JtYXQgQUNMXG5jb25zdCB1bnRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IF9ycGVybSwgX3dwZXJtLCAuLi5vdXRwdXQgfSkgPT4ge1xuICBpZiAoX3JwZXJtIHx8IF93cGVybSkge1xuICAgIG91dHB1dC5BQ0wgPSB7fTtcblxuICAgIChfcnBlcm0gfHwgW10pLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgaWYgKCFvdXRwdXQuQUNMW2VudHJ5XSkge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XSA9IHsgcmVhZDogdHJ1ZSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV1bJ3JlYWQnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAoX3dwZXJtIHx8IFtdKS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmICghb3V0cHV0LkFDTFtlbnRyeV0pIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV0gPSB7IHdyaXRlOiB0cnVlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XVsnd3JpdGUnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbi8qKlxuICogV2hlbiBxdWVyeWluZywgdGhlIGZpZWxkTmFtZSBtYXkgYmUgY29tcG91bmQsIGV4dHJhY3QgdGhlIHJvb3QgZmllbGROYW1lXG4gKiAgICAgYHRlbXBlcmF0dXJlLmNlbHNpdXNgIGJlY29tZXMgYHRlbXBlcmF0dXJlYFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkTmFtZSB0aGF0IG1heSBiZSBhIGNvbXBvdW5kIGZpZWxkIG5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSByb290IG5hbWUgb2YgdGhlIGZpZWxkXG4gKi9cbmNvbnN0IGdldFJvb3RGaWVsZE5hbWUgPSAoZmllbGROYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gZmllbGROYW1lLnNwbGl0KCcuJylbMF07XG59O1xuXG5jb25zdCByZWxhdGlvblNjaGVtYSA9IHtcbiAgZmllbGRzOiB7IHJlbGF0ZWRJZDogeyB0eXBlOiAnU3RyaW5nJyB9LCBvd25pbmdJZDogeyB0eXBlOiAnU3RyaW5nJyB9IH0sXG59O1xuXG5jbGFzcyBEYXRhYmFzZUNvbnRyb2xsZXIge1xuICBhZGFwdGVyOiBTdG9yYWdlQWRhcHRlcjtcbiAgc2NoZW1hQ2FjaGU6IGFueTtcbiAgc2NoZW1hUHJvbWlzZTogP1Byb21pc2U8U2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyPjtcbiAgX3RyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55O1xuXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5hZGFwdGVyID0gYWRhcHRlcjtcbiAgICB0aGlzLnNjaGVtYUNhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgLy8gV2UgZG9uJ3Qgd2FudCBhIG11dGFibGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgdGhlbiB5b3UgY291bGQgaGF2ZVxuICAgIC8vIG9uZSByZXF1ZXN0IHRoYXQgdXNlcyBkaWZmZXJlbnQgc2NoZW1hcyBmb3IgZGlmZmVyZW50IHBhcnRzIG9mXG4gICAgLy8gaXQuIEluc3RlYWQsIHVzZSBsb2FkU2NoZW1hIHRvIGdldCBhIHNjaGVtYS5cbiAgICB0aGlzLnNjaGVtYVByb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uID0gbnVsbDtcbiAgfVxuXG4gIGNvbGxlY3Rpb25FeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gIH1cblxuICBwdXJnZUNvbGxlY3Rpb24oY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKHNjaGVtYSA9PiB0aGlzLmFkYXB0ZXIuZGVsZXRlT2JqZWN0c0J5UXVlcnkoY2xhc3NOYW1lLCBzY2hlbWEsIHt9KSk7XG4gIH1cblxuICB2YWxpZGF0ZUNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghU2NoZW1hQ29udHJvbGxlci5jbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgJ2ludmFsaWQgY2xhc3NOYW1lOiAnICsgY2xhc3NOYW1lKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgc2NoZW1hQ29udHJvbGxlci5cbiAgbG9hZFNjaGVtYShcbiAgICBvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfVxuICApOiBQcm9taXNlPFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLnNjaGVtYVByb21pc2UgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2NoZW1hUHJvbWlzZTtcbiAgICB9XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlID0gU2NoZW1hQ29udHJvbGxlci5sb2FkKHRoaXMuYWRhcHRlciwgdGhpcy5zY2hlbWFDYWNoZSwgb3B0aW9ucyk7XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlLnRoZW4oXG4gICAgICAoKSA9PiBkZWxldGUgdGhpcy5zY2hlbWFQcm9taXNlLFxuICAgICAgKCkgPT4gZGVsZXRlIHRoaXMuc2NoZW1hUHJvbWlzZVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIGxvYWRTY2hlbWFJZk5lZWRlZChcbiAgICBzY2hlbWFDb250cm9sbGVyOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXI+IHtcbiAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlciA/IFByb21pc2UucmVzb2x2ZShzY2hlbWFDb250cm9sbGVyKSA6IHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgY2xhc3NuYW1lIHRoYXQgaXMgcmVsYXRlZCB0byB0aGUgZ2l2ZW5cbiAgLy8gY2xhc3NuYW1lIHRocm91Z2ggdGhlIGtleS5cbiAgLy8gVE9ETzogbWFrZSB0aGlzIG5vdCBpbiB0aGUgRGF0YWJhc2VDb250cm9sbGVyIGludGVyZmFjZVxuICByZWRpcmVjdENsYXNzTmFtZUZvcktleShjbGFzc05hbWU6IHN0cmluZywga2V5OiBzdHJpbmcpOiBQcm9taXNlPD9zdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4ge1xuICAgICAgdmFyIHQgPSBzY2hlbWEuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwga2V5KTtcbiAgICAgIGlmICh0ICE9IG51bGwgJiYgdHlwZW9mIHQgIT09ICdzdHJpbmcnICYmIHQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICByZXR1cm4gdC50YXJnZXRDbGFzcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGFzc05hbWU7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVc2VzIHRoZSBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIG9iamVjdCAoUkVTVCBBUEkgZm9ybWF0KS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYS5cbiAgLy8gVGhpcyBkb2VzIG5vdCB1cGRhdGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgaW4gYSBzaXR1YXRpb24gbGlrZSBhXG4gIC8vIGJhdGNoIHJlcXVlc3QsIHRoYXQgY291bGQgY29uZnVzZSBvdGhlciB1c2VycyBvZiB0aGUgc2NoZW1hLlxuICB2YWxpZGF0ZU9iamVjdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvYmplY3Q6IGFueSxcbiAgICBxdWVyeTogYW55LFxuICAgIHJ1bk9wdGlvbnM6IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgc2NoZW1hO1xuICAgIGNvbnN0IGFjbCA9IHJ1bk9wdGlvbnMuYWNsO1xuICAgIGNvbnN0IGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwOiBzdHJpbmdbXSA9IGFjbCB8fCBbXTtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHMgPT4ge1xuICAgICAgICBzY2hlbWEgPSBzO1xuICAgICAgICBpZiAoaXNNYXN0ZXIpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY2FuQWRkRmllbGQoc2NoZW1hLCBjbGFzc05hbWUsIG9iamVjdCwgYWNsR3JvdXAsIHJ1bk9wdGlvbnMpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS52YWxpZGF0ZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB7IGFjbCwgbWFueSwgdXBzZXJ0LCBhZGRzRmllbGQgfTogRnVsbFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHNraXBTYW5pdGl6YXRpb246IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZGF0ZU9ubHk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IG9yaWdpbmFsUXVlcnkgPSBxdWVyeTtcbiAgICBjb25zdCBvcmlnaW5hbFVwZGF0ZSA9IHVwZGF0ZTtcbiAgICAvLyBNYWtlIGEgY29weSBvZiB0aGUgb2JqZWN0LCBzbyB3ZSBkb24ndCBtdXRhdGUgdGhlIGluY29taW5nIGRhdGEuXG4gICAgdXBkYXRlID0gZGVlcGNvcHkodXBkYXRlKTtcbiAgICB2YXIgcmVsYXRpb25VcGRhdGVzID0gW107XG4gICAgdmFyIGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwID0gYWNsIHx8IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICd1cGRhdGUnKVxuICAgICAgKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmVsYXRpb25VcGRhdGVzID0gdGhpcy5jb2xsZWN0UmVsYXRpb25VcGRhdGVzKGNsYXNzTmFtZSwgb3JpZ2luYWxRdWVyeS5vYmplY3RJZCwgdXBkYXRlKTtcbiAgICAgICAgICBpZiAoIWlzTWFzdGVyKSB7XG4gICAgICAgICAgICBxdWVyeSA9IHRoaXMuYWRkUG9pbnRlclBlcm1pc3Npb25zKFxuICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICd1cGRhdGUnLFxuICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChhZGRzRmllbGQpIHtcbiAgICAgICAgICAgICAgcXVlcnkgPSB7XG4gICAgICAgICAgICAgICAgJGFuZDogW1xuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB0aGlzLmFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAnYWRkRmllbGQnLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFxdWVyeSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYWNsKSB7XG4gICAgICAgICAgICBxdWVyeSA9IGFkZFdyaXRlQUNMKHF1ZXJ5LCBhY2wpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlclxuICAgICAgICAgICAgLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAvLyBJZiB0aGUgc2NoZW1hIGRvZXNuJ3QgZXhpc3QsIHByZXRlbmQgaXQgZXhpc3RzIHdpdGggbm8gZmllbGRzLiBUaGlzIGJlaGF2aW9yXG4gICAgICAgICAgICAgIC8vIHdpbGwgbGlrZWx5IG5lZWQgcmV2aXNpdGluZy5cbiAgICAgICAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBmaWVsZHM6IHt9IH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXModXBkYXRlKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5tYXRjaCgvXmF1dGhEYXRhXFwuKFthLXpBLVowLTlfXSspXFwuaWQkLykpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgYEludmFsaWQgZmllbGQgbmFtZSBmb3IgdXBkYXRlOiAke2ZpZWxkTmFtZX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByb290RmllbGROYW1lID0gZ2V0Um9vdEZpZWxkTmFtZShmaWVsZE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICFTY2hlbWFDb250cm9sbGVyLmZpZWxkTmFtZUlzVmFsaWQocm9vdEZpZWxkTmFtZSkgJiZcbiAgICAgICAgICAgICAgICAgICFpc1NwZWNpYWxVcGRhdGVLZXkocm9vdEZpZWxkTmFtZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgYEludmFsaWQgZmllbGQgbmFtZSBmb3IgdXBkYXRlOiAke2ZpZWxkTmFtZX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgdXBkYXRlT3BlcmF0aW9uIGluIHVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZVt1cGRhdGVPcGVyYXRpb25dICYmXG4gICAgICAgICAgICAgICAgICB0eXBlb2YgdXBkYXRlW3VwZGF0ZU9wZXJhdGlvbl0gPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh1cGRhdGVbdXBkYXRlT3BlcmF0aW9uXSkuc29tZShcbiAgICAgICAgICAgICAgICAgICAgaW5uZXJLZXkgPT4gaW5uZXJLZXkuaW5jbHVkZXMoJyQnKSB8fCBpbm5lcktleS5pbmNsdWRlcygnLicpXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfTkVTVEVEX0tFWSxcbiAgICAgICAgICAgICAgICAgICAgXCJOZXN0ZWQga2V5cyBzaG91bGQgbm90IGNvbnRhaW4gdGhlICckJyBvciAnLicgY2hhcmFjdGVyc1wiXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB1cGRhdGUgPSB0cmFuc2Zvcm1PYmplY3RBQ0wodXBkYXRlKTtcbiAgICAgICAgICAgICAgdHJhbnNmb3JtQXV0aERhdGEoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgICAgICAgICAgIGlmICh2YWxpZGF0ZU9ubHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmZpbmQoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCB7fSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChtYW55KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cGRhdGVPYmplY3RzQnlRdWVyeShcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgdXBkYXRlLFxuICAgICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVwc2VydCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0T25lT2JqZWN0KFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5maW5kT25lQW5kVXBkYXRlKFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFsaWRhdGVPbmx5KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZWxhdGlvblVwZGF0ZXMoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICBvcmlnaW5hbFF1ZXJ5Lm9iamVjdElkLFxuICAgICAgICAgICAgdXBkYXRlLFxuICAgICAgICAgICAgcmVsYXRpb25VcGRhdGVzXG4gICAgICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKHNraXBTYW5pdGl6YXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxVcGRhdGUsIHJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ29sbGVjdCBhbGwgcmVsYXRpb24tdXBkYXRpbmcgb3BlcmF0aW9ucyBmcm9tIGEgUkVTVC1mb3JtYXQgdXBkYXRlLlxuICAvLyBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgcmVsYXRpb24gdXBkYXRlcyB0byBwZXJmb3JtXG4gIC8vIFRoaXMgbXV0YXRlcyB1cGRhdGUuXG4gIGNvbGxlY3RSZWxhdGlvblVwZGF0ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdElkOiA/c3RyaW5nLCB1cGRhdGU6IGFueSkge1xuICAgIHZhciBvcHMgPSBbXTtcbiAgICB2YXIgZGVsZXRlTWUgPSBbXTtcbiAgICBvYmplY3RJZCA9IHVwZGF0ZS5vYmplY3RJZCB8fCBvYmplY3RJZDtcblxuICAgIHZhciBwcm9jZXNzID0gKG9wLCBrZXkpID0+IHtcbiAgICAgIGlmICghb3ApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ0FkZFJlbGF0aW9uJykge1xuICAgICAgICBvcHMucHVzaCh7IGtleSwgb3AgfSk7XG4gICAgICAgIGRlbGV0ZU1lLnB1c2goa2V5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ1JlbW92ZVJlbGF0aW9uJykge1xuICAgICAgICBvcHMucHVzaCh7IGtleSwgb3AgfSk7XG4gICAgICAgIGRlbGV0ZU1lLnB1c2goa2V5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ0JhdGNoJykge1xuICAgICAgICBmb3IgKHZhciB4IG9mIG9wLm9wcykge1xuICAgICAgICAgIHByb2Nlc3MoeCwga2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiB1cGRhdGUpIHtcbiAgICAgIHByb2Nlc3ModXBkYXRlW2tleV0sIGtleSk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGRlbGV0ZU1lKSB7XG4gICAgICBkZWxldGUgdXBkYXRlW2tleV07XG4gICAgfVxuICAgIHJldHVybiBvcHM7XG4gIH1cblxuICAvLyBQcm9jZXNzZXMgcmVsYXRpb24tdXBkYXRpbmcgb3BlcmF0aW9ucyBmcm9tIGEgUkVTVC1mb3JtYXQgdXBkYXRlLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIHVwZGF0ZXMgaGF2ZSBiZWVuIHBlcmZvcm1lZFxuICBoYW5kbGVSZWxhdGlvblVwZGF0ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdElkOiBzdHJpbmcsIHVwZGF0ZTogYW55LCBvcHM6IGFueSkge1xuICAgIHZhciBwZW5kaW5nID0gW107XG4gICAgb2JqZWN0SWQgPSB1cGRhdGUub2JqZWN0SWQgfHwgb2JqZWN0SWQ7XG4gICAgb3BzLmZvckVhY2goKHsga2V5LCBvcCB9KSA9PiB7XG4gICAgICBpZiAoIW9wKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChvcC5fX29wID09ICdBZGRSZWxhdGlvbicpIHtcbiAgICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2Ygb3Aub2JqZWN0cykge1xuICAgICAgICAgIHBlbmRpbmcucHVzaCh0aGlzLmFkZFJlbGF0aW9uKGtleSwgY2xhc3NOYW1lLCBvYmplY3RJZCwgb2JqZWN0Lm9iamVjdElkKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ1JlbW92ZVJlbGF0aW9uJykge1xuICAgICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBvcC5vYmplY3RzKSB7XG4gICAgICAgICAgcGVuZGluZy5wdXNoKHRoaXMucmVtb3ZlUmVsYXRpb24oa2V5LCBjbGFzc05hbWUsIG9iamVjdElkLCBvYmplY3Qub2JqZWN0SWQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHBlbmRpbmcpO1xuICB9XG5cbiAgLy8gQWRkcyBhIHJlbGF0aW9uLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIGFkZCB3YXMgc3VjY2Vzc2Z1bC5cbiAgYWRkUmVsYXRpb24oa2V5OiBzdHJpbmcsIGZyb21DbGFzc05hbWU6IHN0cmluZywgZnJvbUlkOiBzdHJpbmcsIHRvSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGRvYyA9IHtcbiAgICAgIHJlbGF0ZWRJZDogdG9JZCxcbiAgICAgIG93bmluZ0lkOiBmcm9tSWQsXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwc2VydE9uZU9iamVjdChcbiAgICAgIGBfSm9pbjoke2tleX06JHtmcm9tQ2xhc3NOYW1lfWAsXG4gICAgICByZWxhdGlvblNjaGVtYSxcbiAgICAgIGRvYyxcbiAgICAgIGRvYyxcbiAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlbW92ZXMgYSByZWxhdGlvbi5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgaWZmIHRoZSByZW1vdmUgd2FzXG4gIC8vIHN1Y2Nlc3NmdWwuXG4gIHJlbW92ZVJlbGF0aW9uKGtleTogc3RyaW5nLCBmcm9tQ2xhc3NOYW1lOiBzdHJpbmcsIGZyb21JZDogc3RyaW5nLCB0b0lkOiBzdHJpbmcpIHtcbiAgICB2YXIgZG9jID0ge1xuICAgICAgcmVsYXRlZElkOiB0b0lkLFxuICAgICAgb3duaW5nSWQ6IGZyb21JZCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXJcbiAgICAgIC5kZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICAgICAgYF9Kb2luOiR7a2V5fToke2Zyb21DbGFzc05hbWV9YCxcbiAgICAgICAgcmVsYXRpb25TY2hlbWEsXG4gICAgICAgIGRvYyxcbiAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFdlIGRvbid0IGNhcmUgaWYgdGhleSB0cnkgdG8gZGVsZXRlIGEgbm9uLWV4aXN0ZW50IHJlbGF0aW9uLlxuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZW1vdmVzIG9iamVjdHMgbWF0Y2hlcyB0aGlzIHF1ZXJ5IGZyb20gdGhlIGRhdGFiYXNlLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIG9iamVjdCB3YXNcbiAgLy8gZGVsZXRlZC5cbiAgLy8gT3B0aW9uczpcbiAgLy8gICBhY2w6ICBhIGxpc3Qgb2Ygc3RyaW5ncy4gSWYgdGhlIG9iamVjdCB0byBiZSB1cGRhdGVkIGhhcyBhbiBBQ0wsXG4gIC8vICAgICAgICAgb25lIG9mIHRoZSBwcm92aWRlZCBzdHJpbmdzIG11c3QgcHJvdmlkZSB0aGUgY2FsbGVyIHdpdGhcbiAgLy8gICAgICAgICB3cml0ZSBwZXJtaXNzaW9ucy5cbiAgZGVzdHJveShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55LFxuICAgIHsgYWNsIH06IFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHZhbGlkU2NoZW1hQ29udHJvbGxlcjogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgaXNNYXN0ZXIgPSBhY2wgPT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBhY2xHcm91cCA9IGFjbCB8fCBbXTtcblxuICAgIHJldHVybiB0aGlzLmxvYWRTY2hlbWFJZk5lZWRlZCh2YWxpZFNjaGVtYUNvbnRyb2xsZXIpLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiB7XG4gICAgICByZXR1cm4gKGlzTWFzdGVyXG4gICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgOiBzY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWUsIGFjbEdyb3VwLCAnZGVsZXRlJylcbiAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgIGlmICghaXNNYXN0ZXIpIHtcbiAgICAgICAgICBxdWVyeSA9IHRoaXMuYWRkUG9pbnRlclBlcm1pc3Npb25zKFxuICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICdkZWxldGUnLFxuICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICBhY2xHcm91cFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFxdWVyeSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBkZWxldGUgYnkgcXVlcnlcbiAgICAgICAgaWYgKGFjbCkge1xuICAgICAgICAgIHF1ZXJ5ID0gYWRkV3JpdGVBQ0wocXVlcnksIGFjbCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVRdWVyeShxdWVyeSk7XG4gICAgICAgIHJldHVybiBzY2hlbWFDb250cm9sbGVyXG4gICAgICAgICAgLmdldE9uZVNjaGVtYShjbGFzc05hbWUpXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBzY2hlbWEgZG9lc24ndCBleGlzdCwgcHJldGVuZCBpdCBleGlzdHMgd2l0aCBubyBmaWVsZHMuIFRoaXMgYmVoYXZpb3JcbiAgICAgICAgICAgIC8vIHdpbGwgbGlrZWx5IG5lZWQgcmV2aXNpdGluZy5cbiAgICAgICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IGZpZWxkczoge30gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4ocGFyc2VGb3JtYXRTY2hlbWEgPT5cbiAgICAgICAgICAgIHRoaXMuYWRhcHRlci5kZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBwYXJzZUZvcm1hdFNjaGVtYSxcbiAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAvLyBXaGVuIGRlbGV0aW5nIHNlc3Npb25zIHdoaWxlIGNoYW5naW5nIHBhc3N3b3JkcywgZG9uJ3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhleSBkb24ndCBoYXZlIGFueSBzZXNzaW9ucy5cbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfU2Vzc2lvbicgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBJbnNlcnRzIGFuIG9iamVjdCBpbnRvIHRoZSBkYXRhYmFzZS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgaWZmIHRoZSBvYmplY3Qgc2F2ZWQuXG4gIGNyZWF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvYmplY3Q6IGFueSxcbiAgICB7IGFjbCB9OiBRdWVyeU9wdGlvbnMgPSB7fSxcbiAgICB2YWxpZGF0ZU9ubHk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIE1ha2UgYSBjb3B5IG9mIHRoZSBvYmplY3QsIHNvIHdlIGRvbid0IG11dGF0ZSB0aGUgaW5jb21pbmcgZGF0YS5cbiAgICBjb25zdCBvcmlnaW5hbE9iamVjdCA9IG9iamVjdDtcbiAgICBvYmplY3QgPSB0cmFuc2Zvcm1PYmplY3RBQ0wob2JqZWN0KTtcblxuICAgIG9iamVjdC5jcmVhdGVkQXQgPSB7IGlzbzogb2JqZWN0LmNyZWF0ZWRBdCwgX190eXBlOiAnRGF0ZScgfTtcbiAgICBvYmplY3QudXBkYXRlZEF0ID0geyBpc286IG9iamVjdC51cGRhdGVkQXQsIF9fdHlwZTogJ0RhdGUnIH07XG5cbiAgICB2YXIgaXNNYXN0ZXIgPSBhY2wgPT09IHVuZGVmaW5lZDtcbiAgICB2YXIgYWNsR3JvdXAgPSBhY2wgfHwgW107XG4gICAgY29uc3QgcmVsYXRpb25VcGRhdGVzID0gdGhpcy5jb2xsZWN0UmVsYXRpb25VcGRhdGVzKGNsYXNzTmFtZSwgbnVsbCwgb2JqZWN0KTtcblxuICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xhc3NOYW1lKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikpXG4gICAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgICAgcmV0dXJuIChpc01hc3RlclxuICAgICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICdjcmVhdGUnKVxuICAgICAgICApXG4gICAgICAgICAgLnRoZW4oKCkgPT4gc2NoZW1hQ29udHJvbGxlci5lbmZvcmNlQ2xhc3NFeGlzdHMoY2xhc3NOYW1lKSlcbiAgICAgICAgICAudGhlbigoKSA9PiBzY2hlbWFDb250cm9sbGVyLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpKVxuICAgICAgICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICAgICAgICB0cmFuc2Zvcm1BdXRoRGF0YShjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKTtcbiAgICAgICAgICAgIGZsYXR0ZW5VcGRhdGVPcGVyYXRvcnNGb3JDcmVhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIGlmICh2YWxpZGF0ZU9ubHkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5jcmVhdGVPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgU2NoZW1hQ29udHJvbGxlci5jb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKHNjaGVtYSksXG4gICAgICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbGlkYXRlT25seSkge1xuICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxPYmplY3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZWxhdGlvblVwZGF0ZXMoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgb2JqZWN0Lm9iamVjdElkLFxuICAgICAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgICAgIHJlbGF0aW9uVXBkYXRlc1xuICAgICAgICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxPYmplY3QsIHJlc3VsdC5vcHNbMF0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNhbkFkZEZpZWxkKFxuICAgIHNjaGVtYTogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyLFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIG9iamVjdDogYW55LFxuICAgIGFjbEdyb3VwOiBzdHJpbmdbXSxcbiAgICBydW5PcHRpb25zOiBRdWVyeU9wdGlvbnNcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2xhc3NTY2hlbWEgPSBzY2hlbWEuc2NoZW1hRGF0YVtjbGFzc05hbWVdO1xuICAgIGlmICghY2xhc3NTY2hlbWEpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMob2JqZWN0KTtcbiAgICBjb25zdCBzY2hlbWFGaWVsZHMgPSBPYmplY3Qua2V5cyhjbGFzc1NjaGVtYS5maWVsZHMpO1xuICAgIGNvbnN0IG5ld0tleXMgPSBmaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIC8vIFNraXAgZmllbGRzIHRoYXQgYXJlIHVuc2V0XG4gICAgICBpZiAob2JqZWN0W2ZpZWxkXSAmJiBvYmplY3RbZmllbGRdLl9fb3AgJiYgb2JqZWN0W2ZpZWxkXS5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2NoZW1hRmllbGRzLmluZGV4T2YoZmllbGQpIDwgMDtcbiAgICB9KTtcbiAgICBpZiAobmV3S2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBhZGRzIGEgbWFya2VyIHRoYXQgbmV3IGZpZWxkIGlzIGJlaW5nIGFkZGluZyBkdXJpbmcgdXBkYXRlXG4gICAgICBydW5PcHRpb25zLmFkZHNGaWVsZCA9IHRydWU7XG5cbiAgICAgIGNvbnN0IGFjdGlvbiA9IHJ1bk9wdGlvbnMuYWN0aW9uO1xuICAgICAgcmV0dXJuIHNjaGVtYS52YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lLCBhY2xHcm91cCwgJ2FkZEZpZWxkJywgYWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gV29uJ3QgZGVsZXRlIGNvbGxlY3Rpb25zIGluIHRoZSBzeXN0ZW0gbmFtZXNwYWNlXG4gIC8qKlxuICAgKiBEZWxldGUgYWxsIGNsYXNzZXMgYW5kIGNsZWFycyB0aGUgc2NoZW1hIGNhY2hlXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZGVsZXRlIHJvd3MgYW5kIG5vdCBpbmRleGVzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSB3aGVuIHRoZSBkZWxldGlvbnMgY29tcGxldGVzXG4gICAqL1xuICBkZWxldGVFdmVyeXRoaW5nKGZhc3Q6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8YW55PiB7XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlID0gbnVsbDtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3RoaXMuYWRhcHRlci5kZWxldGVBbGxDbGFzc2VzKGZhc3QpLCB0aGlzLnNjaGVtYUNhY2hlLmNsZWFyKCldKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIGxpc3Qgb2YgcmVsYXRlZCBpZHMgZ2l2ZW4gYW4gb3duaW5nIGlkLlxuICAvLyBjbGFzc05hbWUgaGVyZSBpcyB0aGUgb3duaW5nIGNsYXNzTmFtZS5cbiAgcmVsYXRlZElkcyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyxcbiAgICBvd25pbmdJZDogc3RyaW5nLFxuICAgIHF1ZXJ5T3B0aW9uczogUXVlcnlPcHRpb25zXG4gICk6IFByb21pc2U8QXJyYXk8c3RyaW5nPj4ge1xuICAgIGNvbnN0IHsgc2tpcCwgbGltaXQsIHNvcnQgfSA9IHF1ZXJ5T3B0aW9ucztcbiAgICBjb25zdCBmaW5kT3B0aW9ucyA9IHt9O1xuICAgIGlmIChzb3J0ICYmIHNvcnQuY3JlYXRlZEF0ICYmIHRoaXMuYWRhcHRlci5jYW5Tb3J0T25Kb2luVGFibGVzKSB7XG4gICAgICBmaW5kT3B0aW9ucy5zb3J0ID0geyBfaWQ6IHNvcnQuY3JlYXRlZEF0IH07XG4gICAgICBmaW5kT3B0aW9ucy5saW1pdCA9IGxpbWl0O1xuICAgICAgZmluZE9wdGlvbnMuc2tpcCA9IHNraXA7XG4gICAgICBxdWVyeU9wdGlvbnMuc2tpcCA9IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXJcbiAgICAgIC5maW5kKGpvaW5UYWJsZU5hbWUoY2xhc3NOYW1lLCBrZXkpLCByZWxhdGlvblNjaGVtYSwgeyBvd25pbmdJZCB9LCBmaW5kT3B0aW9ucylcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4gcmVzdWx0cy5tYXAocmVzdWx0ID0+IHJlc3VsdC5yZWxhdGVkSWQpKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIGxpc3Qgb2Ygb3duaW5nIGlkcyBnaXZlbiBzb21lIHJlbGF0ZWQgaWRzLlxuICAvLyBjbGFzc05hbWUgaGVyZSBpcyB0aGUgb3duaW5nIGNsYXNzTmFtZS5cbiAgb3duaW5nSWRzKGNsYXNzTmFtZTogc3RyaW5nLCBrZXk6IHN0cmluZywgcmVsYXRlZElkczogc3RyaW5nW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLmZpbmQoXG4gICAgICAgIGpvaW5UYWJsZU5hbWUoY2xhc3NOYW1lLCBrZXkpLFxuICAgICAgICByZWxhdGlvblNjaGVtYSxcbiAgICAgICAgeyByZWxhdGVkSWQ6IHsgJGluOiByZWxhdGVkSWRzIH0gfSxcbiAgICAgICAgeyBrZXlzOiBbJ293bmluZ0lkJ10gfVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzLm1hcChyZXN1bHQgPT4gcmVzdWx0Lm93bmluZ0lkKSk7XG4gIH1cblxuICAvLyBNb2RpZmllcyBxdWVyeSBzbyB0aGF0IGl0IG5vIGxvbmdlciBoYXMgJGluIG9uIHJlbGF0aW9uIGZpZWxkcywgb3JcbiAgLy8gZXF1YWwtdG8tcG9pbnRlciBjb25zdHJhaW50cyBvbiByZWxhdGlvbiBmaWVsZHMuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBxdWVyeSBpcyBtdXRhdGVkXG4gIHJlZHVjZUluUmVsYXRpb24oY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBhbnksIHNjaGVtYTogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICAvLyBTZWFyY2ggZm9yIGFuIGluLXJlbGF0aW9uIG9yIGVxdWFsLXRvLXJlbGF0aW9uXG4gICAgLy8gTWFrZSBpdCBzZXF1ZW50aWFsIGZvciBub3csIG5vdCBzdXJlIG9mIHBhcmFsbGVpemF0aW9uIHNpZGUgZWZmZWN0c1xuICAgIGlmIChxdWVyeVsnJG9yJ10pIHtcbiAgICAgIGNvbnN0IG9ycyA9IHF1ZXJ5Wyckb3InXTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgICAgb3JzLm1hcCgoYVF1ZXJ5LCBpbmRleCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlZHVjZUluUmVsYXRpb24oY2xhc3NOYW1lLCBhUXVlcnksIHNjaGVtYSkudGhlbihhUXVlcnkgPT4ge1xuICAgICAgICAgICAgcXVlcnlbJyRvciddW2luZGV4XSA9IGFRdWVyeTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocXVlcnkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvbWlzZXMgPSBPYmplY3Qua2V5cyhxdWVyeSkubWFwKGtleSA9PiB7XG4gICAgICBjb25zdCB0ID0gc2NoZW1hLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGtleSk7XG4gICAgICBpZiAoIXQgfHwgdC50eXBlICE9PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocXVlcnkpO1xuICAgICAgfVxuICAgICAgbGV0IHF1ZXJpZXM6ID8oYW55W10pID0gbnVsbDtcbiAgICAgIGlmIChcbiAgICAgICAgcXVlcnlba2V5XSAmJlxuICAgICAgICAocXVlcnlba2V5XVsnJGluJ10gfHxcbiAgICAgICAgICBxdWVyeVtrZXldWyckbmUnXSB8fFxuICAgICAgICAgIHF1ZXJ5W2tleV1bJyRuaW4nXSB8fFxuICAgICAgICAgIHF1ZXJ5W2tleV0uX190eXBlID09ICdQb2ludGVyJylcbiAgICAgICkge1xuICAgICAgICAvLyBCdWlsZCB0aGUgbGlzdCBvZiBxdWVyaWVzXG4gICAgICAgIHF1ZXJpZXMgPSBPYmplY3Qua2V5cyhxdWVyeVtrZXldKS5tYXAoY29uc3RyYWludEtleSA9PiB7XG4gICAgICAgICAgbGV0IHJlbGF0ZWRJZHM7XG4gICAgICAgICAgbGV0IGlzTmVnYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICBpZiAoY29uc3RyYWludEtleSA9PT0gJ29iamVjdElkJykge1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IFtxdWVyeVtrZXldLm9iamVjdElkXTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN0cmFpbnRLZXkgPT0gJyRpbicpIHtcbiAgICAgICAgICAgIHJlbGF0ZWRJZHMgPSBxdWVyeVtrZXldWyckaW4nXS5tYXAociA9PiByLm9iamVjdElkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN0cmFpbnRLZXkgPT0gJyRuaW4nKSB7XG4gICAgICAgICAgICBpc05lZ2F0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlbGF0ZWRJZHMgPSBxdWVyeVtrZXldWyckbmluJ10ubWFwKHIgPT4gci5vYmplY3RJZCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChjb25zdHJhaW50S2V5ID09ICckbmUnKSB7XG4gICAgICAgICAgICBpc05lZ2F0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlbGF0ZWRJZHMgPSBbcXVlcnlba2V5XVsnJG5lJ10ub2JqZWN0SWRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpc05lZ2F0aW9uLFxuICAgICAgICAgICAgcmVsYXRlZElkcyxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXJpZXMgPSBbeyBpc05lZ2F0aW9uOiBmYWxzZSwgcmVsYXRlZElkczogW10gfV07XG4gICAgICB9XG5cbiAgICAgIC8vIHJlbW92ZSB0aGUgY3VycmVudCBxdWVyeUtleSBhcyB3ZSBkb24sdCBuZWVkIGl0IGFueW1vcmVcbiAgICAgIGRlbGV0ZSBxdWVyeVtrZXldO1xuICAgICAgLy8gZXhlY3V0ZSBlYWNoIHF1ZXJ5IGluZGVwZW5kZW50bHkgdG8gYnVpbGQgdGhlIGxpc3Qgb2ZcbiAgICAgIC8vICRpbiAvICRuaW5cbiAgICAgIGNvbnN0IHByb21pc2VzID0gcXVlcmllcy5tYXAocSA9PiB7XG4gICAgICAgIGlmICghcSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5vd25pbmdJZHMoY2xhc3NOYW1lLCBrZXksIHEucmVsYXRlZElkcykudGhlbihpZHMgPT4ge1xuICAgICAgICAgIGlmIChxLmlzTmVnYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuYWRkTm90SW5PYmplY3RJZHNJZHMoaWRzLCBxdWVyeSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW5PYmplY3RJZHNJZHMoaWRzLCBxdWVyeSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShxdWVyeSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBNb2RpZmllcyBxdWVyeSBzbyB0aGF0IGl0IG5vIGxvbmdlciBoYXMgJHJlbGF0ZWRUb1xuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gcXVlcnkgaXMgbXV0YXRlZFxuICByZWR1Y2VSZWxhdGlvbktleXMoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBhbnksIHF1ZXJ5T3B0aW9uczogYW55KTogP1Byb21pc2U8dm9pZD4ge1xuICAgIGlmIChxdWVyeVsnJG9yJ10pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgICAgcXVlcnlbJyRvciddLm1hcChhUXVlcnkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlZHVjZVJlbGF0aW9uS2V5cyhjbGFzc05hbWUsIGFRdWVyeSwgcXVlcnlPcHRpb25zKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdmFyIHJlbGF0ZWRUbyA9IHF1ZXJ5WyckcmVsYXRlZFRvJ107XG4gICAgaWYgKHJlbGF0ZWRUbykge1xuICAgICAgcmV0dXJuIHRoaXMucmVsYXRlZElkcyhcbiAgICAgICAgcmVsYXRlZFRvLm9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgIHJlbGF0ZWRUby5rZXksXG4gICAgICAgIHJlbGF0ZWRUby5vYmplY3Qub2JqZWN0SWQsXG4gICAgICAgIHF1ZXJ5T3B0aW9uc1xuICAgICAgKVxuICAgICAgICAudGhlbihpZHMgPT4ge1xuICAgICAgICAgIGRlbGV0ZSBxdWVyeVsnJHJlbGF0ZWRUbyddO1xuICAgICAgICAgIHRoaXMuYWRkSW5PYmplY3RJZHNJZHMoaWRzLCBxdWVyeSk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVkdWNlUmVsYXRpb25LZXlzKGNsYXNzTmFtZSwgcXVlcnksIHF1ZXJ5T3B0aW9ucyk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHt9KTtcbiAgICB9XG4gIH1cblxuICBhZGRJbk9iamVjdElkc0lkcyhpZHM6ID9BcnJheTxzdHJpbmc+ID0gbnVsbCwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGlkc0Zyb21TdHJpbmc6ID9BcnJheTxzdHJpbmc+ID1cbiAgICAgIHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZycgPyBbcXVlcnkub2JqZWN0SWRdIDogbnVsbDtcbiAgICBjb25zdCBpZHNGcm9tRXE6ID9BcnJheTxzdHJpbmc+ID1cbiAgICAgIHF1ZXJ5Lm9iamVjdElkICYmIHF1ZXJ5Lm9iamVjdElkWyckZXEnXSA/IFtxdWVyeS5vYmplY3RJZFsnJGVxJ11dIDogbnVsbDtcbiAgICBjb25zdCBpZHNGcm9tSW46ID9BcnJheTxzdHJpbmc+ID1cbiAgICAgIHF1ZXJ5Lm9iamVjdElkICYmIHF1ZXJ5Lm9iamVjdElkWyckaW4nXSA/IHF1ZXJ5Lm9iamVjdElkWyckaW4nXSA6IG51bGw7XG5cbiAgICAvLyBAZmxvdy1kaXNhYmxlLW5leHRcbiAgICBjb25zdCBhbGxJZHM6IEFycmF5PEFycmF5PHN0cmluZz4+ID0gW2lkc0Zyb21TdHJpbmcsIGlkc0Zyb21FcSwgaWRzRnJvbUluLCBpZHNdLmZpbHRlcihcbiAgICAgIGxpc3QgPT4gbGlzdCAhPT0gbnVsbFxuICAgICk7XG4gICAgY29uc3QgdG90YWxMZW5ndGggPSBhbGxJZHMucmVkdWNlKChtZW1vLCBsaXN0KSA9PiBtZW1vICsgbGlzdC5sZW5ndGgsIDApO1xuXG4gICAgbGV0IGlkc0ludGVyc2VjdGlvbiA9IFtdO1xuICAgIGlmICh0b3RhbExlbmd0aCA+IDEyNSkge1xuICAgICAgaWRzSW50ZXJzZWN0aW9uID0gaW50ZXJzZWN0LmJpZyhhbGxJZHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHNJbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3QoYWxsSWRzKTtcbiAgICB9XG5cbiAgICAvLyBOZWVkIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBjbG9iYmVyIGV4aXN0aW5nIHNob3J0aGFuZCAkZXEgY29uc3RyYWludHMgb24gb2JqZWN0SWQuXG4gICAgaWYgKCEoJ29iamVjdElkJyBpbiBxdWVyeSkpIHtcbiAgICAgIHF1ZXJ5Lm9iamVjdElkID0ge1xuICAgICAgICAkaW46IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHtcbiAgICAgICAgJGluOiB1bmRlZmluZWQsXG4gICAgICAgICRlcTogcXVlcnkub2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cbiAgICBxdWVyeS5vYmplY3RJZFsnJGluJ10gPSBpZHNJbnRlcnNlY3Rpb247XG5cbiAgICByZXR1cm4gcXVlcnk7XG4gIH1cblxuICBhZGROb3RJbk9iamVjdElkc0lkcyhpZHM6IHN0cmluZ1tdID0gW10sIHF1ZXJ5OiBhbnkpIHtcbiAgICBjb25zdCBpZHNGcm9tTmluID0gcXVlcnkub2JqZWN0SWQgJiYgcXVlcnkub2JqZWN0SWRbJyRuaW4nXSA/IHF1ZXJ5Lm9iamVjdElkWyckbmluJ10gOiBbXTtcbiAgICBsZXQgYWxsSWRzID0gWy4uLmlkc0Zyb21OaW4sIC4uLmlkc10uZmlsdGVyKGxpc3QgPT4gbGlzdCAhPT0gbnVsbCk7XG5cbiAgICAvLyBtYWtlIGEgc2V0IGFuZCBzcHJlYWQgdG8gcmVtb3ZlIGR1cGxpY2F0ZXNcbiAgICBhbGxJZHMgPSBbLi4ubmV3IFNldChhbGxJZHMpXTtcblxuICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIHdlIGRvbid0IGNsb2JiZXIgZXhpc3Rpbmcgc2hvcnRoYW5kICRlcSBjb25zdHJhaW50cyBvbiBvYmplY3RJZC5cbiAgICBpZiAoISgnb2JqZWN0SWQnIGluIHF1ZXJ5KSkge1xuICAgICAgcXVlcnkub2JqZWN0SWQgPSB7XG4gICAgICAgICRuaW46IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHtcbiAgICAgICAgJG5pbjogdW5kZWZpbmVkLFxuICAgICAgICAkZXE6IHF1ZXJ5Lm9iamVjdElkLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBxdWVyeS5vYmplY3RJZFsnJG5pbiddID0gYWxsSWRzO1xuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8vIFJ1bnMgYSBxdWVyeSBvbiB0aGUgZGF0YWJhc2UuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBsaXN0IG9mIGl0ZW1zLlxuICAvLyBPcHRpb25zOlxuICAvLyAgIHNraXAgICAgbnVtYmVyIG9mIHJlc3VsdHMgdG8gc2tpcC5cbiAgLy8gICBsaW1pdCAgIGxpbWl0IHRvIHRoaXMgbnVtYmVyIG9mIHJlc3VsdHMuXG4gIC8vICAgc29ydCAgICBhbiBvYmplY3Qgd2hlcmUga2V5cyBhcmUgdGhlIGZpZWxkcyB0byBzb3J0IGJ5LlxuICAvLyAgICAgICAgICAgdGhlIHZhbHVlIGlzICsxIGZvciBhc2NlbmRpbmcsIC0xIGZvciBkZXNjZW5kaW5nLlxuICAvLyAgIGNvdW50ICAgcnVuIGEgY291bnQgaW5zdGVhZCBvZiByZXR1cm5pbmcgcmVzdWx0cy5cbiAgLy8gICBhY2wgICAgIHJlc3RyaWN0IHRoaXMgb3BlcmF0aW9uIHdpdGggYW4gQUNMIGZvciB0aGUgcHJvdmlkZWQgYXJyYXlcbiAgLy8gICAgICAgICAgIG9mIHVzZXIgb2JqZWN0SWRzIGFuZCByb2xlcy4gYWNsOiBudWxsIG1lYW5zIG5vIHVzZXIuXG4gIC8vICAgICAgICAgICB3aGVuIHRoaXMgZmllbGQgaXMgbm90IHByZXNlbnQsIGRvbid0IGRvIGFueXRoaW5nIHJlZ2FyZGluZyBBQ0xzLlxuICAvLyAgY2FzZUluc2Vuc2l0aXZlIG1ha2Ugc3RyaW5nIGNvbXBhcmlzb25zIGNhc2UgaW5zZW5zaXRpdmVcbiAgLy8gVE9ETzogbWFrZSB1c2VySWRzIG5vdCBuZWVkZWQgaGVyZS4gVGhlIGRiIGFkYXB0ZXIgc2hvdWxkbid0IGtub3dcbiAgLy8gYW55dGhpbmcgYWJvdXQgdXNlcnMsIGlkZWFsbHkuIFRoZW4sIGltcHJvdmUgdGhlIGZvcm1hdCBvZiB0aGUgQUNMXG4gIC8vIGFyZyB0byB3b3JrIGxpa2UgdGhlIG90aGVycy5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55LFxuICAgIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIGFjbCxcbiAgICAgIHNvcnQgPSB7fSxcbiAgICAgIGNvdW50LFxuICAgICAga2V5cyxcbiAgICAgIG9wLFxuICAgICAgZGlzdGluY3QsXG4gICAgICBwaXBlbGluZSxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSA9IGZhbHNlLFxuICAgICAgZXhwbGFpbixcbiAgICB9OiBhbnkgPSB7fSxcbiAgICBhdXRoOiBhbnkgPSB7fSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgY29uc3QgYWNsR3JvdXAgPSBhY2wgfHwgW107XG4gICAgb3AgPVxuICAgICAgb3AgfHwgKHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PSAnc3RyaW5nJyAmJiBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoID09PSAxID8gJ2dldCcgOiAnZmluZCcpO1xuICAgIC8vIENvdW50IG9wZXJhdGlvbiBpZiBjb3VudGluZ1xuICAgIG9wID0gY291bnQgPT09IHRydWUgPyAnY291bnQnIDogb3A7XG5cbiAgICBsZXQgY2xhc3NFeGlzdHMgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLmxvYWRTY2hlbWFJZk5lZWRlZCh2YWxpZFNjaGVtYUNvbnRyb2xsZXIpLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiB7XG4gICAgICAvL0FsbG93IHZvbGF0aWxlIGNsYXNzZXMgaWYgcXVlcnlpbmcgd2l0aCBNYXN0ZXIgKGZvciBfUHVzaFN0YXR1cylcbiAgICAgIC8vVE9ETzogTW92ZSB2b2xhdGlsZSBjbGFzc2VzIGNvbmNlcHQgaW50byBtb25nbyBhZGFwdGVyLCBwb3N0Z3JlcyBhZGFwdGVyIHNob3VsZG4ndCBjYXJlXG4gICAgICAvL3RoYXQgYXBpLnBhcnNlLmNvbSBicmVha3Mgd2hlbiBfUHVzaFN0YXR1cyBleGlzdHMgaW4gbW9uZ28uXG4gICAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlclxuICAgICAgICAuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgaXNNYXN0ZXIpXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgLy8gQmVoYXZpb3IgZm9yIG5vbi1leGlzdGVudCBjbGFzc2VzIGlzIGtpbmRhIHdlaXJkIG9uIFBhcnNlLmNvbS4gUHJvYmFibHkgZG9lc24ndCBtYXR0ZXIgdG9vIG11Y2guXG4gICAgICAgICAgLy8gRm9yIG5vdywgcHJldGVuZCB0aGUgY2xhc3MgZXhpc3RzIGJ1dCBoYXMgbm8gb2JqZWN0cyxcbiAgICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY2xhc3NFeGlzdHMgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB7IGZpZWxkczoge30gfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICAgICAgLy8gUGFyc2UuY29tIHRyZWF0cyBxdWVyaWVzIG9uIF9jcmVhdGVkX2F0IGFuZCBfdXBkYXRlZF9hdCBhcyBpZiB0aGV5IHdlcmUgcXVlcmllcyBvbiBjcmVhdGVkQXQgYW5kIHVwZGF0ZWRBdCxcbiAgICAgICAgICAvLyBzbyBkdXBsaWNhdGUgdGhhdCBiZWhhdmlvciBoZXJlLiBJZiBib3RoIGFyZSBzcGVjaWZpZWQsIHRoZSBjb3JyZWN0IGJlaGF2aW9yIHRvIG1hdGNoIFBhcnNlLmNvbSBpcyB0b1xuICAgICAgICAgIC8vIHVzZSB0aGUgb25lIHRoYXQgYXBwZWFycyBmaXJzdCBpbiB0aGUgc29ydCBsaXN0LlxuICAgICAgICAgIGlmIChzb3J0Ll9jcmVhdGVkX2F0KSB7XG4gICAgICAgICAgICBzb3J0LmNyZWF0ZWRBdCA9IHNvcnQuX2NyZWF0ZWRfYXQ7XG4gICAgICAgICAgICBkZWxldGUgc29ydC5fY3JlYXRlZF9hdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNvcnQuX3VwZGF0ZWRfYXQpIHtcbiAgICAgICAgICAgIHNvcnQudXBkYXRlZEF0ID0gc29ydC5fdXBkYXRlZF9hdDtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3J0Ll91cGRhdGVkX2F0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBxdWVyeU9wdGlvbnMgPSB7XG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgICAgICAgIGV4cGxhaW4sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhzb3J0KS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoZmllbGROYW1lLm1hdGNoKC9eYXV0aERhdGFcXC4oW2EtekEtWjAtOV9dKylcXC5pZCQvKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYENhbm5vdCBzb3J0IGJ5ICR7ZmllbGROYW1lfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgcm9vdEZpZWxkTmFtZSA9IGdldFJvb3RGaWVsZE5hbWUoZmllbGROYW1lKTtcbiAgICAgICAgICAgIGlmICghU2NoZW1hQ29udHJvbGxlci5maWVsZE5hbWVJc1ZhbGlkKHJvb3RGaWVsZE5hbWUpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICAgICAgIGBJbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfS5gXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIChpc01hc3RlclxuICAgICAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgICAgOiBzY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWUsIGFjbEdyb3VwLCBvcClcbiAgICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJlZHVjZVJlbGF0aW9uS2V5cyhjbGFzc05hbWUsIHF1ZXJ5LCBxdWVyeU9wdGlvbnMpKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWR1Y2VJblJlbGF0aW9uKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYUNvbnRyb2xsZXIpKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICBsZXQgcHJvdGVjdGVkRmllbGRzO1xuICAgICAgICAgICAgICBpZiAoIWlzTWFzdGVyKSB7XG4gICAgICAgICAgICAgICAgcXVlcnkgPSB0aGlzLmFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICAgICAgICAgICAgICAgIHNjaGVtYUNvbnRyb2xsZXIsXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICBvcCxcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIC8qIERvbid0IHVzZSBwcm9qZWN0aW9ucyB0byBvcHRpbWl6ZSB0aGUgcHJvdGVjdGVkRmllbGRzIHNpbmNlIHRoZSBwcm90ZWN0ZWRGaWVsZHNcbiAgICAgICAgICAgICAgICAgIGJhc2VkIG9uIHBvaW50ZXItcGVybWlzc2lvbnMgYXJlIGRldGVybWluZWQgYWZ0ZXIgcXVlcnlpbmcuIFRoZSBmaWx0ZXJpbmcgY2FuXG4gICAgICAgICAgICAgICAgICBvdmVyd3JpdGUgdGhlIHByb3RlY3RlZCBmaWVsZHMuICovXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzID0gdGhpcy5hZGRQcm90ZWN0ZWRGaWVsZHMoXG4gICAgICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgICAgICBxdWVyeU9wdGlvbnNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICghcXVlcnkpIHtcbiAgICAgICAgICAgICAgICBpZiAob3AgPT09ICdnZXQnKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKCFpc01hc3Rlcikge1xuICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gJ3VwZGF0ZScgfHwgb3AgPT09ICdkZWxldGUnKSB7XG4gICAgICAgICAgICAgICAgICBxdWVyeSA9IGFkZFdyaXRlQUNMKHF1ZXJ5LCBhY2xHcm91cCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5ID0gYWRkUmVhZEFDTChxdWVyeSwgYWNsR3JvdXApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGFzc0V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY291bnQoXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgaGludFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlzdGluY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNsYXNzRXhpc3RzKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGlzdGluY3QoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCBkaXN0aW5jdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBpcGVsaW5lKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGFzc0V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFnZ3JlZ2F0ZShcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgICAgIHBpcGVsaW5lLFxuICAgICAgICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgICAgICAgICAgZXhwbGFpblxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhwbGFpbikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZmluZChjbGFzc05hbWUsIHNjaGVtYSwgcXVlcnksIHF1ZXJ5T3B0aW9ucyk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgICAgICAgICAgICAgLmZpbmQoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCBxdWVyeU9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAudGhlbihvYmplY3RzID0+XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdHMubWFwKG9iamVjdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgb2JqZWN0ID0gdW50cmFuc2Zvcm1PYmplY3RBQ0wob2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyU2Vuc2l0aXZlRGF0YShcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzTWFzdGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3AsXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBkZWxldGVTY2hlbWEoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4geyBmaWVsZHM6IHt9IH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAudGhlbigoc2NoZW1hOiBhbnkpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29sbGVjdGlvbkV4aXN0cyhjbGFzc05hbWUpXG4gICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5hZGFwdGVyLmNvdW50KGNsYXNzTmFtZSwgeyBmaWVsZHM6IHt9IH0sIG51bGwsICcnLCBmYWxzZSkpXG4gICAgICAgICAgLnRoZW4oY291bnQgPT4ge1xuICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgMjU1LFxuICAgICAgICAgICAgICAgIGBDbGFzcyAke2NsYXNzTmFtZX0gaXMgbm90IGVtcHR5LCBjb250YWlucyAke2NvdW50fSBvYmplY3RzLCBjYW5ub3QgZHJvcCBzY2hlbWEuYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5kZWxldGVDbGFzcyhjbGFzc05hbWUpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4od2FzUGFyc2VDb2xsZWN0aW9uID0+IHtcbiAgICAgICAgICAgIGlmICh3YXNQYXJzZUNvbGxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgY29uc3QgcmVsYXRpb25GaWVsZE5hbWVzID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZmlsdGVyKFxuICAgICAgICAgICAgICAgIGZpZWxkTmFtZSA9PiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ1JlbGF0aW9uJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgICAgcmVsYXRpb25GaWVsZE5hbWVzLm1hcChuYW1lID0+XG4gICAgICAgICAgICAgICAgICB0aGlzLmFkYXB0ZXIuZGVsZXRlQ2xhc3Moam9pblRhYmxlTmFtZShjbGFzc05hbWUsIG5hbWUpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBDb25zdHJhaW50cyBxdWVyeSB1c2luZyBDTFAncyBwb2ludGVyIHBlcm1pc3Npb25zIChQUCkgaWYgYW55LlxuICAvLyAxLiBFdHJhY3QgdGhlIHVzZXIgaWQgZnJvbSBjYWxsZXIncyBBQ0xncm91cDtcbiAgLy8gMi4gRXhjdHJhY3QgYSBsaXN0IG9mIGZpZWxkIG5hbWVzIHRoYXQgYXJlIFBQIGZvciB0YXJnZXQgY29sbGVjdGlvbiBhbmQgb3BlcmF0aW9uO1xuICAvLyAzLiBDb25zdHJhaW50IHRoZSBvcmlnaW5hbCBxdWVyeSBzbyB0aGF0IGVhY2ggUFAgZmllbGQgbXVzdFxuICAvLyBwb2ludCB0byBjYWxsZXIncyBpZCAob3IgY29udGFpbiBpdCBpbiBjYXNlIG9mIFBQIGZpZWxkIGJlaW5nIGFuIGFycmF5KVxuICBhZGRQb2ludGVyUGVybWlzc2lvbnMoXG4gICAgc2NoZW1hOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueSxcbiAgICBhY2xHcm91cDogYW55W10gPSBbXVxuICApOiBhbnkge1xuICAgIC8vIENoZWNrIGlmIGNsYXNzIGhhcyBwdWJsaWMgcGVybWlzc2lvbiBmb3Igb3BlcmF0aW9uXG4gICAgLy8gSWYgdGhlIEJhc2VDTFAgcGFzcywgbGV0IGdvIHRocm91Z2hcbiAgICBpZiAoc2NoZW1hLnRlc3RQZXJtaXNzaW9uc0ZvckNsYXNzTmFtZShjbGFzc05hbWUsIGFjbEdyb3VwLCBvcGVyYXRpb24pKSB7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfVxuICAgIGNvbnN0IHBlcm1zID0gc2NoZW1hLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpO1xuXG4gICAgY29uc3QgdXNlckFDTCA9IGFjbEdyb3VwLmZpbHRlcihhY2wgPT4ge1xuICAgICAgcmV0dXJuIGFjbC5pbmRleE9mKCdyb2xlOicpICE9IDAgJiYgYWNsICE9ICcqJztcbiAgICB9KTtcblxuICAgIGNvbnN0IGdyb3VwS2V5ID1cbiAgICAgIFsnZ2V0JywgJ2ZpbmQnLCAnY291bnQnXS5pbmRleE9mKG9wZXJhdGlvbikgPiAtMSA/ICdyZWFkVXNlckZpZWxkcycgOiAnd3JpdGVVc2VyRmllbGRzJztcblxuICAgIGNvbnN0IHBlcm1GaWVsZHMgPSBbXTtcblxuICAgIGlmIChwZXJtc1tvcGVyYXRpb25dICYmIHBlcm1zW29wZXJhdGlvbl0ucG9pbnRlckZpZWxkcykge1xuICAgICAgcGVybUZpZWxkcy5wdXNoKC4uLnBlcm1zW29wZXJhdGlvbl0ucG9pbnRlckZpZWxkcyk7XG4gICAgfVxuXG4gICAgaWYgKHBlcm1zW2dyb3VwS2V5XSkge1xuICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiBwZXJtc1tncm91cEtleV0pIHtcbiAgICAgICAgaWYgKCFwZXJtRmllbGRzLmluY2x1ZGVzKGZpZWxkKSkge1xuICAgICAgICAgIHBlcm1GaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGhlIEFDTCBzaG91bGQgaGF2ZSBleGFjdGx5IDEgdXNlclxuICAgIGlmIChwZXJtRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIHRoZSBBQ0wgc2hvdWxkIGhhdmUgZXhhY3RseSAxIHVzZXJcbiAgICAgIC8vIE5vIHVzZXIgc2V0IHJldHVybiB1bmRlZmluZWRcbiAgICAgIC8vIElmIHRoZSBsZW5ndGggaXMgPiAxLCB0aGF0IG1lYW5zIHdlIGRpZG4ndCBkZS1kdXBlIHVzZXJzIGNvcnJlY3RseVxuICAgICAgaWYgKHVzZXJBQ0wubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdXNlcklkID0gdXNlckFDTFswXTtcbiAgICAgIGNvbnN0IHVzZXJQb2ludGVyID0ge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdXNlcklkLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcXVlcmllcyA9IHBlcm1GaWVsZHMubWFwKGtleSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkRGVzY3JpcHRvciA9IHNjaGVtYS5nZXRFeHBlY3RlZFR5cGUoY2xhc3NOYW1lLCBrZXkpO1xuICAgICAgICBjb25zdCBmaWVsZFR5cGUgPVxuICAgICAgICAgIGZpZWxkRGVzY3JpcHRvciAmJlxuICAgICAgICAgIHR5cGVvZiBmaWVsZERlc2NyaXB0b3IgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZpZWxkRGVzY3JpcHRvciwgJ3R5cGUnKVxuICAgICAgICAgICAgPyBmaWVsZERlc2NyaXB0b3IudHlwZVxuICAgICAgICAgICAgOiBudWxsO1xuXG4gICAgICAgIGxldCBxdWVyeUNsYXVzZTtcblxuICAgICAgICBpZiAoZmllbGRUeXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICAvLyBjb25zdHJhaW50IGZvciBzaW5nbGUgcG9pbnRlciBzZXR1cFxuICAgICAgICAgIHF1ZXJ5Q2xhdXNlID0geyBba2V5XTogdXNlclBvaW50ZXIgfTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgICAvLyBjb25zdHJhaW50IGZvciB1c2Vycy1hcnJheSBzZXR1cFxuICAgICAgICAgIHF1ZXJ5Q2xhdXNlID0geyBba2V5XTogeyAkYWxsOiBbdXNlclBvaW50ZXJdIH0gfTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFR5cGUgPT09ICdPYmplY3QnKSB7XG4gICAgICAgICAgLy8gY29uc3RyYWludCBmb3Igb2JqZWN0IHNldHVwXG4gICAgICAgICAgcXVlcnlDbGF1c2UgPSB7IFtrZXldOiB1c2VyUG9pbnRlciB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFRoaXMgbWVhbnMgdGhhdCB0aGVyZSBpcyBhIENMUCBmaWVsZCBvZiBhbiB1bmV4cGVjdGVkIHR5cGUuIFRoaXMgY29uZGl0aW9uIHNob3VsZCBub3QgaGFwcGVuLCB3aGljaCBpc1xuICAgICAgICAgIC8vIHdoeSBpcyBiZWluZyB0cmVhdGVkIGFzIGFuIGVycm9yLlxuICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgYEFuIHVuZXhwZWN0ZWQgY29uZGl0aW9uIG9jY3VycmVkIHdoZW4gcmVzb2x2aW5nIHBvaW50ZXIgcGVybWlzc2lvbnM6ICR7Y2xhc3NOYW1lfSAke2tleX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBjb25zdHJhaW50IG9uIHRoZSBrZXksIHVzZSB0aGUgJGFuZFxuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHF1ZXJ5LCBrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgJGFuZDogW3F1ZXJ5Q2xhdXNlLCBxdWVyeV0gfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBvdGhlcndpc2UganVzdCBhZGQgdGhlIGNvbnN0YWludFxuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgcXVlcnksIHF1ZXJ5Q2xhdXNlKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcXVlcmllcy5sZW5ndGggPT09IDEgPyBxdWVyaWVzWzBdIDogeyAkb3I6IHF1ZXJpZXMgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIGFkZFByb3RlY3RlZEZpZWxkcyhcbiAgICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55ID0ge30sXG4gICAgYWNsR3JvdXA6IGFueVtdID0gW10sXG4gICAgYXV0aDogYW55ID0ge30sXG4gICAgcXVlcnlPcHRpb25zOiBGdWxsUXVlcnlPcHRpb25zID0ge31cbiAgKTogbnVsbCB8IHN0cmluZ1tdIHtcbiAgICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgICBpZiAoIXBlcm1zKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkcyA9IHBlcm1zLnByb3RlY3RlZEZpZWxkcztcbiAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAoYWNsR3JvdXAuaW5kZXhPZihxdWVyeS5vYmplY3RJZCkgPiAtMSkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBmb3IgcXVlcmllcyB3aGVyZSBcImtleXNcIiBhcmUgc2V0IGFuZCBkbyBub3QgaW5jbHVkZSBhbGwgJ3VzZXJGaWVsZCc6e2ZpZWxkfSxcbiAgICAvLyB3ZSBoYXZlIHRvIHRyYW5zcGFyZW50bHkgaW5jbHVkZSBpdCwgYW5kIHRoZW4gcmVtb3ZlIGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50XG4gICAgLy8gQmVjYXVzZSBpZiBzdWNoIGtleSBub3QgcHJvamVjdGVkIHRoZSBwZXJtaXNzaW9uIHdvbid0IGJlIGVuZm9yY2VkIHByb3Blcmx5XG4gICAgLy8gUFMgdGhpcyBpcyBjYWxsZWQgd2hlbiAnZXhjbHVkZUtleXMnIGFscmVhZHkgcmVkdWNlZCB0byAna2V5cydcbiAgICBjb25zdCBwcmVzZXJ2ZUtleXMgPSBxdWVyeU9wdGlvbnMua2V5cztcblxuICAgIC8vIHRoZXNlIGFyZSBrZXlzIHRoYXQgbmVlZCB0byBiZSBpbmNsdWRlZCBvbmx5XG4gICAgLy8gdG8gYmUgYWJsZSB0byBhcHBseSBwcm90ZWN0ZWRGaWVsZHMgYnkgcG9pbnRlclxuICAgIC8vIGFuZCB0aGVuIHVuc2V0IGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50IChsYXRlciBpbiAgZmlsdGVyU2Vuc2l0aXZlRmllbGRzKVxuICAgIGNvbnN0IHNlcnZlck9ubHlLZXlzID0gW107XG5cbiAgICBjb25zdCBhdXRoZW50aWNhdGVkID0gYXV0aC51c2VyO1xuXG4gICAgLy8gbWFwIHRvIGFsbG93IGNoZWNrIHdpdGhvdXQgYXJyYXkgc2VhcmNoXG4gICAgY29uc3Qgcm9sZXMgPSAoYXV0aC51c2VyUm9sZXMgfHwgW10pLnJlZHVjZSgoYWNjLCByKSA9PiB7XG4gICAgICBhY2Nbcl0gPSBwcm90ZWN0ZWRGaWVsZHNbcl07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcblxuICAgIC8vIGFycmF5IG9mIHNldHMgb2YgcHJvdGVjdGVkIGZpZWxkcy4gc2VwYXJhdGUgaXRlbSBmb3IgZWFjaCBhcHBsaWNhYmxlIGNyaXRlcmlhXG4gICAgY29uc3QgcHJvdGVjdGVkS2V5c1NldHMgPSBbXTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgLy8gc2tpcCB1c2VyRmllbGRzXG4gICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ3VzZXJGaWVsZDonKSkge1xuICAgICAgICBpZiAocHJlc2VydmVLZXlzKSB7XG4gICAgICAgICAgY29uc3QgZmllbGROYW1lID0ga2V5LnN1YnN0cmluZygxMCk7XG4gICAgICAgICAgaWYgKCFwcmVzZXJ2ZUtleXMuaW5jbHVkZXMoZmllbGROYW1lKSkge1xuICAgICAgICAgICAgLy8gMS4gcHV0IGl0IHRoZXJlIHRlbXBvcmFyaWx5XG4gICAgICAgICAgICBxdWVyeU9wdGlvbnMua2V5cyAmJiBxdWVyeU9wdGlvbnMua2V5cy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgICAvLyAyLiBwcmVzZXJ2ZSBpdCBkZWxldGUgbGF0ZXJcbiAgICAgICAgICAgIHNlcnZlck9ubHlLZXlzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBwdWJsaWMgdGllclxuICAgICAgaWYgKGtleSA9PT0gJyonKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ2F1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgICAgLy8gZm9yIGxvZ2dlZCBpbiB1c2Vyc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJvbGVzW2tleV0gJiYga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpIHtcbiAgICAgICAgICAvLyBhZGQgYXBwbGljYWJsZSByb2xlc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocm9sZXNba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiB0aGVyZSdzIGEgcnVsZSBmb3IgY3VycmVudCB1c2VyJ3MgaWRcbiAgICBpZiAoYXV0aGVudGljYXRlZCkge1xuICAgICAgY29uc3QgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuICAgICAgaWYgKHBlcm1zLnByb3RlY3RlZEZpZWxkc1t1c2VySWRdKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocGVybXMucHJvdGVjdGVkRmllbGRzW3VzZXJJZF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHByZXNlcnZlIGZpZWxkcyB0byBiZSByZW1vdmVkIGJlZm9yZSBzZW5kaW5nIHJlc3BvbnNlIHRvIGNsaWVudFxuICAgIGlmIChzZXJ2ZXJPbmx5S2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyA9IHNlcnZlck9ubHlLZXlzO1xuICAgIH1cblxuICAgIGxldCBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5c1NldHMucmVkdWNlKChhY2MsIG5leHQpID0+IHtcbiAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgIGFjYy5wdXNoKC4uLm5leHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICAvLyBpbnRlcnNlY3QgYWxsIHNldHMgb2YgcHJvdGVjdGVkRmllbGRzXG4gICAgcHJvdGVjdGVkS2V5c1NldHMuZm9yRWFjaChmaWVsZHMgPT4ge1xuICAgICAgaWYgKGZpZWxkcykge1xuICAgICAgICBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5cy5maWx0ZXIodiA9PiBmaWVsZHMuaW5jbHVkZXModikpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHByb3RlY3RlZEtleXM7XG4gIH1cblxuICBjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCkudGhlbih0cmFuc2FjdGlvbmFsU2Vzc2lvbiA9PiB7XG4gICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbiA9IHRyYW5zYWN0aW9uYWxTZXNzaW9uO1xuICAgIH0pO1xuICB9XG5cbiAgY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKSB7XG4gICAgaWYgKCF0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGVyZSBpcyBubyB0cmFuc2FjdGlvbmFsIHNlc3Npb24gdG8gY29tbWl0Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICBpZiAoIXRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIHRyYW5zYWN0aW9uYWwgc2Vzc2lvbiB0byBhYm9ydCcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gVE9ETzogY3JlYXRlIGluZGV4ZXMgb24gZmlyc3QgY3JlYXRpb24gb2YgYSBfVXNlciBvYmplY3QuIE90aGVyd2lzZSBpdCdzIGltcG9zc2libGUgdG9cbiAgLy8gaGF2ZSBhIFBhcnNlIGFwcCB3aXRob3V0IGl0IGhhdmluZyBhIF9Vc2VyIGNvbGxlY3Rpb24uXG4gIHBlcmZvcm1Jbml0aWFsaXphdGlvbigpIHtcbiAgICBjb25zdCByZXF1aXJlZFVzZXJGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fVXNlcixcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZFJvbGVGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fUm9sZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZElkZW1wb3RlbmN5RmllbGRzID0ge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQsXG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlckNsYXNzUHJvbWlzZSA9IHRoaXMubG9hZFNjaGVtYSgpLnRoZW4oc2NoZW1hID0+IHNjaGVtYS5lbmZvcmNlQ2xhc3NFeGlzdHMoJ19Vc2VyJykpO1xuICAgIGNvbnN0IHJvbGVDbGFzc1Byb21pc2UgPSB0aGlzLmxvYWRTY2hlbWEoKS50aGVuKHNjaGVtYSA9PiBzY2hlbWEuZW5mb3JjZUNsYXNzRXhpc3RzKCdfUm9sZScpKTtcbiAgICBjb25zdCBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZSA9XG4gICAgICB0aGlzLmFkYXB0ZXIgaW5zdGFuY2VvZiBNb25nb1N0b3JhZ2VBZGFwdGVyXG4gICAgICAgID8gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4gc2NoZW1hLmVuZm9yY2VDbGFzc0V4aXN0cygnX0lkZW1wb3RlbmN5JykpXG4gICAgICAgIDogUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICBjb25zdCB1c2VybmFtZVVuaXF1ZW5lc3MgPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX1VzZXInLCByZXF1aXJlZFVzZXJGaWVsZHMsIFsndXNlcm5hbWUnXSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGVuc3VyZSB1bmlxdWVuZXNzIGZvciB1c2VybmFtZXM6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXggPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PlxuICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlSW5kZXgoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICByZXF1aXJlZFVzZXJGaWVsZHMsXG4gICAgICAgICAgWyd1c2VybmFtZSddLFxuICAgICAgICAgICdjYXNlX2luc2Vuc2l0aXZlX3VzZXJuYW1lJyxcbiAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gY3JlYXRlIGNhc2UgaW5zZW5zaXRpdmUgdXNlcm5hbWUgaW5kZXg6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGVtYWlsVW5pcXVlbmVzcyA9IHVzZXJDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfVXNlcicsIHJlcXVpcmVkVXNlckZpZWxkcywgWydlbWFpbCddKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gZW5zdXJlIHVuaXF1ZW5lc3MgZm9yIHVzZXIgZW1haWwgYWRkcmVzc2VzOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4ID0gdXNlckNsYXNzUHJvbWlzZVxuICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5hZGFwdGVyLmVuc3VyZUluZGV4KFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgcmVxdWlyZWRVc2VyRmllbGRzLFxuICAgICAgICAgIFsnZW1haWwnXSxcbiAgICAgICAgICAnY2FzZV9pbnNlbnNpdGl2ZV9lbWFpbCcsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGNyZWF0ZSBjYXNlIGluc2Vuc2l0aXZlIGVtYWlsIGluZGV4OiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCByb2xlVW5pcXVlbmVzcyA9IHJvbGVDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfUm9sZScsIHJlcXVpcmVkUm9sZUZpZWxkcywgWyduYW1lJ10pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3Igcm9sZSBuYW1lOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4ID1cbiAgICAgIHRoaXMuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXJcbiAgICAgICAgPyBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZVxuICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX0lkZW1wb3RlbmN5JywgcmVxdWlyZWRJZGVtcG90ZW5jeUZpZWxkcywgWydyZXFJZCddKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3IgaWRlbXBvdGVuY3kgcmVxdWVzdCBJRDogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGlkZW1wb3RlbmN5RXhwaXJlSW5kZXggPVxuICAgICAgdGhpcy5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlclxuICAgICAgICA/IGlkZW1wb3RlbmN5Q2xhc3NQcm9taXNlXG4gICAgICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgICAgIHRoaXMuYWRhcHRlci5lbnN1cmVJbmRleChcbiAgICAgICAgICAgICAgJ19JZGVtcG90ZW5jeScsXG4gICAgICAgICAgICAgIHJlcXVpcmVkSWRlbXBvdGVuY3lGaWVsZHMsXG4gICAgICAgICAgICAgIFsnZXhwaXJlJ10sXG4gICAgICAgICAgICAgICd0dGwnLFxuICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgeyB0dGw6IDAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBjcmVhdGUgVFRMIGluZGV4IGZvciBpZGVtcG90ZW5jeSBleHBpcmUgZGF0ZTogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGluZGV4UHJvbWlzZSA9IHRoaXMuYWRhcHRlci51cGRhdGVTY2hlbWFXaXRoSW5kZXhlcygpO1xuXG4gICAgLy8gQ3JlYXRlIHRhYmxlcyBmb3Igdm9sYXRpbGUgY2xhc3Nlc1xuICAgIGNvbnN0IGFkYXB0ZXJJbml0ID0gdGhpcy5hZGFwdGVyLnBlcmZvcm1Jbml0aWFsaXphdGlvbih7XG4gICAgICBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzOiBTY2hlbWFDb250cm9sbGVyLlZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMsXG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgIHVzZXJuYW1lVW5pcXVlbmVzcyxcbiAgICAgIHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXgsXG4gICAgICBlbWFpbFVuaXF1ZW5lc3MsXG4gICAgICBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4LFxuICAgICAgcm9sZVVuaXF1ZW5lc3MsXG4gICAgICBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4LFxuICAgICAgaWRlbXBvdGVuY3lFeHBpcmVJbmRleCxcbiAgICAgIGFkYXB0ZXJJbml0LFxuICAgICAgaW5kZXhQcm9taXNlLFxuICAgIF0pO1xuICB9XG5cbiAgc3RhdGljIF92YWxpZGF0ZVF1ZXJ5OiBhbnkgPT4gdm9pZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhYmFzZUNvbnRyb2xsZXI7XG4vLyBFeHBvc2UgdmFsaWRhdGVRdWVyeSBmb3IgdGVzdHNcbm1vZHVsZS5leHBvcnRzLl92YWxpZGF0ZVF1ZXJ5ID0gdmFsaWRhdGVRdWVyeTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/FilesController.js b/lib/Controllers/FilesController.js deleted file mode 100644 index c189e36093..0000000000 --- a/lib/Controllers/FilesController.js +++ /dev/null @@ -1,136 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.FilesController = void 0; - -var _cryptoUtils = require("../cryptoUtils"); - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); - -var _path = _interopRequireDefault(require("path")); - -var _mime = _interopRequireDefault(require("mime")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// FilesController.js -const Parse = require('parse').Parse; - -const legacyFilesRegex = new RegExp('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}-.*'); - -class FilesController extends _AdaptableController.default { - getFileData(config, filename) { - return this.adapter.getFileData(filename); - } - - createFile(config, filename, data, contentType, options) { - const extname = _path.default.extname(filename); - - const hasExtension = extname.length > 0; - - if (!hasExtension && contentType && _mime.default.getExtension(contentType)) { - filename = filename + '.' + _mime.default.getExtension(contentType); - } else if (hasExtension && !contentType) { - contentType = _mime.default.getType(filename); - } - - if (!this.options.preserveFileName) { - filename = (0, _cryptoUtils.randomHexString)(32) + '_' + filename; - } - - const location = this.adapter.getFileLocation(config, filename); - return this.adapter.createFile(filename, data, contentType, options).then(() => { - return Promise.resolve({ - url: location, - name: filename - }); - }); - } - - deleteFile(config, filename) { - return this.adapter.deleteFile(filename); - } - - getMetadata(filename) { - if (typeof this.adapter.getMetadata === 'function') { - return this.adapter.getMetadata(filename); - } - - return Promise.resolve({}); - } - /** - * Find file references in REST-format object and adds the url key - * with the current mount point and app id. - * Object may be a single object or list of REST-format objects. - */ - - - expandFilesInObject(config, object) { - if (object instanceof Array) { - object.map(obj => this.expandFilesInObject(config, obj)); - return; - } - - if (typeof object !== 'object') { - return; - } - - for (const key in object) { - const fileObject = object[key]; - - if (fileObject && fileObject['__type'] === 'File') { - if (fileObject['url']) { - continue; - } - - const filename = fileObject['name']; // all filenames starting with "tfss-" should be from files.parsetfss.com - // all filenames starting with a "-" seperated UUID should be from files.parse.com - // all other filenames have been migrated or created from Parse Server - - if (config.fileKey === undefined) { - fileObject['url'] = this.adapter.getFileLocation(config, filename); - } else { - if (filename.indexOf('tfss-') === 0) { - fileObject['url'] = 'http://files.parsetfss.com/' + config.fileKey + '/' + encodeURIComponent(filename); - } else if (legacyFilesRegex.test(filename)) { - fileObject['url'] = 'http://files.parse.com/' + config.fileKey + '/' + encodeURIComponent(filename); - } else { - fileObject['url'] = this.adapter.getFileLocation(config, filename); - } - } - } - } - } - - expectedAdapterType() { - return _FilesAdapter.FilesAdapter; - } - - handleFileStream(config, filename, req, res, contentType) { - return this.adapter.handleFileStream(filename, req, res, contentType); - } - - validateFilename(filename) { - if (typeof this.adapter.validateFilename === 'function') { - const error = this.adapter.validateFilename(filename); - - if (typeof error !== 'string') { - return error; - } - - return new Parse.Error(Parse.Error.INVALID_FILE_NAME, error); - } - - return (0, _FilesAdapter.validateFilename)(filename); - } - -} - -exports.FilesController = FilesController; -var _default = FilesController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9GaWxlc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwibGVnYWN5RmlsZXNSZWdleCIsIlJlZ0V4cCIsIkZpbGVzQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJnZXRGaWxlRGF0YSIsImNvbmZpZyIsImZpbGVuYW1lIiwiYWRhcHRlciIsImNyZWF0ZUZpbGUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJvcHRpb25zIiwiZXh0bmFtZSIsInBhdGgiLCJoYXNFeHRlbnNpb24iLCJsZW5ndGgiLCJtaW1lIiwiZ2V0RXh0ZW5zaW9uIiwiZ2V0VHlwZSIsInByZXNlcnZlRmlsZU5hbWUiLCJsb2NhdGlvbiIsImdldEZpbGVMb2NhdGlvbiIsInRoZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsInVybCIsIm5hbWUiLCJkZWxldGVGaWxlIiwiZ2V0TWV0YWRhdGEiLCJleHBhbmRGaWxlc0luT2JqZWN0Iiwib2JqZWN0IiwiQXJyYXkiLCJtYXAiLCJvYmoiLCJrZXkiLCJmaWxlT2JqZWN0IiwiZmlsZUtleSIsInVuZGVmaW5lZCIsImluZGV4T2YiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ0ZXN0IiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkZpbGVzQWRhcHRlciIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiZXJyb3IiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFMQTtBQU1BLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBUCxDQUFpQkQsS0FBL0I7O0FBRUEsTUFBTUUsZ0JBQWdCLEdBQUcsSUFBSUMsTUFBSixDQUN2QixpRkFEdUIsQ0FBekI7O0FBSU8sTUFBTUMsZUFBTixTQUE4QkMsNEJBQTlCLENBQWtEO0FBQ3ZE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QUFDekIsUUFBSSxPQUFPLEtBQUtDLE9BQUwsQ0FBYXVDLGdCQUFwQixLQUF5QyxVQUE3QyxFQUF5RDtBQUN2RCxZQUFNQyxLQUFLLEdBQUcsS0FBS3hDLE9BQUwsQ0FBYXVDLGdCQUFiLENBQThCeEMsUUFBOUIsQ0FBZDs7QUFDQSxVQUFJLE9BQU95QyxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLGVBQU9BLEtBQVA7QUFDRDs7QUFDRCxhQUFPLElBQUlqRCxLQUFLLENBQUNrRCxLQUFWLENBQWdCbEQsS0FBSyxDQUFDa0QsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0NGLEtBQS9DLENBQVA7QUFDRDs7QUFDRCxXQUFPLG9DQUFpQnpDLFFBQWpCLENBQVA7QUFDRDs7QUFqR3NEOzs7ZUFvRzFDSixlIiwic291cmNlc0NvbnRlbnQiOlsiLy8gRmlsZXNDb250cm9sbGVyLmpzXG5pbXBvcnQgeyByYW5kb21IZXhTdHJpbmcgfSBmcm9tICcuLi9jcnlwdG9VdGlscyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IHsgdmFsaWRhdGVGaWxlbmFtZSwgRmlsZXNBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRmlsZXMvRmlsZXNBZGFwdGVyJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IG1pbWUgZnJvbSAnbWltZSc7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlJykuUGFyc2U7XG5cbmNvbnN0IGxlZ2FjeUZpbGVzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAnXlswLTlhLWZBLUZdezh9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfS0uKidcbik7XG5cbmV4cG9ydCBjbGFzcyBGaWxlc0NvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgZ2V0RmlsZURhdGEoY29uZmlnLCBmaWxlbmFtZSkge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZ2V0RmlsZURhdGEoZmlsZW5hbWUpO1xuICB9XG5cbiAgY3JlYXRlRmlsZShjb25maWcsIGZpbGVuYW1lLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucykge1xuICAgIGNvbnN0IGV4dG5hbWUgPSBwYXRoLmV4dG5hbWUoZmlsZW5hbWUpO1xuXG4gICAgY29uc3QgaGFzRXh0ZW5zaW9uID0gZXh0bmFtZS5sZW5ndGggPiAwO1xuXG4gICAgaWYgKCFoYXNFeHRlbnNpb24gJiYgY29udGVudFR5cGUgJiYgbWltZS5nZXRFeHRlbnNpb24oY29udGVudFR5cGUpKSB7XG4gICAgICBmaWxlbmFtZSA9IGZpbGVuYW1lICsgJy4nICsgbWltZS5nZXRFeHRlbnNpb24oY29udGVudFR5cGUpO1xuICAgIH0gZWxzZSBpZiAoaGFzRXh0ZW5zaW9uICYmICFjb250ZW50VHlwZSkge1xuICAgICAgY29udGVudFR5cGUgPSBtaW1lLmdldFR5cGUoZmlsZW5hbWUpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5vcHRpb25zLnByZXNlcnZlRmlsZU5hbWUpIHtcbiAgICAgIGZpbGVuYW1lID0gcmFuZG9tSGV4U3RyaW5nKDMyKSArICdfJyArIGZpbGVuYW1lO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5hZGFwdGVyLmdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZUZpbGUoZmlsZW5hbWUsIGRhdGEsIGNvbnRlbnRUeXBlLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICB1cmw6IGxvY2F0aW9uLFxuICAgICAgICBuYW1lOiBmaWxlbmFtZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRmlsZShjb25maWcsIGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5kZWxldGVGaWxlKGZpbGVuYW1lKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKGZpbGVuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmFkYXB0ZXIuZ2V0TWV0YWRhdGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZ2V0TWV0YWRhdGEoZmlsZW5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGZpbGUgcmVmZXJlbmNlcyBpbiBSRVNULWZvcm1hdCBvYmplY3QgYW5kIGFkZHMgdGhlIHVybCBrZXlcbiAgICogd2l0aCB0aGUgY3VycmVudCBtb3VudCBwb2ludCBhbmQgYXBwIGlkLlxuICAgKiBPYmplY3QgbWF5IGJlIGEgc2luZ2xlIG9iamVjdCBvciBsaXN0IG9mIFJFU1QtZm9ybWF0IG9iamVjdHMuXG4gICAqL1xuICBleHBhbmRGaWxlc0luT2JqZWN0KGNvbmZpZywgb2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBvYmplY3QubWFwKG9iaiA9PiB0aGlzLmV4cGFuZEZpbGVzSW5PYmplY3QoY29uZmlnLCBvYmopKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkge1xuICAgICAgY29uc3QgZmlsZU9iamVjdCA9IG9iamVjdFtrZXldO1xuICAgICAgaWYgKGZpbGVPYmplY3QgJiYgZmlsZU9iamVjdFsnX190eXBlJ10gPT09ICdGaWxlJykge1xuICAgICAgICBpZiAoZmlsZU9iamVjdFsndXJsJ10pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaWxlbmFtZSA9IGZpbGVPYmplY3RbJ25hbWUnXTtcbiAgICAgICAgLy8gYWxsIGZpbGVuYW1lcyBzdGFydGluZyB3aXRoIFwidGZzcy1cIiBzaG91bGQgYmUgZnJvbSBmaWxlcy5wYXJzZXRmc3MuY29tXG4gICAgICAgIC8vIGFsbCBmaWxlbmFtZXMgc3RhcnRpbmcgd2l0aCBhIFwiLVwiIHNlcGVyYXRlZCBVVUlEIHNob3VsZCBiZSBmcm9tIGZpbGVzLnBhcnNlLmNvbVxuICAgICAgICAvLyBhbGwgb3RoZXIgZmlsZW5hbWVzIGhhdmUgYmVlbiBtaWdyYXRlZCBvciBjcmVhdGVkIGZyb20gUGFyc2UgU2VydmVyXG4gICAgICAgIGlmIChjb25maWcuZmlsZUtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPSB0aGlzLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChmaWxlbmFtZS5pbmRleE9mKCd0ZnNzLScpID09PSAwKSB7XG4gICAgICAgICAgICBmaWxlT2JqZWN0Wyd1cmwnXSA9XG4gICAgICAgICAgICAgICdodHRwOi8vZmlsZXMucGFyc2V0ZnNzLmNvbS8nICsgY29uZmlnLmZpbGVLZXkgKyAnLycgKyBlbmNvZGVVUklDb21wb25lbnQoZmlsZW5hbWUpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobGVnYWN5RmlsZXNSZWdleC50ZXN0KGZpbGVuYW1lKSkge1xuICAgICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPVxuICAgICAgICAgICAgICAnaHR0cDovL2ZpbGVzLnBhcnNlLmNvbS8nICsgY29uZmlnLmZpbGVLZXkgKyAnLycgKyBlbmNvZGVVUklDb21wb25lbnQoZmlsZW5hbWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaWxlT2JqZWN0Wyd1cmwnXSA9IHRoaXMuYWRhcHRlci5nZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gRmlsZXNBZGFwdGVyO1xuICB9XG5cbiAgaGFuZGxlRmlsZVN0cmVhbShjb25maWcsIGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmhhbmRsZUZpbGVTdHJlYW0oZmlsZW5hbWUsIHJlcSwgcmVzLCBjb250ZW50VHlwZSk7XG4gIH1cblxuICB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmFkYXB0ZXIudmFsaWRhdGVGaWxlbmFtZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgZXJyb3IgPSB0aGlzLmFkYXB0ZXIudmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk7XG4gICAgICBpZiAodHlwZW9mIGVycm9yICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCBlcnJvcik7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBGaWxlc0NvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/HooksController.js b/lib/Controllers/HooksController.js deleted file mode 100644 index 8ebe771207..0000000000 --- a/lib/Controllers/HooksController.js +++ /dev/null @@ -1,301 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.HooksController = void 0; - -var triggers = _interopRequireWildcard(require("../triggers")); - -var Parse = _interopRequireWildcard(require("parse/node")); - -var _request = _interopRequireDefault(require("../request")); - -var _logger = require("../logger"); - -var _http = _interopRequireDefault(require("http")); - -var _https = _interopRequireDefault(require("https")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -// -disable-next -// -disable-next -const DefaultHooksCollectionName = '_Hooks'; -const HTTPAgents = { - http: new _http.default.Agent({ - keepAlive: true - }), - https: new _https.default.Agent({ - keepAlive: true - }) -}; - -class HooksController { - constructor(applicationId, databaseController, webhookKey) { - this._applicationId = applicationId; - this._webhookKey = webhookKey; - this.database = databaseController; - } - - load() { - return this._getHooks().then(hooks => { - hooks = hooks || []; - hooks.forEach(hook => { - this.addHookToTriggers(hook); - }); - }); - } - - getFunction(functionName) { - return this._getHooks({ - functionName: functionName - }).then(results => results[0]); - } - - getFunctions() { - return this._getHooks({ - functionName: { - $exists: true - } - }); - } - - getTrigger(className, triggerName) { - return this._getHooks({ - className: className, - triggerName: triggerName - }).then(results => results[0]); - } - - getTriggers() { - return this._getHooks({ - className: { - $exists: true - }, - triggerName: { - $exists: true - } - }); - } - - deleteFunction(functionName) { - triggers.removeFunction(functionName, this._applicationId); - return this._removeHooks({ - functionName: functionName - }); - } - - deleteTrigger(className, triggerName) { - triggers.removeTrigger(triggerName, className, this._applicationId); - return this._removeHooks({ - className: className, - triggerName: triggerName - }); - } - - _getHooks(query = {}) { - return this.database.find(DefaultHooksCollectionName, query).then(results => { - return results.map(result => { - delete result.objectId; - return result; - }); - }); - } - - _removeHooks(query) { - return this.database.destroy(DefaultHooksCollectionName, query).then(() => { - return Promise.resolve({}); - }); - } - - saveHook(hook) { - var query; - - if (hook.functionName && hook.url) { - query = { - functionName: hook.functionName - }; - } else if (hook.triggerName && hook.className && hook.url) { - query = { - className: hook.className, - triggerName: hook.triggerName - }; - } else { - throw new Parse.Error(143, 'invalid hook declaration'); - } - - return this.database.update(DefaultHooksCollectionName, query, hook, { - upsert: true - }).then(() => { - return Promise.resolve(hook); - }); - } - - addHookToTriggers(hook) { - var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey); - wrappedFunction.url = hook.url; - - if (hook.className) { - triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId); - } else { - triggers.addFunction(hook.functionName, wrappedFunction, null, this._applicationId); - } - } - - addHook(hook) { - this.addHookToTriggers(hook); - return this.saveHook(hook); - } - - createOrUpdateHook(aHook) { - var hook; - - if (aHook && aHook.functionName && aHook.url) { - hook = {}; - hook.functionName = aHook.functionName; - hook.url = aHook.url; - } else if (aHook && aHook.className && aHook.url && aHook.triggerName && triggers.Types[aHook.triggerName]) { - hook = {}; - hook.className = aHook.className; - hook.url = aHook.url; - hook.triggerName = aHook.triggerName; - } else { - throw new Parse.Error(143, 'invalid hook declaration'); - } - - return this.addHook(hook); - } - - createHook(aHook) { - if (aHook.functionName) { - return this.getFunction(aHook.functionName).then(result => { - if (result) { - throw new Parse.Error(143, `function name: ${aHook.functionName} already exits`); - } else { - return this.createOrUpdateHook(aHook); - } - }); - } else if (aHook.className && aHook.triggerName) { - return this.getTrigger(aHook.className, aHook.triggerName).then(result => { - if (result) { - throw new Parse.Error(143, `class ${aHook.className} already has trigger ${aHook.triggerName}`); - } - - return this.createOrUpdateHook(aHook); - }); - } - - throw new Parse.Error(143, 'invalid hook declaration'); - } - - updateHook(aHook) { - if (aHook.functionName) { - return this.getFunction(aHook.functionName).then(result => { - if (result) { - return this.createOrUpdateHook(aHook); - } - - throw new Parse.Error(143, `no function named: ${aHook.functionName} is defined`); - }); - } else if (aHook.className && aHook.triggerName) { - return this.getTrigger(aHook.className, aHook.triggerName).then(result => { - if (result) { - return this.createOrUpdateHook(aHook); - } - - throw new Parse.Error(143, `class ${aHook.className} does not exist`); - }); - } - - throw new Parse.Error(143, 'invalid hook declaration'); - } - -} - -exports.HooksController = HooksController; - -function wrapToHTTPRequest(hook, key) { - return req => { - const jsonBody = {}; - - for (var i in req) { - jsonBody[i] = req[i]; - } - - if (req.object) { - jsonBody.object = req.object.toJSON(); - jsonBody.object.className = req.object.className; - } - - if (req.original) { - jsonBody.original = req.original.toJSON(); - jsonBody.original.className = req.original.className; - } - - const jsonRequest = { - url: hook.url, - headers: { - 'Content-Type': 'application/json' - }, - body: jsonBody, - method: 'POST' - }; - const agent = hook.url.startsWith('https') ? HTTPAgents['https'] : HTTPAgents['http']; - jsonRequest.agent = agent; - - if (key) { - jsonRequest.headers['X-Parse-Webhook-Key'] = key; - } else { - _logger.logger.warn('Making outgoing webhook request without webhookKey being set!'); - } - - return (0, _request.default)(jsonRequest).then(response => { - let err; - let result; - let body = response.data; - - if (body) { - if (typeof body === 'string') { - try { - body = JSON.parse(body); - } catch (e) { - err = { - error: 'Malformed response', - code: -1, - partialResponse: body.substring(0, 100) - }; - } - } - - if (!err) { - result = body.success; - err = body.error; - } - } - - if (err) { - throw err; - } else if (hook.triggerName === 'beforeSave') { - if (typeof result === 'object') { - delete result.createdAt; - delete result.updatedAt; - } - - return { - object: result - }; - } else { - return result; - } - }); - }; -} - -var _default = HooksController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Ib29rc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUiLCJIVFRQQWdlbnRzIiwiaHR0cCIsIkFnZW50Iiwia2VlcEFsaXZlIiwiaHR0cHMiLCJIb29rc0NvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcGxpY2F0aW9uSWQiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJ3ZWJob29rS2V5IiwiX2FwcGxpY2F0aW9uSWQiLCJfd2ViaG9va0tleSIsImRhdGFiYXNlIiwibG9hZCIsIl9nZXRIb29rcyIsInRoZW4iLCJob29rcyIsImZvckVhY2giLCJob29rIiwiYWRkSG9va1RvVHJpZ2dlcnMiLCJnZXRGdW5jdGlvbiIsImZ1bmN0aW9uTmFtZSIsInJlc3VsdHMiLCJnZXRGdW5jdGlvbnMiLCIkZXhpc3RzIiwiZ2V0VHJpZ2dlciIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlcnMiLCJkZWxldGVGdW5jdGlvbiIsInRyaWdnZXJzIiwicmVtb3ZlRnVuY3Rpb24iLCJfcmVtb3ZlSG9va3MiLCJkZWxldGVUcmlnZ2VyIiwicmVtb3ZlVHJpZ2dlciIsInF1ZXJ5IiwiZmluZCIsIm1hcCIsInJlc3VsdCIsIm9iamVjdElkIiwiZGVzdHJveSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2F2ZUhvb2siLCJ1cmwiLCJQYXJzZSIsIkVycm9yIiwidXBkYXRlIiwidXBzZXJ0Iiwid3JhcHBlZEZ1bmN0aW9uIiwid3JhcFRvSFRUUFJlcXVlc3QiLCJhZGRUcmlnZ2VyIiwiYWRkRnVuY3Rpb24iLCJhZGRIb29rIiwiY3JlYXRlT3JVcGRhdGVIb29rIiwiYUhvb2siLCJUeXBlcyIsImNyZWF0ZUhvb2siLCJ1cGRhdGVIb29rIiwia2V5IiwicmVxIiwianNvbkJvZHkiLCJpIiwib2JqZWN0IiwidG9KU09OIiwib3JpZ2luYWwiLCJqc29uUmVxdWVzdCIsImhlYWRlcnMiLCJib2R5IiwibWV0aG9kIiwiYWdlbnQiLCJzdGFydHNXaXRoIiwibG9nZ2VyIiwid2FybiIsInJlc3BvbnNlIiwiZXJyIiwiZGF0YSIsIkpTT04iLCJwYXJzZSIsImUiLCJlcnJvciIsImNvZGUiLCJwYXJ0aWFsUmVzcG9uc2UiLCJzdWJzdHJpbmciLCJzdWNjZXNzIiwiY3JlYXRlZEF0IiwidXBkYXRlZEF0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBRUE7O0FBRUE7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBTkE7QUFFQTtBQU1BLE1BQU1BLDBCQUEwQixHQUFHLFFBQW5DO0FBQ0EsTUFBTUMsVUFBVSxHQUFHO0FBQ2pCQyxFQUFBQSxJQUFJLEVBQUUsSUFBSUEsY0FBS0MsS0FBVCxDQUFlO0FBQUVDLElBQUFBLFNBQVMsRUFBRTtBQUFiLEdBQWYsQ0FEVztBQUVqQkMsRUFBQUEsS0FBSyxFQUFFLElBQUlBLGVBQU1GLEtBQVYsQ0FBZ0I7QUFBRUMsSUFBQUEsU0FBUyxFQUFFO0FBQWIsR0FBaEI7QUFGVSxDQUFuQjs7QUFLTyxNQUFNRSxlQUFOLENBQXNCO0FBSzNCQyxFQUFBQSxXQUFXLENBQUNDLGFBQUQsRUFBd0JDLGtCQUF4QixFQUE0Q0MsVUFBNUMsRUFBd0Q7QUFDakUsU0FBS0MsY0FBTCxHQUFzQkgsYUFBdEI7QUFDQSxTQUFLSSxXQUFMLEdBQW1CRixVQUFuQjtBQUNBLFNBQUtHLFFBQUwsR0FBZ0JKLGtCQUFoQjtBQUNEOztBQUVESyxFQUFBQSxJQUFJLEdBQUc7QUFDTCxXQUFPLEtBQUtDLFNBQUwsR0FBaUJDLElBQWpCLENBQXNCQyxLQUFLLElBQUk7QUFDcENBLE1BQUFBLEtBQUssR0FBR0EsS0FBSyxJQUFJLEVBQWpCO0FBQ0FBLE1BQUFBLEtBQUssQ0FBQ0MsT0FBTixDQUFjQyxJQUFJLElBQUk7QUFDcEIsYUFBS0MsaUJBQUwsQ0FBdUJELElBQXZCO0FBQ0QsT0FGRDtBQUdELEtBTE0sQ0FBUDtBQU1EOztBQUVERSxFQUFBQSxXQUFXLENBQUNDLFlBQUQsRUFBZTtB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RUpDLGNBQUFBLElBQUksRUFBRSxDQUFDLENBRkg7QUFHSkMsY0FBQUEsZUFBZSxFQUFFZCxJQUFJLENBQUNlLFNBQUwsQ0FBZSxDQUFmLEVBQWtCLEdBQWxCO0FBSGIsYUFBTjtBQUtEO0FBQ0Y7O0FBQ0QsWUFBSSxDQUFDUixHQUFMLEVBQVU7QUFDUnJDLFVBQUFBLE1BQU0sR0FBRzhCLElBQUksQ0FBQ2dCLE9BQWQ7QUFDQVQsVUFBQUEsR0FBRyxHQUFHUCxJQUFJLENBQUNZLEtBQVg7QUFDRDtBQUNGOztBQUNELFVBQUlMLEdBQUosRUFBUztBQUNQLGNBQU1BLEdBQU47QUFDRCxPQUZELE1BRU8sSUFBSXpELElBQUksQ0FBQ1MsV0FBTCxLQUFxQixZQUF6QixFQUF1QztBQUM1QyxZQUFJLE9BQU9XLE1BQVAsS0FBa0IsUUFBdEIsRUFBZ0M7QUFDOUIsaUJBQU9BLE1BQU0sQ0FBQytDLFNBQWQ7QUFDQSxpQkFBTy9DLE1BQU0sQ0FBQ2dELFNBQWQ7QUFDRDs7QUFDRCxlQUFPO0FBQUV2QixVQUFBQSxNQUFNLEVBQUV6QjtBQUFWLFNBQVA7QUFDRCxPQU5NLE1BTUE7QUFDTCxlQUFPQSxNQUFQO0FBQ0Q7QUFDRixLQWhDTSxDQUFQO0FBaUNELEdBL0REO0FBZ0VEOztlQUVjakMsZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBAZmxvdyB3ZWFrICovXG5cbmltcG9ydCAqIGFzIHRyaWdnZXJzIGZyb20gJy4uL3RyaWdnZXJzJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0ICogYXMgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCByZXF1ZXN0IGZyb20gJy4uL3JlcXVlc3QnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IGh0dHBzIGZyb20gJ2h0dHBzJztcblxuY29uc3QgRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUgPSAnX0hvb2tzJztcbmNvbnN0IEhUVFBBZ2VudHMgPSB7XG4gIGh0dHA6IG5ldyBodHRwLkFnZW50KHsga2VlcEFsaXZlOiB0cnVlIH0pLFxuICBodHRwczogbmV3IGh0dHBzLkFnZW50KHsga2VlcEFsaXZlOiB0cnVlIH0pLFxufTtcblxuZXhwb3J0IGNsYXNzIEhvb2tzQ29udHJvbGxlciB7XG4gIF9hcHBsaWNhdGlvbklkOiBzdHJpbmc7XG4gIF93ZWJob29rS2V5OiBzdHJpbmc7XG4gIGRhdGFiYXNlOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoYXBwbGljYXRpb25JZDogc3RyaW5nLCBkYXRhYmFzZUNvbnRyb2xsZXIsIHdlYmhvb2tLZXkpIHtcbiAgICB0aGlzLl9hcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZDtcbiAgICB0aGlzLl93ZWJob29rS2V5ID0gd2ViaG9va0tleTtcbiAgICB0aGlzLmRhdGFiYXNlID0gZGF0YWJhc2VDb250cm9sbGVyO1xuICB9XG5cbiAgbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3MoKS50aGVuKGhvb2tzID0+IHtcbiAgICAgIGhvb2tzID0gaG9va3MgfHwgW107XG4gICAgICBob29rcy5mb3JFYWNoKGhvb2sgPT4ge1xuICAgICAgICB0aGlzLmFkZEhvb2tUb1RyaWdnZXJzKGhvb2spO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRGdW5jdGlvbihmdW5jdGlvbk5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3MoeyBmdW5jdGlvbk5hbWU6IGZ1bmN0aW9uTmFtZSB9KS50aGVuKHJlc3VsdHMgPT4gcmVzdWx0c1swXSk7XG4gIH1cblxuICBnZXRGdW5jdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldEhvb2tzKHsgZnVuY3Rpb25OYW1lOiB7ICRleGlzdHM6IHRydWUgfSB9KTtcbiAgfVxuXG4gIGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyTmFtZSkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcyh7XG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyTmFtZSxcbiAgICB9KS50aGVuKHJlc3VsdHMgPT4gcmVzdWx0c1swXSk7XG4gIH1cblxuICBnZXRUcmlnZ2VycygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3Moe1xuICAgICAgY2xhc3NOYW1lOiB7ICRleGlzdHM6IHRydWUgfSxcbiAgICAgIHRyaWdnZXJOYW1lOiB7ICRleGlzdHM6IHRydWUgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGRlbGV0ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSkge1xuICAgIHRyaWdnZXJzLnJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgdGhpcy5fYXBwbGljYXRpb25JZCk7XG4gICAgcmV0dXJuIHRoaXMuX3JlbW92ZUhvb2tzKHsgZnVuY3Rpb25OYW1lOiBmdW5jdGlvbk5hbWUgfSk7XG4gIH1cblxuICBkZWxldGVUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlck5hbWUpIHtcbiAgICB0cmlnZ2Vycy5yZW1vdmVUcmlnZ2VyKHRyaWdnZXJOYW1lLCBjbGFzc05hbWUsIHRoaXMuX2FwcGxpY2F0aW9uSWQpO1xuICAgIHJldHVybiB0aGlzLl9yZW1vdmVIb29rcyh7XG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyTmFtZSxcbiAgICB9KTtcbiAgfVxuXG4gIF9nZXRIb29rcyhxdWVyeSA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UuZmluZChEZWZhdWx0SG9va3NDb2xsZWN0aW9uTmFtZSwgcXVlcnkpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXR1cm4gcmVzdWx0cy5tYXAocmVzdWx0ID0+IHtcbiAgICAgICAgZGVsZXRlIHJlc3VsdC5vYmplY3RJZDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3JlbW92ZUhvb2tzKHF1ZXJ5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UuZGVzdHJveShEZWZhdWx0SG9va3NDb2xsZWN0aW9uTmFtZSwgcXVlcnkpLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSk7XG4gIH1cblxuICBzYXZlSG9vayhob29rKSB7XG4gICAgdmFyIHF1ZXJ5O1xuICAgIGlmIChob29rLmZ1bmN0aW9uTmFtZSAmJiBob29rLnVybCkge1xuICAgICAgcXVlcnkgPSB7IGZ1bmN0aW9uTmFtZTogaG9vay5mdW5jdGlvbk5hbWUgfTtcbiAgICB9IGVsc2UgaWYgKGhvb2sudHJpZ2dlck5hbWUgJiYgaG9vay5jbGFzc05hbWUgJiYgaG9vay51cmwpIHtcbiAgICAgIHF1ZXJ5ID0geyBjbGFzc05hbWU6IGhvb2suY2xhc3NOYW1lLCB0cmlnZ2VyTmFtZTogaG9vay50cmlnZ2VyTmFtZSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlXG4gICAgICAudXBkYXRlKERlZmF1bHRIb29rc0NvbGxlY3Rpb25OYW1lLCBxdWVyeSwgaG9vaywgeyB1cHNlcnQ6IHRydWUgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShob29rKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgYWRkSG9va1RvVHJpZ2dlcnMoaG9vaykge1xuICAgIHZhciB3cmFwcGVkRnVuY3Rpb24gPSB3cmFwVG9IVFRQUmVxdWVzdChob29rLCB0aGlzLl93ZWJob29rS2V5KTtcbiAgICB3cmFwcGVkRnVuY3Rpb24udXJsID0gaG9vay51cmw7XG4gICAgaWYgKGhvb2suY2xhc3NOYW1lKSB7XG4gICAgICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKGhvb2sudHJpZ2dlck5hbWUsIGhvb2suY2xhc3NOYW1lLCB3cmFwcGVkRnVuY3Rpb24sIHRoaXMuX2FwcGxpY2F0aW9uSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmlnZ2Vycy5hZGRGdW5jdGlvbihob29rLmZ1bmN0aW9uTmFtZSwgd3JhcHBlZEZ1bmN0aW9uLCBudWxsLCB0aGlzLl9hcHBsaWNhdGlvbklkKTtcbiAgICB9XG4gIH1cblxuICBhZGRIb29rKGhvb2spIHtcbiAgICB0aGlzLmFkZEhvb2tUb1RyaWdnZXJzKGhvb2spO1xuICAgIHJldHVybiB0aGlzLnNhdmVIb29rKGhvb2spO1xuICB9XG5cbiAgY3JlYXRlT3JVcGRhdGVIb29rKGFIb29rKSB7XG4gICAgdmFyIGhvb2s7XG4gICAgaWYgKGFIb29rICYmIGFIb29rLmZ1bmN0aW9uTmFtZSAmJiBhSG9vay51cmwpIHtcbiAgICAgIGhvb2sgPSB7fTtcbiAgICAgIGhvb2suZnVuY3Rpb25OYW1lID0gYUhvb2suZnVuY3Rpb25OYW1lO1xuICAgICAgaG9vay51cmwgPSBhSG9vay51cmw7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGFIb29rICYmXG4gICAgICBhSG9vay5jbGFzc05hbWUgJiZcbiAgICAgIGFIb29rLnVybCAmJlxuICAgICAgYUhvb2sudHJpZ2dlck5hbWUgJiZcbiAgICAgIHRyaWdnZXJzLlR5cGVzW2FIb29rLnRyaWdnZXJOYW1lXVxuICAgICkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5jbGFzc05hbWUgPSBhSG9vay5jbGFzc05hbWU7XG4gICAgICBob29rLnVybCA9IGFIb29rLnVybDtcbiAgICAgIGhvb2sudHJpZ2dlck5hbWUgPSBhSG9vay50cmlnZ2VyTmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgJ2ludmFsaWQgaG9vayBkZWNsYXJhdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFkZEhvb2soaG9vayk7XG4gIH1cblxuICBjcmVhdGVIb29rKGFIb29rKSB7XG4gICAgaWYgKGFIb29rLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb24oYUhvb2suZnVuY3Rpb25OYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgZnVuY3Rpb24gbmFtZTogJHthSG9vay5mdW5jdGlvbk5hbWV9IGFscmVhZHkgZXhpdHNgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGFIb29rLmNsYXNzTmFtZSAmJiBhSG9vay50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHJpZ2dlcihhSG9vay5jbGFzc05hbWUsIGFIb29rLnRyaWdnZXJOYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAxNDMsXG4gICAgICAgICAgICBgY2xhc3MgJHthSG9vay5jbGFzc05hbWV9IGFscmVhZHkgaGFzIHRyaWdnZXIgJHthSG9vay50cmlnZ2VyTmFtZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgJ2ludmFsaWQgaG9vayBkZWNsYXJhdGlvbicpO1xuICB9XG5cbiAgdXBkYXRlSG9vayhhSG9vaykge1xuICAgIGlmIChhSG9vay5mdW5jdGlvbk5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEZ1bmN0aW9uKGFIb29rLmZ1bmN0aW9uTmFtZSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3JVcGRhdGVIb29rKGFIb29rKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgbm8gZnVuY3Rpb24gbmFtZWQ6ICR7YUhvb2suZnVuY3Rpb25OYW1lfSBpcyBkZWZpbmVkYCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGFIb29rLmNsYXNzTmFtZSAmJiBhSG9vay50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHJpZ2dlcihhSG9vay5jbGFzc05hbWUsIGFIb29rLnRyaWdnZXJOYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsIGBjbGFzcyAke2FIb29rLmNsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gd3JhcFRvSFRUUFJlcXVlc3QoaG9vaywga2V5KSB7XG4gIHJldHVybiByZXEgPT4ge1xuICAgIGNvbnN0IGpzb25Cb2R5ID0ge307XG4gICAgZm9yICh2YXIgaSBpbiByZXEpIHtcbiAgICAgIGpzb25Cb2R5W2ldID0gcmVxW2ldO1xuICAgIH1cbiAgICBpZiAocmVxLm9iamVjdCkge1xuICAgICAganNvbkJvZHkub2JqZWN0ID0gcmVxLm9iamVjdC50b0pTT04oKTtcbiAgICAgIGpzb25Cb2R5Lm9iamVjdC5jbGFzc05hbWUgPSByZXEub2JqZWN0LmNsYXNzTmFtZTtcbiAgICB9XG4gICAgaWYgKHJlcS5vcmlnaW5hbCkge1xuICAgICAganNvbkJvZHkub3JpZ2luYWwgPSByZXEub3JpZ2luYWwudG9KU09OKCk7XG4gICAgICBqc29uQm9keS5vcmlnaW5hbC5jbGFzc05hbWUgPSByZXEub3JpZ2luYWwuY2xhc3NOYW1lO1xuICAgIH1cbiAgICBjb25zdCBqc29uUmVxdWVzdDogYW55ID0ge1xuICAgICAgdXJsOiBob29rLnVybCxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBqc29uQm9keSxcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIH07XG5cbiAgICBjb25zdCBhZ2VudCA9IGhvb2sudXJsLnN0YXJ0c1dpdGgoJ2h0dHBzJykgPyBIVFRQQWdlbnRzWydodHRwcyddIDogSFRUUEFnZW50c1snaHR0cCddO1xuICAgIGpzb25SZXF1ZXN0LmFnZW50ID0gYWdlbnQ7XG5cbiAgICBpZiAoa2V5KSB7XG4gICAgICBqc29uUmVxdWVzdC5oZWFkZXJzWydYLVBhcnNlLVdlYmhvb2stS2V5J10gPSBrZXk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZ2dlci53YXJuKCdNYWtpbmcgb3V0Z29pbmcgd2ViaG9vayByZXF1ZXN0IHdpdGhvdXQgd2ViaG9va0tleSBiZWluZyBzZXQhJyk7XG4gICAgfVxuICAgIHJldHVybiByZXF1ZXN0KGpzb25SZXF1ZXN0KS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgIGxldCBlcnI7XG4gICAgICBsZXQgcmVzdWx0O1xuICAgICAgbGV0IGJvZHkgPSByZXNwb25zZS5kYXRhO1xuICAgICAgaWYgKGJvZHkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBlcnIgPSB7XG4gICAgICAgICAgICAgIGVycm9yOiAnTWFsZm9ybWVkIHJlc3BvbnNlJyxcbiAgICAgICAgICAgICAgY29kZTogLTEsXG4gICAgICAgICAgICAgIHBhcnRpYWxSZXNwb25zZTogYm9keS5zdWJzdHJpbmcoMCwgMTAwKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghZXJyKSB7XG4gICAgICAgICAgcmVzdWx0ID0gYm9keS5zdWNjZXNzO1xuICAgICAgICAgIGVyciA9IGJvZHkuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfSBlbHNlIGlmIChob29rLnRyaWdnZXJOYW1lID09PSAnYmVmb3JlU2F2ZScpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgZGVsZXRlIHJlc3VsdC5jcmVhdGVkQXQ7XG4gICAgICAgICAgZGVsZXRlIHJlc3VsdC51cGRhdGVkQXQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgb2JqZWN0OiByZXN1bHQgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IEhvb2tzQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/LiveQueryController.js b/lib/Controllers/LiveQueryController.js deleted file mode 100644 index 208a38083c..0000000000 --- a/lib/Controllers/LiveQueryController.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LiveQueryController = void 0; - -var _ParseCloudCodePublisher = require("../LiveQuery/ParseCloudCodePublisher"); - -var _Options = require("../Options"); - -class LiveQueryController { - constructor(config) { - // If config is empty, we just assume no classs needs to be registered as LiveQuery - if (!config || !config.classNames) { - this.classNames = new Set(); - } else if (config.classNames instanceof Array) { - this.classNames = new Set(config.classNames); - } else { - throw 'liveQuery.classes should be an array of string'; - } - - this.liveQueryPublisher = new _ParseCloudCodePublisher.ParseCloudCodePublisher(config); - } - - onAfterSave(className, currentObject, originalObject, classLevelPermissions) { - if (!this.hasLiveQuery(className)) { - return; - } - - const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); - - this.liveQueryPublisher.onCloudCodeAfterSave(req); - } - - onAfterDelete(className, currentObject, originalObject, classLevelPermissions) { - if (!this.hasLiveQuery(className)) { - return; - } - - const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); - - this.liveQueryPublisher.onCloudCodeAfterDelete(req); - } - - hasLiveQuery(className) { - return this.classNames.has(className); - } - - _makePublisherRequest(currentObject, originalObject, classLevelPermissions) { - const req = { - object: currentObject - }; - - if (currentObject) { - req.original = originalObject; - } - - if (classLevelPermissions) { - req.classLevelPermissions = classLevelPermissions; - } - - return req; - } - -} - -exports.LiveQueryController = LiveQueryController; -var _default = LiveQueryController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9MaXZlUXVlcnlDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkxpdmVRdWVyeUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNsYXNzTmFtZXMiLCJTZXQiLCJBcnJheSIsImxpdmVRdWVyeVB1Ymxpc2hlciIsIlBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyIiwib25BZnRlclNhdmUiLCJjbGFzc05hbWUiLCJjdXJyZW50T2JqZWN0Iiwib3JpZ2luYWxPYmplY3QiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJoYXNMaXZlUXVlcnkiLCJyZXEiLCJfbWFrZVB1Ymxpc2hlclJlcXVlc3QiLCJvbkNsb3VkQ29kZUFmdGVyU2F2ZSIsIm9uQWZ0ZXJEZWxldGUiLCJvbkNsb3VkQ29kZUFmdGVyRGVsZXRlIiwiaGFzIiwib2JqZWN0Iiwib3JpZ2luYWwiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDTyxNQUFNQSxtQkFBTixDQUEwQjtBQUkvQkMsRUFBQUEsV0FBVyxDQUFDQyxNQUFELEVBQTRCO0FBQ3JDO0FBQ0EsUUFBSSxDQUFDQSxNQUFELElBQVcsQ0FBQ0EsTUFBTSxDQUFDQyxVQUF2QixFQUFtQztBQUNqQyxXQUFLQSxVQUFMLEdBQWtCLElBQUlDLEdBQUosRUFBbEI7QUFDRCxLQUZELE1BRU8sSUFBSUYsTUFBTSxDQUFDQyxVQUFQLFlBQTZCRSxLQUFqQyxFQUF3QztBQUM3QyxXQUFLRixVQUFMLEdBQWtCLElBQUlDLEdBQUosQ0FBUUYsTUFBTSxDQUFDQyxVQUFmLENBQWxCO0FBQ0QsS0FGTSxNQUVBO0FBQ0wsWUFBTSxnREFBTjtBQUNEOztBQUNELFNBQUtHLGtCQUFMLEdBQTBCLElBQUlDLGdEQUFKLENBQTRCTCxNQUE1QixDQUExQjtBQUNEOztBQUVETSxFQUFBQSxXQUFXLENBQ1RDLFNBRFMsRUFFVEMsYUFGUyxFQUdUQyxjQUhTLEVBSVRDLHFCQUpTLEVBS1Q7QUFDQSxRQUFJLENBQUMsS0FBS0MsWUFBTCxDQUFrQkosU0FBbEIsQ0FBTCxFQUFtQztBQUNqQztBQUNEOztBQUNELFVBQU1LLEdBQUcsR0FBRyxLQUFLQyxxQkFBTCxDQUEyQkwsYUFBM0IsRUFBMENDLGNBQTFDLEVBQTBEQyxxQkFBMUQsQ0FBWjs7QUFDQSxTQUFLTixrQkFBTCxDQUF3QlUsb0JBQXhCLENBQTZDRixHQUE3QztBQUNEOztBQUVERyxFQUFBQSxhQUFhLENBQ1hSLFNBRFcsRUFFWEMsYUFGVyxFQUdYQyxjQUhXLEVBSVhDLHFCQUpXLEVBS1g7QUFDQSxRQUFJLENBQUMsS0FBS0MsWUFBTCxDQUFrQkosU0FBbEIsQ0FBTCxFQUFtQztBQUNqQztBQUNEOztBQUNELFVBQU1LLEdBQUcsR0FBRyxLQUFLQyxxQkFBTCxDQUEyQkwsYUFBM0IsRUFBMENDLGNBQTFDLEVBQTBEQyxxQkFBMUQsQ0FBWjs7QUFDQSxTQUFLTixrQkFBTCxDQUF3Qlksc0JBQXhCLENBQStDSixHQUEvQztBQUNEOztBQUVERCxFQUFBQSxZQUFZLENBQUNKLFNBQUQsRUFBNkI7QUFDdkMsV0FBTyxLQUFLTixVQUFMLENBQWdCZ0IsR0FBaEIsQ0FBb0JWLFNBQXBCLENBQVA7QUFDRDs7QUFFRE0sRUFBQUEscUJBQXFCLENBQUNMLGFBQUQsRUFBcUJDLGNBQXJCLEVBQTBDQyxxQkFBMUMsRUFBNEU7QUFDL0YsVUFBTUUsR0FBRyxHQUFHO0FBQ1ZNLE1BQUFBLE1BQU0sRUFBRVY7QUFERSxLQUFaOztBQUdBLFFBQUlBLGFBQUosRUFBbUI7QUFDakJJLE1BQUFBLEdBQUcsQ0FBQ08sUUFBSixHQUFlVixjQUFmO0FBQ0Q7O0FBQ0QsUUFBSUMscUJBQUosRUFBMkI7QUFDekJFLE1BQUFBLEdBQUcsQ0FBQ0YscUJBQUosR0FBNEJBLHFCQUE1QjtBQUNEOztBQUNELFdBQU9FLEdBQVA7QUFDRDs7QUF6RDhCOzs7ZUE0RGxCZCxtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyIH0gZnJvbSAnLi4vTGl2ZVF1ZXJ5L1BhcnNlQ2xvdWRDb2RlUHVibGlzaGVyJztcbmltcG9ydCB7IExpdmVRdWVyeU9wdGlvbnMgfSBmcm9tICcuLi9PcHRpb25zJztcbmV4cG9ydCBjbGFzcyBMaXZlUXVlcnlDb250cm9sbGVyIHtcbiAgY2xhc3NOYW1lczogYW55O1xuICBsaXZlUXVlcnlQdWJsaXNoZXI6IGFueTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6ID9MaXZlUXVlcnlPcHRpb25zKSB7XG4gICAgLy8gSWYgY29uZmlnIGlzIGVtcHR5LCB3ZSBqdXN0IGFzc3VtZSBubyBjbGFzc3MgbmVlZHMgdG8gYmUgcmVnaXN0ZXJlZCBhcyBMaXZlUXVlcnlcbiAgICBpZiAoIWNvbmZpZyB8fCAhY29uZmlnLmNsYXNzTmFtZXMpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IG5ldyBTZXQoKTtcbiAgICB9IGVsc2UgaWYgKGNvbmZpZy5jbGFzc05hbWVzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IG5ldyBTZXQoY29uZmlnLmNsYXNzTmFtZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyAnbGl2ZVF1ZXJ5LmNsYXNzZXMgc2hvdWxkIGJlIGFuIGFycmF5IG9mIHN0cmluZyc7XG4gICAgfVxuICAgIHRoaXMubGl2ZVF1ZXJ5UHVibGlzaGVyID0gbmV3IFBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyKGNvbmZpZyk7XG4gIH1cblxuICBvbkFmdGVyU2F2ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBjdXJyZW50T2JqZWN0OiBhbnksXG4gICAgb3JpZ2luYWxPYmplY3Q6IGFueSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6ID9hbnlcbiAgKSB7XG4gICAgaWYgKCF0aGlzLmhhc0xpdmVRdWVyeShjbGFzc05hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlcSA9IHRoaXMuX21ha2VQdWJsaXNoZXJSZXF1ZXN0KGN1cnJlbnRPYmplY3QsIG9yaWdpbmFsT2JqZWN0LCBjbGFzc0xldmVsUGVybWlzc2lvbnMpO1xuICAgIHRoaXMubGl2ZVF1ZXJ5UHVibGlzaGVyLm9uQ2xvdWRDb2RlQWZ0ZXJTYXZlKHJlcSk7XG4gIH1cblxuICBvbkFmdGVyRGVsZXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGN1cnJlbnRPYmplY3Q6IGFueSxcbiAgICBvcmlnaW5hbE9iamVjdDogYW55LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55XG4gICkge1xuICAgIGlmICghdGhpcy5oYXNMaXZlUXVlcnkoY2xhc3NOYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXEgPSB0aGlzLl9tYWtlUHVibGlzaGVyUmVxdWVzdChjdXJyZW50T2JqZWN0LCBvcmlnaW5hbE9iamVjdCwgY2xhc3NMZXZlbFBlcm1pc3Npb25zKTtcbiAgICB0aGlzLmxpdmVRdWVyeVB1Ymxpc2hlci5vbkNsb3VkQ29kZUFmdGVyRGVsZXRlKHJlcSk7XG4gIH1cblxuICBoYXNMaXZlUXVlcnkoY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jbGFzc05hbWVzLmhhcyhjbGFzc05hbWUpO1xuICB9XG5cbiAgX21ha2VQdWJsaXNoZXJSZXF1ZXN0KGN1cnJlbnRPYmplY3Q6IGFueSwgb3JpZ2luYWxPYmplY3Q6IGFueSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55KTogYW55IHtcbiAgICBjb25zdCByZXEgPSB7XG4gICAgICBvYmplY3Q6IGN1cnJlbnRPYmplY3QsXG4gICAgfTtcbiAgICBpZiAoY3VycmVudE9iamVjdCkge1xuICAgICAgcmVxLm9yaWdpbmFsID0gb3JpZ2luYWxPYmplY3Q7XG4gICAgfVxuICAgIGlmIChjbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICAgIHJlcS5jbGFzc0xldmVsUGVybWlzc2lvbnMgPSBjbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgfVxuICAgIHJldHVybiByZXE7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTGl2ZVF1ZXJ5Q29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/LoggerController.js b/lib/Controllers/LoggerController.js deleted file mode 100644 index be11d8877f..0000000000 --- a/lib/Controllers/LoggerController.js +++ /dev/null @@ -1,265 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LoggerController = exports.LogOrder = exports.LogLevel = void 0; - -var _node = require("parse/node"); - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); - -var _url = _interopRequireDefault(require("url")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; -const LOG_STRING_TRUNCATE_LENGTH = 1000; -const truncationMarker = '... (truncated)'; -const LogLevel = { - INFO: 'info', - ERROR: 'error' -}; -exports.LogLevel = LogLevel; -const LogOrder = { - DESCENDING: 'desc', - ASCENDING: 'asc' -}; -exports.LogOrder = LogOrder; -const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly']; - -class LoggerController extends _AdaptableController.default { - constructor(adapter, appId, options = { - logLevel: 'info' - }) { - super(adapter, appId, options); - let level = 'info'; - - if (options.verbose) { - level = 'verbose'; - } - - if (options.logLevel) { - level = options.logLevel; - } - - const index = logLevels.indexOf(level); // info by default - - logLevels.forEach((level, levelIndex) => { - if (levelIndex > index) { - // silence the levels that are > maxIndex - this[level] = () => {}; - } - }); - } - - maskSensitiveUrl(urlString) { - const urlObj = _url.default.parse(urlString, true); - - const query = urlObj.query; - let sanitizedQuery = '?'; - - for (const key in query) { - if (key !== 'password') { - // normal value - sanitizedQuery += key + '=' + query[key] + '&'; - } else { - // password value, redact it - sanitizedQuery += key + '=' + '********' + '&'; - } - } // trim last character, ? or & - - - sanitizedQuery = sanitizedQuery.slice(0, -1); // return original path name with sanitized params attached - - return urlObj.pathname + sanitizedQuery; - } - - maskSensitive(argArray) { - return argArray.map(e => { - if (!e) { - return e; - } - - if (typeof e === 'string') { - return e.replace(/(password".?:.?")[^"]*"/g, '$1********"'); - } // else it is an object... - // check the url - - - if (e.url) { - // for strings - if (typeof e.url === 'string') { - e.url = this.maskSensitiveUrl(e.url); - } else if (Array.isArray(e.url)) { - // for strings in array - e.url = e.url.map(item => { - if (typeof item === 'string') { - return this.maskSensitiveUrl(item); - } - - return item; - }); - } - } - - if (e.body) { - for (const key of Object.keys(e.body)) { - if (key === 'password') { - e.body[key] = '********'; - break; - } - } - } - - if (e.params) { - for (const key of Object.keys(e.params)) { - if (key === 'password') { - e.params[key] = '********'; - break; - } - } - } - - return e; - }); - } - - log(level, args) { - // make the passed in arguments object an array with the spread operator - args = this.maskSensitive([...args]); - args = [].concat(level, args.map(arg => { - if (typeof arg === 'function') { - return arg(); - } - - return arg; - })); - this.adapter.log.apply(this.adapter, args); - } - - info() { - return this.log('info', arguments); - } - - error() { - return this.log('error', arguments); - } - - warn() { - return this.log('warn', arguments); - } - - verbose() { - return this.log('verbose', arguments); - } - - debug() { - return this.log('debug', arguments); - } - - silly() { - return this.log('silly', arguments); - } - - logRequest({ - method, - url, - headers, - body - }) { - this.verbose(() => { - const stringifiedBody = JSON.stringify(body, null, 2); - return `REQUEST for [${method}] ${url}: ${stringifiedBody}`; - }, { - method, - url, - headers, - body - }); - } - - logResponse({ - method, - url, - result - }) { - this.verbose(() => { - const stringifiedResponse = JSON.stringify(result, null, 2); - return `RESPONSE from [${method}] ${url}: ${stringifiedResponse}`; - }, { - result: result - }); - } // check that date input is valid - - - static validDateTime(date) { - if (!date) { - return null; - } - - date = new Date(date); - - if (!isNaN(date.getTime())) { - return date; - } - - return null; - } - - truncateLogMessage(string) { - if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) { - const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker; - return truncated; - } - - return string; - } - - static parseOptions(options = {}) { - const from = LoggerController.validDateTime(options.from) || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); - const until = LoggerController.validDateTime(options.until) || new Date(); - const size = Number(options.size) || 10; - const order = options.order || LogOrder.DESCENDING; - const level = options.level || LogLevel.INFO; - return { - from, - until, - size, - order, - level - }; - } // Returns a promise for a {response} object. - // query params: - // level (optional) Level of logging you want to query for (info || error) - // from (optional) Start time for the search. Defaults to 1 week ago. - // until (optional) End time for the search. Defaults to current time. - // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. - // size (optional) Number of rows returned by search. Defaults to 10 - - - getLogs(options = {}) { - if (!this.adapter) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); - } - - if (typeof this.adapter.query !== 'function') { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Querying logs is not supported with this adapter'); - } - - options = LoggerController.parseOptions(options); - return this.adapter.query(options); - } - - expectedAdapterType() { - return _LoggerAdapter.LoggerAdapter; - } - -} - -exports.LoggerController = LoggerController; -var _default = LoggerController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Mb2dnZXJDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIk1JTExJU0VDT05EU19JTl9BX0RBWSIsIkxPR19TVFJJTkdfVFJVTkNBVEVfTEVOR1RIIiwidHJ1bmNhdGlvbk1hcmtlciIsIkxvZ0xldmVsIiwiSU5GTyIsIkVSUk9SIiwiTG9nT3JkZXIiLCJERVNDRU5ESU5HIiwiQVNDRU5ESU5HIiwibG9nTGV2ZWxzIiwiTG9nZ2VyQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJhcHBJZCIsIm9wdGlvbnMiLCJsb2dMZXZlbCIsImxldmVsIiwidmVyYm9zZSIsImluZGV4IiwiaW5kZXhPZiIsImZvckVhY2giLCJsZXZlbEluZGV4IiwibWFza1NlbnNpdGl2ZVVybCIsInVybFN0cmluZyIsInVybE9iaiIsInVybCIsInBhcnNlIiwicXVlcnkiLCJzYW5pdGl6ZWRRdWVyeSIsImtleSIsInNsaWNlIiwicGF0aG5hbWUiLCJtYXNrU2Vuc2l0aXZlIiwiYXJnQXJyYXkiLCJtYXAiLCJlIiwicmVwbGFjZSIsIkFycmF5IiwiaXNBcnJheSIsIml0ZW0iLCJib2R5IiwiT2JqZWN0Iiwia2V5cyIsInBhcmFtcyIsImxvZyIsImFyZ3MiLCJjb25jYXQiLCJhcmciLCJhcHBseSIsImluZm8iLCJhcmd1bWVudHMiLCJlcnJvciIsIndhcm4iLCJkZWJ1ZyIsInNpbGx5IiwibG9nUmVxdWVzdCIsIm1ldGhvZCIsImhlYWRlcnMiLCJzdHJpbmdpZmllZEJvZHkiLCJKU09OIiwic3RyaW5naWZ5IiwibG9nUmVzcG9uc2UiLCJyZXN1bHQiLCJzdHJpbmdpZmllZFJlc3BvbnNlIiwidmFsaWREYXRlVGltZSIsImRhdGUiLCJEYXRlIiwiaXNOYU4iLCJnZXRUaW1lIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwic3RyaW5nIiwibGVuZ3RoIiwidHJ1bmNhdGVkIiwic3Vic3RyaW5nIiwicGFyc2VPcHRpb25zIiwiZnJvbSIsIm5vdyIsInVudGlsIiwic2l6ZSIsIk51bWJlciIsIm9yZGVyIiwiZ2V0TG9ncyIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJleHBlY3RlZEFkYXB0ZXJUeXBlIiwiTG9nZ2VyQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEscUJBQXFCLEdBQUcsS0FBSyxFQUFMLEdBQVUsRUFBVixHQUFlLElBQTdDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQUcsSUFBbkM7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxpQkFBekI7QUFFTyxNQUFNQyxRQUFRLEdBQUc7QUFDdEJDLEVBQUFBLElBQUksRUFBRSxNQURnQjtBQUV0QkMsRUFBQUEsS0FBSyxFQUFFO0FBRmUsQ0FBakI7O0FBS0EsTUFBTUMsUUFBUSxHQUFHO0FBQ3RCQyxFQUFBQSxVQUFVLEVBQUUsTUFEVTtBQUV0QkMsRUFBQUEsU0FBUyxFQUFFO0FBRlcsQ0FBakI7O0FBS1AsTUFBTUMsU0FBUyxHQUFHLENBQUMsT0FBRCxFQUFVLE1BQVYsRUFBa0IsTUFBbEIsRUFBMEIsT0FBMUIsRUFBbUMsU0FBbkMsRUFBOEMsT0FBOUMsQ0FBbEI7O0FBRU8sTUFBTUMsZ0JBQU4sU0FBK0JDLDRCQUEvQixDQUFtRDtBQUN4REMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQU8sR0FBRztBQUFFQyxJQUFBQSxRQUFRLEVBQUU7QUFBWixHQUEzQixFQUFpRDtBQUMxRCxVQUFNSCxPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0EsUUFBSUUsS0FBSyxHQUFHLE1BQVo7O0FBQ0EsUUFBSUYsT0FBTyxDQUFDRyxPQUFaLEVBQXFCO0FBQ25CRCxNQUFBQSxLQUFLLEdBQUcsU0FBUjtBQUNEOztBQUNELFFBQUlGLE9BQU8sQ0FBQ0MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsS0FBSyxHQUFHRixPQUFPLENBQUND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LEtBSks7QUFLTGhFLE1BQUFBO0FBTEssS0FBUDtBQU9ELEdBak11RCxDQW1NeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBaUUsRUFBQUEsT0FBTyxDQUFDbkUsT0FBTyxHQUFHLEVBQVgsRUFBZTtBQUNwQixRQUFJLENBQUMsS0FBS0YsT0FBVixFQUFtQjtBQUNqQixZQUFNLElBQUlzRSxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEOztBQUNELFFBQUksT0FBTyxLQUFLeEUsT0FBTCxDQUFhZSxLQUFwQixLQUE4QixVQUFsQyxFQUE4QztBQUM1QyxZQUFNLElBQUl1RCxZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUMsa0JBRFIsRUFFSixrREFGSSxDQUFOO0FBSUQ7O0FBQ0R0RSxJQUFBQSxPQUFPLEdBQUdMLGdCQUFnQixDQUFDaUUsWUFBakIsQ0FBOEI1RCxPQUE5QixDQUFWO0FBQ0EsV0FBTyxLQUFLRixPQUFMLENBQWFlLEtBQWIsQ0FBbUJiLE9BQW5CLENBQVA7QUFDRDs7QUFFRHVFLEVBQUFBLG1CQUFtQixHQUFHO0FBQ3BCLFdBQU9DLDRCQUFQO0FBQ0Q7O0FBMU51RDs7O2VBNk4zQzdFLGdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgeyBMb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvTG9nZ2VyL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuXG5jb25zdCBNSUxMSVNFQ09ORFNfSU5fQV9EQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuY29uc3QgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEggPSAxMDAwO1xuY29uc3QgdHJ1bmNhdGlvbk1hcmtlciA9ICcuLi4gKHRydW5jYXRlZCknO1xuXG5leHBvcnQgY29uc3QgTG9nTGV2ZWwgPSB7XG4gIElORk86ICdpbmZvJyxcbiAgRVJST1I6ICdlcnJvcicsXG59O1xuXG5leHBvcnQgY29uc3QgTG9nT3JkZXIgPSB7XG4gIERFU0NFTkRJTkc6ICdkZXNjJyxcbiAgQVNDRU5ESU5HOiAnYXNjJyxcbn07XG5cbmNvbnN0IGxvZ0xldmVscyA9IFsnZXJyb3InLCAnd2FybicsICdpbmZvJywgJ2RlYnVnJywgJ3ZlcmJvc2UnLCAnc2lsbHknXTtcblxuZXhwb3J0IGNsYXNzIExvZ2dlckNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7IGxvZ0xldmVsOiAnaW5mbycgfSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcbiAgICBsZXQgbGV2ZWwgPSAnaW5mbyc7XG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgbGV2ZWwgPSAndmVyYm9zZSc7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxvZ0xldmVsKSB7XG4gICAgICBsZXZlbCA9IG9wdGlvbnMubG9nTGV2ZWw7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gbG9nTGV2ZWxzLmluZGV4T2YobGV2ZWwpOyAvLyBpbmZvIGJ5IGRlZmF1bHRcbiAgICBsb2dMZXZlbHMuZm9yRWFjaCgobGV2ZWwsIGxldmVsSW5kZXgpID0+IHtcbiAgICAgIGlmIChsZXZlbEluZGV4ID4gaW5kZXgpIHtcbiAgICAgICAgLy8gc2lsZW5jZSB0aGUgbGV2ZWxzIHRoYXQgYXJlID4gbWF4SW5kZXhcbiAgICAgICAgdGhpc1tsZXZlbF0gPSAoKSA9PiB7fTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmVVcmwodXJsU3RyaW5nKSB7XG4gICAgY29uc3QgdXJsT2JqID0gdXJsLnBhcnNlKHVybFN0cmluZywgdHJ1ZSk7XG4gICAgY29uc3QgcXVlcnkgPSB1cmxPYmoucXVlcnk7XG4gICAgbGV0IHNhbml0aXplZFF1ZXJ5ID0gJz8nO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcXVlcnkpIHtcbiAgICAgIGlmIChrZXkgIT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgLy8gbm9ybWFsIHZhbHVlXG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArIHF1ZXJ5W2tleV0gKyAnJic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXNzd29yZCB2YWx1ZSwgcmVkYWN0IGl0XG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArICcqKioqKioqKicgKyAnJic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHJpbSBsYXN0IGNoYXJhY3RlciwgPyBvciAmXG4gICAgc2FuaXRpemVkUXVlcnkgPSBzYW5pdGl6ZWRRdWVyeS5zbGljZSgwLCAtMSk7XG5cbiAgICAvLyByZXR1cm4gb3JpZ2luYWwgcGF0aCBuYW1lIHdpdGggc2FuaXRpemVkIHBhcmFtcyBhdHRhY2hlZFxuICAgIHJldHVybiB1cmxPYmoucGF0aG5hbWUgKyBzYW5pdGl6ZWRRdWVyeTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmUoYXJnQXJyYXkpIHtcbiAgICByZXR1cm4gYXJnQXJyYXkubWFwKGUgPT4ge1xuICAgICAgaWYgKCFlKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBlLnJlcGxhY2UoLyhwYXNzd29yZFwiLj86Lj9cIilbXlwiXSpcIi9nLCAnJDEqKioqKioqKlwiJyk7XG4gICAgICB9XG4gICAgICAvLyBlbHNlIGl0IGlzIGFuIG9iamVjdC4uLlxuXG4gICAgICAvLyBjaGVjayB0aGUgdXJsXG4gICAgICBpZiAoZS51cmwpIHtcbiAgICAgICAgLy8gZm9yIHN0cmluZ3NcbiAgICAgICAgaWYgKHR5cGVvZiBlLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBlLnVybCA9IHRoaXMubWFza1NlbnNpdGl2ZVVybChlLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShlLnVybCkpIHtcbiAgICAgICAgICAvLyBmb3Igc3RyaW5ncyBpbiBhcnJheVxuICAgICAgICAgIGUudXJsID0gZS51cmwubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXNrU2Vuc2l0aXZlVXJsKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5ib2R5KSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUuYm9keSkpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgICAgICBlLmJvZHlba2V5XSA9ICcqKioqKioqKic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUucGFyYW1zKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUucGFyYW1zKSkge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICAgIGUucGFyYW1zW2tleV0gPSAnKioqKioqKionO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlO1xuICAgIH0pO1xuICB9XG5cbiAgbG9nKGxldmVsLCBhcmdzKSB7XG4gICAgLy8gbWFrZSB0aGUgcGFzc2VkIGluIGFyZ3VtZW50cyBvYmplY3QgYW4gYXJyYXkgd2l0aCB0aGUgc3ByZWFkIG9wZXJhdG9yXG4gICAgYXJncyA9IHRoaXMubWFza1NlbnNpdGl2ZShbLi4uYXJnc10pO1xuICAgIGFyZ3MgPSBbXS5jb25jYXQoXG4gICAgICBsZXZlbCxcbiAgICAgIGFyZ3MubWFwKGFyZyA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcmc7XG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hZGFwdGVyLmxvZy5hcHBseSh0aGlzLmFkYXB0ZXIsIGFyZ3MpO1xuICB9XG5cbiAgaW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2luZm8nLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCdlcnJvcicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB3YXJuKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnd2FybicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB2ZXJib3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygndmVyYm9zZScsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBkZWJ1ZygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2RlYnVnJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHNpbGx5KCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnc2lsbHknLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgbG9nUmVxdWVzdCh7IG1ldGhvZCwgdXJsLCBoZWFkZXJzLCBib2R5IH0pIHtcbiAgICB0aGlzLnZlcmJvc2UoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ2lmaWVkQm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHksIG51bGwsIDIpO1xuICAgICAgICByZXR1cm4gYFJFUVVFU1QgZm9yIFske21ldGhvZH1dICR7dXJsfTogJHtzdHJpbmdpZmllZEJvZHl9YDtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBsb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSkge1xuICAgIHRoaXMudmVyYm9zZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RyaW5naWZpZWRSZXNwb25zZSA9IEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMik7XG4gICAgICAgIHJldHVybiBgUkVTUE9OU0UgZnJvbSBbJHttZXRob2R9XSAke3VybH06ICR7c3RyaW5naWZpZWRSZXNwb25zZX1gO1xuICAgICAgfSxcbiAgICAgIHsgcmVzdWx0OiByZXN1bHQgfVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgdGhhdCBkYXRlIGlucHV0IGlzIHZhbGlkXG4gIHN0YXRpYyB2YWxpZERhdGVUaW1lKGRhdGUpIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICBpZiAoIWlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnVuY2F0ZUxvZ01lc3NhZ2Uoc3RyaW5nKSB7XG4gICAgaWYgKHN0cmluZyAmJiBzdHJpbmcubGVuZ3RoID4gTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHRydW5jYXRlZCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpICsgdHJ1bmNhdGlvbk1hcmtlcjtcbiAgICAgIHJldHVybiB0cnVuY2F0ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0cmluZztcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBMb2dnZXJDb250cm9sbGVyLnZhbGlkRGF0ZVRpbWUob3B0aW9ucy5mcm9tKSB8fFxuICAgICAgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gTG9nZ2VyQ29udHJvbGxlci52YWxpZERhdGVUaW1lKG9wdGlvbnMudW50aWwpIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgc2l6ZSA9IE51bWJlcihvcHRpb25zLnNpemUpIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCBMb2dPcmRlci5ERVNDRU5ESU5HO1xuICAgIGNvbnN0IGxldmVsID0gb3B0aW9ucy5sZXZlbCB8fCBMb2dMZXZlbC5JTkZPO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbiAgLy8gcXVlcnkgcGFyYW1zOlxuICAvLyBsZXZlbCAob3B0aW9uYWwpIExldmVsIG9mIGxvZ2dpbmcgeW91IHdhbnQgdG8gcXVlcnkgZm9yIChpbmZvIHx8IGVycm9yKVxuICAvLyBmcm9tIChvcHRpb25hbCkgU3RhcnQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gMSB3ZWVrIGFnby5cbiAgLy8gdW50aWwgKG9wdGlvbmFsKSBFbmQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gY3VycmVudCB0aW1lLlxuICAvLyBvcmRlciAob3B0aW9uYWwpIERpcmVjdGlvbiBvZiByZXN1bHRzIHJldHVybmVkLCBlaXRoZXIg4oCcYXNj4oCdIG9yIOKAnGRlc2PigJ0uIERlZmF1bHRzIHRvIOKAnGRlc2PigJ0uXG4gIC8vIHNpemUgKG9wdGlvbmFsKSBOdW1iZXIgb2Ygcm93cyByZXR1cm5lZCBieSBzZWFyY2guIERlZmF1bHRzIHRvIDEwXG4gIGdldExvZ3Mob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdMb2dnZXIgYWRhcHRlciBpcyBub3QgYXZhaWxhYmxlJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnF1ZXJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1F1ZXJ5aW5nIGxvZ3MgaXMgbm90IHN1cHBvcnRlZCB3aXRoIHRoaXMgYWRhcHRlcidcbiAgICAgICk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBMb2dnZXJDb250cm9sbGVyLnBhcnNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnF1ZXJ5KG9wdGlvbnMpO1xuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gTG9nZ2VyQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dnZXJDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/ParseGraphQLController.js b/lib/Controllers/ParseGraphQLController.js deleted file mode 100644 index 14da8815ed..0000000000 --- a/lib/Controllers/ParseGraphQLController.js +++ /dev/null @@ -1,358 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.GraphQLConfigKey = exports.GraphQLConfigId = exports.GraphQLConfigClassName = exports.default = void 0; - -var _requiredParameter = _interopRequireDefault(require("../../lib/requiredParameter")); - -var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); - -var _CacheController = _interopRequireDefault(require("./CacheController")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const GraphQLConfigClassName = '_GraphQLConfig'; -exports.GraphQLConfigClassName = GraphQLConfigClassName; -const GraphQLConfigId = '1'; -exports.GraphQLConfigId = GraphQLConfigId; -const GraphQLConfigKey = 'config'; -exports.GraphQLConfigKey = GraphQLConfigKey; - -class ParseGraphQLController { - constructor(params = {}) { - this.databaseController = params.databaseController || (0, _requiredParameter.default)(`ParseGraphQLController requires a "databaseController" to be instantiated.`); - this.cacheController = params.cacheController; - this.isMounted = !!params.mountGraphQL; - this.configCacheKey = GraphQLConfigKey; - } - - async getGraphQLConfig() { - if (this.isMounted) { - const _cachedConfig = await this._getCachedGraphQLConfig(); - - if (_cachedConfig) { - return _cachedConfig; - } - } - - const results = await this.databaseController.find(GraphQLConfigClassName, { - objectId: GraphQLConfigId - }, { - limit: 1 - }); - let graphQLConfig; - - if (results.length != 1) { - // If there is no config in the database - return empty config. - return {}; - } else { - graphQLConfig = results[0][GraphQLConfigKey]; - } - - if (this.isMounted) { - this._putCachedGraphQLConfig(graphQLConfig); - } - - return graphQLConfig; - } - - async updateGraphQLConfig(graphQLConfig) { - // throws if invalid - this._validateGraphQLConfig(graphQLConfig || (0, _requiredParameter.default)('You must provide a graphQLConfig!')); // Transform in dot notation to make sure it works - - - const update = Object.keys(graphQLConfig).reduce((acc, key) => { - return { - [GraphQLConfigKey]: _objectSpread(_objectSpread({}, acc[GraphQLConfigKey]), {}, { - [key]: graphQLConfig[key] - }) - }; - }, { - [GraphQLConfigKey]: {} - }); - await this.databaseController.update(GraphQLConfigClassName, { - objectId: GraphQLConfigId - }, update, { - upsert: true - }); - - if (this.isMounted) { - this._putCachedGraphQLConfig(graphQLConfig); - } - - return { - response: { - result: true - } - }; - } - - _getCachedGraphQLConfig() { - return this.cacheController.graphQL.get(this.configCacheKey); - } - - _putCachedGraphQLConfig(graphQLConfig) { - return this.cacheController.graphQL.put(this.configCacheKey, graphQLConfig, 60000); - } - - _validateGraphQLConfig(graphQLConfig) { - const errorMessages = []; - - if (!graphQLConfig) { - errorMessages.push('cannot be undefined, null or empty'); - } else if (!isValidSimpleObject(graphQLConfig)) { - errorMessages.push('must be a valid object'); - } else { - const { - enabledForClasses = null, - disabledForClasses = null, - classConfigs = null - } = graphQLConfig, - invalidKeys = _objectWithoutProperties(graphQLConfig, ["enabledForClasses", "disabledForClasses", "classConfigs"]); - - if (Object.keys(invalidKeys).length) { - errorMessages.push(`encountered invalid keys: [${Object.keys(invalidKeys)}]`); - } - - if (enabledForClasses !== null && !isValidStringArray(enabledForClasses)) { - errorMessages.push(`"enabledForClasses" is not a valid array`); - } - - if (disabledForClasses !== null && !isValidStringArray(disabledForClasses)) { - errorMessages.push(`"disabledForClasses" is not a valid array`); - } - - if (classConfigs !== null) { - if (Array.isArray(classConfigs)) { - classConfigs.forEach(classConfig => { - const errorMessage = this._validateClassConfig(classConfig); - - if (errorMessage) { - errorMessages.push(`classConfig:${classConfig.className} is invalid because ${errorMessage}`); - } - }); - } else { - errorMessages.push(`"classConfigs" is not a valid array`); - } - } - } - - if (errorMessages.length) { - throw new Error(`Invalid graphQLConfig: ${errorMessages.join('; ')}`); - } - } - - _validateClassConfig(classConfig) { - if (!isValidSimpleObject(classConfig)) { - return 'it must be a valid object'; - } else { - const { - className, - type = null, - query = null, - mutation = null - } = classConfig, - invalidKeys = _objectWithoutProperties(classConfig, ["className", "type", "query", "mutation"]); - - if (Object.keys(invalidKeys).length) { - return `"invalidKeys" [${Object.keys(invalidKeys)}] should not be present`; - } - - if (typeof className !== 'string' || !className.trim().length) { - // TODO consider checking class exists in schema? - return `"className" must be a valid string`; - } - - if (type !== null) { - if (!isValidSimpleObject(type)) { - return `"type" must be a valid object`; - } - - const { - inputFields = null, - outputFields = null, - constraintFields = null, - sortFields = null - } = type, - invalidKeys = _objectWithoutProperties(type, ["inputFields", "outputFields", "constraintFields", "sortFields"]); - - if (Object.keys(invalidKeys).length) { - return `"type" contains invalid keys, [${Object.keys(invalidKeys)}]`; - } else if (outputFields !== null && !isValidStringArray(outputFields)) { - return `"outputFields" must be a valid string array`; - } else if (constraintFields !== null && !isValidStringArray(constraintFields)) { - return `"constraintFields" must be a valid string array`; - } - - if (sortFields !== null) { - if (Array.isArray(sortFields)) { - let errorMessage; - sortFields.every((sortField, index) => { - if (!isValidSimpleObject(sortField)) { - errorMessage = `"sortField" at index ${index} is not a valid object`; - return false; - } else { - const { - field, - asc, - desc - } = sortField, - invalidKeys = _objectWithoutProperties(sortField, ["field", "asc", "desc"]); - - if (Object.keys(invalidKeys).length) { - errorMessage = `"sortField" at index ${index} contains invalid keys, [${Object.keys(invalidKeys)}]`; - return false; - } else { - if (typeof field !== 'string' || field.trim().length === 0) { - errorMessage = `"sortField" at index ${index} did not provide the "field" as a string`; - return false; - } else if (typeof asc !== 'boolean' || typeof desc !== 'boolean') { - errorMessage = `"sortField" at index ${index} did not provide "asc" or "desc" as booleans`; - return false; - } - } - } - - return true; - }); - - if (errorMessage) { - return errorMessage; - } - } else { - return `"sortFields" must be a valid array.`; - } - } - - if (inputFields !== null) { - if (isValidSimpleObject(inputFields)) { - const { - create = null, - update = null - } = inputFields, - invalidKeys = _objectWithoutProperties(inputFields, ["create", "update"]); - - if (Object.keys(invalidKeys).length) { - return `"inputFields" contains invalid keys: [${Object.keys(invalidKeys)}]`; - } else { - if (update !== null && !isValidStringArray(update)) { - return `"inputFields.update" must be a valid string array`; - } else if (create !== null) { - if (!isValidStringArray(create)) { - return `"inputFields.create" must be a valid string array`; - } else if (className === '_User') { - if (!create.includes('username') || !create.includes('password')) { - return `"inputFields.create" must include required fields, username and password`; - } - } - } - } - } else { - return `"inputFields" must be a valid object`; - } - } - } - - if (query !== null) { - if (isValidSimpleObject(query)) { - const { - find = null, - get = null, - findAlias = null, - getAlias = null - } = query, - invalidKeys = _objectWithoutProperties(query, ["find", "get", "findAlias", "getAlias"]); - - if (Object.keys(invalidKeys).length) { - return `"query" contains invalid keys, [${Object.keys(invalidKeys)}]`; - } else if (find !== null && typeof find !== 'boolean') { - return `"query.find" must be a boolean`; - } else if (get !== null && typeof get !== 'boolean') { - return `"query.get" must be a boolean`; - } else if (findAlias !== null && typeof findAlias !== 'string') { - return `"query.findAlias" must be a string`; - } else if (getAlias !== null && typeof getAlias !== 'string') { - return `"query.getAlias" must be a string`; - } - } else { - return `"query" must be a valid object`; - } - } - - if (mutation !== null) { - if (isValidSimpleObject(mutation)) { - const { - create = null, - update = null, - destroy = null, - createAlias = null, - updateAlias = null, - destroyAlias = null - } = mutation, - invalidKeys = _objectWithoutProperties(mutation, ["create", "update", "destroy", "createAlias", "updateAlias", "destroyAlias"]); - - if (Object.keys(invalidKeys).length) { - return `"mutation" contains invalid keys, [${Object.keys(invalidKeys)}]`; - } - - if (create !== null && typeof create !== 'boolean') { - return `"mutation.create" must be a boolean`; - } - - if (update !== null && typeof update !== 'boolean') { - return `"mutation.update" must be a boolean`; - } - - if (destroy !== null && typeof destroy !== 'boolean') { - return `"mutation.destroy" must be a boolean`; - } - - if (createAlias !== null && typeof createAlias !== 'string') { - return `"mutation.createAlias" must be a string`; - } - - if (updateAlias !== null && typeof updateAlias !== 'string') { - return `"mutation.updateAlias" must be a string`; - } - - if (destroyAlias !== null && typeof destroyAlias !== 'string') { - return `"mutation.destroyAlias" must be a string`; - } - } else { - return `"mutation" must be a valid object`; - } - } - } - } - -} - -const isValidStringArray = function (array) { - return Array.isArray(array) ? !array.some(s => typeof s !== 'string' || s.trim().length < 1) : false; -}; -/** - * Ensures the obj is a simple JSON/{} - * object, i.e. not an array, null, date - * etc. - */ - - -const isValidSimpleObject = function (obj) { - return typeof obj === 'object' && !Array.isArray(obj) && obj !== null && obj instanceof Date !== true && obj instanceof Promise !== true; -}; - -var _default = ParseGraphQLController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkdyYXBoUUxDb25maWdDbGFzc05hbWUiLCJHcmFwaFFMQ29uZmlnSWQiLCJHcmFwaFFMQ29uZmlnS2V5IiwiUGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwiZGF0YWJhc2VDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiaXNNb3VudGVkIiwibW91bnRHcmFwaFFMIiwiY29uZmlnQ2FjaGVLZXkiLCJnZXRHcmFwaFFMQ29uZmlnIiwiX2NhY2hlZENvbmZpZyIsIl9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwicmVzdWx0cyIsImZpbmQiLCJvYmplY3RJZCIsImxpbWl0IiwiZ3JhcGhRTENvbmZpZyIsImxlbmd0aCIsIl9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwidXBkYXRlR3JhcGhRTENvbmZpZyIsIl92YWxpZGF0ZUdyYXBoUUxDb25maWciLCJ1cGRhdGUiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYWNjIiwia2V5IiwidXBzZXJ0IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJncmFwaFFMIiwiZ2V0IiwicHV0IiwiZXJyb3JNZXNzYWdlcyIsInB1c2giLCJpc1ZhbGlkU2ltcGxlT2JqZWN0IiwiZW5hYmxlZEZvckNsYXNzZXMiLCJkaXNhYmxlZEZvckNsYXNzZXMiLCJjbGFzc0NvbmZpZ3MiLCJpbnZhbGlkS2V5cyIsImlzVmFsaWRTdHJpbmdBcnJheSIsIkFycmF5IiwiaXNBcnJheSIsImZvckVhY2giLCJjbGFzc0NvbmZpZyIsImVycm9yTWVzc2FnZSIsIl92YWxpZGF0ZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiRXJyb3IiLCJqb2luIiwidHlwZSIsInF1ZXJ5IiwibXV0YXRpb24iLCJ0cmltIiwiaW5wdXRGaWVsZHMiLCJvdXRwdXRGaWVsZHMiLCJjb25zdHJhaW50RmllbGRzIiwic29ydEZpZWxkcyIsImV2ZXJ5Iiwic29ydEZpZWxkIiwiaW5kZXgiLCJmaWVsZCIsImFzYyIsImRlc2MiLCJjcmVhdGUiLCJpbmNsdWRlcyIsImZpbmRBbGlhcyIsImdldEFsaWFzIiwiZGVzdHJveSIsImNyZWF0ZUFsaWFzIiwidXBkYXRlQWxpYXMiLCJkZXN0cm95QWxpYXMiLCJhcnJheSIsInNvbWUiLCJzIiwib2JqIiwiRGF0ZSIsIlByb21pc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFFQSxNQUFNQSxzQkFBc0IsR0FBRyxnQkFBL0I7O0FBQ0EsTUFBTUMsZUFBZSxHQUFHLEdBQXhCOztBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFFBQXpCOzs7QUFFQSxNQUFNQyxzQkFBTixDQUE2QjtBQU0zQkMsRUFBQUEsV0FBVyxDQUNUQyxNQUdDLEdBQUcsRUFKSyxFQUtUO0FBQ0EsU0FBS0Msa0JBQUwsR0FDRUQsTUFBTSxDQUFDQyxrQkFBUCxJQUNBLGdDQUNHLDRFQURILENBRkY7QUFLQSxTQUFLQyxlQUFMLEdBQXVCRixNQUFNLENBQUNFLGVBQTlCO0FBQ0EsU0FBS0MsU0FBTCxHQUFpQixDQUFDLENBQUNILE1BQU0sQ0FBQ0ksWUFBMUI7QUFDQSxTQUFLQyxjQUFMLEdBQXNCUixnQkFBdEI7QUFDRDs7QUFFRCxRQUFNUyxnQkFBTixHQUFzRDtBQUNwRCxRQUFJLEtBQUtILFNBQVQsRUFBb0I7QUFDbEIsWUFBTUksYUFBYSxHQUFHLE1BQU0sS0FBS0MsdUJBQUwsRUFBNUI7O0FBQ0EsVUFBSUQsYUFBSixFQUFtQjtBQUNqQixlQUFPQSxhQUFQO0FBQ0Q7QUFDRjs7QUFFRCxVQUFNRSxPQUFPLEdBQUcsTUFBTSxLQUFLUixrQkFBTCxDQUF3QlMsSUFBeEIsQ0FDcEJmLHNCQURvQixFQUVwQjtBQUFFZ0IsTUFBQUEsUUFBUSxFQUFFZjtBQUFaLEtBRm9CLEVBR3BCO0FBQUVnQixNQUFBQSxLQUFLLEVBQUU7QUFBVCxLQUhvQixDQUF0QjtBQU1BLFFBQUlDLGFBQUo7O0FBQ0EsUUFBSUosT0FBTyxDQUFDSyxNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCO0FBQ0EsYUFBTyxFQUFQO0FBQ0QsS0FIRCxNQUdPO0FBQ0xELE1BQUFBLGFBQWEsR0FBR0osT0FBTyxDQUFDLENBQUQsQ0FBUCxDQUFXWixnQkFBWCxDQUFoQjtBQUNEOztBQUVELFFBQUksS0FBS00sU0FBVCxFQUFvQjtBQUNsQixXQUFLWSx1QkFBTCxDQUE2QkYsYUFBN0I7QUFDRDs7QUFFRCxXQUFPQSxhQUFQO0FBQ0Q7O0FBRUQsUUFBTUcsbUJBQU4sQ0FBMEJILGFBQTFCLEVBQTBGO0FBQ3hGO0FBQ0EsU0FBS0ksc0JBQUwsQ0FDRUosYUFBYSxJQUFJLGdDQUFrQixtQ0FBbEIsQ0FEbkIsRUFGd0YsQ0FNeEY7OztBQUNBLFVBQU1LLE1BQU0sR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlQLGFBQVosRUFBMkJRLE1BQTNCLENBQ2IsQ0FBQ0MsR0FBRCxFQUFNQyxHQUFOLEtBQWM7QUFDWixhQUFPO0FBQ0wsU0FBQzFCLGdCQUFELG1DQUNLeUIsR0FBRyxDQUFDekIsZ0JBQUQsQ0FEUjtBQUVFLFdBQUMwQixHQUFELEdBQU9WLGFBQWEsQ0FBQ1UsR0FBRDtBQUZ0QjtBQURLLE9BQVA7QUFNRCxLQVJZLEVBU2I7QUFBRSxPQUFDMUIsZ0JBQUQsR0FBb0I7QUFBdEIsS0FUYSxDQUFmO0FBWUEsVUFBTSxLQUFLSSxrQkFBTCxDQUF3QmlCLE1BQXhCLENBQ0p2QixzQkFESSxFQUVKO0FBQUVnQixNQUFBQSxRQUFRLEVBQUVmO0FBQVosS0FGSSxFQUdKc0IsTUFISSxFQUlKO0FBQUVNLE1BQUFBLE1BQU0sRUFBRTtBQUFWLEtBSkksQ0FBTjs7QUFPQSxRQUFJLEtBQUtyQixTQUFULEVBQW9CO0FBQ2xCLFdBQUtZLHVCQUFMLENBQTZCRixhQUE3QjtBQUNEOztBQUVELFdBQU87QUFBRVksTUFBQUEsUUFBUSxFQUFFO0FBQUVDLFFBQUFBLE1BQU0sRUFBRTtBQUFWO0FBQVosS0FBUDtBQUNEOztBQUVEbEIsRUFBQUEsdUJBQXVCLEdBQUc7QUFDeEIsV0FBTyxLQUFLTixlQUFMLENBQXFCeUIsT0FBckIsQ0FBNkJDLEdBQTdCLENBQWlDLEtBQUt2QixjQUF0QyxDQUFQO0FBQ0Q7O0FBRURVLEVBQUFBLHVCQUF1QixDQUFDRixhQUFELEVBQW9DO0FBQ3pELFdBQU8sS0FBS1gsZUFBTCxDQUFxQnlCLE9BQXJCLENBQTZCRSxHQUE3QixDQUFpQyxLQUFLeEIsY0FBdEMsRUFBc0RRLGFBQXRELEVBQXFFLEtBQXJFLENBQVA7QUFDRDs7QUFFREksRUFBQUEsc0JBQXNCLENBQUNKLGFBQUQsRUFBMkM7QUFDL0QsVUFBTWlCLGFBQXFCLEdBQUcsRUFBOUI7O0FBQ0EsUUFBSSxDQUFDakIsYUFBTCxFQUFvQjtBQUNsQmlCLE1BQUFBLGFBQWEsQ0FBQ0MsSUFBZCxDQUFtQixvQ0FBbkI7QUFDRCxLQUZELE1BRU8sSUFBSSxDQUFDQyxtQkFBbUIsQ0FBQ25CLGFBQUQsQ0FBeEIsRUFBeUM7QUFDOUNpQixNQUFBQSxhQUFhLENBQUNDLElBQWQsQ0FBbUIsd0JBQW5CO0FBQ0QsS0FGTSxNQUVBO0FBQ0wsWUFBTTtBQUNKRSxRQUFBQSxpQkFBaUIsR0FBRyxJQURoQjtBQUVKQyxRQUFBQSxrQkFBa0IsR0FBRyxJQUZqQjtBQUdKQyxRQUFBQSxZQUFZLEdBQUc7QUFIWCxVQUtGdEIsYUFMSjtBQUFBLFlBSUt1QixXQUpMLDRCQUtJdkIsYUFMSjs7QUFPQSxVQUFJTSxNQUFNLENBQUNDLElBQVAsQ0FBWWdCLFdBQVosRUFBeUJ0QixNQUE3QixFQUFxQztBQUNuQ2dCLFFBQUFBLGFBQWEsQ0FBQ0MsSUFBZCxDQUFvQiw4QkFBNkJaLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZZ0IsV0FBWixDQUF5QixHQUExRTtBQUNEOztBQUNELFVBQUlILGlCQUFpQixLQUFLLElBQXRCLElBQThCLENBQUNJLGtCQUFrQixDQUFDSixpQkFBRCxDQUFyRCxFQUEwRTtBQUN4RUgsUUFBQUEsYUFBYSxDQUFDQyxJQUFkLENBQW9CLDBDQUFwQjtBQUNEOztBQUNELFVBQUlHLGtCQUFrQixLQUFLLElBQXZCLElBQStCLENBQUNHLGtCQUFrQixDQUFDSCxrQkFBRCxDQUF0RCxFQUE0RTtBQUMxRUosUUFBQUEsYUFBYSxDQUFDQyxJQUFkLENBQW9CLDJDQUFwQjtBQUNEOztBQUNELFVBQUlJLFlBQVksS0FBSyxJQUFyQixFQUEyQjtBQUN6QixZQUFJRyxLQUFLLENBQUNDLE9BQU4sQ0FBY0osWUFBZCxDQUFKLEVBQWlDO0FBQy9CQSxVQUFBQSxZQUFZLENBQUNLLE9BQWIsQ0FBcUJDLFdBQVcsSUFBSTtBQUNsQyxrQkFBTUMsWUFBWSxHQUFHLEtBQUtDLG9CQUFMLENBQTBCRixXQUExQixDQUFyQjs7QUFDQSxnQkFBSUMsWUFBSixFQUFrQjtBQUNoQlosY0FBQUEsYUFBYSxDQUFDQyxJQUFkLENBQ0csZUFBY1UsV0FBVyxDQUFDRyxTQUFVLHVCQUFzQkYsWUFBYSxFQUQxRTtBQUdEO0FBQ0YsV0FQRDtBQVFELFNBVEQsTUFTTztBQUNMWixVQUFBQSxhQUFhLENBQUNDLElBQWQsQ0FBb0IscUNBQXBCO0FBQ0Q7QUFDRjtBQUNGOztBQUNELFFBQUlELGFBQWEsQ0FBQ2hCLE1BQWxCLEVBQTBCO0FBQ3hCLFlBQU0sSUFBSStCLEtBQUosQ0FBVywwQkFBeUJmLGFBQWEsQ0FBQ2dCLElBQWQsQ0FBbUIsSUFBbkIsQ0FBeUIsRUFBN0QsQ0FBTjtBQUNEO0FBQ0Y7O0FBRURILEVBQUFBLG9CQUFvQixDQUFDRixXQUFELEVBQXVEO0FBQ3pFLFFBQUksQ0FBQ1QsbUJBQW1CLENBQUNTLFdBQUQsQ0FBeEIsRUFBdUM7QUFDckMsYUFBTywyQkFBUDtBQUNELEtBRkQsTUFFTztBQUNMLFlBQU07QUFBRUcsUUFBQUEsU0FBRjtBQUFhRyxRQUFBQSxJQUFJLEdBQUcsSUFBcEI7QUFBMEJDLFFBQUFBLEtBQUssR0FBRyxJQUFsQztBQUF3Q0MsUUFBQUEsUUFBUSxHQUFHO0FBQW5ELFVBQTRFUixXQUFsRjtBQUFBLFlBQWtFTCxXQUFsRSw0QkFBa0ZLLFdBQWxGOztBQUNBLFVBQUl0QixNQUFNLENBQUNDLElBQVAsQ0FBWWdCLFdBQVosRUFBeUJ0QixNQUE3QixFQUFxQztBQUNuQyxlQUFRLGtCQUFpQkssTUFBTSxDQUFDQyxJQUFQLENBQVlnQixXQUFaLENBQXlCLHlCQUFsRDtBQUNEOztBQUNELFVBQUksT0FBT1EsU0FBUCxLQUFxQixRQUFyQixJQUFpQyxDQUFDQSxTQUFTLENBQUNNLElBQVYsR0FBaUJwQyxNQUF2RCxFQUErRDtBQUM3RDtBQUNBLGVBQVEsb0NBQVI7QUFDRDs7QUFDRCxVQUFJaUMsSUFBSSxLQUFLLElBQWIsRUFBbUI7QUFDakIsWUFBSSxDQUFDZixtQkFBbUIsQ0FBQ2UsSUFBRCxDQUF4QixFQUFnQztBQUM5QixpQkFBUSwrQkFBUjtBQUNEOztBQUNELGNBQU07QUFDSkksVUFBQUEsV0FBVyxHQUFHLElBRFY7QUFFSkMsVUFBQUEsWUFBWSxHQUFHLElBRlg7QUFHSkMsVUFBQUEsZ0JBQWdCLEdBQUcsSUFIZjtBQUlKQyxVQUFBQSxVQUFVLEdBQUc7QUFKVCxZQU1GUCxJQU5KO0FBQUEsY0FLS1gsV0FMTCw0QkFNSVcsSUFOSjs7QUFPQSxZQUFJNUIsTUFBTSxDQUFDQyxJQUFQLENBQVlnQixXQUFaLEVBQXlCdEIsTUFBN0IsRUFBcUM7QUFDbkMsaUJBQVEsa0NBQWlDSyxNQUFNLENBQUNDLElBQVAsQ0FBWWdCLFdBQVosQ0FBeUIsR0FBbEU7QUFDRCxTQUZELE1BRU8sSUFBSWdCLFlBQVksS0FBSyxJQUFqQixJQUF5QixDQUFDZixrQkFBa0IsQ0FBQ2UsWUFBRCxDQUFoRCxFQUFnRTtBQUNyRSxpQkFBUSw2Q0FBUjtBQUNELFNBRk0sTUFFQSxJQUFJQyxnQkFBZ0IsS0FBSyxJQUFyQixJQUE2QixDQUFDaEIsa0JBQWtCLENBQUNnQixnQkFBRCxDQUFwRCxFQUF3RTtBQUM3RSxpQkFBUSxpREFBUjtBQUNEOztBQUNELFlBQUlDLFVBQVUsS0FBSyxJQUFuQixFQUF5QjtBQUN2QixjQUFJaEIsS0FBSyxDQUFDQyxPQUFOLENBQWNlLFVBQWQsQ0FBSixFQUErQjtBQUM3QixnQkFBSVosWUFBSjtBQUNBWSxZQUFBQSxVQUFVLENBQUNDLEtBQVgsQ0FBaUIsQ0FBQ0MsU0FBRCxFQUFZQyxLQUFaLEtBQXNCO0FBQ3JDLGtCQUFJLENBQUN6QixtQkFBbUIsQ0FBQ3dCLFNBQUQsQ0FBeEIsRUFBcUM7QUFDbkNkLGdCQUFBQSxZQUFZLEdBQUksd0JBQXVCZSxLQUFNLHdCQUE3QztBQUNBLHVCQUFPLEtBQVA7QUFDRCxlQUhELE1BR087QUFDTCxzQkFBTTtBQUFFQyxrQkFBQUEsS0FBRjtBQUFTQyxrQkFBQUEsR0FBVDtBQUFjQyxrQkFBQUE7QUFBZCxvQkFBdUNKLFNBQTdDO0FBQUEsc0JBQTZCcEIsV0FBN0IsNEJBQTZDb0IsU0FBN0M7O0FBQ0Esb0JBQUlyQyxNQUFNLENBQUNDLElBQVAsQ0FBWWdCLFdBQVosRUFBeUJ0QixNQUE3QixFQUFxQztBQUNuQzRCLGtCQUFBQSxZQUFZLEdBQUksd0JBQXVCZSxLQUFNLDRCQUEyQnRDLE1BQU0sQ0FBQ0MsSUFBUCxDQUN0RWdCLFdBRHNFLENBRXRFLEdBRkY7QUFHQSx5QkFBTyxLQUFQO0FBQ0QsaUJBTEQsTUFLTztBQUNMLHNCQUFJLE9BQU9zQixLQUFQLEtBQWlCLFFBQWpCLElBQTZCQSxLQUFLLENBQUNSLElBQU4sR0FBYXBDLE1BQWIsS0FBd0IsQ0FBekQsRUFBNEQ7QUFDMUQ0QixvQkFBQUEsWUFBWSxHQUFJLHdCQUF1QmUsS0FBTSwwQ0FBN0M7QUFDQSwyQkFBTyxLQUFQO0FBQ0QsbUJBSEQsTUFHTyxJQUFJLE9BQU9FLEdBQVAsS0FBZSxTQUFmLElBQTRCLE9BQU9DLElBQVAsS0FBZ0IsU0FBaEQsRUFBMkQ7QUFDaEVsQixvQkFBQUEsWUFBWSxHQUFJLHdCQUF1QmUsS0FBTSw4Q0FBN0M7QUFDQSwyQkFBTyxLQUFQO0FBQ0Q7QUFDRjtBQUNGOztBQUNELHFCQUFPLElBQVA7QUFDRCxhQXRCRDs7QUF1QkEsZ0JBQUlmLFlBQUosRUFBa0I7QUFDaEIscUJBQU9BLFlBQVA7QUFDRDtBQUNGLFdBNUJELE1BNEJPO0FBQ0wsbUJBQVEscUNBQVI7QUFDRDtBQUNGOztBQUNELFlBQUlTLFdBQVcsS0FBSyxJQUFwQixFQUEwQjtBQUN4QixjQUFJbkIsbUJBQW1CLENBQUNtQixXQUFELENBQXZCLEVBQXNDO0FBQ3BDLGtCQUFNO0FBQUVVLGNBQUFBLE1BQU0sR0FBRyxJQUFYO0FBQWlCM0MsY0FBQUEsTUFBTSxHQUFHO0FBQTFCLGdCQUFtRGlDLFdBQXpEO0FBQUEsa0JBQXlDZixXQUF6Qyw0QkFBeURlLFdBQXpEOztBQUNBLGdCQUFJaEMsTUFBTSxDQUFDQyxJQUFQLENBQVlnQixXQUFaLEVBQXlCdEIsTUFBN0IsRUFBcUM7QUFDbkMscUJBQVEseUNBQXdDSyxNQUFNLENBQUNDLElBQVAsQ0FBWWdCLFdBQVosQ0FBeUIsR0FBekU7QUFDRCxhQUZELE1BRU87QUFDTCxrQkFBSWxCLE1BQU0sS0FBSyxJQUFYLElBQW1CLENBQUNtQixrQkFBa0IsQ0FBQ25CLE1BQUQsQ0FBMUMsRUFBb0Q7QUFDbEQsdUJBQVEsbURBQVI7QUFDRCxlQUZELE1BRU8sSUFBSTJDLE1BQU0sS0FBSyxJQUFmLEVBQXFCO0FBQzFCLG9CQUFJLENBQUN4QixrQkFBa0IsQ0FBQ3dCLE1BQUQsQ0FBdkIsRUFBaUM7QUFDL0IseUJBQVEsbURBQVI7QUFDRCxpQkFGRCxNQUVPLElBQUlqQixTQUFTLEtBQUssT0FBbEIsRUFBMkI7QUFDaEMsc0JBQUksQ0FBQ2lCLE1BQU0sQ0FBQ0MsUUFBUCxDQUFnQixVQUFoQixDQUFELElBQWdDLENBQUNELE1BQU0sQ0FBQ0MsUUFBUCxDQUFnQixVQUFoQixDQUFyQyxFQUFrRTtBQUNoRSwyQkFBUSwwRUFBUjtBQUNEO0FBQ0Y7QUFDRjtBQUNGO0FBQ0YsV0FqQkQsTUFpQk87QUFDTCxtQkFBUSxzQ0FBUjtBQUNEO0FBQ0Y7QUFDRjs7QUFDRCxVQUFJZCxLQUFLLEtBQUssSUFBZCxFQUFvQjtBQUNsQixZQUFJaEIsbUJBQW1CLENBQUNnQixLQUFELENBQXZCLEVBQWdDO0FBQzlCLGdCQUFNO0FBQ0p0QyxZQUFBQSxJQUFJLEdBQUcsSUFESDtBQUVKa0IsWUFBQUEsR0FBRyxHQUFHLElBRkY7QUFHSm1DLFlBQUFBLFNBQVMsR0FBRyxJQUhSO0FBSUpDLFlBQUFBLFFBQVEsR0FBRztBQUpQLGNBTUZoQixLQU5KO0FBQUEsZ0JBS0taLFdBTEwsNEJBTUlZLEtBTko7O0FBT0EsY0FBSTdCLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZZ0IsV0FBWixFQUF5QnRCLE1BQTdCLEVBQXFDO0FBQ25DLG1CQUFRLG1DQUFrQ0ssTUFBTSxDQUFDQyxJQUFQLENBQVlnQixXQUFaLENBQXlCLEdBQW5FO0FBQ0QsV0FGRCxNQUVPLElBQUkxQixJQUFJLEtBQUssSUFBVCxJQUFpQixPQUFPQSxJQUFQLEtBQWdCLFNBQXJDLEVBQWdEO0FBQ3JELG1CQUFRLGdDQUFSO0FBQ0QsV0FGTSxNQUVBLElBQUlrQixHQUFHLEtBQUssSUFBUixJQUFnQixPQUFPQSxHQUFQLEtBQWUsU0FBbkMsRUFBOEM7QUFDbkQsbUJBQVEsK0JBQVI7QUFDRCxXQUZNLE1BRUEsSUFBSW1DLFNBQVMsS0FBSyxJQUFkLElBQXNCLE9BQU9BLFNBQVAsS0FBcUIsUUFBL0MsRUFBeUQ7QUFDOUQsbUJBQVEsb0NBQVI7QUFDRCxXQUZNLE1BRUEsSUFBSUMsUUFBUSxLQUFLLElBQWIsSUFBcUIsT0FBT0EsUUFBUCxLQUFvQixRQUE3QyxFQUF1RDtBQUM1RCxtQkFBUSxtQ0FBUjtBQUNEO0FBQ0YsU0FuQkQsTUFtQk87QUFDTCxpQkFBUSxnQ0FBUjtBQUNEO0FBQ0Y7O0FBQ0QsVUFBSWYsUUFBUSxLQUFLLElBQWpCLEVBQXVCO0FBQ3JCLFlBQUlqQixtQkFBbUIsQ0FBQ2lCLFFBQUQsQ0FBdkIsRUFBbUM7QUFDakMsZ0JBQU07QUFDSlksWUFBQUEsTUFBTSxHQUFHLElBREw7QUFFSjNDLFlBQUFBLE1BQU0sR0FBRyxJQUZMO0FBR0orQyxZQUFBQSxPQUFPLEdBQUcsSUFITjtBQUlKQyxZQUFBQSxXQUFXLEdBQUcsSUFKVjtBQUtKQyxZQUFBQSxXQUFXLEdBQUcsSUFMVjtBQU1KQyxZQUFBQSxZQUFZLEdBQUc7QUFOWCxjQVFGbkIsUUFSSjtBQUFBLGdCQU9LYixXQVBMLDRCQVFJYSxRQVJKOztBQVNBLGNBQUk5QixNQUFNLENBQUNDLElBQVAsQ0FBWWdCLFdBQVosRUFBeUJ0QixNQUE3QixFQUFxQztBQUNuQyxtQkFBUSxzQ0FBcUNLLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZZ0IsV0FBWixDQUF5QixHQUF0RTtBQUNEOztBQUNELGNBQUl5QixNQUFNLEtBQUssSUFBWCxJQUFtQixPQUFPQSxNQUFQLEtBQWtCLFNBQXpDLEVBQW9EO0FBQ2xELG1CQUFRLHFDQUFSO0FBQ0Q7O0FBQ0QsY0FBSTNDLE1BQU0sS0FBSyxJQUFYLElBQW1CLE9BQU9BLE1BQVAsS0FBa0IsU0FBekMsRUFBb0Q7QUFDbEQsbUJBQVEscUNBQVI7QUFDRDs7QUFDRCxjQUFJK0MsT0FBTyxLQUFLLElBQVosSUFBb0IsT0FBT0EsT0FBUCxLQUFtQixTQUEzQyxFQUFzRDtBQUNwRCxtQkFBUSxzQ0FBUjtBQUNEOztBQUNELGNBQUlDLFdBQVcsS0FBSyxJQUFoQixJQUF3QixPQUFPQSxXQUFQLEtBQXVCLFFBQW5ELEVBQTZEO0FBQzNELG1CQUFRLHlDQUFSO0FBQ0Q7O0FBQ0QsY0FBSUMsV0FBVyxLQUFLLElBQWhCLElBQXdCLE9BQU9BLFdBQVAsS0FBdUIsUUFBbkQsRUFBNkQ7QUFDM0QsbUJBQVEseUNBQVI7QUFDRDs7QUFDRCxjQUFJQyxZQUFZLEtBQUssSUFBakIsSUFBeUIsT0FBT0EsWUFBUCxLQUF3QixRQUFyRCxFQUErRDtBQUM3RCxtQkFBUSwwQ0FBUjtBQUNEO0FBQ0YsU0EvQkQsTUErQk87QUFDTCxpQkFBUSxtQ0FBUjtBQUNEO0FBQ0Y7QUFDRjtBQUNGOztBQTFSMEI7O0FBNlI3QixNQUFNL0Isa0JBQWtCLEdBQUcsVUFBVWdDLEtBQVYsRUFBMEI7QUFDbkQsU0FBTy9CLEtBQUssQ0FBQ0MsT0FBTixDQUFjOEIsS0FBZCxJQUNILENBQUNBLEtBQUssQ0FBQ0MsSUFBTixDQUFXQyxDQUFDLElBQUksT0FBT0EsQ0FBUCxLQUFhLFFBQWIsSUFBeUJBLENBQUMsQ0FBQ3JCLElBQUYsR0FBU3BDLE1BQVQsR0FBa0IsQ0FBM0QsQ0FERSxHQUVILEtBRko7QUFHRCxDQUpEO0FBS0E7Ozs7Ozs7QUFLQSxNQUFNa0IsbUJBQW1CLEdBQUcsVUFBVXdDLEdBQVYsRUFBd0I7QUFDbEQsU0FDRSxPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUNBLENBQUNsQyxLQUFLLENBQUNDLE9BQU4sQ0FBY2lDLEdBQWQsQ0FERCxJQUVBQSxHQUFHLEtBQUssSUFGUixJQUdBQSxHQUFHLFlBQVlDLElBQWYsS0FBd0IsSUFIeEIsSUFJQUQsR0FBRyxZQUFZRSxPQUFmLEtBQTJCLElBTDdCO0FBT0QsQ0FSRDs7ZUF3RGU1RSxzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuLi8uLi9saWIvcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0IERhdGFiYXNlQ29udHJvbGxlciBmcm9tICcuL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgQ2FjaGVDb250cm9sbGVyIGZyb20gJy4vQ2FjaGVDb250cm9sbGVyJztcblxuY29uc3QgR3JhcGhRTENvbmZpZ0NsYXNzTmFtZSA9ICdfR3JhcGhRTENvbmZpZyc7XG5jb25zdCBHcmFwaFFMQ29uZmlnSWQgPSAnMSc7XG5jb25zdCBHcmFwaFFMQ29uZmlnS2V5ID0gJ2NvbmZpZyc7XG5cbmNsYXNzIFBhcnNlR3JhcGhRTENvbnRyb2xsZXIge1xuICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlcjtcbiAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXI7XG4gIGlzTW91bnRlZDogYm9vbGVhbjtcbiAgY29uZmlnQ2FjaGVLZXk6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwYXJhbXM6IHtcbiAgICAgIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyLFxuICAgICAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXIsXG4gICAgfSA9IHt9XG4gICkge1xuICAgIHRoaXMuZGF0YWJhc2VDb250cm9sbGVyID1cbiAgICAgIHBhcmFtcy5kYXRhYmFzZUNvbnRyb2xsZXIgfHxcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKFxuICAgICAgICBgUGFyc2VHcmFwaFFMQ29udHJvbGxlciByZXF1aXJlcyBhIFwiZGF0YWJhc2VDb250cm9sbGVyXCIgdG8gYmUgaW5zdGFudGlhdGVkLmBcbiAgICAgICk7XG4gICAgdGhpcy5jYWNoZUNvbnRyb2xsZXIgPSBwYXJhbXMuY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMuaXNNb3VudGVkID0gISFwYXJhbXMubW91bnRHcmFwaFFMO1xuICAgIHRoaXMuY29uZmlnQ2FjaGVLZXkgPSBHcmFwaFFMQ29uZmlnS2V5O1xuICB9XG5cbiAgYXN5bmMgZ2V0R3JhcGhRTENvbmZpZygpOiBQcm9taXNlPFBhcnNlR3JhcGhRTENvbmZpZz4ge1xuICAgIGlmICh0aGlzLmlzTW91bnRlZCkge1xuICAgICAgY29uc3QgX2NhY2hlZENvbmZpZyA9IGF3YWl0IHRoaXMuX2dldENhY2hlZEdyYXBoUUxDb25maWcoKTtcbiAgICAgIGlmIChfY2FjaGVkQ29uZmlnKSB7XG4gICAgICAgIHJldHVybiBfY2FjaGVkQ29uZmlnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci5maW5kKFxuICAgICAgR3JhcGhRTENvbmZpZ0NsYXNzTmFtZSxcbiAgICAgIHsgb2JqZWN0SWQ6IEdyYXBoUUxDb25maWdJZCB9LFxuICAgICAgeyBsaW1pdDogMSB9XG4gICAgKTtcblxuICAgIGxldCBncmFwaFFMQ29uZmlnO1xuICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBubyBjb25maWcgaW4gdGhlIGRhdGFiYXNlIC0gcmV0dXJuIGVtcHR5IGNvbmZpZy5cbiAgICAgIHJldHVybiB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ3JhcGhRTENvbmZpZyA9IHJlc3VsdHNbMF1bR3JhcGhRTENvbmZpZ0tleV07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNNb3VudGVkKSB7XG4gICAgICB0aGlzLl9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnKGdyYXBoUUxDb25maWcpO1xuICAgIH1cblxuICAgIHJldHVybiBncmFwaFFMQ29uZmlnO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlR3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpOiBQcm9taXNlPFBhcnNlR3JhcGhRTENvbmZpZz4ge1xuICAgIC8vIHRocm93cyBpZiBpbnZhbGlkXG4gICAgdGhpcy5fdmFsaWRhdGVHcmFwaFFMQ29uZmlnKFxuICAgICAgZ3JhcGhRTENvbmZpZyB8fCByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIGdyYXBoUUxDb25maWchJylcbiAgICApO1xuXG4gICAgLy8gVHJhbnNmb3JtIGluIGRvdCBub3RhdGlvbiB0byBtYWtlIHN1cmUgaXQgd29ya3NcbiAgICBjb25zdCB1cGRhdGUgPSBPYmplY3Qua2V5cyhncmFwaFFMQ29uZmlnKS5yZWR1Y2UoXG4gICAgICAoYWNjLCBrZXkpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBbR3JhcGhRTENvbmZpZ0tleV06IHtcbiAgICAgICAgICAgIC4uLmFjY1tHcmFwaFFMQ29uZmlnS2V5XSxcbiAgICAgICAgICAgIFtrZXldOiBncmFwaFFMQ29uZmlnW2tleV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICB7IFtHcmFwaFFMQ29uZmlnS2V5XToge30gfVxuICAgICk7XG5cbiAgICBhd2FpdCB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci51cGRhdGUoXG4gICAgICBHcmFwaFFMQ29uZmlnQ2xhc3NOYW1lLFxuICAgICAgeyBvYmplY3RJZDogR3JhcGhRTENvbmZpZ0lkIH0sXG4gICAgICB1cGRhdGUsXG4gICAgICB7IHVwc2VydDogdHJ1ZSB9XG4gICAgKTtcblxuICAgIGlmICh0aGlzLmlzTW91bnRlZCkge1xuICAgICAgdGhpcy5fcHV0Q2FjaGVkR3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByZXNwb25zZTogeyByZXN1bHQ6IHRydWUgfSB9O1xuICB9XG5cbiAgX2dldENhY2hlZEdyYXBoUUxDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVDb250cm9sbGVyLmdyYXBoUUwuZ2V0KHRoaXMuY29uZmlnQ2FjaGVLZXkpO1xuICB9XG5cbiAgX3B1dENhY2hlZEdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZzogUGFyc2VHcmFwaFFMQ29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVDb250cm9sbGVyLmdyYXBoUUwucHV0KHRoaXMuY29uZmlnQ2FjaGVLZXksIGdyYXBoUUxDb25maWcsIDYwMDAwKTtcbiAgfVxuXG4gIF92YWxpZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZzogP1BhcnNlR3JhcGhRTENvbmZpZyk6IHZvaWQge1xuICAgIGNvbnN0IGVycm9yTWVzc2FnZXM6IHN0cmluZyA9IFtdO1xuICAgIGlmICghZ3JhcGhRTENvbmZpZykge1xuICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKCdjYW5ub3QgYmUgdW5kZWZpbmVkLCBudWxsIG9yIGVtcHR5Jyk7XG4gICAgfSBlbHNlIGlmICghaXNWYWxpZFNpbXBsZU9iamVjdChncmFwaFFMQ29uZmlnKSkge1xuICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKCdtdXN0IGJlIGEgdmFsaWQgb2JqZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZW5hYmxlZEZvckNsYXNzZXMgPSBudWxsLFxuICAgICAgICBkaXNhYmxlZEZvckNsYXNzZXMgPSBudWxsLFxuICAgICAgICBjbGFzc0NvbmZpZ3MgPSBudWxsLFxuICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgfSA9IGdyYXBoUUxDb25maWc7XG5cbiAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgIGVycm9yTWVzc2FnZXMucHVzaChgZW5jb3VudGVyZWQgaW52YWxpZCBrZXlzOiBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWApO1xuICAgICAgfVxuICAgICAgaWYgKGVuYWJsZWRGb3JDbGFzc2VzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkoZW5hYmxlZEZvckNsYXNzZXMpKSB7XG4gICAgICAgIGVycm9yTWVzc2FnZXMucHVzaChgXCJlbmFibGVkRm9yQ2xhc3Nlc1wiIGlzIG5vdCBhIHZhbGlkIGFycmF5YCk7XG4gICAgICB9XG4gICAgICBpZiAoZGlzYWJsZWRGb3JDbGFzc2VzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkoZGlzYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYFwiZGlzYWJsZWRGb3JDbGFzc2VzXCIgaXMgbm90IGEgdmFsaWQgYXJyYXlgKTtcbiAgICAgIH1cbiAgICAgIGlmIChjbGFzc0NvbmZpZ3MgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2xhc3NDb25maWdzKSkge1xuICAgICAgICAgIGNsYXNzQ29uZmlncy5mb3JFYWNoKGNsYXNzQ29uZmlnID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IHRoaXMuX3ZhbGlkYXRlQ2xhc3NDb25maWcoY2xhc3NDb25maWcpO1xuICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goXG4gICAgICAgICAgICAgICAgYGNsYXNzQ29uZmlnOiR7Y2xhc3NDb25maWcuY2xhc3NOYW1lfSBpcyBpbnZhbGlkIGJlY2F1c2UgJHtlcnJvck1lc3NhZ2V9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVycm9yTWVzc2FnZXMucHVzaChgXCJjbGFzc0NvbmZpZ3NcIiBpcyBub3QgYSB2YWxpZCBhcnJheWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvck1lc3NhZ2VzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGdyYXBoUUxDb25maWc6ICR7ZXJyb3JNZXNzYWdlcy5qb2luKCc7ICcpfWApO1xuICAgIH1cbiAgfVxuXG4gIF92YWxpZGF0ZUNsYXNzQ29uZmlnKGNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWcpOiBzdHJpbmcgfCB2b2lkIHtcbiAgICBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3QoY2xhc3NDb25maWcpKSB7XG4gICAgICByZXR1cm4gJ2l0IG11c3QgYmUgYSB2YWxpZCBvYmplY3QnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgdHlwZSA9IG51bGwsIHF1ZXJ5ID0gbnVsbCwgbXV0YXRpb24gPSBudWxsLCAuLi5pbnZhbGlkS2V5cyB9ID0gY2xhc3NDb25maWc7XG4gICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gYFwiaW52YWxpZEtleXNcIiBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XSBzaG91bGQgbm90IGJlIHByZXNlbnRgO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjbGFzc05hbWUgIT09ICdzdHJpbmcnIHx8ICFjbGFzc05hbWUudHJpbSgpLmxlbmd0aCkge1xuICAgICAgICAvLyBUT0RPIGNvbnNpZGVyIGNoZWNraW5nIGNsYXNzIGV4aXN0cyBpbiBzY2hlbWE/XG4gICAgICAgIHJldHVybiBgXCJjbGFzc05hbWVcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nYDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlICE9PSBudWxsKSB7XG4gICAgICAgIGlmICghaXNWYWxpZFNpbXBsZU9iamVjdCh0eXBlKSkge1xuICAgICAgICAgIHJldHVybiBgXCJ0eXBlXCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGlucHV0RmllbGRzID0gbnVsbCxcbiAgICAgICAgICBvdXRwdXRGaWVsZHMgPSBudWxsLFxuICAgICAgICAgIGNvbnN0cmFpbnRGaWVsZHMgPSBudWxsLFxuICAgICAgICAgIHNvcnRGaWVsZHMgPSBudWxsLFxuICAgICAgICAgIC4uLmludmFsaWRLZXlzXG4gICAgICAgIH0gPSB0eXBlO1xuICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiBgXCJ0eXBlXCIgY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgIH0gZWxzZSBpZiAob3V0cHV0RmllbGRzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkob3V0cHV0RmllbGRzKSkge1xuICAgICAgICAgIHJldHVybiBgXCJvdXRwdXRGaWVsZHNcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgfSBlbHNlIGlmIChjb25zdHJhaW50RmllbGRzICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkoY29uc3RyYWludEZpZWxkcykpIHtcbiAgICAgICAgICByZXR1cm4gYFwiY29uc3RyYWludEZpZWxkc1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgYXJyYXlgO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzb3J0RmllbGRzICE9PSBudWxsKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydEZpZWxkcykpIHtcbiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICBzb3J0RmllbGRzLmV2ZXJ5KChzb3J0RmllbGQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNWYWxpZFNpbXBsZU9iamVjdChzb3J0RmllbGQpKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGEgdmFsaWQgb2JqZWN0YDtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBmaWVsZCwgYXNjLCBkZXNjLCAuLi5pbnZhbGlkS2V5cyB9ID0gc29ydEZpZWxkO1xuICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBgXCJzb3J0RmllbGRcIiBhdCBpbmRleCAke2luZGV4fSBjb250YWlucyBpbnZhbGlkIGtleXMsIFske09iamVjdC5rZXlzKFxuICAgICAgICAgICAgICAgICAgICBpbnZhbGlkS2V5c1xuICAgICAgICAgICAgICAgICAgKX1dYDtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmaWVsZCAhPT0gJ3N0cmluZycgfHwgZmllbGQudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBgXCJzb3J0RmllbGRcIiBhdCBpbmRleCAke2luZGV4fSBkaWQgbm90IHByb3ZpZGUgdGhlIFwiZmllbGRcIiBhcyBhIHN0cmluZ2A7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFzYyAhPT0gJ2Jvb2xlYW4nIHx8IHR5cGVvZiBkZXNjICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gZGlkIG5vdCBwcm92aWRlIFwiYXNjXCIgb3IgXCJkZXNjXCIgYXMgYm9vbGVhbnNgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoZXJyb3JNZXNzYWdlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJzb3J0RmllbGRzXCIgbXVzdCBiZSBhIHZhbGlkIGFycmF5LmA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpbnB1dEZpZWxkcyAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChpc1ZhbGlkU2ltcGxlT2JqZWN0KGlucHV0RmllbGRzKSkge1xuICAgICAgICAgICAgY29uc3QgeyBjcmVhdGUgPSBudWxsLCB1cGRhdGUgPSBudWxsLCAuLi5pbnZhbGlkS2V5cyB9ID0gaW5wdXRGaWVsZHM7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICByZXR1cm4gYFwiaW5wdXRGaWVsZHNcIiBjb250YWlucyBpbnZhbGlkIGtleXM6IFske09iamVjdC5rZXlzKGludmFsaWRLZXlzKX1dYDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGUgIT09IG51bGwgJiYgIWlzVmFsaWRTdHJpbmdBcnJheSh1cGRhdGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzLnVwZGF0ZVwiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgYXJyYXlgO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNyZWF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZFN0cmluZ0FycmF5KGNyZWF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgXCJpbnB1dEZpZWxkcy5jcmVhdGVcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgICAgICAgaWYgKCFjcmVhdGUuaW5jbHVkZXMoJ3VzZXJuYW1lJykgfHwgIWNyZWF0ZS5pbmNsdWRlcygncGFzc3dvcmQnKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFwiaW5wdXRGaWVsZHMuY3JlYXRlXCIgbXVzdCBpbmNsdWRlIHJlcXVpcmVkIGZpZWxkcywgdXNlcm5hbWUgYW5kIHBhc3N3b3JkYDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzXCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocXVlcnkgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGlzVmFsaWRTaW1wbGVPYmplY3QocXVlcnkpKSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgZmluZCA9IG51bGwsXG4gICAgICAgICAgICBnZXQgPSBudWxsLFxuICAgICAgICAgICAgZmluZEFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIGdldEFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIC4uLmludmFsaWRLZXlzXG4gICAgICAgICAgfSA9IHF1ZXJ5O1xuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnlcIiBjb250YWlucyBpbnZhbGlkIGtleXMsIFske09iamVjdC5rZXlzKGludmFsaWRLZXlzKX1dYDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGZpbmQgIT09IG51bGwgJiYgdHlwZW9mIGZpbmQgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmZpbmRcIiBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICAgICAgfSBlbHNlIGlmIChnZXQgIT09IG51bGwgJiYgdHlwZW9mIGdldCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnkuZ2V0XCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZmluZEFsaWFzICE9PSBudWxsICYmIHR5cGVvZiBmaW5kQWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnkuZmluZEFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfSBlbHNlIGlmIChnZXRBbGlhcyAhPT0gbnVsbCAmJiB0eXBlb2YgZ2V0QWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwicXVlcnkuZ2V0QWxpYXNcIiBtdXN0IGJlIGEgc3RyaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5XCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtdXRhdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNWYWxpZFNpbXBsZU9iamVjdChtdXRhdGlvbikpIHtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBjcmVhdGUgPSBudWxsLFxuICAgICAgICAgICAgdXBkYXRlID0gbnVsbCxcbiAgICAgICAgICAgIGRlc3Ryb3kgPSBudWxsLFxuICAgICAgICAgICAgY3JlYXRlQWxpYXMgPSBudWxsLFxuICAgICAgICAgICAgdXBkYXRlQWxpYXMgPSBudWxsLFxuICAgICAgICAgICAgZGVzdHJveUFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIC4uLmludmFsaWRLZXlzXG4gICAgICAgICAgfSA9IG11dGF0aW9uO1xuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhpbnZhbGlkS2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb25cIiBjb250YWlucyBpbnZhbGlkIGtleXMsIFske09iamVjdC5rZXlzKGludmFsaWRLZXlzKX1dYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNyZWF0ZSAhPT0gbnVsbCAmJiB0eXBlb2YgY3JlYXRlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi5jcmVhdGVcIiBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh1cGRhdGUgIT09IG51bGwgJiYgdHlwZW9mIHVwZGF0ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24udXBkYXRlXCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZGVzdHJveSAhPT0gbnVsbCAmJiB0eXBlb2YgZGVzdHJveSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uZGVzdHJveVwiIG11c3QgYmUgYSBib29sZWFuYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNyZWF0ZUFsaWFzICE9PSBudWxsICYmIHR5cGVvZiBjcmVhdGVBbGlhcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi5jcmVhdGVBbGlhc1wiIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXBkYXRlQWxpYXMgIT09IG51bGwgJiYgdHlwZW9mIHVwZGF0ZUFsaWFzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uLnVwZGF0ZUFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkZXN0cm95QWxpYXMgIT09IG51bGwgJiYgdHlwZW9mIGRlc3Ryb3lBbGlhcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi5kZXN0cm95QWxpYXNcIiBtdXN0IGJlIGEgc3RyaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uXCIgbXVzdCBiZSBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuY29uc3QgaXNWYWxpZFN0cmluZ0FycmF5ID0gZnVuY3Rpb24gKGFycmF5KTogYm9vbGVhbiB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFycmF5KVxuICAgID8gIWFycmF5LnNvbWUocyA9PiB0eXBlb2YgcyAhPT0gJ3N0cmluZycgfHwgcy50cmltKCkubGVuZ3RoIDwgMSlcbiAgICA6IGZhbHNlO1xufTtcbi8qKlxuICogRW5zdXJlcyB0aGUgb2JqIGlzIGEgc2ltcGxlIEpTT04ve31cbiAqIG9iamVjdCwgaS5lLiBub3QgYW4gYXJyYXksIG51bGwsIGRhdGVcbiAqIGV0Yy5cbiAqL1xuY29uc3QgaXNWYWxpZFNpbXBsZU9iamVjdCA9IGZ1bmN0aW9uIChvYmopOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJlxuICAgICFBcnJheS5pc0FycmF5KG9iaikgJiZcbiAgICBvYmogIT09IG51bGwgJiZcbiAgICBvYmogaW5zdGFuY2VvZiBEYXRlICE9PSB0cnVlICYmXG4gICAgb2JqIGluc3RhbmNlb2YgUHJvbWlzZSAhPT0gdHJ1ZVxuICApO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBQYXJzZUdyYXBoUUxDb25maWcge1xuICBlbmFibGVkRm9yQ2xhc3Nlcz86IHN0cmluZ1tdO1xuICBkaXNhYmxlZEZvckNsYXNzZXM/OiBzdHJpbmdbXTtcbiAgY2xhc3NDb25maWdzPzogUGFyc2VHcmFwaFFMQ2xhc3NDb25maWdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXJzZUdyYXBoUUxDbGFzc0NvbmZpZyB7XG4gIGNsYXNzTmFtZTogc3RyaW5nO1xuICAvKiBUaGUgYHR5cGVgIG9iamVjdCBjb250YWlucyBvcHRpb25zIGZvciBob3cgdGhlIGNsYXNzIHR5cGVzIGFyZSBnZW5lcmF0ZWQgKi9cbiAgdHlwZTogP3tcbiAgICAvKiBGaWVsZHMgdGhhdCBhcmUgYWxsb3dlZCB3aGVuIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGFuIG9iamVjdC4gKi9cbiAgICBpbnB1dEZpZWxkczogP3tcbiAgICAgIC8qIExlYXZlIGJsYW5rIHRvIGFsbG93IGFsbCBhdmFpbGFibGUgZmllbGRzIGluIHRoZSBzY2hlbWEuICovXG4gICAgICBjcmVhdGU/OiBzdHJpbmdbXSxcbiAgICAgIHVwZGF0ZT86IHN0cmluZ1tdLFxuICAgIH0sXG4gICAgLyogRmllbGRzIG9uIHRoZSBlZGdlcyB0aGF0IGNhbiBiZSByZXNvbHZlZCBmcm9tIGEgcXVlcnksIGkuZS4gdGhlIFJlc3VsdCBUeXBlLiAqL1xuICAgIG91dHB1dEZpZWxkczogPyhzdHJpbmdbXSksXG4gICAgLyogRmllbGRzIGJ5IHdoaWNoIGEgcXVlcnkgY2FuIGJlIGZpbHRlcmVkLCBpLmUuIHRoZSBgd2hlcmVgIG9iamVjdC4gKi9cbiAgICBjb25zdHJhaW50RmllbGRzOiA/KHN0cmluZ1tdKSxcbiAgICAvKiBGaWVsZHMgYnkgd2hpY2ggYSBxdWVyeSBjYW4gYmUgc29ydGVkOyAqL1xuICAgIHNvcnRGaWVsZHM6ID8oe1xuICAgICAgZmllbGQ6IHN0cmluZyxcbiAgICAgIGFzYzogYm9vbGVhbixcbiAgICAgIGRlc2M6IGJvb2xlYW4sXG4gICAgfVtdKSxcbiAgfTtcbiAgLyogVGhlIGBxdWVyeWAgb2JqZWN0IGNvbnRhaW5zIG9wdGlvbnMgZm9yIHdoaWNoIGNsYXNzIHF1ZXJpZXMgYXJlIGdlbmVyYXRlZCAqL1xuICBxdWVyeTogP3tcbiAgICBnZXQ6ID9ib29sZWFuLFxuICAgIGZpbmQ6ID9ib29sZWFuLFxuICAgIGZpbmRBbGlhczogP1N0cmluZyxcbiAgICBnZXRBbGlhczogP1N0cmluZyxcbiAgfTtcbiAgLyogVGhlIGBtdXRhdGlvbmAgb2JqZWN0IGNvbnRhaW5zIG9wdGlvbnMgZm9yIHdoaWNoIGNsYXNzIG11dGF0aW9ucyBhcmUgZ2VuZXJhdGVkICovXG4gIG11dGF0aW9uOiA/e1xuICAgIGNyZWF0ZTogP2Jvb2xlYW4sXG4gICAgdXBkYXRlOiA/Ym9vbGVhbixcbiAgICAvLyBkZWxldGUgaXMgYSByZXNlcnZlZCBrZXkgd29yZCBpbiBqc1xuICAgIGRlc3Ryb3k6ID9ib29sZWFuLFxuICAgIGNyZWF0ZUFsaWFzOiA/U3RyaW5nLFxuICAgIHVwZGF0ZUFsaWFzOiA/U3RyaW5nLFxuICAgIGRlc3Ryb3lBbGlhczogP1N0cmluZyxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VHcmFwaFFMQ29udHJvbGxlcjtcbmV4cG9ydCB7IEdyYXBoUUxDb25maWdDbGFzc05hbWUsIEdyYXBoUUxDb25maWdJZCwgR3JhcGhRTENvbmZpZ0tleSB9O1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/PushController.js b/lib/Controllers/PushController.js deleted file mode 100644 index dd44dcefc9..0000000000 --- a/lib/Controllers/PushController.js +++ /dev/null @@ -1,257 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushController = void 0; - -var _node = require("parse/node"); - -var _RestQuery = _interopRequireDefault(require("../RestQuery")); - -var _RestWrite = _interopRequireDefault(require("../RestWrite")); - -var _Auth = require("../Auth"); - -var _StatusHandler = require("../StatusHandler"); - -var _utils = require("../Push/utils"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class PushController { - sendPush(body = {}, where = {}, config, auth, onPushStatusSaved = () => {}, now = new Date()) { - if (!config.hasPushSupport) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Missing push configuration'); - } // Replace the expiration_time and push_time with a valid Unix epoch milliseconds time - - - body.expiration_time = PushController.getExpirationTime(body); - body.expiration_interval = PushController.getExpirationInterval(body); - - if (body.expiration_time && body.expiration_interval) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Both expiration_time and expiration_interval cannot be set'); - } // Immediate push - - - if (body.expiration_interval && !Object.prototype.hasOwnProperty.call(body, 'push_time')) { - const ttlMs = body.expiration_interval * 1000; - body.expiration_time = new Date(now.valueOf() + ttlMs).valueOf(); - } - - const pushTime = PushController.getPushTime(body); - - if (pushTime && pushTime.date !== 'undefined') { - body['push_time'] = PushController.formatPushTime(pushTime); - } // TODO: If the req can pass the checking, we return immediately instead of waiting - // pushes to be sent. We probably change this behaviour in the future. - - - let badgeUpdate = () => { - return Promise.resolve(); - }; - - if (body.data && body.data.badge) { - const badge = body.data.badge; - let restUpdate = {}; - - if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { - restUpdate = { - badge: { - __op: 'Increment', - amount: 1 - } - }; - } else if (typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount)) { - restUpdate = { - badge: { - __op: 'Increment', - amount: badge.amount - } - }; - } else if (Number(badge)) { - restUpdate = { - badge: badge - }; - } else { - throw "Invalid value for badge, expected number or 'Increment' or {increment: number}"; - } // Force filtering on only valid device tokens - - - const updateWhere = (0, _utils.applyDeviceTokenExists)(where); - - badgeUpdate = () => { - // Build a real RestQuery so we can use it in RestWrite - const restQuery = new _RestQuery.default(config, (0, _Auth.master)(config), '_Installation', updateWhere); - return restQuery.buildRestWhere().then(() => { - const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Installation', restQuery.restWhere, restUpdate); - write.runOptions.many = true; - return write.execute(); - }); - }; - } - - const pushStatus = (0, _StatusHandler.pushStatusHandler)(config); - return Promise.resolve().then(() => { - return pushStatus.setInitial(body, where); - }).then(() => { - onPushStatusSaved(pushStatus.objectId); - return badgeUpdate(); - }).then(() => { - // Update audience lastUsed and timesUsed - if (body.audience_id) { - const audienceId = body.audience_id; - var updateAudience = { - lastUsed: { - __type: 'Date', - iso: new Date().toISOString() - }, - timesUsed: { - __op: 'Increment', - amount: 1 - } - }; - const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Audience', { - objectId: audienceId - }, updateAudience); - write.execute(); - } // Don't wait for the audience update promise to resolve. - - - return Promise.resolve(); - }).then(() => { - if (Object.prototype.hasOwnProperty.call(body, 'push_time') && config.hasPushScheduledSupport) { - return Promise.resolve(); - } - - return config.pushControllerQueue.enqueue(body, where, config, auth, pushStatus); - }).catch(err => { - return pushStatus.fail(err).then(() => { - throw err; - }); - }); - } - /** - * Get expiration time from the request body. - * @param {Object} request A request object - * @returns {Number|undefined} The expiration time if it exists in the request - */ - - - static getExpirationTime(body = {}) { - var hasExpirationTime = Object.prototype.hasOwnProperty.call(body, 'expiration_time'); - - if (!hasExpirationTime) { - return; - } - - var expirationTimeParam = body['expiration_time']; - var expirationTime; - - if (typeof expirationTimeParam === 'number') { - expirationTime = new Date(expirationTimeParam * 1000); - } else if (typeof expirationTimeParam === 'string') { - expirationTime = new Date(expirationTimeParam); - } else { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); - } // Check expirationTime is valid or not, if it is not valid, expirationTime is NaN - - - if (!isFinite(expirationTime)) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); - } - - return expirationTime.valueOf(); - } - - static getExpirationInterval(body = {}) { - const hasExpirationInterval = Object.prototype.hasOwnProperty.call(body, 'expiration_interval'); - - if (!hasExpirationInterval) { - return; - } - - var expirationIntervalParam = body['expiration_interval']; - - if (typeof expirationIntervalParam !== 'number' || expirationIntervalParam <= 0) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, `expiration_interval must be a number greater than 0`); - } - - return expirationIntervalParam; - } - /** - * Get push time from the request body. - * @param {Object} request A request object - * @returns {Number|undefined} The push time if it exists in the request - */ - - - static getPushTime(body = {}) { - var hasPushTime = Object.prototype.hasOwnProperty.call(body, 'push_time'); - - if (!hasPushTime) { - return; - } - - var pushTimeParam = body['push_time']; - var date; - var isLocalTime = true; - - if (typeof pushTimeParam === 'number') { - date = new Date(pushTimeParam * 1000); - } else if (typeof pushTimeParam === 'string') { - isLocalTime = !PushController.pushTimeHasTimezoneComponent(pushTimeParam); - date = new Date(pushTimeParam); - } else { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); - } // Check pushTime is valid or not, if it is not valid, pushTime is NaN - - - if (!isFinite(date)) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); - } - - return { - date, - isLocalTime - }; - } - /** - * Checks if a ISO8601 formatted date contains a timezone component - * @param pushTimeParam {string} - * @returns {boolean} - */ - - - static pushTimeHasTimezoneComponent(pushTimeParam) { - const offsetPattern = /(.+)([+-])\d\d:\d\d$/; - return pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || offsetPattern.test(pushTimeParam) // 2007-04-05T12:30Z - ; // 2007-04-05T12:30.000+02:00, 2007-04-05T12:30.000-02:00 - } - /** - * Converts a date to ISO format in UTC time and strips the timezone if `isLocalTime` is true - * @param date {Date} - * @param isLocalTime {boolean} - * @returns {string} - */ - - - static formatPushTime({ - date, - isLocalTime - }) { - if (isLocalTime) { - // Strip 'Z' - const isoString = date.toISOString(); - return isoString.substring(0, isoString.indexOf('Z')); - } - - return date.toISOString(); - } - -} - -exports.PushController = PushController; -var _default = PushController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QdXNoQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJQdXNoQ29udHJvbGxlciIsInNlbmRQdXNoIiwiYm9keSIsIndoZXJlIiwiY29uZmlnIiwiYXV0aCIsIm9uUHVzaFN0YXR1c1NhdmVkIiwibm93IiwiRGF0ZSIsImhhc1B1c2hTdXBwb3J0IiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGlyYXRpb25fdGltZSIsImdldEV4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsImdldEV4cGlyYXRpb25JbnRlcnZhbCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR0bE1zIiwidmFsdWVPZiIsInB1c2hUaW1lIiwiZ2V0UHVzaFRpbWUiLCJkYXRlIiwiZm9ybWF0UHVzaFRpbWUiLCJiYWRnZVVwZGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZGF0YSIsImJhZGdlIiwicmVzdFVwZGF0ZSIsInRvTG93ZXJDYXNlIiwiX19vcCIsImFtb3VudCIsIk51bWJlciIsInVwZGF0ZVdoZXJlIiwicmVzdFF1ZXJ5IiwiUmVzdFF1ZXJ5IiwiYnVpbGRSZXN0V2hlcmUiLCJ0aGVuIiwid3JpdGUiLCJSZXN0V3JpdGUiLCJyZXN0V2hlcmUiLCJydW5PcHRpb25zIiwibWFueSIsImV4ZWN1dGUiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsIm9iamVjdElkIiwiYXVkaWVuY2VfaWQiLCJhdWRpZW5jZUlkIiwidXBkYXRlQXVkaWVuY2UiLCJsYXN0VXNlZCIsIl9fdHlwZSIsImlzbyIsInRvSVNPU3RyaW5nIiwidGltZXNVc2VkIiwiaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwiZW5xdWV1ZSIsImNhdGNoIiwiZXJyIiwiZmFpbCIsImhhc0V4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvblRpbWVQYXJhbSIsImV4cGlyYXRpb25UaW1lIiwiaXNGaW5pdGUiLCJoYXNFeHBpcmF0aW9uSW50ZXJ2YWwiLCJleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSIsImhhc1B1c2hUaW1lIiwicHVzaFRpbWVQYXJhbSIsImlzTG9jYWxUaW1lIiwicHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudCIsIm9mZnNldFBhdHRlcm4iLCJpbmRleE9mIiwibGVuZ3RoIiwidGVzdCIsImlzb1N0cmluZyIsInN1YnN0cmluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixDQUFxQjtBQUMxQkMsRUFBQUEsUUFBUSxDQUFDQyxJQUFJLEdBQUcsRUFBUixFQUFZQyxLQUFLLEdBQUcsRUFBcEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQ0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFFLENBQWxFLEVBQW9FQyxHQUFHLEdBQUcsSUFBSUMsSUFBSixFQUExRSxFQUFzRjtBQUM1RixRQUFJLENBQUNKLE1BQU0sQ0FBQ0ssY0FBWixFQUE0QjtBQUMxQixZQUFNLElBQUlDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0QsS0FIMkYsQ0FLNUY7OztBQUNBVixJQUFBQSxJQUFJLENBQUNXLGVBQUwsR0FBdUJiLGNBQWMsQ0FBQ2MsaUJBQWYsQ0FBaUNaLElBQWpDLENBQXZCO0FBQ0FBLElBQUFBLElBQUksQ0FBQ2EsbUJBQUwsR0FBMkJmLGNBQWMsQ0FBQ2dCLHFCQUFmLENBQXFDZCxJQUFyQyxDQUEzQjs7QUFDQSxRQUFJQSxJQUFJLENBQUNXLGVBQUwsSUFBd0JYLElBQUksQ0FBQ2EsbUJBQWpDLEVBQXNEO0FBQ3BELFlBQU0sSUFBSUwsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUosNERBRkksQ0FBTjtBQUlELEtBYjJGLENBZTVGOzs7QUFDQSxRQUFJVixJ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QUFDSjtBQUVEOzs7Ozs7OztBQU1BLFNBQU85QyxjQUFQLENBQXNCO0FBQUVELElBQUFBLElBQUY7QUFBUWdELElBQUFBO0FBQVIsR0FBdEIsRUFBbUY7QUFDakYsUUFBSUEsV0FBSixFQUFpQjtBQUNmO0FBQ0EsWUFBTU0sU0FBUyxHQUFHdEQsSUFBSSxDQUFDZ0MsV0FBTCxFQUFsQjtBQUNBLGFBQU9zQixTQUFTLENBQUNDLFNBQVYsQ0FBb0IsQ0FBcEIsRUFBdUJELFNBQVMsQ0FBQ0gsT0FBVixDQUFrQixHQUFsQixDQUF2QixDQUFQO0FBQ0Q7O0FBQ0QsV0FBT25ELElBQUksQ0FBQ2dDLFdBQUwsRUFBUDtBQUNEOztBQW5PeUI7OztlQXNPYnpELGMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFJlc3RRdWVyeSBmcm9tICcuLi9SZXN0UXVlcnknO1xuaW1wb3J0IFJlc3RXcml0ZSBmcm9tICcuLi9SZXN0V3JpdGUnO1xuaW1wb3J0IHsgbWFzdGVyIH0gZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgeyBwdXNoU3RhdHVzSGFuZGxlciB9IGZyb20gJy4uL1N0YXR1c0hhbmRsZXInO1xuaW1wb3J0IHsgYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyB9IGZyb20gJy4uL1B1c2gvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgUHVzaENvbnRyb2xsZXIge1xuICBzZW5kUHVzaChib2R5ID0ge30sIHdoZXJlID0ge30sIGNvbmZpZywgYXV0aCwgb25QdXNoU3RhdHVzU2F2ZWQgPSAoKSA9PiB7fSwgbm93ID0gbmV3IERhdGUoKSkge1xuICAgIGlmICghY29uZmlnLmhhc1B1c2hTdXBwb3J0KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTWlzc2luZyBwdXNoIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBleHBpcmF0aW9uX3RpbWUgYW5kIHB1c2hfdGltZSB3aXRoIGEgdmFsaWQgVW5peCBlcG9jaCBtaWxsaXNlY29uZHMgdGltZVxuICAgIGJvZHkuZXhwaXJhdGlvbl90aW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvblRpbWUoYm9keSk7XG4gICAgYm9keS5leHBpcmF0aW9uX2ludGVydmFsID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkpO1xuICAgIGlmIChib2R5LmV4cGlyYXRpb25fdGltZSAmJiBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnQm90aCBleHBpcmF0aW9uX3RpbWUgYW5kIGV4cGlyYXRpb25faW50ZXJ2YWwgY2Fubm90IGJlIHNldCdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gSW1tZWRpYXRlIHB1c2hcbiAgICBpZiAoYm9keS5leHBpcmF0aW9uX2ludGVydmFsICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpKSB7XG4gICAgICBjb25zdCB0dGxNcyA9IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCAqIDEwMDA7XG4gICAgICBib2R5LmV4cGlyYXRpb25fdGltZSA9IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyB0dGxNcykudmFsdWVPZigpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1c2hUaW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0UHVzaFRpbWUoYm9keSk7XG4gICAgaWYgKHB1c2hUaW1lICYmIHB1c2hUaW1lLmRhdGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5WydwdXNoX3RpbWUnXSA9IFB1c2hDb250cm9sbGVyLmZvcm1hdFB1c2hUaW1lKHB1c2hUaW1lKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBJZiB0aGUgcmVxIGNhbiBwYXNzIHRoZSBjaGVja2luZywgd2UgcmV0dXJuIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZ1xuICAgIC8vIHB1c2hlcyB0byBiZSBzZW50LiBXZSBwcm9iYWJseSBjaGFuZ2UgdGhpcyBiZWhhdmlvdXIgaW4gdGhlIGZ1dHVyZS5cbiAgICBsZXQgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfTtcblxuICAgIGlmIChib2R5LmRhdGEgJiYgYm9keS5kYXRhLmJhZGdlKSB7XG4gICAgICBjb25zdCBiYWRnZSA9IGJvZHkuZGF0YS5iYWRnZTtcbiAgICAgIGxldCByZXN0VXBkYXRlID0ge307XG4gICAgICBpZiAodHlwZW9mIGJhZGdlID09ICdzdHJpbmcnICYmIGJhZGdlLnRvTG93ZXJDYXNlKCkgPT09ICdpbmNyZW1lbnQnKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IDEgfSB9O1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIGJhZGdlID09ICdvYmplY3QnICYmXG4gICAgICAgIHR5cGVvZiBiYWRnZS5fX29wID09ICdzdHJpbmcnICYmXG4gICAgICAgIGJhZGdlLl9fb3AudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50JyAmJlxuICAgICAgICBOdW1iZXIoYmFkZ2UuYW1vdW50KVxuICAgICAgKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGJhZGdlLmFtb3VudCB9IH07XG4gICAgICB9IGVsc2UgaWYgKE51bWJlcihiYWRnZSkpIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IGJhZGdlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBcIkludmFsaWQgdmFsdWUgZm9yIGJhZGdlLCBleHBlY3RlZCBudW1iZXIgb3IgJ0luY3JlbWVudCcgb3Ige2luY3JlbWVudDogbnVtYmVyfVwiO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3JjZSBmaWx0ZXJpbmcgb24gb25seSB2YWxpZCBkZXZpY2UgdG9rZW5zXG4gICAgICBjb25zdCB1cGRhdGVXaGVyZSA9IGFwcGx5RGV2aWNlVG9rZW5FeGlzdHMod2hlcmUpO1xuICAgICAgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICAgIC8vIEJ1aWxkIGEgcmVhbCBSZXN0UXVlcnkgc28gd2UgY2FuIHVzZSBpdCBpbiBSZXN0V3JpdGVcbiAgICAgICAgY29uc3QgcmVzdFF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShjb25maWcsIG1hc3Rlcihjb25maWcpLCAnX0luc3RhbGxhdGlvbicsIHVwZGF0ZVdoZXJlKTtcbiAgICAgICAgcmV0dXJuIHJlc3RRdWVyeS5idWlsZFJlc3RXaGVyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdyaXRlID0gbmV3IFJlc3RXcml0ZShcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIG1hc3Rlcihjb25maWcpLFxuICAgICAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICAgICAgcmVzdFF1ZXJ5LnJlc3RXaGVyZSxcbiAgICAgICAgICAgIHJlc3RVcGRhdGVcbiAgICAgICAgICApO1xuICAgICAgICAgIHdyaXRlLnJ1bk9wdGlvbnMubWFueSA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBwdXNoU3RhdHVzID0gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuc2V0SW5pdGlhbChib2R5LCB3aGVyZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBvblB1c2hTdGF0dXNTYXZlZChwdXNoU3RhdHVzLm9iamVjdElkKTtcbiAgICAgICAgcmV0dXJuIGJhZGdlVXBkYXRlKCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBVcGRhdGUgYXVkaWVuY2UgbGFzdFVzZWQgYW5kIHRpbWVzVXNlZFxuICAgICAgICBpZiAoYm9keS5hdWRpZW5jZV9pZCkge1xuICAgICAgICAgIGNvbnN0IGF1ZGllbmNlSWQgPSBib2R5LmF1ZGllbmNlX2lkO1xuXG4gICAgICAgICAgdmFyIHVwZGF0ZUF1ZGllbmNlID0ge1xuICAgICAgICAgICAgbGFzdFVzZWQ6IHsgX190eXBlOiAnRGF0ZScsIGlzbzogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0sXG4gICAgICAgICAgICB0aW1lc1VzZWQ6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3Qgd3JpdGUgPSBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICAgICAnX0F1ZGllbmNlJyxcbiAgICAgICAgICAgIHsgb2JqZWN0SWQ6IGF1ZGllbmNlSWQgfSxcbiAgICAgICAgICAgIHVwZGF0ZUF1ZGllbmNlXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3cml0ZS5leGVjdXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRG9uJ3Qgd2FpdCBmb3IgdGhlIGF1ZGllbmNlIHVwZGF0ZSBwcm9taXNlIHRvIHJlc29sdmUuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpICYmXG4gICAgICAgICAgY29uZmlnLmhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0XG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uZmlnLnB1c2hDb250cm9sbGVyUXVldWUuZW5xdWV1ZShib2R5LCB3aGVyZSwgY29uZmlnLCBhdXRoLCBwdXNoU3RhdHVzKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuZmFpbChlcnIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwaXJhdGlvbiB0aW1lIGZyb20gdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgQSByZXF1ZXN0IG9iamVjdFxuICAgKiBAcmV0dXJucyB7TnVtYmVyfHVuZGVmaW5lZH0gVGhlIGV4cGlyYXRpb24gdGltZSBpZiBpdCBleGlzdHMgaW4gdGhlIHJlcXVlc3RcbiAgICovXG4gIHN0YXRpYyBnZXRFeHBpcmF0aW9uVGltZShib2R5ID0ge30pIHtcbiAgICB2YXIgaGFzRXhwaXJhdGlvblRpbWUgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ2V4cGlyYXRpb25fdGltZScpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvblRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGV4cGlyYXRpb25UaW1lUGFyYW0gPSBib2R5WydleHBpcmF0aW9uX3RpbWUnXTtcbiAgICB2YXIgZXhwaXJhdGlvblRpbWU7XG4gICAgaWYgKHR5cGVvZiBleHBpcmF0aW9uVGltZVBhcmFtID09PSAnbnVtYmVyJykge1xuICAgICAgZXhwaXJhdGlvblRpbWUgPSBuZXcgRGF0ZShleHBpcmF0aW9uVGltZVBhcmFtICogMTAwMCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwaXJhdGlvblRpbWVQYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGV4cGlyYXRpb25UaW1lID0gbmV3IERhdGUoZXhwaXJhdGlvblRpbWVQYXJhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydleHBpcmF0aW9uX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgZXhwaXJhdGlvblRpbWUgaXMgdmFsaWQgb3Igbm90LCBpZiBpdCBpcyBub3QgdmFsaWQsIGV4cGlyYXRpb25UaW1lIGlzIE5hTlxuICAgIGlmICghaXNGaW5pdGUoZXhwaXJhdGlvblRpbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsnZXhwaXJhdGlvbl90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBleHBpcmF0aW9uVGltZS52YWx1ZU9mKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkgPSB7fSkge1xuICAgIGNvbnN0IGhhc0V4cGlyYXRpb25JbnRlcnZhbCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAnZXhwaXJhdGlvbl9pbnRlcnZhbCcpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvbkludGVydmFsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtID0gYm9keVsnZXhwaXJhdGlvbl9pbnRlcnZhbCddO1xuICAgIGlmICh0eXBlb2YgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gIT09ICdudW1iZXInIHx8IGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBgZXhwaXJhdGlvbl9pbnRlcnZhbCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwdXNoIHRpbWUgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtOdW1iZXJ8dW5kZWZpbmVkfSBUaGUgcHVzaCB0aW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgcmVxdWVzdFxuICAgKi9cbiAgc3RhdGljIGdldFB1c2hUaW1lKGJvZHkgPSB7fSkge1xuICAgIHZhciBoYXNQdXNoVGltZSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJyk7XG4gICAgaWYgKCFoYXNQdXNoVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcHVzaFRpbWVQYXJhbSA9IGJvZHlbJ3B1c2hfdGltZSddO1xuICAgIHZhciBkYXRlO1xuICAgIHZhciBpc0xvY2FsVGltZSA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdudW1iZXInKSB7XG4gICAgICBkYXRlID0gbmV3IERhdGUocHVzaFRpbWVQYXJhbSAqIDEwMDApO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBpc0xvY2FsVGltZSA9ICFQdXNoQ29udHJvbGxlci5wdXNoVGltZUhhc1RpbWV6b25lQ29tcG9uZW50KHB1c2hUaW1lUGFyYW0pO1xuICAgICAgZGF0ZSA9IG5ldyBEYXRlKHB1c2hUaW1lUGFyYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENoZWNrIHB1c2hUaW1lIGlzIHZhbGlkIG9yIG5vdCwgaWYgaXQgaXMgbm90IHZhbGlkLCBwdXNoVGltZSBpcyBOYU5cbiAgICBpZiAoIWlzRmluaXRlKGRhdGUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGUsXG4gICAgICBpc0xvY2FsVGltZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhIElTTzg2MDEgZm9ybWF0dGVkIGRhdGUgY29udGFpbnMgYSB0aW1lem9uZSBjb21wb25lbnRcbiAgICogQHBhcmFtIHB1c2hUaW1lUGFyYW0ge3N0cmluZ31cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgcHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudChwdXNoVGltZVBhcmFtOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBvZmZzZXRQYXR0ZXJuID0gLyguKykoWystXSlcXGRcXGQ6XFxkXFxkJC87XG4gICAgcmV0dXJuIChcbiAgICAgIHB1c2hUaW1lUGFyYW0uaW5kZXhPZignWicpID09PSBwdXNoVGltZVBhcmFtLmxlbmd0aCAtIDEgfHwgb2Zmc2V0UGF0dGVybi50ZXN0KHB1c2hUaW1lUGFyYW0pIC8vIDIwMDctMDQtMDVUMTI6MzBaXG4gICAgKTsgLy8gMjAwNy0wNC0wNVQxMjozMC4wMDArMDI6MDAsIDIwMDctMDQtMDVUMTI6MzAuMDAwLTAyOjAwXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBkYXRlIHRvIElTTyBmb3JtYXQgaW4gVVRDIHRpbWUgYW5kIHN0cmlwcyB0aGUgdGltZXpvbmUgaWYgYGlzTG9jYWxUaW1lYCBpcyB0cnVlXG4gICAqIEBwYXJhbSBkYXRlIHtEYXRlfVxuICAgKiBAcGFyYW0gaXNMb2NhbFRpbWUge2Jvb2xlYW59XG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBzdGF0aWMgZm9ybWF0UHVzaFRpbWUoeyBkYXRlLCBpc0xvY2FsVGltZSB9OiB7IGRhdGU6IERhdGUsIGlzTG9jYWxUaW1lOiBib29sZWFuIH0pIHtcbiAgICBpZiAoaXNMb2NhbFRpbWUpIHtcbiAgICAgIC8vIFN0cmlwICdaJ1xuICAgICAgY29uc3QgaXNvU3RyaW5nID0gZGF0ZS50b0lTT1N0cmluZygpO1xuICAgICAgcmV0dXJuIGlzb1N0cmluZy5zdWJzdHJpbmcoMCwgaXNvU3RyaW5nLmluZGV4T2YoJ1onKSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaENvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/SchemaCache.js b/lib/Controllers/SchemaCache.js deleted file mode 100644 index ff750893eb..0000000000 --- a/lib/Controllers/SchemaCache.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _cryptoUtils = require("../cryptoUtils"); - -var _defaults = _interopRequireDefault(require("../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const MAIN_SCHEMA = '__MAIN_SCHEMA'; -const SCHEMA_CACHE_PREFIX = '__SCHEMA'; - -class SchemaCache { - constructor(cacheController, ttl = _defaults.default.schemaCacheTTL, singleCache = false) { - this.ttl = ttl; - - if (typeof ttl == 'string') { - this.ttl = parseInt(ttl); - } - - this.cache = cacheController; - this.prefix = SCHEMA_CACHE_PREFIX; - - if (!singleCache) { - this.prefix += (0, _cryptoUtils.randomString)(20); - } - } - - getAllClasses() { - if (!this.ttl) { - return Promise.resolve(null); - } - - return this.cache.get(this.prefix + MAIN_SCHEMA); - } - - setAllClasses(schema) { - if (!this.ttl) { - return Promise.resolve(null); - } - - return this.cache.put(this.prefix + MAIN_SCHEMA, schema); - } - - getOneSchema(className) { - if (!this.ttl) { - return Promise.resolve(null); - } - - return this.cache.get(this.prefix + MAIN_SCHEMA).then(cachedSchemas => { - cachedSchemas = cachedSchemas || []; - const schema = cachedSchemas.find(cachedSchema => { - return cachedSchema.className === className; - }); - - if (schema) { - return Promise.resolve(schema); - } - - return Promise.resolve(null); - }); - } - - clear() { - return this.cache.del(this.prefix + MAIN_SCHEMA); - } - -} - -exports.default = SchemaCache; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDYWNoZS5qcyJdLCJuYW1lcyI6WyJNQUlOX1NDSEVNQSIsIlNDSEVNQV9DQUNIRV9QUkVGSVgiLCJTY2hlbWFDYWNoZSIsImNvbnN0cnVjdG9yIiwiY2FjaGVDb250cm9sbGVyIiwidHRsIiwiZGVmYXVsdHMiLCJzY2hlbWFDYWNoZVRUTCIsInNpbmdsZUNhY2hlIiwicGFyc2VJbnQiLCJjYWNoZSIsInByZWZpeCIsImdldEFsbENsYXNzZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldCIsInNldEFsbENsYXNzZXMiLCJzY2hlbWEiLCJwdXQiLCJnZXRPbmVTY2hlbWEiLCJjbGFzc05hbWUiLCJ0aGVuIiwiY2FjaGVkU2NoZW1hcyIsImZpbmQiLCJjYWNoZWRTY2hlbWEiLCJjbGVhciIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUdBOztBQUNBOzs7O0FBSkEsTUFBTUEsV0FBVyxHQUFHLGVBQXBCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsVUFBNUI7O0FBS2UsTUFBTUMsV0FBTixDQUFrQjtBQUcvQkMsRUFBQUEsV0FBVyxDQUFDQyxlQUFELEVBQWtCQyxHQUFHLEdBQUdDLGtCQUFTQyxjQUFqQyxFQUFpREMsV0FBVyxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtILEdBQUwsR0FBV0EsR0FBWDs7QUFDQSxRQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFLQSxHQUFMLEdBQVdJLFFBQVEsQ0FBQ0osR0FBRCxDQUFuQjtBQUNEOztBQUNELFNBQUtLLEtBQUwsR0FBYU4sZUFBYjtBQUNBLFNBQUtPLE1BQUwsR0FBY1YsbUJBQWQ7O0FBQ0EsUUFBSSxDQUFDTyxXQUFMLEVBQWtCO0FBQ2hCLFdBQUtHLE1BQUwsSUFBZSwrQkFBYSxFQUFiLENBQWY7QUFDRDtBQUNGOztBQUVEQyxFQUFBQSxhQUFhLEdBQUc7QUFDZCxRQUFJLENBQUMsS0FBS1AsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsQ0FBUDtBQUNEOztBQUVEZ0IsRUFBQUEsYUFBYSxDQUFDQyxNQUFELEVBQVM7QUFDcEIsUUFBSSxDQUFDLEtBQUtaLEdBQVYsRUFBZTtBQUNiLGFBQU9RLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxLQUFLSixLQUFMLENBQVdRLEdBQVgsQ0FBZSxLQUFLUCxNQUFMLEdBQWNYLFdBQTdCLEVBQTBDaUIsTUFBMUMsQ0FBUDtBQUNEOztBQUVERSxFQUFBQSxZQUFZLENBQUNDLFNBQUQsRUFBWTtBQUN0QixRQUFJLENBQUMsS0FBS2YsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsRUFBMENxQixJQUExQyxDQUErQ0MsYUFBYSxJQUFJO0FBQ3JFQSxNQUFBQSxhQUFhLEdBQUdBLGFBQWEsSUFBSSxFQUFqQztBQUNBLFlBQU1MLE1BQU0sR0FBR0ssYUFBYSxDQUFDQyxJQUFkLENBQW1CQyxZQUFZLElBQUk7QUFDaEQsZUFBT0EsWUFBWSxDQUFDSixTQUFiLEtBQTJCQSxTQUFsQztBQUNELE9BRmMsQ0FBZjs7QUFHQSxVQUFJSCxNQUFKLEVBQVk7QUFDVixlQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0JHLE1BQWhCLENBQVA7QUFDRDs7QUFDRCxhQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNELEtBVE0sQ0FBUDtBQVVEOztBQUVEVyxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtmLEtBQUwsQ0FBV2dCLEdBQVgsQ0FBZSxLQUFLZixNQUFMLEdBQWNYLFdBQTdCLENBQVA7QUFDRDs7QUEvQzhCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgTUFJTl9TQ0hFTUEgPSAnX19NQUlOX1NDSEVNQSc7XG5jb25zdCBTQ0hFTUFfQ0FDSEVfUFJFRklYID0gJ19fU0NIRU1BJztcblxuaW1wb3J0IHsgcmFuZG9tU3RyaW5nIH0gZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NoZW1hQ2FjaGUge1xuICBjYWNoZTogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKGNhY2hlQ29udHJvbGxlciwgdHRsID0gZGVmYXVsdHMuc2NoZW1hQ2FjaGVUVEwsIHNpbmdsZUNhY2hlID0gZmFsc2UpIHtcbiAgICB0aGlzLnR0bCA9IHR0bDtcbiAgICBpZiAodHlwZW9mIHR0bCA9PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy50dGwgPSBwYXJzZUludCh0dGwpO1xuICAgIH1cbiAgICB0aGlzLmNhY2hlID0gY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMucHJlZml4ID0gU0NIRU1BX0NBQ0hFX1BSRUZJWDtcbiAgICBpZiAoIXNpbmdsZUNhY2hlKSB7XG4gICAgICB0aGlzLnByZWZpeCArPSByYW5kb21TdHJpbmcoMjApO1xuICAgIH1cbiAgfVxuXG4gIGdldEFsbENsYXNzZXMoKSB7XG4gICAgaWYgKCF0aGlzLnR0bCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRoaXMucHJlZml4ICsgTUFJTl9TQ0hFTUEpO1xuICB9XG5cbiAgc2V0QWxsQ2xhc3NlcyhzY2hlbWEpIHtcbiAgICBpZiAoIXRoaXMudHRsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZS5wdXQodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSwgc2NoZW1hKTtcbiAgfVxuXG4gIGdldE9uZVNjaGVtYShjbGFzc05hbWUpIHtcbiAgICBpZiAoIXRoaXMudHRsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXQodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSkudGhlbihjYWNoZWRTY2hlbWFzID0+IHtcbiAgICAgIGNhY2hlZFNjaGVtYXMgPSBjYWNoZWRTY2hlbWFzIHx8IFtdO1xuICAgICAgY29uc3Qgc2NoZW1hID0gY2FjaGVkU2NoZW1hcy5maW5kKGNhY2hlZFNjaGVtYSA9PiB7XG4gICAgICAgIHJldHVybiBjYWNoZWRTY2hlbWEuY2xhc3NOYW1lID09PSBjbGFzc05hbWU7XG4gICAgICB9KTtcbiAgICAgIGlmIChzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzY2hlbWEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlLmRlbCh0aGlzLnByZWZpeCArIE1BSU5fU0NIRU1BKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Controllers/SchemaController.js b/lib/Controllers/SchemaController.js deleted file mode 100644 index c7027fd3f3..0000000000 --- a/lib/Controllers/SchemaController.js +++ /dev/null @@ -1,1662 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.classNameIsValid = classNameIsValid; -exports.fieldNameIsValid = fieldNameIsValid; -exports.invalidClassNameMessage = invalidClassNameMessage; -exports.buildMergedSchemaObject = buildMergedSchemaObject; -exports.VolatileClassesSchemas = exports.convertSchemaToAdapterSchema = exports.defaultColumns = exports.systemClasses = exports.load = exports.SchemaController = exports.default = void 0; - -var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); - -var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -// This class handles schema validation, persistence, and modification. -// -// Each individual Schema object should be immutable. The helpers to -// do things with the Schema just return a new schema when the schema -// is changed. -// -// The canonical place to store this Schema is in the database itself, -// in a _SCHEMA collection. This is not the right way to do it for an -// open source framework, but it's backward compatible, so we're -// keeping it this way for now. -// -// In API-handling code, you should only use the Schema class via the -// DatabaseController. This will let us replace the schema logic for -// different databases. -// TODO: hide all schema logic inside the database adapter. -// -disable-next -const Parse = require('parse/node').Parse; - -const defaultColumns = Object.freeze({ - // Contain the default columns for every parse object type (except _Join collection) - _Default: { - objectId: { - type: 'String' - }, - createdAt: { - type: 'Date' - }, - updatedAt: { - type: 'Date' - }, - ACL: { - type: 'ACL' - } - }, - // The additional default columns for the _User collection (in addition to DefaultCols) - _User: { - username: { - type: 'String' - }, - password: { - type: 'String' - }, - email: { - type: 'String' - }, - emailVerified: { - type: 'Boolean' - }, - authData: { - type: 'Object' - } - }, - // The additional default columns for the _Installation collection (in addition to DefaultCols) - _Installation: { - installationId: { - type: 'String' - }, - deviceToken: { - type: 'String' - }, - channels: { - type: 'Array' - }, - deviceType: { - type: 'String' - }, - pushType: { - type: 'String' - }, - GCMSenderId: { - type: 'String' - }, - timeZone: { - type: 'String' - }, - localeIdentifier: { - type: 'String' - }, - badge: { - type: 'Number' - }, - appVersion: { - type: 'String' - }, - appName: { - type: 'String' - }, - appIdentifier: { - type: 'String' - }, - parseVersion: { - type: 'String' - } - }, - // The additional default columns for the _Role collection (in addition to DefaultCols) - _Role: { - name: { - type: 'String' - }, - users: { - type: 'Relation', - targetClass: '_User' - }, - roles: { - type: 'Relation', - targetClass: '_Role' - } - }, - // The additional default columns for the _Session collection (in addition to DefaultCols) - _Session: { - restricted: { - type: 'Boolean' - }, - user: { - type: 'Pointer', - targetClass: '_User' - }, - installationId: { - type: 'String' - }, - sessionToken: { - type: 'String' - }, - expiresAt: { - type: 'Date' - }, - createdWith: { - type: 'Object' - } - }, - _Product: { - productIdentifier: { - type: 'String' - }, - download: { - type: 'File' - }, - downloadName: { - type: 'String' - }, - icon: { - type: 'File' - }, - order: { - type: 'Number' - }, - title: { - type: 'String' - }, - subtitle: { - type: 'String' - } - }, - _PushStatus: { - pushTime: { - type: 'String' - }, - source: { - type: 'String' - }, - // rest or webui - query: { - type: 'String' - }, - // the stringified JSON query - payload: { - type: 'String' - }, - // the stringified JSON payload, - title: { - type: 'String' - }, - expiry: { - type: 'Number' - }, - expiration_interval: { - type: 'Number' - }, - status: { - type: 'String' - }, - numSent: { - type: 'Number' - }, - numFailed: { - type: 'Number' - }, - pushHash: { - type: 'String' - }, - errorMessage: { - type: 'Object' - }, - sentPerType: { - type: 'Object' - }, - failedPerType: { - type: 'Object' - }, - sentPerUTCOffset: { - type: 'Object' - }, - failedPerUTCOffset: { - type: 'Object' - }, - count: { - type: 'Number' - } // tracks # of batches queued and pending - - }, - _JobStatus: { - jobName: { - type: 'String' - }, - source: { - type: 'String' - }, - status: { - type: 'String' - }, - message: { - type: 'String' - }, - params: { - type: 'Object' - }, - // params received when calling the job - finishedAt: { - type: 'Date' - } - }, - _JobSchedule: { - jobName: { - type: 'String' - }, - description: { - type: 'String' - }, - params: { - type: 'String' - }, - startAfter: { - type: 'String' - }, - daysOfWeek: { - type: 'Array' - }, - timeOfDay: { - type: 'String' - }, - lastRun: { - type: 'Number' - }, - repeatMinutes: { - type: 'Number' - } - }, - _Hooks: { - functionName: { - type: 'String' - }, - className: { - type: 'String' - }, - triggerName: { - type: 'String' - }, - url: { - type: 'String' - } - }, - _GlobalConfig: { - objectId: { - type: 'String' - }, - params: { - type: 'Object' - }, - masterKeyOnly: { - type: 'Object' - } - }, - _GraphQLConfig: { - objectId: { - type: 'String' - }, - config: { - type: 'Object' - } - }, - _Audience: { - objectId: { - type: 'String' - }, - name: { - type: 'String' - }, - query: { - type: 'String' - }, - //storing query as JSON string to prevent "Nested keys should not contain the '$' or '.' characters" error - lastUsed: { - type: 'Date' - }, - timesUsed: { - type: 'Number' - } - }, - _Idempotency: { - reqId: { - type: 'String' - }, - expire: { - type: 'Date' - } - } -}); -exports.defaultColumns = defaultColumns; -const requiredColumns = Object.freeze({ - _Product: ['productIdentifier', 'icon', 'order', 'title', 'subtitle'], - _Role: ['name', 'ACL'] -}); -const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_JobSchedule', '_Audience', '_Idempotency']); -exports.systemClasses = systemClasses; -const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_JobSchedule', '_Audience', '_Idempotency']); // Anything that start with role - -const roleRegex = /^role:.*/; // Anything that starts with userField (allowed for protected fields only) - -const protectedFieldsPointerRegex = /^userField:.*/; // * permission - -const publicRegex = /^\*$/; -const authenticatedRegex = /^authenticated$/; -const requiresAuthenticationRegex = /^requiresAuthentication$/; -const clpPointerRegex = /^pointerFields$/; // regex for validating entities in protectedFields object - -const protectedFieldsRegex = Object.freeze([protectedFieldsPointerRegex, publicRegex, authenticatedRegex, roleRegex]); // clp regex - -const clpFieldsRegex = Object.freeze([clpPointerRegex, publicRegex, requiresAuthenticationRegex, roleRegex]); - -function validatePermissionKey(key, userIdRegExp) { - let matchesSome = false; - - for (const regEx of clpFieldsRegex) { - if (key.match(regEx) !== null) { - matchesSome = true; - break; - } - } // userId depends on startup options so it's dynamic - - - const valid = matchesSome || key.match(userIdRegExp) !== null; - - if (!valid) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); - } -} - -function validateProtectedFieldsKey(key, userIdRegExp) { - let matchesSome = false; - - for (const regEx of protectedFieldsRegex) { - if (key.match(regEx) !== null) { - matchesSome = true; - break; - } - } // userId regex depends on launch options so it's dynamic - - - const valid = matchesSome || key.match(userIdRegExp) !== null; - - if (!valid) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); - } -} - -const CLPValidKeys = Object.freeze(['find', 'count', 'get', 'create', 'update', 'delete', 'addField', 'readUserFields', 'writeUserFields', 'protectedFields']); // validation before setting class-level permissions on collection - -function validateCLP(perms, fields, userIdRegExp) { - if (!perms) { - return; - } - - for (const operationKey in perms) { - if (CLPValidKeys.indexOf(operationKey) == -1) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `${operationKey} is not a valid operation for class level permissions`); - } - - const operation = perms[operationKey]; // proceed with next operationKey - // throws when root fields are of wrong type - - validateCLPjson(operation, operationKey); - - if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { - // validate grouped pointer permissions - // must be an array with field names - for (const fieldName of operation) { - validatePointerPermission(fieldName, fields, operationKey); - } // readUserFields and writerUserFields do not have nesdted fields - // proceed with next operationKey - - - continue; - } // validate protected fields - - - if (operationKey === 'protectedFields') { - for (const entity in operation) { - // throws on unexpected key - validateProtectedFieldsKey(entity, userIdRegExp); - const protectedFields = operation[entity]; - - if (!Array.isArray(protectedFields)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${protectedFields}' is not a valid value for protectedFields[${entity}] - expected an array.`); - } // if the field is in form of array - - - for (const field of protectedFields) { - // do not alloow to protect default fields - if (defaultColumns._Default[field]) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Default field '${field}' can not be protected`); - } // field should exist on collection - - - if (!Object.prototype.hasOwnProperty.call(fields, field)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Field '${field}' in protectedFields:${entity} does not exist`); - } - } - } // proceed with next operationKey - - - continue; - } // validate other fields - // Entity can be: - // "*" - Public, - // "requiresAuthentication" - authenticated users, - // "objectId" - _User id, - // "role:rolename", - // "pointerFields" - array of field names containing pointers to users - - - for (const entity in operation) { - // throws on unexpected key - validatePermissionKey(entity, userIdRegExp); // entity can be either: - // "pointerFields": string[] - - if (entity === 'pointerFields') { - const pointerFields = operation[entity]; - - if (Array.isArray(pointerFields)) { - for (const pointerField of pointerFields) { - validatePointerPermission(pointerField, fields, operation); - } - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${pointerFields}' is not a valid value for ${operationKey}[${entity}] - expected an array.`); - } // proceed with next entity key - - - continue; - } // or [entity]: boolean - - - const permit = operation[entity]; - - if (permit !== true) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${permit}' is not a valid value for class level permissions ${operationKey}:${entity}:${permit}`); - } - } - } -} - -function validateCLPjson(operation, operationKey) { - if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { - if (!Array.isArray(operation)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an array`); - } - } else { - if (typeof operation === 'object' && operation !== null) { - // ok to proceed - return; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an object`); - } - } -} - -function validatePointerPermission(fieldName, fields, operation) { - // Uses collection schema to ensure the field is of type: - // - Pointer<_User> (pointers) - // - Array - // - // It's not possible to enforce type on Array's items in schema - // so we accept any Array field, and later when applying permissions - // only items that are pointers to _User are considered. - if (!(fields[fieldName] && (fields[fieldName].type == 'Pointer' && fields[fieldName].targetClass == '_User' || fields[fieldName].type == 'Array'))) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${fieldName}' is not a valid column for class level pointer permissions ${operation}`); - } -} - -const joinClassRegex = /^_Join:[A-Za-z0-9_]+:[A-Za-z0-9_]+/; -const classAndFieldRegex = /^[A-Za-z][A-Za-z0-9_]*$/; - -function classNameIsValid(className) { - // Valid classes must: - return (// Be one of _User, _Installation, _Role, _Session OR - systemClasses.indexOf(className) > -1 || // Be a join table OR - joinClassRegex.test(className) || // Include only alpha-numeric and underscores, and not start with an underscore or number - fieldNameIsValid(className) - ); -} // Valid fields must be alpha-numeric, and not start with an underscore or number - - -function fieldNameIsValid(fieldName) { - return classAndFieldRegex.test(fieldName); -} // Checks that it's not trying to clobber one of the default fields of the class. - - -function fieldNameIsValidForClass(fieldName, className) { - if (!fieldNameIsValid(fieldName)) { - return false; - } - - if (defaultColumns._Default[fieldName]) { - return false; - } - - if (defaultColumns[className] && defaultColumns[className][fieldName]) { - return false; - } - - return true; -} - -function invalidClassNameMessage(className) { - return 'Invalid classname: ' + className + ', classnames can only have alphanumeric characters and _, and must start with an alpha character '; -} - -const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, 'invalid JSON'); -const validNonRelationOrPointerTypes = ['Number', 'String', 'Boolean', 'Date', 'Object', 'Array', 'GeoPoint', 'File', 'Bytes', 'Polygon']; // Returns an error suitable for throwing if the type is invalid - -const fieldTypeIsInvalid = ({ - type, - targetClass -}) => { - if (['Pointer', 'Relation'].indexOf(type) >= 0) { - if (!targetClass) { - return new Parse.Error(135, `type ${type} needs a class name`); - } else if (typeof targetClass !== 'string') { - return invalidJsonError; - } else if (!classNameIsValid(targetClass)) { - return new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(targetClass)); - } else { - return undefined; - } - } - - if (typeof type !== 'string') { - return invalidJsonError; - } - - if (validNonRelationOrPointerTypes.indexOf(type) < 0) { - return new Parse.Error(Parse.Error.INCORRECT_TYPE, `invalid field type: ${type}`); - } - - return undefined; -}; - -const convertSchemaToAdapterSchema = schema => { - schema = injectDefaultSchema(schema); - delete schema.fields.ACL; - schema.fields._rperm = { - type: 'Array' - }; - schema.fields._wperm = { - type: 'Array' - }; - - if (schema.className === '_User') { - delete schema.fields.password; - schema.fields._hashed_password = { - type: 'String' - }; - } - - return schema; -}; - -exports.convertSchemaToAdapterSchema = convertSchemaToAdapterSchema; - -const convertAdapterSchemaToParseSchema = (_ref) => { - let schema = _extends({}, _ref); - - delete schema.fields._rperm; - delete schema.fields._wperm; - schema.fields.ACL = { - type: 'ACL' - }; - - if (schema.className === '_User') { - delete schema.fields.authData; //Auth data is implicit - - delete schema.fields._hashed_password; - schema.fields.password = { - type: 'String' - }; - } - - if (schema.indexes && Object.keys(schema.indexes).length === 0) { - delete schema.indexes; - } - - return schema; -}; - -class SchemaData { - constructor(allSchemas = [], protectedFields = {}) { - this.__data = {}; - this.__protectedFields = protectedFields; - allSchemas.forEach(schema => { - if (volatileClasses.includes(schema.className)) { - return; - } - - Object.defineProperty(this, schema.className, { - get: () => { - if (!this.__data[schema.className]) { - const data = {}; - data.fields = injectDefaultSchema(schema).fields; - data.classLevelPermissions = (0, _deepcopy.default)(schema.classLevelPermissions); - data.indexes = schema.indexes; - const classProtectedFields = this.__protectedFields[schema.className]; - - if (classProtectedFields) { - for (const key in classProtectedFields) { - const unq = new Set([...(data.classLevelPermissions.protectedFields[key] || []), ...classProtectedFields[key]]); - data.classLevelPermissions.protectedFields[key] = Array.from(unq); - } - } - - this.__data[schema.className] = data; - } - - return this.__data[schema.className]; - } - }); - }); // Inject the in-memory classes - - volatileClasses.forEach(className => { - Object.defineProperty(this, className, { - get: () => { - if (!this.__data[className]) { - const schema = injectDefaultSchema({ - className, - fields: {}, - classLevelPermissions: {} - }); - const data = {}; - data.fields = schema.fields; - data.classLevelPermissions = schema.classLevelPermissions; - data.indexes = schema.indexes; - this.__data[className] = data; - } - - return this.__data[className]; - } - }); - }); - } - -} - -const injectDefaultSchema = ({ - className, - fields, - classLevelPermissions, - indexes -}) => { - const defaultSchema = { - className, - fields: _objectSpread(_objectSpread(_objectSpread({}, defaultColumns._Default), defaultColumns[className] || {}), fields), - classLevelPermissions - }; - - if (indexes && Object.keys(indexes).length !== 0) { - defaultSchema.indexes = indexes; - } - - return defaultSchema; -}; - -const _HooksSchema = { - className: '_Hooks', - fields: defaultColumns._Hooks -}; -const _GlobalConfigSchema = { - className: '_GlobalConfig', - fields: defaultColumns._GlobalConfig -}; -const _GraphQLConfigSchema = { - className: '_GraphQLConfig', - fields: defaultColumns._GraphQLConfig -}; - -const _PushStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_PushStatus', - fields: {}, - classLevelPermissions: {} -})); - -const _JobStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_JobStatus', - fields: {}, - classLevelPermissions: {} -})); - -const _JobScheduleSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_JobSchedule', - fields: {}, - classLevelPermissions: {} -})); - -const _AudienceSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_Audience', - fields: defaultColumns._Audience, - classLevelPermissions: {} -})); - -const _IdempotencySchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_Idempotency', - fields: defaultColumns._Idempotency, - classLevelPermissions: {} -})); - -const VolatileClassesSchemas = [_HooksSchema, _JobStatusSchema, _JobScheduleSchema, _PushStatusSchema, _GlobalConfigSchema, _GraphQLConfigSchema, _AudienceSchema, _IdempotencySchema]; -exports.VolatileClassesSchemas = VolatileClassesSchemas; - -const dbTypeMatchesObjectType = (dbType, objectType) => { - if (dbType.type !== objectType.type) return false; - if (dbType.targetClass !== objectType.targetClass) return false; - if (dbType === objectType.type) return true; - if (dbType.type === objectType.type) return true; - return false; -}; - -const typeToString = type => { - if (typeof type === 'string') { - return type; - } - - if (type.targetClass) { - return `${type.type}<${type.targetClass}>`; - } - - return `${type.type}`; -}; // Stores the entire schema of the app in a weird hybrid format somewhere between -// the mongo format and the Parse format. Soon, this will all be Parse format. - - -class SchemaController { - constructor(databaseAdapter, schemaCache) { - this._dbAdapter = databaseAdapter; - this._cache = schemaCache; - this.schemaData = new SchemaData(); - this.protectedFields = _Config.default.get(Parse.applicationId).protectedFields; - - const customIds = _Config.default.get(Parse.applicationId).allowCustomObjectId; - - const customIdRegEx = /^.{1,}$/u; // 1+ chars - - const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/; - this.userIdRegEx = customIds ? customIdRegEx : autoIdRegEx; - } - - reloadData(options = { - clearCache: false - }) { - if (this.reloadDataPromise && !options.clearCache) { - return this.reloadDataPromise; - } - - this.reloadDataPromise = this.getAllClasses(options).then(allSchemas => { - this.schemaData = new SchemaData(allSchemas, this.protectedFields); - delete this.reloadDataPromise; - }, err => { - this.schemaData = new SchemaData(); - delete this.reloadDataPromise; - throw err; - }).then(() => {}); - return this.reloadDataPromise; - } - - getAllClasses(options = { - clearCache: false - }) { - if (options.clearCache) { - return this.setAllClasses(); - } - - return this._cache.getAllClasses().then(allClasses => { - if (allClasses && allClasses.length) { - return Promise.resolve(allClasses); - } - - return this.setAllClasses(); - }); - } - - setAllClasses() { - return this._dbAdapter.getAllClasses().then(allSchemas => allSchemas.map(injectDefaultSchema)).then(allSchemas => { - /* eslint-disable no-console */ - this._cache.setAllClasses(allSchemas).catch(error => console.error('Error saving schema to cache:', error)); - /* eslint-enable no-console */ - - - return allSchemas; - }); - } - - getOneSchema(className, allowVolatileClasses = false, options = { - clearCache: false - }) { - let promise = Promise.resolve(); - - if (options.clearCache) { - promise = this._cache.clear(); - } - - return promise.then(() => { - if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) { - const data = this.schemaData[className]; - return Promise.resolve({ - className, - fields: data.fields, - classLevelPermissions: data.classLevelPermissions, - indexes: data.indexes - }); - } - - return this._cache.getOneSchema(className).then(cached => { - if (cached && !options.clearCache) { - return Promise.resolve(cached); - } - - return this.setAllClasses().then(allSchemas => { - const oneSchema = allSchemas.find(schema => schema.className === className); - - if (!oneSchema) { - return Promise.reject(undefined); - } - - return oneSchema; - }); - }); - }); - } // Create a new class that includes the three default fields. - // ACL is an implicit column that does not get an entry in the - // _SCHEMAS database. Returns a promise that resolves with the - // created schema, in mongo format. - // on success, and rejects with an error on fail. Ensure you - // have authorization (master key, or client class creation - // enabled) before calling this function. - - - addClassIfNotExists(className, fields = {}, classLevelPermissions, indexes = {}) { - var validationError = this.validateNewClass(className, fields, classLevelPermissions); - - if (validationError) { - if (validationError instanceof Parse.Error) { - return Promise.reject(validationError); - } else if (validationError.code && validationError.error) { - return Promise.reject(new Parse.Error(validationError.code, validationError.error)); - } - - return Promise.reject(validationError); - } - - return this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({ - fields, - classLevelPermissions, - indexes, - className - })).then(convertAdapterSchemaToParseSchema).catch(error => { - if (error && error.code === Parse.Error.DUPLICATE_VALUE) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); - } else { - throw error; - } - }); - } - - updateClass(className, submittedFields, classLevelPermissions, indexes, database) { - return this.getOneSchema(className).then(schema => { - const existingFields = schema.fields; - Object.keys(submittedFields).forEach(name => { - const field = submittedFields[name]; - - if (existingFields[name] && field.__op !== 'Delete') { - throw new Parse.Error(255, `Field ${name} exists, cannot update.`); - } - - if (!existingFields[name] && field.__op === 'Delete') { - throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`); - } - }); - delete existingFields._rperm; - delete existingFields._wperm; - const newSchema = buildMergedSchemaObject(existingFields, submittedFields); - const defaultFields = defaultColumns[className] || defaultColumns._Default; - const fullNewSchema = Object.assign({}, newSchema, defaultFields); - const validationError = this.validateSchemaData(className, newSchema, classLevelPermissions, Object.keys(existingFields)); - - if (validationError) { - throw new Parse.Error(validationError.code, validationError.error); - } // Finally we have checked to make sure the request is valid and we can start deleting fields. - // Do all deletions first, then a single save to _SCHEMA collection to handle all additions. - - - const deletedFields = []; - const insertedFields = []; - Object.keys(submittedFields).forEach(fieldName => { - if (submittedFields[fieldName].__op === 'Delete') { - deletedFields.push(fieldName); - } else { - insertedFields.push(fieldName); - } - }); - let deletePromise = Promise.resolve(); - - if (deletedFields.length > 0) { - deletePromise = this.deleteFields(deletedFields, className, database); - } - - let enforceFields = []; - return deletePromise // Delete Everything - .then(() => this.reloadData({ - clearCache: true - })) // Reload our Schema, so we have all the new values - .then(() => { - const promises = insertedFields.map(fieldName => { - const type = submittedFields[fieldName]; - return this.enforceFieldExists(className, fieldName, type); - }); - return Promise.all(promises); - }).then(results => { - enforceFields = results.filter(result => !!result); - return this.setPermissions(className, classLevelPermissions, newSchema); - }).then(() => this._dbAdapter.setIndexesWithSchemaFormat(className, indexes, schema.indexes, fullNewSchema)).then(() => this.reloadData({ - clearCache: true - })) //TODO: Move this logic into the database adapter - .then(() => { - this.ensureFields(enforceFields); - const schema = this.schemaData[className]; - const reloadedSchema = { - className: className, - fields: schema.fields, - classLevelPermissions: schema.classLevelPermissions - }; - - if (schema.indexes && Object.keys(schema.indexes).length !== 0) { - reloadedSchema.indexes = schema.indexes; - } - - return reloadedSchema; - }); - }).catch(error => { - if (error === undefined) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); - } else { - throw error; - } - }); - } // Returns a promise that resolves successfully to the new schema - // object or fails with a reason. - - - enforceClassExists(className) { - if (this.schemaData[className]) { - return Promise.resolve(this); - } // We don't have this class. Update the schema - - - return this.addClassIfNotExists(className) // The schema update succeeded. Reload the schema - .then(() => this.reloadData({ - clearCache: true - })).catch(() => { - // The schema update failed. This can be okay - it might - // have failed because there's a race condition and a different - // client is making the exact same schema update that we want. - // So just reload the schema. - return this.reloadData({ - clearCache: true - }); - }).then(() => { - // Ensure that the schema now validates - if (this.schemaData[className]) { - return this; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`); - } - }).catch(() => { - // The schema still doesn't validate. Give up - throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate'); - }); - } - - validateNewClass(className, fields = {}, classLevelPermissions) { - if (this.schemaData[className]) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); - } - - if (!classNameIsValid(className)) { - return { - code: Parse.Error.INVALID_CLASS_NAME, - error: invalidClassNameMessage(className) - }; - } - - return this.validateSchemaData(className, fields, classLevelPermissions, []); - } - - validateSchemaData(className, fields, classLevelPermissions, existingFieldNames) { - for (const fieldName in fields) { - if (existingFieldNames.indexOf(fieldName) < 0) { - if (!fieldNameIsValid(fieldName)) { - return { - code: Parse.Error.INVALID_KEY_NAME, - error: 'invalid field name: ' + fieldName - }; - } - - if (!fieldNameIsValidForClass(fieldName, className)) { - return { - code: 136, - error: 'field ' + fieldName + ' cannot be added' - }; - } - - const fieldType = fields[fieldName]; - const error = fieldTypeIsInvalid(fieldType); - if (error) return { - code: error.code, - error: error.message - }; - - if (fieldType.defaultValue !== undefined) { - let defaultValueType = getType(fieldType.defaultValue); - - if (typeof defaultValueType === 'string') { - defaultValueType = { - type: defaultValueType - }; - } else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') { - return { - code: Parse.Error.INCORRECT_TYPE, - error: `The 'default value' option is not applicable for ${typeToString(fieldType)}` - }; - } - - if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) { - return { - code: Parse.Error.INCORRECT_TYPE, - error: `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(fieldType)} but got ${typeToString(defaultValueType)}` - }; - } - } else if (fieldType.required) { - if (typeof fieldType === 'object' && fieldType.type === 'Relation') { - return { - code: Parse.Error.INCORRECT_TYPE, - error: `The 'required' option is not applicable for ${typeToString(fieldType)}` - }; - } - } - } - } - - for (const fieldName in defaultColumns[className]) { - fields[fieldName] = defaultColumns[className][fieldName]; - } - - const geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint'); - - if (geoPoints.length > 1) { - return { - code: Parse.Error.INCORRECT_TYPE, - error: 'currently, only one GeoPoint field may exist in an object. Adding ' + geoPoints[1] + ' when ' + geoPoints[0] + ' already exists.' - }; - } - - validateCLP(classLevelPermissions, fields, this.userIdRegEx); - } // Sets the Class-level permissions for a given className, which must exist. - - - setPermissions(className, perms, newSchema) { - if (typeof perms === 'undefined') { - return Promise.resolve(); - } - - validateCLP(perms, newSchema, this.userIdRegEx); - return this._dbAdapter.setClassLevelPermissions(className, perms); - } // Returns a promise that resolves successfully to the new schema - // object if the provided className-fieldName-type tuple is valid. - // The className must already be validated. - // If 'freeze' is true, refuse to update the schema for this field. - - - enforceFieldExists(className, fieldName, type) { - if (fieldName.indexOf('.') > 0) { - // subdocument key (x.y) => ok if x is of type 'object' - fieldName = fieldName.split('.')[0]; - type = 'Object'; - } - - if (!fieldNameIsValid(fieldName)) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); - } // If someone tries to create a new field with null/undefined as the value, return; - - - if (!type) { - return undefined; - } - - const expectedType = this.getExpectedType(className, fieldName); - - if (typeof type === 'string') { - type = { - type - }; - } - - if (type.defaultValue !== undefined) { - let defaultValueType = getType(type.defaultValue); - - if (typeof defaultValueType === 'string') { - defaultValueType = { - type: defaultValueType - }; - } - - if (!dbTypeMatchesObjectType(type, defaultValueType)) { - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(type)} but got ${typeToString(defaultValueType)}`); - } - } - - if (expectedType) { - if (!dbTypeMatchesObjectType(expectedType, type)) { - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName}; expected ${typeToString(expectedType)} but got ${typeToString(type)}`); - } - - return undefined; - } - - return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).catch(error => { - if (error.code == Parse.Error.INCORRECT_TYPE) { - // Make sure that we throw errors when it is appropriate to do so. - throw error; - } // The update failed. This can be okay - it might have been a race - // condition where another client updated the schema in the same - // way that we wanted to. So, just reload the schema - - - return Promise.resolve(); - }).then(() => { - return { - className, - fieldName, - type - }; - }); - } - - ensureFields(fields) { - for (let i = 0; i < fields.length; i += 1) { - const { - className, - fieldName - } = fields[i]; - let { - type - } = fields[i]; - const expectedType = this.getExpectedType(className, fieldName); - - if (typeof type === 'string') { - type = { - type: type - }; - } - - if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`); - } - } - } // maintain compatibility - - - deleteField(fieldName, className, database) { - return this.deleteFields([fieldName], className, database); - } // Delete fields, and remove that data from all objects. This is intended - // to remove unused fields, if other writers are writing objects that include - // this field, the field may reappear. Returns a Promise that resolves with - // no object on success, or rejects with { code, error } on failure. - // Passing the database and prefix is necessary in order to drop relation collections - // and remove fields from objects. Ideally the database would belong to - // a database adapter and this function would close over it or access it via member. - - - deleteFields(fieldNames, className, database) { - if (!classNameIsValid(className)) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className)); - } - - fieldNames.forEach(fieldName => { - if (!fieldNameIsValid(fieldName)) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`); - } //Don't allow deleting the default fields. - - - if (!fieldNameIsValidForClass(fieldName, className)) { - throw new Parse.Error(136, `field ${fieldName} cannot be changed`); - } - }); - return this.getOneSchema(className, false, { - clearCache: true - }).catch(error => { - if (error === undefined) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); - } else { - throw error; - } - }).then(schema => { - fieldNames.forEach(fieldName => { - if (!schema.fields[fieldName]) { - throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`); - } - }); - - const schemaFields = _objectSpread({}, schema.fields); - - return database.adapter.deleteFields(className, schema, fieldNames).then(() => { - return Promise.all(fieldNames.map(fieldName => { - const field = schemaFields[fieldName]; - - if (field && field.type === 'Relation') { - //For relations, drop the _Join table - return database.adapter.deleteClass(`_Join:${fieldName}:${className}`); - } - - return Promise.resolve(); - })); - }); - }).then(() => this._cache.clear()); - } // Validates an object provided in REST format. - // Returns a promise that resolves to the new schema if this object is - // valid. - - - async validateObject(className, object, query) { - let geocount = 0; - const schema = await this.enforceClassExists(className); - const promises = []; - - for (const fieldName in object) { - if (object[fieldName] === undefined) { - continue; - } - - const expected = getType(object[fieldName]); - - if (expected === 'GeoPoint') { - geocount++; - } - - if (geocount > 1) { - // Make sure all field validation operations run before we return. - // If not - we are continuing to run logic, but already provided response from the server. - return Promise.reject(new Parse.Error(Parse.Error.INCORRECT_TYPE, 'there can only be one geopoint field in a class')); - } - - if (!expected) { - continue; - } - - if (fieldName === 'ACL') { - // Every object has ACL implicitly. - continue; - } - - promises.push(schema.enforceFieldExists(className, fieldName, expected)); - } - - const results = await Promise.all(promises); - const enforceFields = results.filter(result => !!result); - - if (enforceFields.length !== 0) { - await this.reloadData({ - clearCache: true - }); - } - - this.ensureFields(enforceFields); - const promise = Promise.resolve(schema); - return thenValidateRequiredColumns(promise, className, object, query); - } // Validates that all the properties are set for the object - - - validateRequiredColumns(className, object, query) { - const columns = requiredColumns[className]; - - if (!columns || columns.length == 0) { - return Promise.resolve(this); - } - - const missingColumns = columns.filter(function (column) { - if (query && query.objectId) { - if (object[column] && typeof object[column] === 'object') { - // Trying to delete a required column - return object[column].__op == 'Delete'; - } // Not trying to do anything there - - - return false; - } - - return !object[column]; - }); - - if (missingColumns.length > 0) { - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, missingColumns[0] + ' is required.'); - } - - return Promise.resolve(this); - } - - testPermissionsForClassName(className, aclGroup, operation) { - return SchemaController.testPermissions(this.getClassLevelPermissions(className), aclGroup, operation); - } // Tests that the class level permission let pass the operation for a given aclGroup - - - static testPermissions(classPermissions, aclGroup, operation) { - if (!classPermissions || !classPermissions[operation]) { - return true; - } - - const perms = classPermissions[operation]; - - if (perms['*']) { - return true; - } // Check permissions against the aclGroup provided (array of userId/roles) - - - if (aclGroup.some(acl => { - return perms[acl] === true; - })) { - return true; - } - - return false; - } // Validates an operation passes class-level-permissions set in the schema - - - static validatePermission(classPermissions, className, aclGroup, operation, action) { - if (SchemaController.testPermissions(classPermissions, aclGroup, operation)) { - return Promise.resolve(); - } - - if (!classPermissions || !classPermissions[operation]) { - return true; - } - - const perms = classPermissions[operation]; // If only for authenticated users - // make sure we have an aclGroup - - if (perms['requiresAuthentication']) { - // If aclGroup has * (public) - if (!aclGroup || aclGroup.length == 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); - } else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); - } // requiresAuthentication passed, just move forward - // probably would be wise at some point to rename to 'authenticatedUser' - - - return Promise.resolve(); - } // No matching CLP, let's check the Pointer permissions - // And handle those later - - - const permissionField = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; // Reject create when write lockdown - - if (permissionField == 'writeUserFields' && operation == 'create') { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); - } // Process the readUserFields later - - - if (Array.isArray(classPermissions[permissionField]) && classPermissions[permissionField].length > 0) { - return Promise.resolve(); - } - - const pointerFields = classPermissions[operation].pointerFields; - - if (Array.isArray(pointerFields) && pointerFields.length > 0) { - // any op except 'addField as part of create' is ok. - if (operation !== 'addField' || action === 'update') { - // We can allow adding field on update flow only. - return Promise.resolve(); - } - } - - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); - } // Validates an operation passes class-level-permissions set in the schema - - - validatePermission(className, aclGroup, operation, action) { - return SchemaController.validatePermission(this.getClassLevelPermissions(className), className, aclGroup, operation, action); - } - - getClassLevelPermissions(className) { - return this.schemaData[className] && this.schemaData[className].classLevelPermissions; - } // Returns the expected type for a className+key combination - // or undefined if the schema is not set - - - getExpectedType(className, fieldName) { - if (this.schemaData[className]) { - const expectedType = this.schemaData[className].fields[fieldName]; - return expectedType === 'map' ? 'Object' : expectedType; - } - - return undefined; - } // Checks if a given class is in the schema. - - - hasClass(className) { - if (this.schemaData[className]) { - return Promise.resolve(true); - } - - return this.reloadData().then(() => !!this.schemaData[className]); - } - -} // Returns a promise for a new Schema. - - -exports.SchemaController = exports.default = SchemaController; - -const load = (dbAdapter, schemaCache, options) => { - const schema = new SchemaController(dbAdapter, schemaCache); - return schema.reloadData(options).then(() => schema); -}; // Builds a new schema (in schema API response format) out of an -// existing mongo schema + a schemas API put request. This response -// does not include the default fields, as it is intended to be passed -// to mongoSchemaFromFieldsAndClassName. No validation is done here, it -// is done in mongoSchemaFromFieldsAndClassName. - - -exports.load = load; - -function buildMergedSchemaObject(existingFields, putRequest) { - const newSchema = {}; // -disable-next - - const sysSchemaField = Object.keys(defaultColumns).indexOf(existingFields._id) === -1 ? [] : Object.keys(defaultColumns[existingFields._id]); - - for (const oldField in existingFields) { - if (oldField !== '_id' && oldField !== 'ACL' && oldField !== 'updatedAt' && oldField !== 'createdAt' && oldField !== 'objectId') { - if (sysSchemaField.length > 0 && sysSchemaField.indexOf(oldField) !== -1) { - continue; - } - - const fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete'; - - if (!fieldIsDeleted) { - newSchema[oldField] = existingFields[oldField]; - } - } - } - - for (const newField in putRequest) { - if (newField !== 'objectId' && putRequest[newField].__op !== 'Delete') { - if (sysSchemaField.length > 0 && sysSchemaField.indexOf(newField) !== -1) { - continue; - } - - newSchema[newField] = putRequest[newField]; - } - } - - return newSchema; -} // Given a schema promise, construct another schema promise that -// validates this field once the schema loads. - - -function thenValidateRequiredColumns(schemaPromise, className, object, query) { - return schemaPromise.then(schema => { - return schema.validateRequiredColumns(className, object, query); - }); -} // Gets the type from a REST API formatted object, where 'type' is -// extended past javascript types to include the rest of the Parse -// type system. -// The output should be a valid schema value. -// TODO: ensure that this is compatible with the format used in Open DB - - -function getType(obj) { - const type = typeof obj; - - switch (type) { - case 'boolean': - return 'Boolean'; - - case 'string': - return 'String'; - - case 'number': - return 'Number'; - - case 'map': - case 'object': - if (!obj) { - return undefined; - } - - return getObjectType(obj); - - case 'function': - case 'symbol': - case 'undefined': - default: - throw 'bad obj: ' + obj; - } -} // This gets the type for non-JSON types like pointers and files, but -// also gets the appropriate type for $ operators. -// Returns null if the type is unknown. - - -function getObjectType(obj) { - if (obj instanceof Array) { - return 'Array'; - } - - if (obj.__type) { - switch (obj.__type) { - case 'Pointer': - if (obj.className) { - return { - type: 'Pointer', - targetClass: obj.className - }; - } - - break; - - case 'Relation': - if (obj.className) { - return { - type: 'Relation', - targetClass: obj.className - }; - } - - break; - - case 'File': - if (obj.name) { - return 'File'; - } - - break; - - case 'Date': - if (obj.iso) { - return 'Date'; - } - - break; - - case 'GeoPoint': - if (obj.latitude != null && obj.longitude != null) { - return 'GeoPoint'; - } - - break; - - case 'Bytes': - if (obj.base64) { - return 'Bytes'; - } - - break; - - case 'Polygon': - if (obj.coordinates) { - return 'Polygon'; - } - - break; - } - - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, 'This is not a valid ' + obj.__type); - } - - if (obj['$ne']) { - return getObjectType(obj['$ne']); - } - - if (obj.__op) { - switch (obj.__op) { - case 'Increment': - return 'Number'; - - case 'Delete': - return null; - - case 'Add': - case 'AddUnique': - case 'Remove': - return 'Array'; - - case 'AddRelation': - case 'RemoveRelation': - return { - type: 'Relation', - targetClass: obj.objects[0].className - }; - - case 'Batch': - return getObjectType(obj.ops[0]); - - default: - throw 'unexpected op: ' + obj.__op; - } - } - - return 'Object'; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImRlZmF1bHRDb2x1bW5zIiwiT2JqZWN0IiwiZnJlZXplIiwiX0RlZmF1bHQiLCJvYmplY3RJZCIsInR5cGUiLCJjcmVhdGVkQXQiLCJ1cGRhdGVkQXQiLCJBQ0wiLCJfVXNlciIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJlbWFpbCIsImVtYWlsVmVyaWZpZWQiLCJhdXRoRGF0YSIsIl9JbnN0YWxsYXRpb24iLCJpbnN0YWxsYXRpb25JZCIsImRldmljZVRva2VuIiwiY2hhbm5lbHMiLCJkZXZpY2VUeXBlIiwicHVzaFR5cGUiLCJHQ01TZW5kZXJJZCIsInRpbWVab25lIiwibG9jYWxlSWRlbnRpZmllciIsImJhZGdlIiwiYXBwVmVyc2lvbiIsImFwcE5hbWUiLCJhcHBJZGVudGlmaWVyIiwicGFyc2VWZXJzaW9uIiwiX1JvbGUiLCJuYW1lIiwidXNlcnMiLCJ0YXJnZXRDbGFzcyIsInJvbGVzIiwiX1Nlc3Npb24iLCJyZXN0cmljdGVkIiwidXNlciIsInNlc3Npb25Ub2tlbiIsImV4cGlyZXNBdCIsImNyZWF0ZWRXaXRoIiwiX1Byb2R1Y3QiLCJwcm9kdWN0SWRlbnRpZmllciIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwiaWNvbiIsIm9yZGVyIiwidGl0bGUiLCJzdWJ0aXRsZSIsIl9QdXNoU3RhdHVzIiwicHVzaFRpbWUiLCJzb3VyY2UiLCJxdWVyeSIsInBheWxvYWQiLCJleHBpcnkiLCJleHBpcmF0aW9uX2ludGVydmFsIiwic3RhdHVzIiwibnVtU2VudCIsIm51bUZhaWxlZCIsInB1c2hIYXNoIiwiZXJyb3JNZXNzYWdlIiwic2VudFBlclR5cGUiLCJmYWlsZWRQZXJUeXBlIiwic2VudFBlclVUQ09mZnNldCIsImZhaWxlZFBlclVUQ09mZnNldCIsImNvdW50IiwiX0pvYlN0YXR1cyIsImpvYk5hbWUiLCJtZXNzYWdlIiwicGFyYW1zIiwiZmluaXNoZWRBdCIsIl9Kb2JTY2hlZHVsZSIsImRlc2NyaXB0aW9uIiwic3RhcnRBZnRlciIsImRheXNPZldlZWsiLCJ0aW1lT2ZEYXkiLCJsYXN0UnVuIiwicmVwZWF0TWludXRlcyIsIl9Ib29rcyIsImZ1bmN0aW9uTmFtZSIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwidXJsIiwiX0dsb2JhbENvbmZpZyIsIm1hc3RlcktleU9ubHkiLCJfR3JhcGhRTENvbmZpZyIsImNvbmZpZyIsIl9BdWRpZW5jZSIsImxhc3RVc2VkIiwidGltZXNVc2VkIiwiX0lkZW1wb3RlbmN5IiwicmVxSWQiLCJleHBpcmUiLCJyZXF1aXJlZENvbHVtbnMiLCJzeXN0ZW1DbGFzc2VzIiwidm9sYXRpbGVDbGFzc2VzIiwicm9sZVJlZ2V4IiwicHJvdGVjdGVkRmllbGRzUG9pbnRlclJlZ2V4IiwicHVibGljUmVnZXgiLCJhdXRoZW50aWNhdGVkUmVnZXgiLCJyZXF1aXJlc0F1dGhlbnRpY2F0aW9uUmVnZXgiLCJjbHBQb2ludGVyUmVnZXgiLCJwcm90ZWN0ZWRGaWVsZHNSZWdleCIsImNscEZpZWxkc1JlZ2V4IiwidmFsaWRhdGVQZXJtaXNzaW9uS2V5Iiwia2V5IiwidXNlcklkUmVnRXhwIiwibWF0Y2hlc1NvbWUiLCJyZWdFeCIsIm1hdGNoIiwidmFsaWQiLCJFcnJvciIsIklOVkFMSURfSlNPTiIsInZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5IiwiQ0xQVmFsaWRLZXlzIiwidmFsaWRhdGVDTFAiLCJwZXJtcyIsImZpZWxkcyIsIm9wZXJhdGlvbktleSIsImluZGV4T2YiLCJvcGVyYXRpb24iLCJ2YWxpZGF0ZUNMUGpzb24iLCJmaWVsZE5hbWUiLCJ2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uIiwiZW50aXR5IiwicHJvdGVjdGVkRmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwiZmllbGQiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJwb2ludGVyRmllbGRzIiwicG9pbnRlckZpZWxkIiwicGVybWl0Iiwiam9pbkNsYXNzUmVnZXgiLCJjbGFzc0FuZEZpZWxkUmVnZXgiLCJjbGFzc05hbWVJc1ZhbGlkIiwidGVzdCIsImZpZWxkTmFtZUlzVmFsaWQiLCJmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MiLCJpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZSIsImludmFsaWRKc29uRXJyb3IiLCJ2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMiLCJmaWVsZFR5cGVJc0ludmFsaWQiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJ1bmRlZmluZWQiLCJJTkNPUlJFQ1RfVFlQRSIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJzY2hlbWEiLCJpbmplY3REZWZhdWx0U2NoZW1hIiwiX3JwZXJtIiwiX3dwZXJtIiwiX2hhc2hlZF9wYXNzd29yZCIsImNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSIsImluZGV4ZXMiLCJrZXlzIiwibGVuZ3RoIiwiU2NoZW1hRGF0YSIsImNvbnN0cnVjdG9yIiwiYWxsU2NoZW1hcyIsIl9fZGF0YSIsIl9fcHJvdGVjdGVkRmllbGRzIiwiZm9yRWFjaCIsImluY2x1ZGVzIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJkYXRhIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiY2xhc3NQcm90ZWN0ZWRGaWVsZHMiLCJ1bnEiLCJTZXQiLCJmcm9tIiwiZGVmYXVsdFNjaGVtYSIsIl9Ib29rc1NjaGVtYSIsIl9HbG9iYWxDb25maWdTY2hlbWEiLCJfR3JhcGhRTENvbmZpZ1NjaGVtYSIsIl9QdXNoU3RhdHVzU2NoZW1hIiwiX0pvYlN0YXR1c1NjaGVtYSIsIl9Kb2JTY2hlZHVsZVNjaGVtYSIsIl9BdWRpZW5jZVNjaGVtYSIsIl9JZGVtcG90ZW5jeVNjaGVtYSIsIlZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMiLCJkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZSIsImRiVHlwZSIsIm9iamVjdFR5cGUiLCJ0eXBlVG9TdHJpbmciLCJTY2hlbWFDb250cm9sbGVyIiwiZGF0YWJhc2VBZGFwdGVyIiwic2NoZW1hQ2FjaGUiLCJfZGJBZGFwdGVyIiwiX2NhY2hlIiwic2NoZW1hRGF0YSIsIkNvbmZpZyIsImFwcGxpY2F0aW9uSWQiLCJjdXN0b21JZHMiLCJhbGxvd0N1c3RvbU9iamVjdElkIiwiY3VzdG9tSWRSZWdFeCIsImF1dG9JZFJlZ0V4IiwidXNlcklkUmVnRXgiLCJyZWxvYWREYXRhIiwib3B0aW9ucyIsImNsZWFyQ2FjaGUiLCJyZWxvYWREYXRhUHJvbWlzZSIsImdldEFsbENsYXNzZXMiLCJ0aGVuIiwiZXJyIiwic2V0QWxsQ2xhc3NlcyIsImFsbENsYXNzZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1hcCIsImNhdGNoIiwiZXJyb3IiLCJjb25zb2xlIiwiZ2V0T25lU2NoZW1hIiwiYWxsb3dWb2xhdGlsZUNsYXNzZXMiLCJwcm9taXNlIiwiY2xlYXIiLCJjYWNoZWQiLCJvbmVTY2hlbWEiLCJmaW5kIiwicmVqZWN0IiwiYWRkQ2xhc3NJZk5vdEV4aXN0cyIsInZhbGlkYXRpb25FcnJvciIsInZhbGlkYXRlTmV3Q2xhc3MiLCJjb2RlIiwiY3JlYXRlQ2xhc3MiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1cGRhdGVDbGFzcyIsInN1Ym1pdHRlZEZpZWxkcyIsImRhdGFiYXNlIiwiZXhpc3RpbmdGaWVsZHMiLCJfX29wIiwibmV3U2NoZW1hIiwiYnVpbGRNZXJnZWRTY2hlbWFPYmplY3QiLCJkZWZhdWx0RmllbGRzIiwiZnVsbE5ld1NjaGVtYSIsImFzc2lnbiIsInZhbGlkYXRlU2NoZW1hRGF0YSIsImRlbGV0ZWRGaWVsZHMiLCJpbnNlcnRlZEZpZWxkcyIsInB1c2giLCJkZWxldGVQcm9taXNlIiwiZGVsZXRlRmllbGRzIiwiZW5mb3JjZUZpZWxkcyIsInByb21pc2VzIiwiZW5mb3JjZUZpZWxkRXhpc3RzIiwiYWxsIiwicmVzdWx0cyIsImZpbHRlciIsInJlc3VsdCIsInNldFBlcm1pc3Npb25zIiwic2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQiLCJlbnN1cmVGaWVsZHMiLCJyZWxvYWRlZFNjaGVtYSIsImVuZm9yY2VDbGFzc0V4aXN0cyIsImV4aXN0aW5nRmllbGROYW1lcyIsIklOVkFMSURfS0VZX05BTUUiLCJmaWVsZFR5cGUiLCJkZWZhdWx0VmFsdWUiLCJkZWZhdWx0VmFsdWVUeXBlIiwiZ2V0VHlwZSIsInJlcXVpcmVkIiwiZ2VvUG9pbnRzIiwic2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwic3BsaXQiLCJleHBlY3RlZFR5cGUiLCJnZXRFeHBlY3RlZFR5cGUiLCJhZGRGaWVsZElmTm90RXhpc3RzIiwiaSIsImRlbGV0ZUZpZWxkIiwiZmllbGROYW1lcyIsInNjaGVtYUZpZWxkcyIsImFkYXB0ZXIiLCJkZWxldGVDbGFzcyIsInZhbGlkYXRlT2JqZWN0Iiwib2JqZWN0IiwiZ2VvY291bnQiLCJleHBlY3RlZCIsInRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyIsInZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zIiwiY29sdW1ucyIsIm1pc3NpbmdDb2x1bW5zIiwiY29sdW1uIiwidGVzdFBlcm1pc3Npb25zRm9yQ2xhc3NOYW1lIiwiYWNsR3JvdXAiLCJ0ZXN0UGVybWlzc2lvbnMiLCJnZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJjbGFzc1Blcm1pc3Npb25zIiwic29tZSIsImFjbCIsInZhbGlkYXRlUGVybWlzc2lvbiIsImFjdGlvbiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJwZXJtaXNzaW9uRmllbGQiLCJPUEVSQVRJT05fRk9SQklEREVOIiwiaGFzQ2xhc3MiLCJsb2FkIiwiZGJBZGFwdGVyIiwicHV0UmVxdWVzdCIsInN5c1NjaGVtYUZpZWxkIiwiX2lkIiwib2xkRmllbGQiLCJmaWVsZElzRGVsZXRlZCIsIm5ld0ZpZWxkIiwic2NoZW1hUHJvbWlzZSIsIm9iaiIsImdldE9iamVjdFR5cGUiLCJfX3R5cGUiLCJpc28iLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsImJhc2U2NCIsImNvb3JkaW5hdGVzIiwib2JqZWN0cyIsIm9wcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFrQkE7O0FBQ0E7O0FBQ0E7O0FBRUE7Ozs7Ozs7Ozs7OztBQXJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBcEM7O0FBY0EsTUFBTUUsY0FBMEMsR0FBR0MsTUFBTSxDQUFDQyxNQUFQLENBQWM7QUFDL0Q7QUFDQUMsRUFBQUEsUUFBUSxFQUFFO0FBQ1JDLElBQUFBLFFBQVEsRUFBRTtBQUFFQyxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQURGO0FBRVJDLElBQUFBLFNBQVMsRUFBRTtBQUFFRCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUZIO0FBR1JFLElBQUFBLFNBQVMsRUFBRTtBQUFFRixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUhIO0FBSVJHLElBQUFBLEdBQUcsRUFBRTtBQUFFSCxNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQUpHLEdBRnFEO0FBUS9EO0FBQ0FJLEVBQUFBLEtBQUssRUFBRTtBQUNMQyxJQUFBQSxRQUFRLEVBQUU7QUFBRUwsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FETDtBQUVMTSxJQUFBQSxRQUFRLEVBQUU7QUFBRU4sTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FGTDtBQUdMTyxJQUFBQSxLQUFLLEVBQUU7QUFBRVAsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FIRjtBQUlMUSxJQUFBQSxhQUFhLEVBQUU7QUFBRVIsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FKVjtBQUtMUyxJQUFBQSxRQUFRLEVBQUU7QUFBRVQsTUFBQUEsSUFBSSxFQUFFO0FBQVI7QUFMTCxHQVR3RDtBQWdCL0Q7QUFDQVUsRUFBQUEsYUFBYSxFQUFFO0FBQ2JDLElBQUFBLGNBQWMsRUFBRTtBQUFFWCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQURIO0FBRWJZLElBQUFBLFdBQVcsRUFBRTtBQUFFWixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUZBO0FBR2JhLElBQUFBLFFBQVEsRUFBRTtBQUFFYixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUhHO0FBSWJjLElBQUFBLFVBQVUsRUFBRTtBQUFFZCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUpDO0FBS2JlLElBQUFBLFFBQVEsRUFBRTtBQUFFZixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUxHO0FBTWJnQixJQUFBQSxXQUFXLEVBQUU7QUFBRWhCLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBTkE7QUFPYmlCLElBQUFBLFFBQVEsRUFBRTtBQUFFakIsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FQRztBQVFia0IsSUFBQUEsZ0JBQWdCLEVBQUU7QUFBRWxCLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBUkw7QUFTYm1CLElBQUFBLEtBQUssRUFBRTtBQUFFbkIsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FUTTtBQVVib0IsSUFBQUEsVUFBVSxFQUFFO0FBQUVwQixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQVZDO0FBV2JxQixJQUFBQSxPQUFPLEVBQUU7QUFBRXJCLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBWEk7QUFZYnNCLElBQUFBLGFBQWEsRUFBRTtBQUFFdEIsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FaRjtBQWFidUIsSUFBQUEsWUFBWSxFQUFFO0FBQUV2QixNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQWJELEdBakJnRDtBQWdDL0Q7QUFDQXdCLEVBQUFBLEtBQUssRUFBRTtBQUNMQyxJQUFBQSxJQUFJLEVBQUU7QUFBRXpCLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBREQ7QUFFTDBCLElBQUFBLEtBQUssRUFBRTtBQUFFMUIsTUFBQUEsSUFBSSxFQUFFLFVBQVI7QUFBb0IyQixNQUFBQSxXQUFXLEVBQUU7QUFBakMsS0FGRjtBQUdMQyxJQUFBQSxLQUFLLEVBQUU7QUFBRTVCLE1BQUFBLElBQUksRUFBRSxVQUFSO0FBQW9CMkIsTUFBQUEsV0FBVyxFQUFFO0FBQWpDO0FBSEYsR0FqQ3dEO0FBc0MvRDtBQUNBRSxFQUFBQSxRQUFRLEVBQUU7QUFDUkMsSUFBQUEsVUFBVSxFQUFFO0FBQUU5QixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQURKO0FBRVIrQixJQUFBQSxJQUFJLEVBQUU7QUFBRS9CLE1BQUFBLElBQUksRUFBRSxTQUFSO0FBQW1CMkIsTUFBQUEsV0FBVyxFQUFFO0FBQWhDLEtBRkU7QUFHUmhCLElBQUFBLGNBQWMsRUFBRTtBQUFFWCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUhSO0FBSVJnQyxJQUFBQSxZQUFZLEVBQUU7QUFBRWhDLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBSk47QUFLUmlDLElBQUFBLFNBQVMsRUFBRTtBQUFFakMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FMSDtBQU1Sa0MsSUFBQUEsV0FBVyxFQUFFO0FBQUVsQyxNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQU5MLEdBdkNxRDtBQStDL0RtQyxFQUFBQSxRQUFRLEVBQUU7QUFDUkMsSUFBQUEsaUJBQWlCLEVBQUU7QUFBRXBDLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBRFg7QUFFUnFDLElBQUFBLFFBQVEsRUFBRTtBQUFFckMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FGRjtBQUdSc0MsSUFBQUEsWUFBWSxFQUFFO0FBQUV0QyxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUhOO0FBSVJ1QyxJQUFBQSxJQUFJLEVBQUU7QUFBRXZDLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBSkU7QUFLUndDLElBQUFBLEtBQUssRUFBRTtBQUFFeEMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FMQztBQU1SeUMsSUFBQUEsS0FBSyxFQUFFO0FBQUV6QyxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQU5DO0FBT1IwQyxJQUFBQSxRQUFRLEVBQUU7QUFBRTFDLE1BQUFBLElBQUksRUFBRTtBQUFSO0FBUEYsR0EvQ3FEO0FBd0QvRDJDLEVBQUFBLFdBQVcsRUFBRTtBQUNYQyxJQUFBQSxRQUFRLEVBQUU7QUFBRTVDLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBREM7QUFFWDZDLElBQUFBLE1BQU0sRUFBRTtBQUFFN0MsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FGRztBQUVpQjtBQUM1QjhDLElBQUFBLEtBQUssRUFBRTtBQUFFOUMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FISTtBQUdnQjtBQUMzQitDLElBQUFBLE9BQU8sRUFBRTtBQUFFL0MsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FKRTtBQUlrQjtBQUM3QnlDLElBQUFBLEtBQUssRUFBRTtBQUFFekMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FMSTtBQU1YZ0QsSUFBQUEsTUFBTSxFQUFFO0FBQUVoRCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQU5HO0FBT1hpRCxJQUFBQSxtQkFBbUIsRUFBRTtBQUFFakQsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FQVjtBQVFYa0QsSUFBQUEsTUFBTSxFQUFFO0FBQUVsRCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQVJHO0FBU1htRCxJQUFBQSxPQUFPLEVBQUU7QUFBRW5ELE1BQUFBLElBQUksRUFBRTtBQUFSLEtBVEU7QUFVWG9ELElBQUFBLFNBQVMsRUFBRTtBQUFFcEQsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FWQTtBQVdYcUQsSUFBQUEsUUFBUSxFQUFFO0FBQUVyRCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQVhDO0FBWVhzRCxJQUFBQSxZQUFZLEVBQUU7QUFBRXRELE1BQUFBLElBQUksRUFBRTtBQUFSLEtBWkg7QUFhWHVELElBQUFBLFdBQVcsRUFBRTtBQUFFdkQsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FiRjtBQWNYd0QsSUFBQUEsYUFBYSxFQUFFO0FBQUV4RCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQWRKO0FBZVh5RCxJQUFBQSxnQkFBZ0IsRUFBRTtBQUFFekQsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FmUDtBQWdCWDBELElBQUFBLGtCQUFrQixFQUFFO0FBQUUxRCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQWhCVDtBQWlCWDJELElBQUFBLEtBQUssRUFBRTtBQUFFM0QsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FqQkksQ0FpQmdCOztBQWpCaEIsR0F4RGtEO0FBMkUvRDRELEVBQUFBLFVBQVUsRUFBRTtBQUNWQyxJQUFBQSxPQUFPLEVBQUU7QUFBRTdELE1BQUFBLElBQUksRUFBRTtBQUFSLEtBREM7QUFFVjZDLElBQUFBLE1BQU0sRUFBRTtBQUFFN0MsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FGRTtBQUdWa0QsSUFBQUEsTUFBTSxFQUFFO0FBQUVsRCxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUhFO0FBSVY4RCxJQUFBQSxPQUFPLEVBQUU7QUFBRTlELE1BQUFBLElBQUksRUFBRTtBQUFSLEtBSkM7QUFLVitELElBQUFBLE1BQU0sRUFBRTtBQUFFL0QsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FMRTtBQUtrQjtBQUM1QmdFLElBQUFBLFVBQVUsRUFBRTtBQUFFaEUsTUFBQUEsSUFBSSxFQUFFO0FBQVI7QUFORixHQTNFbUQ7QUFtRi9EaUUsRUFBQUEsWUFBWSxFQUFFO0FBQ1pKLElBQUFBLE9BQU8sRUFBRTtBQUFFN0QsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FERztBQUVaa0UsSUFBQUEsV0FBVyxFQUFFO0FBQUVsRSxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUZEO0FBR1orRCxJQUFBQSxNQUFNLEVBQUU7QUFBRS9ELE1BQUFBLElBQUksRUFBRTtBQUFSLEtBSEk7QUFJWm1FLElBQUFBLFVBQVUsRUFBRTtBQUFFbkUsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FKQTtBQUtab0UsSUFBQUEsVUFBVSxFQUFFO0FBQUVwRSxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUxBO0FBTVpxRSxJQUFBQSxTQUFTLEVBQUU7QUFBRXJFLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBTkM7QUFPWnNFLElBQUFBLE9BQU8sRUFBRTtBQUFFdEUsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FQRztBQVFadUUsSUFBQUEsYUFBYSxFQUFFO0FBQUV2RSxNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQVJILEdBbkZpRDtBQTZGL0R3RSxFQUFBQSxNQUFNLEVBQUU7QUFDTkMsSUFBQUEsWUFBWSxFQUFFO0FBQUV6RSxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQURSO0FBRU4wRSxJQUFBQSxTQUFTLEVBQUU7QUFBRTFFLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBRkw7QUFHTjJFLElBQUFBLFdBQVcsRUFBRTtBQUFFM0UsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FIUDtBQUlONEUsSUFBQUEsR0FBRyxFQUFFO0FBQUU1RSxNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQUpDLEdBN0Z1RDtBQW1HL0Q2RSxFQUFBQSxhQUFhLEVBQUU7QUFDYjlFLElBQUFBLFFBQVEsRUFBRTtBQUFFQyxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQURHO0FBRWIrRCxJQUFBQSxNQUFNLEVBQUU7QUFBRS9ELE1BQUFBLElBQUksRUFBRTtBQUFSLEtBRks7QUFHYjhFLElBQUFBLGFBQWEsRUFBRTtBQUFFOUUsTUFBQUEsSUFBSSxFQUFFO0FBQVI7QUFIRixHQW5HZ0Q7QUF3Ry9EK0UsRUFBQUEsY0FBYyxFQUFFO0FBQ2RoRixJQUFBQSxRQUFRLEVBQUU7QUFBRUMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FESTtBQUVkZ0YsSUFBQUEsTUFBTSxFQUFFO0FBQUVoRixNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQUZNLEdBeEcrQztBQTRHL0RpRixFQUFBQSxTQUFTLEVBQUU7QUFDVGxGLElBQUFBLFFBQVEsRUFBRTtBQUFFQyxNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUREO0FBRVR5QixJQUFBQSxJQUFJLEVBQUU7QUFBRXpCLE1BQUFBLElBQUksRUFBRTtBQUFSLEtBRkc7QUFHVDhDLElBQUFBLEtBQUssRUFBRTtBQUFFOUMsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FIRTtBQUdrQjtBQUMzQmtGLElBQUFBLFFBQVEsRUFBRTtBQUFFbEYsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FKRDtBQUtUbUYsSUFBQUEsU0FBUyxFQUFFO0FBQUVuRixNQUFBQSxJQUFJLEVBQUU7QUFBUjtBQUxGLEdBNUdvRDtBQW1IL0RvRixFQUFBQSxZQUFZLEVBQUU7QUFDWkMsSUFBQUEsS0FBSyxFQUFFO0FBQUVyRixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQURLO0FBRVpzRixJQUFBQSxNQUFNLEVBQUU7QUFBRXRGLE1BQUFBLElBQUksRUFBRTtBQUFSO0FBRkk7QUFuSGlELENBQWQsQ0FBbkQ7O0FBeUhBLE1BQU11RixlQUFlLEdBQUczRixNQUFNLENBQUNDLE1BQVAsQ0FBYztBQUNwQ3NDLEVBQUFBLFFBQVEsRUFBRSxDQUFDLG1CQUFELEVBQXNCLE1BQXRCLEVBQThCLE9BQTlCLEVBQXVDLE9BQXZDLEVBQWdELFVBQWhELENBRDBCO0FBRXBDWCxFQUFBQSxLQUFLLEVBQUUsQ0FBQyxNQUFELEVBQVMsS0FBVDtBQUY2QixDQUFkLENBQXhCO0FBS0EsTUFBTWdFLGFBQWEsR0FBRzVGLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLENBQ2xDLE9BRGtDLEVBRWxDLGVBRmtDLEVBR2xDLE9BSGtDLEVBSWxDLFVBSmtDLEVBS2xDLFVBTGtDLEVBTWxDLGFBTmtDLEVBT2xDLFlBUGtDLEVBUWxDLGNBUmtDLEVBU2xDLFdBVGtDLEVBVWxDLGNBVmtDLENBQWQsQ0FBdEI7O0FBYUEsTUFBTTRGLGVBQWUsR0FBRzdGLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLENBQ3BDLFlBRG9DLEVBRXBDLGFBRm9DLEVBR3BDLFFBSG9DLEVBSXBDLGVBSm9DLEVBS3BDLGdCQUxvQyxFQU1wQyxjQU5vQyxFQU9wQyxXQVBvQyxFQVFwQyxjQVJvQyxDQUFkLENBQXhCLEMsQ0FXQTs7QUFDQSxNQUFNNkYsU0FBUyxHQUFHLFVBQWxCLEMsQ0FDQTs7QUFDQSxNQUFNQywyQkFBMkIsR0FBRyxlQUFwQyxDLENBQ0E7O0FBQ0EsTUFBTUMsV0FBVyxHQUFHLE1BQXBCO0FBRUEsTUFBTUMsa0JBQWtCLEdBQUcsaUJBQTNCO0FBRUEsTUFBTUMsMkJBQTJCLEdBQUcsMEJBQXBDO0FBRUEsTUFBTUMsZUFBZSxHQUFHLGlCQUF4QixDLENBRUE7O0FBQ0EsTUFBTUMsb0JBQW9CLEdBQUdwRyxNQUFNLENBQUNDLE1BQVAsQ0FBYyxDQUN6QzhGLDJCQUR5QyxFQUV6Q0MsV0FGeUMsRUFHekNDLGtCQUh5QyxFQUl6Q0gsU0FKeUMsQ0FBZCxDQUE3QixDLENBT0E7O0FBQ0EsTUFBTU8sY0FBYyxHQUFHckcsTUFBTSxDQUFDQyxNQUFQLENBQWMsQ0FDbkNrRyxlQURtQyxFQUVuQ0gsV0FGbUMsRUFHbkNFLDJCQUhtQyxFQUluQ0osU0FKbUMsQ0FBZCxDQUF2Qjs7QUFPQSxTQUFTUSxxQkFBVCxDQUErQkMsR0FBL0IsRUFBb0NDLFlBQXBDLEVBQWtEO0FBQ2hELE1BQUlDLFdBQVcsR0FBRyxLQUFsQjs7QUFDQSxPQUFLLE1BQU1DLEtBQVgsSUFBb0JMLGNBQXBCLEVBQW9DO0FBQ2xDLFFBQUlFLEdBQUcsQ0FBQ0ksS0FBSixDQUFVRCxLQUFWLE1BQXFCLElBQXpCLEVBQStCO0FBQzdCRCxNQUFBQSxXQUFXLEdBQUcsSUFBZDtBQUNBO0FBQ0Q7QUFDRixHQVArQyxDQVNoRDs7O0FBQ0EsUUFBTUcsS0FBSyxHQUFHSCxXQUFXLElBQUlGLEdBQUcsQ0FBQ0ksS0FBSixDQUFVSCxZQUFWLE1BQTRCLElBQXpEOztBQUNBLE1BQUksQ0FBQ0ksS0FBTCxFQUFZO0FBQ1YsVUFBTSxJQUFJL0csS0FBSyxDQUFDZ0gsS0FBVixDQUNKaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZQyxZQURSLEVBRUgsSUFBR1AsR0FBSSxrREFGSixDQUFOO0FBSUQ7QUFDRjs7QUFFRCxTQUFTUSwwQkFBVCxDQUFvQ1IsR0FBcEMsRUFBeUNDLFlBQXpDLEVBQXVEO0FBQ3JELE1BQUlDLFdBQVcsR0FBRyxLQUFsQjs7QUFDQSxPQUFLLE1BQU1DLEtBQVgsSUFBb0JOLG9CQUFwQixFQUEwQztBQUN4QyxRQUFJRyxHQUFHLENBQUNJLEtBQUosQ0FBVUQsS0FBVixNQUFxQixJQUF6QixFQUErQjtBQUM3QkQsTUFBQUEsV0FBVyxHQUFHLElBQWQ7QUFDQTtBQUNEO0FBQ0YsR0FQb0QsQ0FTckQ7OztBQUNBLFFBQU1HLEtBQUssR0FBR0gsV0FBVyxJQUFJRixHQUFHLENBQUNJLEtBQUosQ0FBVUgsWUFBVixNQUE0QixJQUF6RDs7QUFDQSxNQUFJLENBQUNJLEtBQUwsRUFBWTtBQUNWLFVBQU0sSUFBSS9HLEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWUMsWUFEUixFQUVILElBQUdQLEdBQUksa0RBRkosQ0FBTjtBQUlEO0FBQ0Y7O0FBRUQsTUFBTVMsWUFBWSxHQUFHaEgsTUFBTSxDQUFDQyxNQUFQLENBQWMsQ0FDakMsTUFEaUMsRUFFakMsT0FGaUMsRUFHakMsS0FIaUMsRUFJakMsUUFKaUMsRUFLakMsUUFMaUMsRUFNakMsUUFOaUMsRUFPakMsVUFQaUMsRUFRakMsZ0JBUmlDLEVBU2pDLGlCQVRpQyxFQVVqQyxpQkFWaUMsQ0FBZCxDQUFyQixDLENBYUE7O0FBQ0EsU0FBU2dILFdBQVQsQ0FBcUJDLEtBQXJCLEVBQW1EQyxNQUFuRCxFQUF5RVgsWUFBekUsRUFBK0Y7QUFDN0YsTUFBSSxDQUFDVSxLQUFMLEVBQVk7QUFDVjtBQUNEOztBQUNELE9BQUssTUFBTUUsWUFBWCxJQUEyQkYsS0FBM0IsRUFBa0M7QUFDaEMsUUFBSUYsWUFBWSxDQUFDSyxPQUFiLENBQXFCRCxZQUFyQixLQUFzQyxDQUFDLENBQTNDLEVBQThDO0FBQzVDLFlBQU0sSUFBSXZILEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWUMsWUFEUixFQUVILEdBQUVNLFlBQWEsdURBRlosQ0FBTjtBQUlEOztBQUVELFVBQU1FLFNBQVMsR0FBR0osS0FBSyxDQUFDRSxZQUFELENBQXZCLENBUmdDLENBU2hDO0FBRUE7O0FBQ0FHLElBQUFBLGVBQWUsQ0FBQ0QsU0FBRCxFQUFZRixZQUFaLENBQWY7O0FBRUEsUUFBSUEsWUFBWSxLQUFLLGdCQUFqQixJQUFxQ0EsWUFBWSxLQUFLLGlCQUExRCxFQUE2RTtBQUMzRTtBQUNBO0FBQ0EsV0FBSyxNQUFNSSxTQUFYLElBQXdCRixTQUF4QixFQUFtQztBQUNqQ0csUUFBQUEseUJBQXlCLENBQUNELFNBQUQsRUFBWUwsTUFBWixFQUFvQkMsWUFBcEIsQ0FBekI7QUFDRCxPQUwwRSxDQU0zRTtBQUNBOzs7QUFDQTtBQUNELEtBdkIrQixDQXlCaEM7OztBQUNBLFFBQUlBLFlBQVksS0FBSyxpQkFBckIsRUFBd0M7QUFDdEMsV0FBSyxNQUFNTSxNQUFYLElBQXFCSixTQUFyQixFQUFnQztBQUM5QjtBQUNBUCxRQUFBQSwwQkFBMEIsQ0FBQ1csTUFBRCxFQUFTbEIsWUFBVCxDQUExQjtBQUVBLGNBQU1tQixlQUFlLEdBQUdMLFNBQVMsQ0FBQ0ksTUFBRCxDQUFqQzs7QUFFQSxZQUFJLENBQUNFLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixlQUFkLENBQUwsRUFBcUM7QUFDbkMsZ0JBQU0sSUFBSTlILEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWUMsWUFEUixFQUVILElBQUdhLGVBQWdCLDhDQUE2Q0QsTUFBTyx3QkFGcEUsQ0FBTjtBQUlELFNBWDZCLENBYTlCOzs7QUFDQSxhQUFLLE1BQU1JLEtBQVgsSUFBb0JILGVBQXBCLEVBQXFDO0FBQ25DO0FBQ0EsY0FBSTVILGNBQWMsQ0FBQ0csUUFBZixDQUF3QjRILEtBQXhCLENBQUosRUFBb0M7QUFDbEMsa0JBQU0sSUFBSWpJLEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWUMsWUFEUixFQUVILGtCQUFpQmdCLEtBQU0sd0JBRnBCLENBQU47QUFJRCxXQVBrQyxDQVFuQzs7O0FBQ0EsY0FBSSxDQUFDOUgsTUFBTSxDQUFDK0gsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDZCxNQUFyQyxFQUE2Q1csS0FBN0MsQ0FBTCxFQUEwRDtBQUN4RCxrQkFBTSxJQUFJakksS0FBSyxDQUFDZ0gsS0FBVixDQUNKaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZQyxZQURSLEVBRUgsVUFBU2dCLEtBQU0sd0JBQXVCSixNQUFPLGlCQUYxQyxDQUFOO0FBSUQ7QUFDRjtBQUNGLE9BL0JxQyxDQWdDdEM7OztBQUNBO0FBQ0QsS0E1RCtCLENBOERoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBSyxNQUFNQSxNQUFYLElBQXFCSixTQUFyQixFQUFnQztBQUM5QjtBQUNBaEIsTUFBQUEscUJBQXFCLENBQUNvQixNQUFELEVBQVNsQixZQUFULENBQXJCLENBRjhCLENBSTlCO0FBQ0E7O0FBQ0EsVUFBSWtCLE1BQU0sS0FBSyxlQUFmLEVBQWdDO0FBQzlCLGNBQU1RLGFBQWEsR0FBR1osU0FBUyxDQUFDSSxNQUFELENBQS9COztBQUVBLFlBQUlFLEtBQUssQ0FBQ0MsT0FBTixDQUFjSyxhQUFkLENBQUosRUFBa0M7QUFDaEMsZUFBSyxNQUFNQyxZQUFYLElBQTJCRCxhQUEzQixFQUEwQztBQUN4Q1QsWUFBQUEseUJBQXlCLENBQUNVLFlBQUQsRUFBZWhCLE1BQWYsRUFBdUJHLFNBQXZCLENBQXpCO0FBQ0Q7QUFDRixTQUpELE1BSU87QUFDTCxnQkFBTSxJQUFJekgsS0FBSyxDQUFDZ0gsS0FBVixDQUNKaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZQyxZQURSLEVBRUgsSUFBR29CLGFBQWMsOEJBQTZCZCxZQUFhLElBQUdNLE1BQU8sd0JBRmxFLENBQU47QUFJRCxTQVo2QixDQWE5Qjs7O0FBQ0E7QUFDRCxPQXJCNkIsQ0F1QjlCOzs7QUFDQSxZQUFNVSxNQUFNLEdBQUdkLFNBQVMsQ0FBQ0ksTUFBRCxDQUF4Qjs7QUFFQSxVQUFJVSxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixjQUFNLElBQUl2SSxLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVlDLFlBRFIsRUFFSCxJQUFHc0IsTUFBTyxzREFBcURoQixZQUFhLElBQUdNLE1BQU8sSUFBR1UsTUFBTyxFQUY3RixDQUFOO0FBSUQ7QUFDRjtBQUNGO0FBQ0Y7O0FBRUQsU0FBU2IsZUFBVCxDQUF5QkQsU0FBekIsRUFBeUNGLFlBQXpDLEVBQStEO0FBQzdELE1BQUlBLFlBQVksS0FBSyxnQkFBakIsSUFBcUNBLFlBQVksS0FBSyxpQkFBMUQsRUFBNkU7QUFDM0UsUUFBSSxDQUFDUSxLQUFLLENBQUNDLE9BQU4sQ0FBY1AsU0FBZCxDQUFMLEVBQStCO0FBQzdCLFlBQU0sSUFBSXpILEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWUMsWUFEUixFQUVILElBQUdRLFNBQVUsc0RBQXFERixZQUFhLHFCQUY1RSxDQUFOO0FBSUQ7QUFDRixHQVBELE1BT087QUFDTCxRQUFJLE9BQU9FLFNBQVAsS0FBcUIsUUFBckIsSUFBaUNBLFNBQVMsS0FBSyxJQUFuRCxFQUF5RDtBQUN2RDtBQUNBO0FBQ0QsS0FIRCxNQUdPO0FBQ0wsWUFBTSxJQUFJekgsS0FBSyxDQUFDZ0gsS0FBVixDQUNKaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZQyxZQURSLEVBRUgsSUFBR1EsU0FBVSxzREFBcURGLFlBQWEsc0JBRjVFLENBQU47QUFJRDtBQUNGO0FBQ0Y7O0FBRUQsU0FBU0sseUJBQVQsQ0FBbUNELFNBQW5DLEVBQXNETCxNQUF0RCxFQUFzRUcsU0FBdEUsRUFBeUY7QUFDdkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUNFLEVBQ0VILE1BQU0sQ0FBQ0ssU0FBRCxDQUFOLEtBQ0VMLE1BQU0sQ0FBQ0ssU0FBRCxDQUFOLENBQWtCcEgsSUFBbEIsSUFBMEIsU0FBMUIsSUFBdUMrRyxNQUFNLENBQUNLLFNBQUQsQ0FBTixDQUFrQnpGLFdBQWxCLElBQWlDLE9BQXpFLElBQ0NvRixNQUFNLENBQUNLLFNBQUQsQ0FBTixDQUFrQnBILElBQWxCLElBQTBCLE9BRjVCLENBREYsQ0FERixFQU1FO0FBQ0EsVUFBTSxJQUFJUCxLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVlDLFlBRFIsRUFFSCxJQUFHVSxTQUFVLCtEQUE4REYsU0FBVSxFQUZsRixDQUFOO0FBSUQ7QUFDRjs7QUFFRCxNQUFNZSxjQUFjLEdBQUcsb0NBQXZCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcseUJBQTNCOztBQUNBLFNBQVNDLGdCQUFULENBQTBCekQsU0FBMUIsRUFBc0Q7QUFDcEQ7QUFDQSxTQUNFO0FBQ0FjLElBQUFBLGFBQWEsQ0FBQ3lCLE9BQWQsQ0FBc0J2QyxTQUF0QixJQUFtQyxDQUFDLENBQXBDLElBQ0E7QUFDQXVELElBQUFBLGNBQWMsQ0FBQ0csSUFBZixDQUFvQjFELFNBQXBCLENBRkEsSUFHQTtBQUNBMkQsSUFBQUEsZ0JBQWdCLENBQUMzRCxTQUFEO0FBTmxCO0FBUUQsQyxDQUVEOzs7QUFDQSxTQUFTMkQsZ0JBQVQsQ0FBMEJqQixTQUExQixFQUFzRDtBQUNwRCxTQUFPYyxrQkFBa0IsQ0FBQ0UsSUFBbkIsQ0FBd0JoQixTQUF4QixDQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTa0Isd0JBQVQsQ0FBa0NsQixTQUFsQyxFQUFxRDFDLFNBQXJELEVBQWlGO0FBQy9FLE1BQUksQ0FBQzJELGdCQUFnQixDQUFDakIsU0FBRCxDQUFyQixFQUFrQztBQUNoQyxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJekgsY0FBYyxDQUFDRyxRQUFmLENBQXdCc0gsU0FBeEIsQ0FBSixFQUF3QztBQUN0QyxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJekgsY0FBYyxDQUFDK0UsU0FBRCxDQUFkLElBQTZCL0UsY0FBYyxDQUFDK0UsU0FBRCxDQUFkLENBQTBCMEMsU0FBMUIsQ0FBakMsRUFBdUU7QUFDckUsV0FBTyxLQUFQO0FBQ0Q7O0FBQ0QsU0FBTyxJQUFQO0FBQ0Q7O0FBRUQsU0FBU21CLHVCQUFULENBQWlDN0QsU0FBakMsRUFBNEQ7QUFDMUQsU0FDRSx3QkFDQUEsU0FEQSxHQUVBLG1HQUhGO0FBS0Q7O0FBRUQsTUFBTThELGdCQUFnQixHQUFHLElBQUkvSSxLQUFLLENBQUNnSCxLQUFWLENBQWdCaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZQyxZQUE1QixFQUEwQyxjQUExQyxDQUF6QjtBQUNBLE1BQU0rQiw4QkFBOEIsR0FBRyxDQUNyQyxRQURxQyxFQUVyQyxRQUZxQyxFQUdyQyxTQUhxQyxFQUlyQyxNQUpxQyxFQUtyQyxRQUxxQyxFQU1yQyxPQU5xQyxFQU9yQyxVQVBxQyxFQVFyQyxNQVJxQyxFQVNyQyxPQVRxQyxFQVVyQyxTQVZxQyxDQUF2QyxDLENBWUE7O0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsQ0FBQztBQUFFMUksRUFBQUEsSUFBRjtBQUFRMkIsRUFBQUE7QUFBUixDQUFELEtBQTJCO0FBQ3BELE1BQUksQ0FBQyxTQUFELEVBQVksVUFBWixFQUF3QnNGLE9BQXhCLENBQWdDakgsSUFBaEMsS0FBeUMsQ0FBN0MsRUFBZ0Q7QUFDOUMsUUFBSSxDQUFDMkIsV0FBTCxFQUFrQjtBQUNoQixhQUFPLElBQUlsQyxLQUFLLENBQUNnSCxLQUFWLENBQWdCLEdBQWhCLEVBQXNCLFFBQU96RyxJQUFLLHFCQUFsQyxDQUFQO0FBQ0QsS0FGRCxNQUVPLElBQUksT0FBTzJCLFdBQVAsS0FBdUIsUUFBM0IsRUFBcUM7QUFDMUMsYUFBTzZHLGdCQUFQO0FBQ0QsS0FGTSxNQUVBLElBQUksQ0FBQ0wsZ0JBQWdCLENBQUN4RyxXQUFELENBQXJCLEVBQW9DO0FBQ3pDLGFBQU8sSUFBSWxDLEtBQUssQ0FBQ2dILEtBQVYsQ0FBZ0JoSCxLQUFLLENBQUNnSCxLQUFOLENBQVlrQyxrQkFBNUIsRUFBZ0RKLHVCQUF1QixDQUFDNUcsV0FBRCxDQUF2RSxDQUFQO0FBQ0QsS0FGTSxNQUVBO0FBQ0wsYUFBT2lILFNBQVA7QUFDRDtBQUNGOztBQUNELE1BQUksT0FBTzVJLElBQVAsS0FBZ0IsUUFBcEIsRUFBOEI7QUFDNUIsV0FBT3dJLGdCQUFQO0FBQ0Q7O0FBQ0QsTUFBSUMsOEJBQThCLENBQUN4QixPQUEvQixDQUF1Q2pILElBQXZDLElBQStDLENBQW5ELEVBQXNEO0FBQ3BELFdBQU8sSUFBSVAsS0FBSyxDQUFDZ0gsS0FBVixDQUFnQmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWW9DLGNBQTVCLEVBQTZDLHVCQUFzQjdJLElBQUssRUFBeEUsQ0FBUDtBQUNEOztBQUNELFNBQU80SSxTQUFQO0FBQ0QsQ0FuQkQ7O0FBcUJBLE1BQU1FLDRCQUE0QixHQUFJQyxNQUFELElBQWlCO0FBQ3BEQSxFQUFBQSxNQUFNLEdBQUdDLG1CQUFtQixDQUFDRCxNQUFELENBQTVCO0FBQ0EsU0FBT0EsTUFBTSxDQUFDaEMsTUFBUCxDQUFjNUcsR0FBckI7QUFDQTRJLEVBQUFBLE1BQU0sQ0FBQ2hDLE1BQVAsQ0FBY2tDLE1BQWQsR0FBdUI7QUFBRWpKLElBQUFBLElBQUksRUFBRTtBQUFSLEdBQXZCO0FBQ0ErSSxFQUFBQSxNQUFNLENBQUNoQyxNQUFQLENBQWNtQyxNQUFkLEdBQXVCO0FBQUVsSixJQUFBQSxJQUFJLEVBQUU7QUFBUixHQUF2Qjs7QUFFQSxNQUFJK0ksTUFBTSxDQUFDckUsU0FBUCxLQUFxQixPQUF6QixFQUFrQztBQUNoQyxXQUFPcUUsTUFBTSxDQUFDaEMsTUFBUCxDQUFjekcsUUFBckI7QUFDQXlJLElBQUFBLE1BQU0sQ0FBQ2hDLE1BQVAsQ0FBY29DLGdCQUFkLEdBQWlDO0FBQUVuSixNQUFBQSxJQUFJLEVBQUU7QUFBUixLQUFqQztBQUNEOztBQUVELFNBQU8rSSxNQUFQO0FBQ0QsQ0FaRDs7OztBQWNBLE1BQU1LLGlDQUFpQyxHQUFHLFVBQW1CO0FBQUEsTUFBYkwsTUFBYTs7QUFDM0QsU0FBT0EsTUFBTSxDQUFDaEMsTUFBUCxDQUFja0MsTUFBckI7QUFDQSxTQUFPRixNQUFNLENBQUNoQyxNQUFQLENBQWNtQyxNQUFyQjtBQUVBSCxFQUFBQSxNQUFNLENBQUNoQyxNQUFQLENBQWM1RyxHQUFkLEdBQW9CO0FBQUVILElBQUFBLElBQUksRUFBRTtBQUFSLEdBQXBCOztBQUVBLE1BQUkrSSxNQUFNLENBQUNyRSxTQUFQLEtBQXFCLE9BQXpCLEVBQWtDO0FBQ2hDLFdBQU9xRSxNQUFNLENBQUNoQyxNQUFQLENBQWN0RyxRQUFyQixDQURnQyxDQUNEOztBQUMvQixXQUFPc0ksTUFBTSxDQUFDaEMsTUFBUCxDQUFjb0MsZ0JBQXJCO0FBQ0FKLElBQUFBLE1BQU0sQ0FBQ2hDLE1BQVAsQ0FBY3pHLFFBQWQsR0FBeUI7QUFBRU4sTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FBekI7QUFDRDs7QUFFRCxNQUFJK0ksTUFBTSxDQUFDTSxPQUFQLElBQWtCekosTUFBTSxDQUFDMEosSUFBUCxDQUFZUCxNQUFNLENBQUNNLE9BQW5CLEVBQTRCRSxNQUE1QixLQUF1QyxDQUE3RCxFQUFnRTtBQUM5RCxXQUFPUixNQUFNLENBQUNNLE9BQWQ7QUFDRDs7QUFFRCxTQUFPTixNQUFQO0FBQ0QsQ0FqQkQ7O0FBbUJBLE1BQU1TLFVBQU4sQ0FBaUI7QUFHZkMsRUFBQUEsV0FBVyxDQUFDQyxVQUFVLEdBQUcsRUFBZCxFQUFrQm5DLGVBQWUsR0FBRyxFQUFwQyxFQUF3QztBQUNqRCxTQUFLb0MsTUFBTCxHQUFjLEVBQWQ7QUFDQSxTQUFLQyxpQkFBTCxHQUF5QnJDLGVBQXpCO0FBQ0FtQyxJQUFBQSxVQUFVLENBQUNHLE9BQVgsQ0FBbUJkLE1BQU0sSUFBSTtBQUMzQixVQUFJdEQsZUFBZSxDQUFDcUUsUUFBaEIsQ0FBeUJmLE1BQU0sQ0FBQ3JFLFNBQWhDLENBQUosRUFBZ0Q7QUFDOUM7QUFDRDs7QUFDRDlFLE1BQUFBLE1BQU0sQ0FBQ21LLGNBQVAsQ0FBc0IsSUFBdEIsRUFBNEJoQixNQUFNLENBQUNyRSxTQUFuQyxFQUE4QztBQUM1Q3NGLFFBQUFBLEdBQUcsRUFBRSxNQUFNO0FBQ1QsY0FBSSxDQUFDLEtBQUtMLE1BQUwsQ0FBWVosTUFBTSxDQUFDckUsU0FBbkIsQ0FBTCxFQUFvQztBQUNsQyxrQkFBTXVGLElBQUksR0FBRyxFQUFiO0FBQ0FBLFlBQUFBLElBQUksQ0FBQ2xELE1BQUwsR0FBY2lDLG1CQUFtQixDQUFDRCxNQUFELENBQW5CLENBQTRCaEMsTUFBMUM7QUFDQWtELFlBQUFBLElBQUksQ0FBQ0MscUJBQUwsR0FBNkIsdUJBQVNuQixNQUFNLENBQUNtQixxQkFBaEIsQ0FBN0I7QUFDQUQsWUFBQUEsSUFBSSxDQUFDWixPQUFMLEdBQWVOLE1BQU0sQ0FBQ00sT0FBdEI7QUFFQSxrQkFBTWMsb0JBQW9CLEdBQUcsS0FBS1AsaUJBQUwsQ0FBdUJiLE1BQU0sQ0FBQ3JFLFNBQTlCLENBQTdCOztBQUNBLGdCQUFJeUYsb0JBQUosRUFBMEI7QUFDeEIsbUJBQUssTUFBTWhFLEdBQVgsSUFBa0JnRSxvQkFBbEIsRUFBd0M7QUFDdEMsc0JBQU1DLEdBQUcsR0FBRyxJQUFJQyxHQUFKLENBQVEsQ0FDbEIsSUFBSUosSUFBSSxDQUFDQyxxQkFBTCxDQUEyQjNDLGVBQTNCLENBQTJDcEIsR0FBM0MsS0FBbUQsRUFBdkQsQ0FEa0IsRUFFbEIsR0FBR2dFLG9CQUFvQixDQUFDaEUsR0FBRCxDQUZMLENBQVIsQ0FBWjtBQUlBOEQsZ0JBQUFBLElBQUksQ0FBQ0MscUJBQUwsQ0FBMkIzQyxlQUEzQixDQUEyQ3BCLEdBQTNDLElBQWtEcUIsS0FBSyxDQUFDOEMsSUFBTixDQUFXRixHQUFYLENBQWxEO0FBQ0Q7QUFDRjs7QUFFRCxpQkFBS1QsTUFBTCxDQUFZWixNQUFNLENBQUNyRSxTQUFuQixJQUFnQ3VGLElBQWhDO0FBQ0Q7O0FBQ0QsaUJBQU8sS0FBS04sTUFBTCxDQUFZWixNQUFNLENBQUNyRSxTQUFuQixDQUFQO0FBQ0Q7QUF0QjJDLE9BQTlDO0FBd0JELEtBNUJELEVBSGlELENBaUNqRDs7QUFDQWUsSUFBQUEsZUFBZSxDQUFDb0UsT0FBaEIsQ0FBd0JuRixTQUFTLElBQUk7QUFDbkM5RSxNQUFBQSxNQUFNLENBQUNtSyxjQUFQLENBQXNCLElBQXRCLEVBQTRCckYsU0FBNUIsRUFBdUM7QUFDckNzRixRQUFBQSxHQUFHLEVBQUUsTUFBTTtBQUNULGNBQUksQ0FBQyxLQUFLTCxNQUFMLENBQVlqRixTQUFaLENBQUwsRUFBNkI7QUFDM0Isa0JBQU1xRSxNQUFNLEdBQUdDLG1CQUFtQixDQUFDO0FBQ2pDdEUsY0FBQUEsU0FEaUM7QUFFakNxQyxjQUFBQSxNQUFNLEVBQUUsRUFGeUI7QUFHakNtRCxjQUFBQSxxQkFBcUIsRUFBRTtBQUhVLGFBQUQsQ0FBbEM7QUFLQSxrQkFBTUQsSUFBSSxHQUFHLEVBQWI7QUFDQUEsWUFBQUEsSUFBSSxDQUFDbEQsTUFBTCxHQUFjZ0MsTUFBTSxDQUFDaEMsTUFBckI7QUFDQWtELFlBQUFBLElBQUksQ0FBQ0MscUJBQUwsR0FBNkJuQixNQUFNLENBQUNtQixxQkFBcEM7QUFDQUQsWUFBQUEsSUFBSSxDQUFDWixPQUFMLEdBQWVOLE1BQU0sQ0FBQ00sT0FBdEI7QUFDQSxpQkFBS00sTUFBTCxDQUFZakYsU0FBWixJQUF5QnVGLElBQXpCO0FBQ0Q7O0FBQ0QsaUJBQU8sS0FBS04sTUFBTCxDQUFZakYsU0FBWixDQUFQO0FBQ0Q7QUFmb0MsT0FBdkM7QUFpQkQsS0FsQkQ7QUFtQkQ7O0FBeERjOztBQTJEakIsTUFBTXNFLG1CQUFtQixHQUFHLENBQUM7QUFBRXRFLEVBQUFBLFNBQUY7QUFBYXFDLEVBQUFBLE1BQWI7QUFBcUJtRCxFQUFBQSxxQkFBckI7QUFBNENiLEVBQUFBO0FBQTVDLENBQUQsS0FBbUU7QUFDN0YsUUFBTWtCLGFBQXFCLEdBQUc7QUFDNUI3RixJQUFBQSxTQUQ0QjtBQUU1QnFDLElBQUFBLE1BQU0sZ0RBQ0RwSCxjQUFjLENBQUNHLFFBRGQsR0FFQUgsY0FBYyxDQUFDK0UsU0FBRCxDQUFkLElBQTZCLEVBRjdCLEdBR0RxQyxNQUhDLENBRnNCO0FBTzVCbUQsSUFBQUE7QUFQNEIsR0FBOUI7O0FBU0EsTUFBSWIsT0FBTyxJQUFJekosTUFBTSxDQUFDMEosSUFBUCxDQUFZRCxPQUFaLEVBQXFCRSxNQUFyQixLQUFnQyxDQUEvQyxFQUFrRDtBQUNoRGdCLElBQUFBLGFBQWEsQ0FBQ2xCLE9BQWQsR0FBd0JBLE9BQXhCO0FBQ0Q7O0FBQ0QsU0FBT2tCLGFBQVA7QUFDRCxDQWREOztBQWdCQSxNQUFNQyxZQUFZLEdBQUc7QUFBRTlGLEVBQUFBLFNBQVMsRUFBRSxRQUFiO0FBQXVCcUMsRUFBQUEsTUFBTSxFQUFFcEgsY0FBYyxDQUFDNkU7QUFBOUMsQ0FBckI7QUFDQSxNQUFNaUcsbUJBQW1CLEdBQUc7QUFDMUIvRixFQUFBQSxTQUFTLEVBQUUsZUFEZTtBQUUxQnFDLEVBQUFBLE1BQU0sRUFBRXBILGNBQWMsQ0FBQ2tGO0FBRkcsQ0FBNUI7QUFJQSxNQUFNNkYsb0JBQW9CLEdBQUc7QUFDM0JoRyxFQUFBQSxTQUFTLEVBQUUsZ0JBRGdCO0FBRTNCcUMsRUFBQUEsTUFBTSxFQUFFcEgsY0FBYyxDQUFDb0Y7QUFGSSxDQUE3Qjs7QUFJQSxNQUFNNEYsaUJBQWlCLEdBQUc3Qiw0QkFBNEIsQ0FDcERFLG1CQUFtQixDQUFDO0FBQ2xCdEUsRUFBQUEsU0FBUyxFQUFFLGFBRE87QUFFbEJxQyxFQUFBQSxNQUFNLEVBQUUsRUFGVTtBQUdsQm1ELEVBQUFBLHFCQUFxQixFQUFFO0FBSEwsQ0FBRCxDQURpQyxDQUF0RDs7QUFPQSxNQUFNVSxnQkFBZ0IsR0FBRzlCLDRCQUE0QixDQUNuREUsbUJBQW1CLENBQUM7QUFDbEJ0RSxFQUFBQSxTQUFTLEVBQUUsWUFETztBQUVsQnFDLEVBQUFBLE1BQU0sRUFBRSxFQUZVO0FBR2xCbUQsRUFBQUEscUJBQXFCLEVBQUU7QUFITCxDQUFELENBRGdDLENBQXJEOztBQU9BLE1BQU1XLGtCQUFrQixHQUFHL0IsNEJBQTRCLENBQ3JERSxtQkFBbUIsQ0FBQztBQUNsQnRFLEVBQUFBLFNBQVMsRUFBRSxjQURPO0FBRWxCcUMsRUFBQUEsTUFBTSxFQUFFLEVBRlU7QUFHbEJtRCxFQUFBQSxxQkFBcUIsRUFBRTtBQUhMLENBQUQsQ0FEa0MsQ0FBdkQ7O0FBT0EsTUFBTVksZUFBZSxHQUFHaEMsNEJBQTRCLENBQ2xERSxtQkFBbUIsQ0FBQztBQUNsQnRFLEVBQUFBLFNBQVMsRUFBRSxXQURPO0FBRWxCcUMsRUFBQUEsTUFBTSxFQUFFcEgsY0FBYyxDQUFDc0YsU0FGTDtBQUdsQmlGLEVBQUFBLHFCQUFxQixFQUFFO0FBSEwsQ0FBRCxDQUQrQixDQUFwRDs7QUFPQSxNQUFNYSxrQkFBa0IsR0FBR2pDLDRCQUE0QixDQUNyREUsbUJBQW1CLENBQUM7QUFDbEJ0RSxFQUFBQSxTQUFTLEVBQUUsY0FETztBQUVsQnFDLEVBQUFBLE1BQU0sRUFBRXBILGNBQWMsQ0FBQ3lGLFlBRkw7QUFHbEI4RSxFQUFBQSxxQkFBcUIsRUFBRTtBQUhMLENBQUQsQ0FEa0MsQ0FBdkQ7O0FBT0EsTUFBTWMsc0JBQXNCLEdBQUcsQ0FDN0JSLFlBRDZCLEVBRTdCSSxnQkFGNkIsRUFHN0JDLGtCQUg2QixFQUk3QkYsaUJBSjZCLEVBSzdCRixtQkFMNkIsRUFNN0JDLG9CQU42QixFQU83QkksZUFQNkIsRUFRN0JDLGtCQVI2QixDQUEvQjs7O0FBV0EsTUFBTUUsdUJBQXVCLEdBQUcsQ0FBQ0MsTUFBRCxFQUErQkMsVUFBL0IsS0FBMkQ7QUFDekYsTUFBSUQsTUFBTSxDQUFDbEwsSUFBUCxLQUFnQm1MLFVBQVUsQ0FBQ25MLElBQS9CLEVBQXFDLE9BQU8sS0FBUDtBQUNyQyxNQUFJa0wsTUFBTSxDQUFDdkosV0FBUCxLQUF1QndKLFVBQVUsQ0FBQ3hKLFdBQXRDLEVBQW1ELE9BQU8sS0FBUDtBQUNuRCxNQUFJdUosTUFBTSxLQUFLQyxVQUFVLENBQUNuTCxJQUExQixFQUFnQyxPQUFPLElBQVA7QUFDaEMsTUFBSWtMLE1BQU0sQ0FBQ2xMLElBQVAsS0FBZ0JtTCxVQUFVLENBQUNuTCxJQUEvQixFQUFxQyxPQUFPLElBQVA7QUFDckMsU0FBTyxLQUFQO0FBQ0QsQ0FORDs7QUFRQSxNQUFNb0wsWUFBWSxHQUFJcEwsSUFBRCxJQUF3QztBQUMzRCxNQUFJLE9BQU9BLElBQVAsS0FBZ0IsUUFBcEIsRUFBOEI7QUFDNUIsV0FBT0EsSUFBUDtBQUNEOztBQUNELE1BQUlBLElBQUksQ0FBQzJCLFdBQVQsRUFBc0I7QUFDcEIsV0FBUSxHQUFFM0IsSUFBSSxDQUFDQSxJQUFLLElBQUdBLElBQUksQ0FBQzJCLFdBQVksR0FBeEM7QUFDRDs7QUFDRCxTQUFRLEdBQUUzQixJQUFJLENBQUNBLElBQUssRUFBcEI7QUFDRCxDQVJELEMsQ0FVQTtBQUNBOzs7QUFDZSxNQUFNcUwsZ0JBQU4sQ0FBdUI7QUFRcEM1QixFQUFBQSxXQUFXLENBQUM2QixlQUFELEVBQWtDQyxXQUFsQyxFQUFvRDtBQUM3RCxTQUFLQyxVQUFMLEdBQWtCRixlQUFsQjtBQUNBLFNBQUtHLE1BQUwsR0FBY0YsV0FBZDtBQUNBLFNBQUtHLFVBQUwsR0FBa0IsSUFBSWxDLFVBQUosRUFBbEI7QUFDQSxTQUFLakMsZUFBTCxHQUF1Qm9FLGdCQUFPM0IsR0FBUCxDQUFXdkssS0FBSyxDQUFDbU0sYUFBakIsRUFBZ0NyRSxlQUF2RDs7QUFFQSxVQUFNc0UsU0FBUyxHQUFHRixnQkFBTzNCLEdBQVAsQ0FBV3ZLLEtBQUssQ0FBQ21NLGFBQWpCLEVBQWdDRSxtQkFBbEQ7O0FBRUEsVUFBTUMsYUFBYSxHQUFHLFVBQXRCLENBUjZELENBUTNCOztBQUNsQyxVQUFNQyxXQUFXLEdBQUcsbUJBQXBCO0FBRUEsU0FBS0MsV0FBTCxHQUFtQkosU0FBUyxHQUFHRSxhQUFILEdBQW1CQyxXQUEvQztBQUNEOztBQUVERSxFQUFBQSxVQUFVLENBQUNDLE9BQTBCLEdBQUc7QUFBRUMsSUFBQUEsVUFBVSxFQUFFO0FBQWQsR0FBOUIsRUFBbUU7QUFDM0UsUUFBSSxLQUFLQyxpQkFBTCxJQUEwQixDQUFDRixPQUFPLENBQUNDLFVBQXZDLEVBQW1EO0FBQ2pELGFBQU8sS0FBS0MsaUJBQVo7QUFDRDs7QUFDRCxTQUFLQSxpQkFBTCxHQUF5QixLQUFLQyxhQUFMLENBQW1CSCxPQUFuQixFQUN0QkksSUFEc0IsQ0FFckI3QyxVQUFVLElBQUk7QUFDWixXQUFLZ0MsVUFBTCxHQUFrQixJQUFJbEMsVUFBSixDQUFlRSxVQUFmLEVBQTJCLEtBQUtuQyxlQUFoQyxDQUFsQjtBQUNBLGFBQU8sS0FBSzhFLGlCQUFaO0FBQ0QsS0FMb0IsRUFNckJHLEdBQUcsSUFBSTtBQUNMLFdBQUtkLFVBQUwsR0FBa0IsSUFBSWxDLFVBQUosRUFBbEI7QUFDQSxhQUFPLEtBQUs2QyxpQkFBWjtBQUNBLFlBQU1HLEdBQU47QUFDRCxLQVZvQixFQVl0QkQsSUFac0IsQ0FZakIsTUFBTSxDQUFFLENBWlMsQ0FBekI7QUFhQSxXQUFPLEtBQUtGLGlCQUFaO0FBQ0Q7O0FBRURDLEVBQUFBLGFBQWEsQ0FBQ0gsT0FBMEIsR0FBRztBQUFFQyxJQUFBQSxVQUFVLEVBQUU7QUFBZCxHQUE5QixFQUE2RTtBQUN4RixRQUFJRCxPQUFPLENBQUNDLFVBQVosRUFBd0I7QUFDdEIsYUFBTyxLQUFLSyxhQUFMLEVBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtoQixNQUFMLENBQVlhLGFBQVosR0FBNEJDLElBQTVCLENBQWlDRyxVQUFVLElBQUk7QUFDcEQsVUFBSUEsVUFBVSxJQUFJQSxVQUFVLENBQUNuRCxNQUE3QixFQUFxQztBQUNuQyxlQUFPb0QsT0FBTyxDQUFDQyxPQUFSLENBQWdCRixVQUFoQixDQUFQO0FBQ0Q7O0FBQ0QsYUFBTyxLQUFLRCxhQUFMLEVBQVA7QUFDRCxLQUxNLENBQVA7QUFNRDs7QUFFREEsRUFBQUEsYUFBYSxHQUEyQjtBQUN0QyxXQUFPLEtBQUtqQixVQUFMLENBQ0pjLGFBREksR0FFSkMsSUFGSSxDQUVDN0MsVUFBVSxJQUFJQSxVQUFVLENBQUNtRCxHQUFYLENBQWU3RCxtQkFBZixDQUZmLEVBR0p1RCxJQUhJLENBR0M3QyxVQUFVLElBQUk7QUFDbEI7QUFDQSxXQUFLK0IsTUFBTCxDQUNHZ0IsYUFESCxDQUNpQi9DLFVBRGpCLEVBRUdvRCxLQUZILENBRVNDLEtBQUssSUFBSUMsT0FBTyxDQUFDRCxLQUFSLENBQWMsK0JBQWQsRUFBK0NBLEtBQS9DLENBRmxCO0FBR0E7OztBQUNBLGFBQU9yRCxVQUFQO0FBQ0QsS0FWSSxDQUFQO0FBV0Q7O0FBRUR1RCxFQUFBQSxZQUFZLENBQ1Z2SSxTQURVLEVBRVZ3SSxvQkFBNkIsR0FBRyxLQUZ0QixFQUdWZixPQUEwQixHQUFHO0FBQUVDLElBQUFBLFVBQVUsRUFBRTtBQUFkLEdBSG5CLEVBSU87QUFDakIsUUFBSWUsT0FBTyxHQUFHUixPQUFPLENBQUNDLE9BQVIsRUFBZDs7QUFDQSxRQUFJVCxPQUFPLENBQUNDLFVBQVosRUFBd0I7QUFDdEJlLE1BQUFBLE9BQU8sR0FBRyxLQUFLMUIsTUFBTCxDQUFZMkIsS0FBWixFQUFWO0FBQ0Q7O0FBQ0QsV0FBT0QsT0FBTyxDQUFDWixJQUFSLENBQWEsTUFBTTtBQUN4QixVQUFJVyxvQkFBb0IsSUFBSXpILGVBQWUsQ0FBQ3dCLE9BQWhCLENBQXdCdkMsU0FBeEIsSUFBcUMsQ0FBQyxDQUFsRSxFQUFxRTtBQUNuRSxjQUFNdUYsSUFBSSxHQUFHLEtBQUt5QixVQUFMLENBQWdCaEgsU0FBaEIsQ0FBYjtBQUNBLGVBQU9pSSxPQUFPLENBQUNDLE9BQVIsQ0FBZ0I7QUFDckJsSSxVQUFBQSxTQURxQjtBQUVyQnFDLFVBQUFBLE1BQU0sRUFBRWtELElBQUksQ0FBQ2xELE1BRlE7QUFHckJtRCxVQUFBQSxxQkFBcUIsRUFBRUQsSUFBSSxDQUFDQyxxQkFIUDtBQUlyQmIsVUFBQUEsT0FBTyxFQUFFWSxJQUFJLENBQUNaO0FBSk8sU0FBaEIsQ0FBUDtBQU1EOztBQUNELGFBQU8sS0FBS29DLE1BQUwsQ0FBWXdCLFlBQVosQ0FBeUJ2SSxTQUF6QixFQUFvQzZILElBQXBDLENBQXlDYyxNQUFNLElBQUk7QUFDeEQsWUFBSUEsTUFBTSxJQUFJLENBQUNsQixPQUFPLENBQUNDLFVBQXZCLEVBQW1DO0FBQ2pDLGlCQUFPTyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JTLE1BQWhCLENBQVA7QUFDRDs7QUFDRCxlQUFPLEtBQUtaLGFBQUwsR0FBcUJGLElBQXJCLENBQTBCN0MsVUFBVSxJQUFJO0FBQzdDLGdCQUFNNEQsU0FBUyxHQUFHNUQsVUFBVSxDQUFDNkQsSUFBWCxDQUFnQnhFLE1BQU0sSUFBSUEsTUFBTSxDQUFDckUsU0FBUCxLQUFxQkEsU0FBL0MsQ0FBbEI7O0FBQ0EsY0FBSSxDQUFDNEksU0FBTCxFQUFnQjtBQUNkLG1CQUFPWCxPQUFPLENBQUNhLE1BQVIsQ0FBZTVFLFNBQWYsQ0FBUDtBQUNEOztBQUNELGlCQUFPMEUsU0FBUDtBQUNELFNBTk0sQ0FBUDtBQU9ELE9BWE0sQ0FBUDtBQVlELEtBdEJNLENBQVA7QUF1QkQsR0FwR21DLENBc0dwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0FHLEVBQUFBLG1CQUFtQixDQUNqQi9JLFNBRGlCLEVBRWpCcUMsTUFBb0IsR0FBRyxFQUZOLEVBR2pCbUQscUJBSGlCLEVBSWpCYixPQUFZLEdBQUcsRUFKRSxFQUtPO0FBQ3hCLFFBQUlxRSxlQUFlLEdBQUcsS0FBS0MsZ0JBQUwsQ0FBc0JqSixTQUF0QixFQUFpQ3FDLE1BQWpDLEVBQXlDbUQscUJBQXpDLENBQXRCOztBQUNBLFFBQUl3RCxlQUFKLEVBQXFCO0FBQ25CLFVBQUlBLGVBQWUsWUFBWWpPLEtBQUssQ0FBQ2dILEtBQXJDLEVBQTRDO0FBQzFDLGVBQU9rRyxPQUFPLENBQUNhLE1BQVIsQ0FBZUUsZUFBZixDQUFQO0FBQ0QsT0FGRCxNQUVPLElBQUlBLGVBQWUsQ0FBQ0UsSUFBaEIsSUFBd0JGLGVBQWUsQ0FBQ1gsS0FBNUMsRUFBbUQ7QUFDeEQsZUFBT0osT0FBTyxDQUFDYSxNQUFSLENBQWUsSUFBSS9OLEtBQUssQ0FBQ2dILEtBQVYsQ0FBZ0JpSCxlQUFlLENBQUNFLElBQWhDLEVBQXNDRixlQUFlLENBQUNYLEtBQXRELENBQWYsQ0FBUDtBQUNEOztBQUNELGFBQU9KLE9BQU8sQ0FBQ2EsTUFBUixDQUFlRSxlQUFmLENBQVA7QUFDRDs7QUFFRCxXQUFPLEtBQUtsQyxVQUFMLENBQ0pxQyxXQURJLENBRUhuSixTQUZHLEVBR0hvRSw0QkFBNEIsQ0FBQztBQUMzQi9CLE1BQUFBLE1BRDJCO0FBRTNCbUQsTUFBQUEscUJBRjJCO0FBRzNCYixNQUFBQSxPQUgyQjtBQUkzQjNFLE1BQUFBO0FBSjJCLEtBQUQsQ0FIekIsRUFVSjZILElBVkksQ0FVQ25ELGlDQVZELEVBV0owRCxLQVhJLENBV0VDLEtBQUssSUFBSTtBQUNkLFVBQUlBLEtBQUssSUFBSUEsS0FBSyxDQUFDYSxJQUFOLEtBQWVuTyxLQUFLLENBQUNnSCxLQUFOLENBQVlxSCxlQUF4QyxFQUF5RDtBQUN2RCxjQUFNLElBQUlyTyxLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVlrQyxrQkFEUixFQUVILFNBQVFqRSxTQUFVLGtCQUZmLENBQU47QUFJRCxPQUxELE1BS087QUFDTCxjQUFNcUksS0FBTjtBQUNEO0FBQ0YsS0FwQkksQ0FBUDtBQXFCRDs7QUFFRGdCLEVBQUFBLFdBQVcsQ0FDVHJKLFNBRFMsRUFFVHNKLGVBRlMsRUFHVDlELHFCQUhTLEVBSVRiLE9BSlMsRUFLVDRFLFFBTFMsRUFNVDtBQUNBLFdBQU8sS0FBS2hCLFlBQUwsQ0FBa0J2SSxTQUFsQixFQUNKNkgsSUFESSxDQUNDeEQsTUFBTSxJQUFJO0FBQ2QsWUFBTW1GLGNBQWMsR0FBR25GLE1BQU0sQ0FBQ2hDLE1BQTlCO0FBQ0FuSCxNQUFBQSxNQUFNLENBQUMwSixJQUFQLENBQVkwRSxlQUFaLEVBQTZCbkUsT0FBN0IsQ0FBcUNwSSxJQUFJLElBQUk7QUFDM0MsY0FBTWlHLEtBQUssR0FBR3NHLGVBQWUsQ0FBQ3ZNLElBQUQsQ0FBN0I7O0FBQ0EsWUFBSXlNLGNBQWMsQ0FBQ3pNLElBQUQsQ0FBZCxJQUF3QmlHLEtBQUssQ0FBQ3lHLElBQU4sS0FBZSxRQUEzQyxFQUFxRDtBQUNuRCxnQkFBTSxJQUFJMU8sS0FBSyxDQUFDZ0gsS0FBVixDQUFnQixHQUFoQixFQUFzQixTQUFRaEYsSUFBSyx5QkFBbkMsQ0FBTjtBQUNEOztBQUNELFlBQUksQ0FBQ3lNLGNBQWMsQ0FBQ3pNLElBQUQsQ0FBZixJQUF5QmlHLEtBQUssQ0FBQ3lHLElBQU4sS0FBZSxRQUE1QyxFQUFzRDtBQUNwRCxnQkFBTSxJQUFJMU8sS0FBSyxDQUFDZ0gsS0FBVixDQUFnQixHQUFoQixFQUFzQixTQUFRaEYsSUFBSyxpQ0FBbkMsQ0FBTjtBQUNEO0FBQ0YsT0FSRDtBQVVBLGFBQU95TSxjQUFjLENBQUNqRixNQUF0QjtBQUNBLGFBQU9pRixjQUFjLENBQUNoRixNQUF0QjtBQUNBLFlBQU1rRixTQUFTLEdBQUdDLHVCQUF1QixDQUFDSCxjQUFELEVBQWlCRixlQUFqQixDQUF6QztBQUNBLFlBQU1NLGFBQWEsR0FBRzNPLGNBQWMsQ0FBQytFLFNBQUQsQ0FBZCxJQUE2Qi9FLGNBQWMsQ0FBQ0csUUFBbEU7QUFDQSxZQUFNeU8sYUFBYSxHQUFHM08sTUFBTSxDQUFDNE8sTUFBUCxDQUFjLEVBQWQsRUFBa0JKLFNBQWxCLEVBQTZCRSxhQUE3QixDQUF0QjtBQUNBLFlBQU1aLGVBQWUsR0FBRyxLQUFLZSxrQkFBTCxDQUN0Qi9KLFNBRHNCLEVBRXRCMEosU0FGc0IsRUFHdEJsRSxxQkFIc0IsRUFJdEJ0SyxNQUFNLENBQUMwSixJQUFQLENBQVk0RSxjQUFaLENBSnNCLENBQXhCOztBQU1BLFVBQUlSLGVBQUosRUFBcUI7QUFDbkIsY0FBTSxJQUFJak8sS0FBSyxDQUFDZ0gsS0FBVixDQUFnQmlILGVBQWUsQ0FBQ0UsSUFBaEMsRUFBc0NGLGVBQWUsQ0FBQ1gsS0FBdEQsQ0FBTjtBQUNELE9BekJhLENBMkJkO0FBQ0E7OztBQUNBLFlBQU0yQixhQUF1QixHQUFHLEVBQWhDO0FBQ0EsWUFBTUMsY0FBYyxHQUFHLEVBQXZCO0FBQ0EvTyxNQUFBQSxNQUFNLENBQUMwSixJQUFQLENBQVkwRSxlQUFaLEVBQTZCbkUsT0FBN0IsQ0FBcUN6QyxTQUFTLElBQUk7QUFDaEQsWUFBSTRHLGVBQWUsQ0FBQzVHLFNBQUQsQ0FBZixDQUEyQitHLElBQTNCLEtBQW9DLFFBQXhDLEVBQWtEO0FBQ2hETyxVQUFBQSxhQUFhLENBQUNFLElBQWQsQ0FBbUJ4SCxTQUFuQjtBQUNELFNBRkQsTUFFTztBQUNMdUgsVUFBQUEsY0FBYyxDQUFDQyxJQUFmLENBQW9CeEgsU0FBcEI7QUFDRDtBQUNGLE9BTkQ7QUFRQSxVQUFJeUgsYUFBYSxHQUFHbEMsT0FBTyxDQUFDQyxPQUFSLEVBQXBCOztBQUNBLFVBQUk4QixhQUFhLENBQUNuRixNQUFkLEdBQXVCLENBQTNCLEVBQThCO0FBQzVCc0YsUUFBQUEsYUFBYSxHQUFHLEtBQUtDLFlBQUwsQ0FBa0JKLGFBQWxCLEVBQWlDaEssU0FBakMsRUFBNEN1SixRQUE1QyxDQUFoQjtBQUNEOztBQUNELFVBQUljLGFBQWEsR0FBRyxFQUFwQjtBQUNBLGFBQ0VGLGFBQWEsQ0FBQztBQUFELE9BQ1Z0QyxJQURILENBQ1EsTUFBTSxLQUFLTCxVQUFMLENBQWdCO0FBQUVFLFFBQUFBLFVBQVUsRUFBRTtBQUFkLE9BQWhCLENBRGQsRUFDcUQ7QUFEckQsT0FFR0csSUFGSCxDQUVRLE1BQU07QUFDVixjQUFNeUMsUUFBUSxHQUFHTCxjQUFjLENBQUM5QixHQUFmLENBQW1CekYsU0FBUyxJQUFJO0FBQy9DLGdCQUFNcEgsSUFBSSxHQUFHZ08sZUFBZSxDQUFDNUcsU0FBRCxDQUE1QjtBQUNBLGlCQUFPLEtBQUs2SCxrQkFBTCxDQUF3QnZLLFNBQXhCLEVBQW1DMEMsU0FBbkMsRUFBOENwSCxJQUE5QyxDQUFQO0FBQ0QsU0FIZ0IsQ0FBakI7QUFJQSxlQUFPMk0sT0FBTyxDQUFDdUMsR0FBUixDQUFZRixRQUFaLENBQVA7QUFDRCxPQVJILEVBU0d6QyxJQVRILENBU1E0QyxPQUFPLElBQUk7QUFDZkosUUFBQUEsYUFBYSxHQUFHSSxPQUFPLENBQUNDLE1BQVIsQ0FBZUMsTUFBTSxJQUFJLENBQUMsQ0FBQ0EsTUFBM0IsQ0FBaEI7QUFDQSxlQUFPLEtBQUtDLGNBQUwsQ0FBb0I1SyxTQUFwQixFQUErQndGLHFCQUEvQixFQUFzRGtFLFNBQXRELENBQVA7QUFDRCxPQVpILEVBYUc3QixJQWJILENBYVEsTUFDSixLQUFLZixVQUFMLENBQWdCK0QsMEJBQWhCLENBQ0U3SyxTQURGLEVBRUUyRSxPQUZGLEVBR0VOLE1BQU0sQ0FBQ00sT0FIVCxFQUlFa0YsYUFKRixDQWRKLEVBcUJHaEMsSUFyQkgsQ0FxQlEsTUFBTSxLQUFLTCxVQUFMLENBQWdCO0FBQUVFLFFBQUFBLFVBQVUsRUFBRTtBQUFkLE9BQWhCLENBckJkLEVBc0JFO0FBdEJGLE9BdUJHRyxJQXZCSCxDQXVCUSxNQUFNO0FBQ1YsYUFBS2lELFlBQUwsQ0FBa0JULGFBQWxCO0FBQ0EsY0FBTWhHLE1BQU0sR0FBRyxLQUFLMkMsVUFBTCxDQUFnQmhILFNBQWhCLENBQWY7QUFDQSxjQUFNK0ssY0FBc0IsR0FBRztBQUM3Qi9LLFVBQUFBLFNBQVMsRUFBRUEsU0FEa0I7QUFFN0JxQyxVQUFBQSxNQUFNLEVBQUVnQyxNQUFNLENBQUNoQyxNQUZjO0FBRzdCbUQsVUFBQUEscUJBQXFCLEVBQUVuQixNQUFNLENBQUNtQjtBQUhELFNBQS9COztBQUtBLFlBQUluQixNQUFNLENBQUNNLE9BQVAsSUFBa0J6SixNQUFNLENBQUMwSixJQUFQLENBQVlQLE1BQU0sQ0FBQ00sT0FBbkIsRUFBNEJFLE1BQTVCLEtBQXVDLENBQTdELEVBQWdFO0FBQzlEa0csVUFBQUEsY0FBYyxDQUFDcEcsT0FBZixHQUF5Qk4sTUFBTSxDQUFDTSxPQUFoQztBQUNEOztBQUNELGVBQU9vRyxjQUFQO0FBQ0QsT0FuQ0gsQ0FERjtBQXNDRCxLQW5GSSxFQW9GSjNDLEtBcEZJLENBb0ZFQyxLQUFLLElBQUk7QUFDZCxVQUFJQSxLQUFLLEtBQUtuRSxTQUFkLEVBQXlCO0FBQ3ZCLGNBQU0sSUFBSW5KLEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWWtDLGtCQURSLEVBRUgsU0FBUWpFLFNBQVUsa0JBRmYsQ0FBTjtBQUlELE9BTEQsTUFLTztBQUNMLGNBQU1xSSxLQUFOO0FBQ0Q7QUFDRixLQTdGSSxDQUFQO0FBOEZELEdBelBtQyxDQTJQcEM7QUFDQTs7O0FBQ0EyQyxFQUFBQSxrQkFBa0IsQ0FBQ2hMLFNBQUQsRUFBK0M7QUFDL0QsUUFBSSxLQUFLZ0gsVUFBTCxDQUFnQmhILFNBQWhCLENBQUosRUFBZ0M7QUFDOUIsYUFBT2lJLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0QsS0FIOEQsQ0FJL0Q7OztBQUNBLFdBQ0UsS0FBS2EsbUJBQUwsQ0FBeUIvSSxTQUF6QixFQUNFO0FBREYsS0FFRzZILElBRkgsQ0FFUSxNQUFNLEtBQUtMLFVBQUwsQ0FBZ0I7QUFBRUUsTUFBQUEsVUFBVSxFQUFFO0FBQWQsS0FBaEIsQ0FGZCxFQUdHVSxLQUhILENBR1MsTUFBTTtBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBTyxLQUFLWixVQUFMLENBQWdCO0FBQUVFLFFBQUFBLFVBQVUsRUFBRTtBQUFkLE9BQWhCLENBQVA7QUFDRCxLQVRILEVBVUdHLElBVkgsQ0FVUSxNQUFNO0FBQ1Y7QUFDQSxVQUFJLEtBQUtiLFVBQUwsQ0FBZ0JoSCxTQUFoQixDQUFKLEVBQWdDO0FBQzlCLGVBQU8sSUFBUDtBQUNELE9BRkQsTUFFTztBQUNMLGNBQU0sSUFBSWpGLEtBQUssQ0FBQ2dILEtBQVYsQ0FBZ0JoSCxLQUFLLENBQUNnSCxLQUFOLENBQVlDLFlBQTVCLEVBQTJDLGlCQUFnQmhDLFNBQVUsRUFBckUsQ0FBTjtBQUNEO0FBQ0YsS0FqQkgsRUFrQkdvSSxLQWxCSCxDQWtCUyxNQUFNO0FBQ1g7QUFDQSxZQUFNLElBQUlyTixLQUFLLENBQUNnSCxLQUFWLENBQWdCaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZQyxZQUE1QixFQUEwQyx1Q0FBMUMsQ0FBTjtBQUNELEtBckJILENBREY7QUF3QkQ7O0FBRURpSCxFQUFBQSxnQkFBZ0IsQ0FBQ2pKLFNBQUQsRUFBb0JxQyxNQUFvQixHQUFHLEVBQTNDLEVBQStDbUQscUJBQS9DLEVBQWdGO0FBQzlGLFFBQUksS0FBS3dCLFVBQUwsQ0FBZ0JoSCxTQUFoQixDQUFKLEVBQWdDO0FBQzlCLFlBQU0sSUFBSWpGLEtBQUssQ0FBQ2dILEtBQVYsQ0FBZ0JoSCxLQUFLLENBQUNnSCxLQUFOLENBQVlrQyxrQkFBNUIsRUFBaUQsU0FBUWpFLFNBQVUsa0JBQW5FLENBQU47QUFDRDs7QUFDRCxRQUFJLENBQUN5RCxnQkFBZ0IsQ0FBQ3pELFNBQUQsQ0FBckIsRUFBa0M7QUFDaEMsYUFBTztBQUNMa0osUUFBQUEsSUFBSSxFQUFFbk8sS0FBSyxDQUFDZ0gsS0FBTixDQUFZa0Msa0JBRGI7QUFFTG9FLFFBQUFBLEtBQUssRUFBRXhFLHVCQUF1QixDQUFDN0QsU0FBRDtBQUZ6QixPQUFQO0FBSUQ7O0FBQ0QsV0FBTyxLQUFLK0osa0JBQUwsQ0FBd0IvSixTQUF4QixFQUFtQ3FDLE1BQW5DLEVBQTJDbUQscUJBQTNDLEVBQWtFLEVBQWxFLENBQVA7QUFDRDs7QUFFRHVFLEVBQUFBLGtCQUFrQixDQUNoQi9KLFNBRGdCLEVBRWhCcUMsTUFGZ0IsRUFHaEJtRCxxQkFIZ0IsRUFJaEJ5RixrQkFKZ0IsRUFLaEI7QUFDQSxTQUFLLE1BQU12SSxTQUFYLElBQXdCTCxNQUF4QixFQUFnQztBQUM5QixVQUFJNEksa0JBQWtCLENBQUMxSSxPQUFuQixDQUEyQkcsU0FBM0IsSUFBd0MsQ0FBNUMsRUFBK0M7QUFDN0MsWUFBSSxDQUFDaUIsZ0JBQWdCLENBQUNqQixTQUFELENBQXJCLEVBQWtDO0FBQ2hDLGlCQUFPO0FBQ0x3RyxZQUFBQSxJQUFJLEVBQUVuTyxLQUFLLENBQUNnSCxLQUFOLENBQVltSixnQkFEYjtBQUVMN0MsWUFBQUEsS0FBSyxFQUFFLHlCQUF5QjNGO0FBRjNCLFdBQVA7QUFJRDs7QUFDRCxZQUFJLENBQUNrQix3QkFBd0IsQ0FBQ2xCLFNBQUQsRUFBWTFDLFNBQVosQ0FBN0IsRUFBcUQ7QUFDbkQsaUJBQU87QUFDTGtKLFlBQUFBLElBQUksRUFBRSxHQUREO0FBRUxiLFlBQUFBLEtBQUssRUFBRSxXQUFXM0YsU0FBWCxHQUF1QjtBQUZ6QixXQUFQO0FBSUQ7O0FBQ0QsY0FBTXlJLFNBQVMsR0FBRzlJLE1BQU0sQ0FBQ0ssU0FBRCxDQUF4QjtBQUNBLGNBQU0yRixLQUFLLEdBQUdyRSxrQkFBa0IsQ0FBQ21ILFNBQUQsQ0FBaEM7QUFDQSxZQUFJOUMsS0FBSixFQUFXLE9BQU87QUFBRWEsVUFBQUEsSUFBSSxFQUFFYixLQUFLLENBQUNhLElBQWQ7QUFBb0JiLFVBQUFBLEtBQUssRUFBRUEsS0FBSyxDQUFDako7QUFBakMsU0FBUDs7QUFDWCxZQUFJK0wsU0FBUyxDQUFDQyxZQUFWLEtBQTJCbEgsU0FBL0IsRUFBMEM7QUFDeEMsY0FBSW1ILGdCQUFnQixHQUFHQyxPQUFPLENBQUNILFNBQVMsQ0FBQ0MsWUFBWCxDQUE5Qjs7QUFDQSxjQUFJLE9BQU9DLGdCQUFQLEtBQTRCLFFBQWhDLEVBQTBDO0FBQ3hDQSxZQUFBQSxnQkFBZ0IsR0FBRztBQUFFL1AsY0FBQUEsSUFBSSxFQUFFK1A7QUFBUixhQUFuQjtBQUNELFdBRkQsTUFFTyxJQUFJLE9BQU9BLGdCQUFQLEtBQTRCLFFBQTVCLElBQXdDRixTQUFTLENBQUM3UCxJQUFWLEtBQW1CLFVBQS9ELEVBQTJFO0FBQ2hGLG1CQUFPO0FBQ0w0TixjQUFBQSxJQUFJLEVBQUVuTyxLQUFLLENBQUNnSCxLQUFOLENBQVlvQyxjQURiO0FBRUxrRSxjQUFBQSxLQUFLLEVBQUcsb0RBQW1EM0IsWUFBWSxDQUFDeUUsU0FBRCxDQUFZO0FBRjlFLGFBQVA7QUFJRDs7QUFDRCxjQUFJLENBQUM1RSx1QkFBdUIsQ0FBQzRFLFNBQUQsRUFBWUUsZ0JBQVosQ0FBNUIsRUFBMkQ7QUFDekQsbUJBQU87QUFDTG5DLGNBQUFBLElBQUksRUFBRW5PLEtBQUssQ0FBQ2dILEtBQU4sQ0FBWW9DLGNBRGI7QUFFTGtFLGNBQUFBLEtBQUssRUFBRyx1QkFBc0JySSxTQUFVLElBQUcwQyxTQUFVLDRCQUEyQmdFLFlBQVksQ0FDMUZ5RSxTQUQwRixDQUUxRixZQUFXekUsWUFBWSxDQUFDMkUsZ0JBQUQsQ0FBbUI7QUFKdkMsYUFBUDtBQU1EO0FBQ0YsU0FsQkQsTUFrQk8sSUFBSUYsU0FBUyxDQUFDSSxRQUFkLEVBQXdCO0FBQzdCLGNBQUksT0FBT0osU0FBUCxLQUFxQixRQUFyQixJQUFpQ0EsU0FBUyxDQUFDN1AsSUFBVixLQUFtQixVQUF4RCxFQUFvRTtBQUNsRSxtQkFBTztBQUNMNE4sY0FBQUEsSUFBSSxFQUFFbk8sS0FBSyxDQUFDZ0gsS0FBTixDQUFZb0MsY0FEYjtBQUVMa0UsY0FBQUEsS0FBSyxFQUFHLCtDQUE4QzNCLFlBQVksQ0FBQ3lFLFNBQUQsQ0FBWTtBQUZ6RSxhQUFQO0FBSUQ7QUFDRjtBQUNGO0FBQ0Y7O0FBRUQsU0FBSyxNQUFNekksU0FBWCxJQUF3QnpILGNBQWMsQ0FBQytFLFNBQUQsQ0FBdEMsRUFBbUQ7QUFDakRxQyxNQUFBQSxNQUFNLENBQUNLLFNBQUQsQ0FBTixHQUFvQnpILGNBQWMsQ0FBQytFLFNBQUQsQ0FBZCxDQUEwQjBDLFNBQTFCLENBQXBCO0FBQ0Q7O0FBRUQsVUFBTThJLFNBQVMsR0FBR3RRLE1BQU0sQ0FBQzBKLElBQVAsQ0FBWXZDLE1BQVosRUFBb0JxSSxNQUFwQixDQUNoQmpKLEdBQUcsSUFBSVksTUFBTSxDQUFDWixHQUFELENBQU4sSUFBZVksTUFBTSxDQUFDWixHQUFELENBQU4sQ0FBWW5HLElBQVosS0FBcUIsVUFEM0IsQ0FBbEI7O0FBR0EsUUFBSWtRLFNBQVMsQ0FBQzNHLE1BQVYsR0FBbUIsQ0FBdkIsRUFBMEI7QUFDeEIsYUFBTztBQUNMcUUsUUFBQUEsSUFBSSxFQUFFbk8sS0FBSyxDQUFDZ0gsS0FBTixDQUFZb0MsY0FEYjtBQUVMa0UsUUFBQUEsS0FBSyxFQUNILHVFQUNBbUQsU0FBUyxDQUFDLENBQUQsQ0FEVCxHQUVBLFFBRkEsR0FHQUEsU0FBUyxDQUFDLENBQUQsQ0FIVCxHQUlBO0FBUEcsT0FBUDtBQVNEOztBQUNEckosSUFBQUEsV0FBVyxDQUFDcUQscUJBQUQsRUFBd0JuRCxNQUF4QixFQUFnQyxLQUFLa0YsV0FBckMsQ0FBWDtBQUNELEdBaFhtQyxDQWtYcEM7OztBQUNBcUQsRUFBQUEsY0FBYyxDQUFDNUssU0FBRCxFQUFvQm9DLEtBQXBCLEVBQWdDc0gsU0FBaEMsRUFBeUQ7QUFDckUsUUFBSSxPQUFPdEgsS0FBUCxLQUFpQixXQUFyQixFQUFrQztBQUNoQyxhQUFPNkYsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFDRC9GLElBQUFBLFdBQVcsQ0FBQ0MsS0FBRCxFQUFRc0gsU0FBUixFQUFtQixLQUFLbkMsV0FBeEIsQ0FBWDtBQUNBLFdBQU8sS0FBS1QsVUFBTCxDQUFnQjJFLHdCQUFoQixDQUF5Q3pMLFNBQXpDLEVBQW9Eb0MsS0FBcEQsQ0FBUDtBQUNELEdBelhtQyxDQTJYcEM7QUFDQTtBQUNBO0FBQ0E7OztBQUNBbUksRUFBQUEsa0JBQWtCLENBQUN2SyxTQUFELEVBQW9CMEMsU0FBcEIsRUFBdUNwSCxJQUF2QyxFQUFtRTtBQUNuRixRQUFJb0gsU0FBUyxDQUFDSCxPQUFWLENBQWtCLEdBQWxCLElBQXlCLENBQTdCLEVBQWdDO0FBQzlCO0FBQ0FHLE1BQUFBLFNBQVMsR0FBR0EsU0FBUyxDQUFDZ0osS0FBVixDQUFnQixHQUFoQixFQUFxQixDQUFyQixDQUFaO0FBQ0FwUSxNQUFBQSxJQUFJLEdBQUcsUUFBUDtBQUNEOztBQUNELFFBQUksQ0FBQ3FJLGdCQUFnQixDQUFDakIsU0FBRCxDQUFyQixFQUFrQztBQUNoQyxZQUFNLElBQUkzSCxLQUFLLENBQUNnSCxLQUFWLENBQWdCaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZbUosZ0JBQTVCLEVBQStDLHVCQUFzQnhJLFNBQVUsR0FBL0UsQ0FBTjtBQUNELEtBUmtGLENBVW5GOzs7QUFDQSxRQUFJLENBQUNwSCxJQUFMLEVBQVc7QUFDVCxhQUFPNEksU0FBUDtBQUNEOztBQUVELFVBQU15SCxZQUFZLEdBQUcsS0FBS0MsZUFBTCxDQUFxQjVMLFNBQXJCLEVBQWdDMEMsU0FBaEMsQ0FBckI7O0FBQ0EsUUFBSSxPQUFPcEgsSUFBUCxLQUFnQixRQUFwQixFQUE4QjtBQUM1QkEsTUFBQUEsSUFBSSxHQUFJO0FBQUVBLFFBQUFBO0FBQUYsT0FBUjtBQUNEOztBQUVELFFBQUlBLElBQUksQ0FBQzhQLFlBQUwsS0FBc0JsSCxTQUExQixFQUFxQztBQUNuQyxVQUFJbUgsZ0JBQWdCLEdBQUdDLE9BQU8sQ0FBQ2hRLElBQUksQ0FBQzhQLFlBQU4sQ0FBOUI7O0FBQ0EsVUFBSSxPQUFPQyxnQkFBUCxLQUE0QixRQUFoQyxFQUEwQztBQUN4Q0EsUUFBQUEsZ0JBQWdCLEdBQUc7QUFBRS9QLFVBQUFBLElBQUksRUFBRStQO0FBQVIsU0FBbkI7QUFDRDs7QUFDRCxVQUFJLENBQUM5RSx1QkFBdUIsQ0FBQ2pMLElBQUQsRUFBTytQLGdCQUFQLENBQTVCLEVBQXNEO0FBQ3BELGNBQU0sSUFBSXRRLEtBQUssQ0FBQ2dILEtBQVYsQ0FDSmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWW9DLGNBRFIsRUFFSCx1QkFBc0JuRSxTQUFVLElBQUcwQyxTQUFVLDRCQUEyQmdFLFlBQVksQ0FDbkZwTCxJQURtRixDQUVuRixZQUFXb0wsWUFBWSxDQUFDMkUsZ0JBQUQsQ0FBbUIsRUFKeEMsQ0FBTjtBQU1EO0FBQ0Y7O0FBRUQsUUFBSU0sWUFBSixFQUFrQjtBQUNoQixVQUFJLENBQUNwRix1QkFBdUIsQ0FBQ29GLFlBQUQsRUFBZXJRLElBQWYsQ0FBNUIsRUFBa0Q7QUFDaEQsY0FBTSxJQUFJUCxLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVlvQyxjQURSLEVBRUgsdUJBQXNCbkUsU0FBVSxJQUFHMEMsU0FBVSxjQUFhZ0UsWUFBWSxDQUNyRWlGLFlBRHFFLENBRXJFLFlBQVdqRixZQUFZLENBQUNwTCxJQUFELENBQU8sRUFKNUIsQ0FBTjtBQU1EOztBQUNELGFBQU80SSxTQUFQO0FBQ0Q7O0FBRUQsV0FBTyxLQUFLNEMsVUFBTCxDQUNKK0UsbUJBREksQ0FDZ0I3TCxTQURoQixFQUMyQjBDLFNBRDNCLEVBQ3NDcEgsSUFEdEMsRUFFSjhNLEtBRkksQ0FFRUMsS0FBSyxJQUFJO0FBQ2QsVUFBSUEsS0FBSyxDQUFDYSxJQUFOLElBQWNuTyxLQUFLLENBQUNnSCxLQUFOLENBQVlvQyxjQUE5QixFQUE4QztBQUM1QztBQUNBLGNBQU1rRSxLQUFOO0FBQ0QsT0FKYSxDQUtkO0FBQ0E7QUFDQTs7O0FBQ0EsYUFBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxLQVhJLEVBWUpMLElBWkksQ0FZQyxNQUFNO0FBQ1YsYUFBTztBQUNMN0gsUUFBQUEsU0FESztBQUVMMEMsUUFBQUEsU0FGSztBQUdMcEgsUUFBQUE7QUFISyxPQUFQO0FBS0QsS0FsQkksQ0FBUDtBQW1CRDs7QUFFRHdQLEVBQUFBLFlBQVksQ0FBQ3pJLE1BQUQsRUFBYztBQUN4QixTQUFLLElBQUl5SixDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHekosTUFBTSxDQUFDd0MsTUFBM0IsRUFBbUNpSCxDQUFDLElBQUksQ0FBeEMsRUFBMkM7QUFDekMsWUFBTTtBQUFFOUwsUUFBQUEsU0FBRjtBQUFhMEMsUUFBQUE7QUFBYixVQUEyQkwsTUFBTSxDQUFDeUosQ0FBRCxDQUF2QztBQUNBLFVBQUk7QUFBRXhRLFFBQUFBO0FBQUYsVUFBVytHLE1BQU0sQ0FBQ3lKLENBQUQsQ0FBckI7QUFDQSxZQUFNSCxZQUFZLEdBQUcsS0FBS0MsZUFBTCxDQUFxQjVMLFNBQXJCLEVBQWdDMEMsU0FBaEMsQ0FBckI7O0FBQ0EsVUFBSSxPQUFPcEgsSUFBUCxLQUFnQixRQUFwQixFQUE4QjtBQUM1QkEsUUFBQUEsSUFBSSxHQUFHO0FBQUVBLFVBQUFBLElBQUksRUFBRUE7QUFBUixTQUFQO0FBQ0Q7O0FBQ0QsVUFBSSxDQUFDcVEsWUFBRCxJQUFpQixDQUFDcEYsdUJBQXVCLENBQUNvRixZQUFELEVBQWVyUSxJQUFmLENBQTdDLEVBQW1FO0FBQ2pFLGNBQU0sSUFBSVAsS0FBSyxDQUFDZ0gsS0FBVixDQUFnQmhILEtBQUssQ0FBQ2dILEtBQU4sQ0FBWUMsWUFBNUIsRUFBMkMsdUJBQXNCVSxTQUFVLEVBQTNFLENBQU47QUFDRDtBQUNGO0FBQ0YsR0EvY21DLENBaWRwQzs7O0FBQ0FxSixFQUFBQSxXQUFXLENBQUNySixTQUFELEVBQW9CMUMsU0FBcEIsRUFBdUN1SixRQUF2QyxFQUFxRTtBQUM5RSxXQUFPLEtBQUthLFlBQUwsQ0FBa0IsQ0FBQzFILFNBQUQsQ0FBbEIsRUFBK0IxQyxTQUEvQixFQUEwQ3VKLFFBQTFDLENBQVA7QUFDRCxHQXBkbUMsQ0FzZHBDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQWEsRUFBQUEsWUFBWSxDQUFDNEIsVUFBRCxFQUE0QmhNLFNBQTVCLEVBQStDdUosUUFBL0MsRUFBNkU7QUFDdkYsUUFBSSxDQUFDOUYsZ0JBQWdCLENBQUN6RCxTQUFELENBQXJCLEVBQWtDO0FBQ2hDLFlBQU0sSUFBSWpGLEtBQUssQ0FBQ2dILEtBQVYsQ0FBZ0JoSCxLQUFLLENBQUNnSCxLQUFOLENBQVlrQyxrQkFBNUIsRUFBZ0RKLHVCQUF1QixDQUFDN0QsU0FBRCxDQUF2RSxDQUFOO0FBQ0Q7O0FBRURnTSxJQUFBQSxVQUFVLENBQUM3RyxPQUFYLENBQW1CekMsU0FBUyxJQUFJO0FBQzlCLFVBQUksQ0FBQ2lCLGdCQUFnQixDQUFDakIsU0FBRCxDQUFyQixFQUFrQztBQUNoQyxjQUFNLElBQUkzSCxLQUFLLENBQUNnSCxLQUFWLENBQWdCaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZbUosZ0JBQTVCLEVBQStDLHVCQUFzQnhJLFNBQVUsRUFBL0UsQ0FBTjtBQUNELE9BSDZCLENBSTlCOzs7QUFDQSxVQUFJLENBQUNrQix3QkFBd0IsQ0FBQ2xCLFNBQUQsRUFBWTFDLFNBQVosQ0FBN0IsRUFBcUQ7QUFDbkQsY0FBTSxJQUFJakYsS0FBSyxDQUFDZ0gsS0FBVixDQUFnQixHQUFoQixFQUFzQixTQUFRVyxTQUFVLG9CQUF4QyxDQUFOO0FBQ0Q7QUFDRixLQVJEO0FBVUEsV0FBTyxLQUFLNkYsWUFBTCxDQUFrQnZJLFNBQWxCLEVBQTZCLEtBQTdCLEVBQW9DO0FBQUUwSCxNQUFBQSxVQUFVLEVBQUU7QUFBZCxLQUFwQyxFQUNKVSxLQURJLENBQ0VDLEtBQUssSUFBSTtBQUNkLFVBQUlBLEtBQUssS0FBS25FLFNBQWQsRUFBeUI7QUFDdkIsY0FBTSxJQUFJbkosS0FBSyxDQUFDZ0gsS0FBVixDQUNKaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZa0Msa0JBRFIsRUFFSCxTQUFRakUsU0FBVSxrQkFGZixDQUFOO0FBSUQsT0FMRCxNQUtPO0FBQ0wsY0FBTXFJLEtBQU47QUFDRDtBQUNGLEtBVkksRUFXSlIsSUFYSSxDQVdDeEQsTUFBTSxJQUFJO0FBQ2QySCxNQUFBQSxVQUFVLENBQUM3RyxPQUFYLENBQW1CekMsU0FBUyxJQUFJO0FBQzlCLFlBQUksQ0FBQzJCLE1BQU0sQ0FBQ2hDLE1BQVAsQ0FBY0ssU0FBZCxDQUFMLEVBQStCO0FBQzdCLGdCQUFNLElBQUkzSCxLQUFLLENBQUNnSCxLQUFWLENBQWdCLEdBQWhCLEVBQXNCLFNBQVFXLFNBQVUsaUNBQXhDLENBQU47QUFDRDtBQUNGLE9BSkQ7O0FBTUEsWUFBTXVKLFlBQVkscUJBQVE1SCxNQUFNLENBQUNoQyxNQUFmLENBQWxCOztBQUNBLGFBQU9rSCxRQUFRLENBQUMyQyxPQUFULENBQWlCOUIsWUFBakIsQ0FBOEJwSyxTQUE5QixFQUF5Q3FFLE1BQXpDLEVBQWlEMkgsVUFBakQsRUFBNkRuRSxJQUE3RCxDQUFrRSxNQUFNO0FBQzdFLGVBQU9JLE9BQU8sQ0FBQ3VDLEdBQVIsQ0FDTHdCLFVBQVUsQ0FBQzdELEdBQVgsQ0FBZXpGLFNBQVMsSUFBSTtBQUMxQixnQkFBTU0sS0FBSyxHQUFHaUosWUFBWSxDQUFDdkosU0FBRCxDQUExQjs7QUFDQSxjQUFJTSxLQUFLLElBQUlBLEtBQUssQ0FBQzFILElBQU4sS0FBZSxVQUE1QixFQUF3QztBQUN0QztBQUNBLG1CQUFPaU8sUUFBUSxDQUFDMkMsT0FBVCxDQUFpQkMsV0FBakIsQ0FBOEIsU0FBUXpKLFNBQVUsSUFBRzFDLFNBQVUsRUFBN0QsQ0FBUDtBQUNEOztBQUNELGlCQUFPaUksT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxTQVBELENBREssQ0FBUDtBQVVELE9BWE0sQ0FBUDtBQVlELEtBL0JJLEVBZ0NKTCxJQWhDSSxDQWdDQyxNQUFNLEtBQUtkLE1BQUwsQ0FBWTJCLEtBQVosRUFoQ1AsQ0FBUDtBQWlDRCxHQTdnQm1DLENBK2dCcEM7QUFDQTtBQUNBOzs7QUFDQSxRQUFNMEQsY0FBTixDQUFxQnBNLFNBQXJCLEVBQXdDcU0sTUFBeEMsRUFBcURqTyxLQUFyRCxFQUFpRTtBQUMvRCxRQUFJa08sUUFBUSxHQUFHLENBQWY7QUFDQSxVQUFNakksTUFBTSxHQUFHLE1BQU0sS0FBSzJHLGtCQUFMLENBQXdCaEwsU0FBeEIsQ0FBckI7QUFDQSxVQUFNc0ssUUFBUSxHQUFHLEVBQWpCOztBQUVBLFNBQUssTUFBTTVILFNBQVgsSUFBd0IySixNQUF4QixFQUFnQztBQUM5QixVQUFJQSxNQUFNLENBQUMzSixTQUFELENBQU4sS0FBc0J3QixTQUExQixFQUFxQztBQUNuQztBQUNEOztBQUNELFlBQU1xSSxRQUFRLEdBQUdqQixPQUFPLENBQUNlLE1BQU0sQ0FBQzNKLFNBQUQsQ0FBUCxDQUF4Qjs7QUFDQSxVQUFJNkosUUFBUSxLQUFLLFVBQWpCLEVBQTZCO0FBQzNCRCxRQUFBQSxRQUFRO0FBQ1Q7O0FBQ0QsVUFBSUEsUUFBUSxHQUFHLENBQWYsRUFBa0I7QUFDaEI7QUFDQTtBQUNBLGVBQU9yRSxPQUFPLENBQUNhLE1BQVIsQ0FDTCxJQUFJL04sS0FBSyxDQUFDZ0gsS0FBVixDQUNFaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZb0MsY0FEZCxFQUVFLGlEQUZGLENBREssQ0FBUDtBQU1EOztBQUNELFVBQUksQ0FBQ29JLFFBQUwsRUFBZTtBQUNiO0FBQ0Q7O0FBQ0QsVUFBSTdKLFNBQVMsS0FBSyxLQUFsQixFQUF5QjtBQUN2QjtBQUNBO0FBQ0Q7O0FBQ0Q0SCxNQUFBQSxRQUFRLENBQUNKLElBQVQsQ0FBYzdGLE1BQU0sQ0FBQ2tHLGtCQUFQLENBQTBCdkssU0FBMUIsRUFBcUMwQyxTQUFyQyxFQUFnRDZKLFFBQWhELENBQWQ7QUFDRDs7QUFDRCxVQUFNOUIsT0FBTyxHQUFHLE1BQU14QyxPQUFPLENBQUN1QyxHQUFSLENBQVlGLFFBQVosQ0FBdEI7QUFDQSxVQUFNRCxhQUFhLEdBQUdJLE9BQU8sQ0FBQ0MsTUFBUixDQUFlQyxNQUFNLElBQUksQ0FBQyxDQUFDQSxNQUEzQixDQUF0Qjs7QUFFQSxRQUFJTixhQUFhLENBQUN4RixNQUFkLEtBQXlCLENBQTdCLEVBQWdDO0FBQzlCLFlBQU0sS0FBSzJDLFVBQUwsQ0FBZ0I7QUFBRUUsUUFBQUEsVUFBVSxFQUFFO0FBQWQsT0FBaEIsQ0FBTjtBQUNEOztBQUNELFNBQUtvRCxZQUFMLENBQWtCVCxhQUFsQjtBQUVBLFVBQU01QixPQUFPLEdBQUdSLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjdELE1BQWhCLENBQWhCO0FBQ0EsV0FBT21JLDJCQUEyQixDQUFDL0QsT0FBRCxFQUFVekksU0FBVixFQUFxQnFNLE1BQXJCLEVBQTZCak8sS0FBN0IsQ0FBbEM7QUFDRCxHQTVqQm1DLENBOGpCcEM7OztBQUNBcU8sRUFBQUEsdUJBQXVCLENBQUN6TSxTQUFELEVBQW9CcU0sTUFBcEIsRUFBaUNqTyxLQUFqQyxFQUE2QztBQUNsRSxVQUFNc08sT0FBTyxHQUFHN0wsZUFBZSxDQUFDYixTQUFELENBQS9COztBQUNBLFFBQUksQ0FBQzBNLE9BQUQsSUFBWUEsT0FBTyxDQUFDN0gsTUFBUixJQUFrQixDQUFsQyxFQUFxQztBQUNuQyxhQUFPb0QsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFFRCxVQUFNeUUsY0FBYyxHQUFHRCxPQUFPLENBQUNoQyxNQUFSLENBQWUsVUFBVWtDLE1BQVYsRUFBa0I7QUFDdEQsVUFBSXhPLEtBQUssSUFBSUEsS0FBSyxDQUFDL0MsUUFBbkIsRUFBNkI7QUFDM0IsWUFBSWdSLE1BQU0sQ0FBQ08sTUFBRCxDQUFOLElBQWtCLE9BQU9QLE1BQU0sQ0FBQ08sTUFBRCxDQUFiLEtBQTBCLFFBQWhELEVBQTBEO0FBQ3hEO0FBQ0EsaUJBQU9QLE1BQU0sQ0FBQ08sTUFBRCxDQUFOLENBQWVuRCxJQUFmLElBQXVCLFFBQTlCO0FBQ0QsU0FKMEIsQ0FLM0I7OztBQUNBLGVBQU8sS0FBUDtBQUNEOztBQUNELGFBQU8sQ0FBQzRDLE1BQU0sQ0FBQ08sTUFBRCxDQUFkO0FBQ0QsS0FWc0IsQ0FBdkI7O0FBWUEsUUFBSUQsY0FBYyxDQUFDOUgsTUFBZixHQUF3QixDQUE1QixFQUErQjtBQUM3QixZQUFNLElBQUk5SixLQUFLLENBQUNnSCxLQUFWLENBQWdCaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZb0MsY0FBNUIsRUFBNEN3SSxjQUFjLENBQUMsQ0FBRCxDQUFkLEdBQW9CLGVBQWhFLENBQU47QUFDRDs7QUFDRCxXQUFPMUUsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFFRDJFLEVBQUFBLDJCQUEyQixDQUFDN00sU0FBRCxFQUFvQjhNLFFBQXBCLEVBQXdDdEssU0FBeEMsRUFBMkQ7QUFDcEYsV0FBT21FLGdCQUFnQixDQUFDb0csZUFBakIsQ0FDTCxLQUFLQyx3QkFBTCxDQUE4QmhOLFNBQTlCLENBREssRUFFTDhNLFFBRkssRUFHTHRLLFNBSEssQ0FBUDtBQUtELEdBN2xCbUMsQ0ErbEJwQzs7O0FBQ0EsU0FBT3VLLGVBQVAsQ0FBdUJFLGdCQUF2QixFQUErQ0gsUUFBL0MsRUFBbUV0SyxTQUFuRSxFQUErRjtBQUM3RixRQUFJLENBQUN5SyxnQkFBRCxJQUFxQixDQUFDQSxnQkFBZ0IsQ0FBQ3pLLFNBQUQsQ0FBMUMsRUFBdUQ7QUFDckQsYUFBTyxJQUFQO0FBQ0Q7O0FBQ0QsVUFBTUosS0FBSyxHQUFHNkssZ0JBQWdCLENBQUN6SyxTQUFELENBQTlCOztBQUNBLFFBQUlKLEtBQUssQ0FBQyxHQUFELENBQVQsRUFBZ0I7QUFDZCxhQUFPLElBQVA7QUFDRCxLQVA0RixDQVE3Rjs7O0FBQ0EsUUFDRTBLLFFBQVEsQ0FBQ0ksSUFBVCxDQUFjQyxHQUFHLElBQUk7QUFDbkIsYUFBTy9LLEtBQUssQ0FBQytLLEdBQUQsQ0FBTCxLQUFlLElBQXRCO0FBQ0QsS0FGRCxDQURGLEVBSUU7QUFDQSxhQUFPLElBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRCxHQWpuQm1DLENBbW5CcEM7OztBQUNBLFNBQU9DLGtCQUFQLENBQ0VILGdCQURGLEVBRUVqTixTQUZGLEVBR0U4TSxRQUhGLEVBSUV0SyxTQUpGLEVBS0U2SyxNQUxGLEVBTUU7QUFDQSxRQUFJMUcsZ0JBQWdCLENBQUNvRyxlQUFqQixDQUFpQ0UsZ0JBQWpDLEVBQW1ESCxRQUFuRCxFQUE2RHRLLFNBQTdELENBQUosRUFBNkU7QUFDM0UsYUFBT3lGLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDK0UsZ0JBQUQsSUFBcUIsQ0FBQ0EsZ0JBQWdCLENBQUN6SyxTQUFELENBQTFDLEVBQXVEO0FBQ3JELGFBQU8sSUFBUDtBQUNEOztBQUNELFVBQU1KLEtBQUssR0FBRzZLLGdCQUFnQixDQUFDekssU0FBRCxDQUE5QixDQVJBLENBU0E7QUFDQTs7QUFDQSxRQUFJSixLQUFLLENBQUMsd0JBQUQsQ0FBVCxFQUFxQztBQUNuQztBQUNBLFVBQUksQ0FBQzBLLFFBQUQsSUFBYUEsUUFBUSxDQUFDakksTUFBVCxJQUFtQixDQUFwQyxFQUF1QztBQUNyQyxjQUFNLElBQUk5SixLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVl1TCxnQkFEUixFQUVKLG9EQUZJLENBQU47QUFJRCxPQUxELE1BS08sSUFBSVIsUUFBUSxDQUFDdkssT0FBVCxDQUFpQixHQUFqQixJQUF3QixDQUFDLENBQXpCLElBQThCdUssUUFBUSxDQUFDakksTUFBVCxJQUFtQixDQUFyRCxFQUF3RDtBQUM3RCxjQUFNLElBQUk5SixLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVl1TCxnQkFEUixFQUVKLG9EQUZJLENBQU47QUFJRCxPQVprQyxDQWFuQztBQUNBOzs7QUFDQSxhQUFPckYsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxLQTNCRCxDQTZCQTtBQUNBOzs7QUFDQSxVQUFNcUYsZUFBZSxHQUNuQixDQUFDLEtBQUQsRUFBUSxNQUFSLEVBQWdCLE9BQWhCLEVBQXlCaEwsT0FBekIsQ0FBaUNDLFNBQWpDLElBQThDLENBQUMsQ0FBL0MsR0FBbUQsZ0JBQW5ELEdBQXNFLGlCQUR4RSxDQS9CQSxDQWtDQTs7QUFDQSxRQUFJK0ssZUFBZSxJQUFJLGlCQUFuQixJQUF3Qy9LLFNBQVMsSUFBSSxRQUF6RCxFQUFtRTtBQUNqRSxZQUFNLElBQUl6SCxLQUFLLENBQUNnSCxLQUFWLENBQ0poSCxLQUFLLENBQUNnSCxLQUFOLENBQVl5TCxtQkFEUixFQUVILGdDQUErQmhMLFNBQVUsYUFBWXhDLFNBQVUsR0FGNUQsQ0FBTjtBQUlELEtBeENELENBMENBOzs7QUFDQSxRQUNFOEMsS0FBSyxDQUFDQyxPQUFOLENBQWNrSyxnQkFBZ0IsQ0FBQ00sZUFBRCxDQUE5QixLQUNBTixnQkFBZ0IsQ0FBQ00sZUFBRCxDQUFoQixDQUFrQzFJLE1BQWxDLEdBQTJDLENBRjdDLEVBR0U7QUFDQSxhQUFPb0QsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFRCxVQUFNOUUsYUFBYSxHQUFHNkosZ0JBQWdCLENBQUN6SyxTQUFELENBQWhCLENBQTRCWSxhQUFsRDs7QUFDQSxRQUFJTixLQUFLLENBQUNDLE9BQU4sQ0FBY0ssYUFBZCxLQUFnQ0EsYUFBYSxDQUFDeUIsTUFBZCxHQUF1QixDQUEzRCxFQUE4RDtBQUM1RDtBQUNBLFVBQUlyQyxTQUFTLEtBQUssVUFBZCxJQUE0QjZLLE1BQU0sS0FBSyxRQUEzQyxFQUFxRDtBQUNuRDtBQUNBLGVBQU9wRixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEO0FBQ0Y7O0FBRUQsVUFBTSxJQUFJbk4sS0FBSyxDQUFDZ0gsS0FBVixDQUNKaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZeUwsbUJBRFIsRUFFSCxnQ0FBK0JoTCxTQUFVLGFBQVl4QyxTQUFVLEdBRjVELENBQU47QUFJRCxHQXpyQm1DLENBMnJCcEM7OztBQUNBb04sRUFBQUEsa0JBQWtCLENBQUNwTixTQUFELEVBQW9COE0sUUFBcEIsRUFBd0N0SyxTQUF4QyxFQUEyRDZLLE1BQTNELEVBQTRFO0FBQzVGLFdBQU8xRyxnQkFBZ0IsQ0FBQ3lHLGtCQUFqQixDQUNMLEtBQUtKLHdCQUFMLENBQThCaE4sU0FBOUIsQ0FESyxFQUVMQSxTQUZLLEVBR0w4TSxRQUhLLEVBSUx0SyxTQUpLLEVBS0w2SyxNQUxLLENBQVA7QUFPRDs7QUFFREwsRUFBQUEsd0JBQXdCLENBQUNoTixTQUFELEVBQXlCO0FBQy9DLFdBQU8sS0FBS2dILFVBQUwsQ0FBZ0JoSCxTQUFoQixLQUE4QixLQUFLZ0gsVUFBTCxDQUFnQmhILFNBQWhCLEVBQTJCd0YscUJBQWhFO0FBQ0QsR0F4c0JtQyxDQTBzQnBDO0FBQ0E7OztBQUNBb0csRUFBQUEsZUFBZSxDQUFDNUwsU0FBRCxFQUFvQjBDLFNBQXBCLEVBQWdFO0FBQzdFLFFBQUksS0FBS3NFLFVBQUwsQ0FBZ0JoSCxTQUFoQixDQUFKLEVBQWdDO0FBQzlCLFlBQU0yTCxZQUFZLEdBQUcsS0FBSzNFLFVBQUwsQ0FBZ0JoSCxTQUFoQixFQUEyQnFDLE1BQTNCLENBQWtDSyxTQUFsQyxDQUFyQjtBQUNBLGFBQU9pSixZQUFZLEtBQUssS0FBakIsR0FBeUIsUUFBekIsR0FBb0NBLFlBQTNDO0FBQ0Q7O0FBQ0QsV0FBT3pILFNBQVA7QUFDRCxHQWx0Qm1DLENBb3RCcEM7OztBQUNBdUosRUFBQUEsUUFBUSxDQUFDek4sU0FBRCxFQUFvQjtBQUMxQixRQUFJLEtBQUtnSCxVQUFMLENBQWdCaEgsU0FBaEIsQ0FBSixFQUFnQztBQUM5QixhQUFPaUksT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtWLFVBQUwsR0FBa0JLLElBQWxCLENBQXVCLE1BQU0sQ0FBQyxDQUFDLEtBQUtiLFVBQUwsQ0FBZ0JoSCxTQUFoQixDQUEvQixDQUFQO0FBQ0Q7O0FBMXRCbUMsQyxDQTZ0QnRDOzs7OztBQUNBLE1BQU0wTixJQUFJLEdBQUcsQ0FDWEMsU0FEVyxFQUVYOUcsV0FGVyxFQUdYWSxPQUhXLEtBSW1CO0FBQzlCLFFBQU1wRCxNQUFNLEdBQUcsSUFBSXNDLGdCQUFKLENBQXFCZ0gsU0FBckIsRUFBZ0M5RyxXQUFoQyxDQUFmO0FBQ0EsU0FBT3hDLE1BQU0sQ0FBQ21ELFVBQVAsQ0FBa0JDLE9BQWxCLEVBQTJCSSxJQUEzQixDQUFnQyxNQUFNeEQsTUFBdEMsQ0FBUDtBQUNELENBUEQsQyxDQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBQ0EsU0FBU3NGLHVCQUFULENBQWlDSCxjQUFqQyxFQUErRG9FLFVBQS9ELEVBQThGO0FBQzVGLFFBQU1sRSxTQUFTLEdBQUcsRUFBbEIsQ0FENEYsQ0FFNUY7O0FBQ0EsUUFBTW1FLGNBQWMsR0FDbEIzUyxNQUFNLENBQUMwSixJQUFQLENBQVkzSixjQUFaLEVBQTRCc0gsT0FBNUIsQ0FBb0NpSCxjQUFjLENBQUNzRSxHQUFuRCxNQUE0RCxDQUFDLENBQTdELEdBQ0ksRUFESixHQUVJNVMsTUFBTSxDQUFDMEosSUFBUCxDQUFZM0osY0FBYyxDQUFDdU8sY0FBYyxDQUFDc0UsR0FBaEIsQ0FBMUIsQ0FITjs7QUFJQSxPQUFLLE1BQU1DLFFBQVgsSUFBdUJ2RSxjQUF2QixFQUF1QztBQUNyQyxRQUNFdUUsUUFBUSxLQUFLLEtBQWIsSUFDQUEsUUFBUSxLQUFLLEtBRGIsSUFFQUEsUUFBUSxLQUFLLFdBRmIsSUFHQUEsUUFBUSxLQUFLLFdBSGIsSUFJQUEsUUFBUSxLQUFLLFVBTGYsRUFNRTtBQUNBLFVBQUlGLGNBQWMsQ0FBQ2hKLE1BQWYsR0FBd0IsQ0FBeEIsSUFBNkJnSixjQUFjLENBQUN0TCxPQUFmLENBQXVCd0wsUUFBdkIsTUFBcUMsQ0FBQyxDQUF2RSxFQUEwRTtBQUN4RTtBQUNEOztBQUNELFlBQU1DLGNBQWMsR0FBR0osVUFBVSxDQUFDRyxRQUFELENBQVYsSUFBd0JILFVBQVUsQ0FBQ0csUUFBRCxDQUFWLENBQXFCdEUsSUFBckIsS0FBOEIsUUFBN0U7O0FBQ0EsVUFBSSxDQUFDdUUsY0FBTCxFQUFxQjtBQUNuQnRFLFFBQUFBLFNBQVMsQ0FBQ3FFLFFBQUQsQ0FBVCxHQUFzQnZFLGNBQWMsQ0FBQ3VFLFFBQUQsQ0FBcEM7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsT0FBSyxNQUFNRSxRQUFYLElBQXVCTCxVQUF2QixFQUFtQztBQUNqQyxRQUFJSyxRQUFRLEtBQUssVUFBYixJQUEyQkwsVUFBVSxDQUFDSyxRQUFELENBQVYsQ0FBcUJ4RSxJQUFyQixLQUE4QixRQUE3RCxFQUF1RTtBQUNyRSxVQUFJb0UsY0FBYyxDQUFDaEosTUFBZixHQUF3QixDQUF4QixJQUE2QmdKLGNBQWMsQ0FBQ3RMLE9BQWYsQ0FBdUIwTCxRQUF2QixNQUFxQyxDQUFDLENBQXZFLEVBQTBFO0FBQ3hFO0FBQ0Q7O0FBQ0R2RSxNQUFBQSxTQUFTLENBQUN1RSxRQUFELENBQVQsR0FBc0JMLFVBQVUsQ0FBQ0ssUUFBRCxDQUFoQztBQUNEO0FBQ0Y7O0FBQ0QsU0FBT3ZFLFNBQVA7QUFDRCxDLENBRUQ7QUFDQTs7O0FBQ0EsU0FBUzhDLDJCQUFULENBQXFDMEIsYUFBckMsRUFBb0RsTyxTQUFwRCxFQUErRHFNLE1BQS9ELEVBQXVFak8sS0FBdkUsRUFBOEU7QUFDNUUsU0FBTzhQLGFBQWEsQ0FBQ3JHLElBQWQsQ0FBbUJ4RCxNQUFNLElBQUk7QUFDbEMsV0FBT0EsTUFBTSxDQUFDb0ksdUJBQVAsQ0FBK0J6TSxTQUEvQixFQUEwQ3FNLE1BQTFDLEVBQWtEak8sS0FBbEQsQ0FBUDtBQUNELEdBRk0sQ0FBUDtBQUdELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQSxTQUFTa04sT0FBVCxDQUFpQjZDLEdBQWpCLEVBQW9EO0FBQ2xELFFBQU03UyxJQUFJLEdBQUcsT0FBTzZTLEdBQXBCOztBQUNBLFVBQVE3UyxJQUFSO0FBQ0UsU0FBSyxTQUFMO0FBQ0UsYUFBTyxTQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU8sUUFBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPLFFBQVA7O0FBQ0YsU0FBSyxLQUFMO0FBQ0EsU0FBSyxRQUFMO0FBQ0UsVUFBSSxDQUFDNlMsR0FBTCxFQUFVO0FBQ1IsZUFBT2pLLFNBQVA7QUFDRDs7QUFDRCxhQUFPa0ssYUFBYSxDQUFDRCxHQUFELENBQXBCOztBQUNGLFNBQUssVUFBTDtBQUNBLFNBQUssUUFBTDtBQUNBLFNBQUssV0FBTDtBQUNBO0FBQ0UsWUFBTSxjQUFjQSxHQUFwQjtBQWpCSjtBQW1CRCxDLENBRUQ7QUFDQTtBQUNBOzs7QUFDQSxTQUFTQyxhQUFULENBQXVCRCxHQUF2QixFQUFxRDtBQUNuRCxNQUFJQSxHQUFHLFlBQVlyTCxLQUFuQixFQUEwQjtBQUN4QixXQUFPLE9BQVA7QUFDRDs7QUFDRCxNQUFJcUwsR0FBRyxDQUFDRSxNQUFSLEVBQWdCO0FBQ2QsWUFBUUYsR0FBRyxDQUFDRSxNQUFaO0FBQ0UsV0FBSyxTQUFMO0FBQ0UsWUFBSUYsR0FBRyxDQUFDbk8sU0FBUixFQUFtQjtBQUNqQixpQkFBTztBQUNMMUUsWUFBQUEsSUFBSSxFQUFFLFNBREQ7QUFFTDJCLFlBQUFBLFdBQVcsRUFBRWtSLEdBQUcsQ0FBQ25PO0FBRlosV0FBUDtBQUlEOztBQUNEOztBQUNGLFdBQUssVUFBTDtBQUNFLFlBQUltTyxHQUFHLENBQUNuTyxTQUFSLEVBQW1CO0FBQ2pCLGlCQUFPO0FBQ0wxRSxZQUFBQSxJQUFJLEVBQUUsVUFERDtBQUVMMkIsWUFBQUEsV0FBVyxFQUFFa1IsR0FBRyxDQUFDbk87QUFGWixXQUFQO0FBSUQ7O0FBQ0Q7O0FBQ0YsV0FBSyxNQUFMO0FBQ0UsWUFBSW1PLEdBQUcsQ0FBQ3BSLElBQVIsRUFBYztBQUNaLGlCQUFPLE1BQVA7QUFDRDs7QUFDRDs7QUFDRixXQUFLLE1BQUw7QUFDRSxZQUFJb1IsR0FBRyxDQUFDRyxHQUFSLEVBQWE7QUFDWCxpQkFBTyxNQUFQO0FBQ0Q7O0FBQ0Q7O0FBQ0YsV0FBSyxVQUFMO0FBQ0UsWUFBSUgsR0FBRyxDQUFDSSxRQUFKLElBQWdCLElBQWhCLElBQXdCSixHQUFHLENBQUNLLFNBQUosSUFBaUIsSUFBN0MsRUFBbUQ7QUFDakQsaUJBQU8sVUFBUDtBQUNEOztBQUNEOztBQUNGLFdBQUssT0FBTDtBQUNFLFlBQUlMLEdBQUcsQ0FBQ00sTUFBUixFQUFnQjtBQUNkLGlCQUFPLE9BQVA7QUFDRDs7QUFDRDs7QUFDRixXQUFLLFNBQUw7QUFDRSxZQUFJTixHQUFHLENBQUNPLFdBQVIsRUFBcUI7QUFDbkIsaUJBQU8sU0FBUDtBQUNEOztBQUNEO0FBekNKOztBQTJDQSxVQUFNLElBQUkzVCxLQUFLLENBQUNnSCxLQUFWLENBQWdCaEgsS0FBSyxDQUFDZ0gsS0FBTixDQUFZb0MsY0FBNUIsRUFBNEMseUJBQXlCZ0ssR0FBRyxDQUFDRSxNQUF6RSxDQUFOO0FBQ0Q7O0FBQ0QsTUFBSUYsR0FBRyxDQUFDLEtBQUQsQ0FBUCxFQUFnQjtBQUNkLFdBQU9DLGFBQWEsQ0FBQ0QsR0FBRyxDQUFDLEtBQUQsQ0FBSixDQUFwQjtBQUNEOztBQUNELE1BQUlBLEdBQUcsQ0FBQzFFLElBQVIsRUFBYztBQUNaLFlBQVEwRSxHQUFHLENBQUMxRSxJQUFaO0FBQ0UsV0FBSyxXQUFMO0FBQ0UsZUFBTyxRQUFQOztBQUNGLFdBQUssUUFBTDtBQUNFLGVBQU8sSUFBUDs7QUFDRixXQUFLLEtBQUw7QUFDQSxXQUFLLFdBQUw7QUFDQSxXQUFLLFFBQUw7QUFDRSxlQUFPLE9BQVA7O0FBQ0YsV0FBSyxhQUFMO0FBQ0EsV0FBSyxnQkFBTDtBQUNFLGVBQU87QUFDTG5PLFVBQUFBLElBQUksRUFBRSxVQUREO0FBRUwyQixVQUFBQSxXQUFXLEVBQUVrUixHQUFHLENBQUNRLE9BQUosQ0FBWSxDQUFaLEVBQWUzTztBQUZ2QixTQUFQOztBQUlGLFdBQUssT0FBTDtBQUNFLGVBQU9vTyxhQUFhLENBQUNELEdBQUcsQ0FBQ1MsR0FBSixDQUFRLENBQVIsQ0FBRCxDQUFwQjs7QUFDRjtBQUNFLGNBQU0sb0JBQW9CVCxHQUFHLENBQUMxRSxJQUE5QjtBQWxCSjtBQW9CRDs7QUFDRCxTQUFPLFFBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBUaGlzIGNsYXNzIGhhbmRsZXMgc2NoZW1hIHZhbGlkYXRpb24sIHBlcnNpc3RlbmNlLCBhbmQgbW9kaWZpY2F0aW9uLlxuLy9cbi8vIEVhY2ggaW5kaXZpZHVhbCBTY2hlbWEgb2JqZWN0IHNob3VsZCBiZSBpbW11dGFibGUuIFRoZSBoZWxwZXJzIHRvXG4vLyBkbyB0aGluZ3Mgd2l0aCB0aGUgU2NoZW1hIGp1c3QgcmV0dXJuIGEgbmV3IHNjaGVtYSB3aGVuIHRoZSBzY2hlbWFcbi8vIGlzIGNoYW5nZWQuXG4vL1xuLy8gVGhlIGNhbm9uaWNhbCBwbGFjZSB0byBzdG9yZSB0aGlzIFNjaGVtYSBpcyBpbiB0aGUgZGF0YWJhc2UgaXRzZWxmLFxuLy8gaW4gYSBfU0NIRU1BIGNvbGxlY3Rpb24uIFRoaXMgaXMgbm90IHRoZSByaWdodCB3YXkgdG8gZG8gaXQgZm9yIGFuXG4vLyBvcGVuIHNvdXJjZSBmcmFtZXdvcmssIGJ1dCBpdCdzIGJhY2t3YXJkIGNvbXBhdGlibGUsIHNvIHdlJ3JlXG4vLyBrZWVwaW5nIGl0IHRoaXMgd2F5IGZvciBub3cuXG4vL1xuLy8gSW4gQVBJLWhhbmRsaW5nIGNvZGUsIHlvdSBzaG91bGQgb25seSB1c2UgdGhlIFNjaGVtYSBjbGFzcyB2aWEgdGhlXG4vLyBEYXRhYmFzZUNvbnRyb2xsZXIuIFRoaXMgd2lsbCBsZXQgdXMgcmVwbGFjZSB0aGUgc2NoZW1hIGxvZ2ljIGZvclxuLy8gZGlmZmVyZW50IGRhdGFiYXNlcy5cbi8vIFRPRE86IGhpZGUgYWxsIHNjaGVtYSBsb2dpYyBpbnNpZGUgdGhlIGRhdGFiYXNlIGFkYXB0ZXIuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9TdG9yYWdlL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgZGVlcGNvcHkgZnJvbSAnZGVlcGNvcHknO1xuaW1wb3J0IHR5cGUge1xuICBTY2hlbWEsXG4gIFNjaGVtYUZpZWxkcyxcbiAgQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICBTY2hlbWFGaWVsZCxcbiAgTG9hZFNjaGVtYU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkZWZhdWx0Q29sdW1uczogeyBbc3RyaW5nXTogU2NoZW1hRmllbGRzIH0gPSBPYmplY3QuZnJlZXplKHtcbiAgLy8gQ29udGFpbiB0aGUgZGVmYXVsdCBjb2x1bW5zIGZvciBldmVyeSBwYXJzZSBvYmplY3QgdHlwZSAoZXhjZXB0IF9Kb2luIGNvbGxlY3Rpb24pXG4gIF9EZWZhdWx0OiB7XG4gICAgb2JqZWN0SWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBjcmVhdGVkQXQ6IHsgdHlwZTogJ0RhdGUnIH0sXG4gICAgdXBkYXRlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIEFDTDogeyB0eXBlOiAnQUNMJyB9LFxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfVXNlciBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1VzZXI6IHtcbiAgICB1c2VybmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhc3N3b3JkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZW1haWw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBlbWFpbFZlcmlmaWVkOiB7IHR5cGU6ICdCb29sZWFuJyB9LFxuICAgIGF1dGhEYXRhOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9JbnN0YWxsYXRpb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9JbnN0YWxsYXRpb246IHtcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRldmljZVRva2VuOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2hhbm5lbHM6IHsgdHlwZTogJ0FycmF5JyB9LFxuICAgIGRldmljZVR5cGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwdXNoVHlwZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIEdDTVNlbmRlcklkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdGltZVpvbmU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBsb2NhbGVJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYmFkZ2U6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBhcHBWZXJzaW9uOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYXBwTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGFwcElkZW50aWZpZXI6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJzZVZlcnNpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1JvbGUgY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9Sb2xlOiB7XG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHVzZXJzOiB7IHR5cGU6ICdSZWxhdGlvbicsIHRhcmdldENsYXNzOiAnX1VzZXInIH0sXG4gICAgcm9sZXM6IHsgdHlwZTogJ1JlbGF0aW9uJywgdGFyZ2V0Q2xhc3M6ICdfUm9sZScgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1Nlc3Npb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9TZXNzaW9uOiB7XG4gICAgcmVzdHJpY3RlZDogeyB0eXBlOiAnQm9vbGVhbicgfSxcbiAgICB1c2VyOiB7IHR5cGU6ICdQb2ludGVyJywgdGFyZ2V0Q2xhc3M6ICdfVXNlcicgfSxcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNlc3Npb25Ub2tlbjogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZXNBdDogeyB0eXBlOiAnRGF0ZScgfSxcbiAgICBjcmVhdGVkV2l0aDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfUHJvZHVjdDoge1xuICAgIHByb2R1Y3RJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZG93bmxvYWQ6IHsgdHlwZTogJ0ZpbGUnIH0sXG4gICAgZG93bmxvYWROYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgaWNvbjogeyB0eXBlOiAnRmlsZScgfSxcbiAgICBvcmRlcjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHRpdGxlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3VidGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX1B1c2hTdGF0dXM6IHtcbiAgICBwdXNoVGltZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNvdXJjZTogeyB0eXBlOiAnU3RyaW5nJyB9LCAvLyByZXN0IG9yIHdlYnVpXG4gICAgcXVlcnk6IHsgdHlwZTogJ1N0cmluZycgfSwgLy8gdGhlIHN0cmluZ2lmaWVkIEpTT04gcXVlcnlcbiAgICBwYXlsb2FkOiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vIHRoZSBzdHJpbmdpZmllZCBKU09OIHBheWxvYWQsXG4gICAgdGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBleHBpcnk6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBleHBpcmF0aW9uX2ludGVydmFsOiB7IHR5cGU6ICdOdW1iZXInIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbnVtU2VudDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIG51bUZhaWxlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHB1c2hIYXNoOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZXJyb3JNZXNzYWdlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclR5cGU6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgICBmYWlsZWRQZXJUeXBlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGZhaWxlZFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGNvdW50OiB7IHR5cGU6ICdOdW1iZXInIH0sIC8vIHRyYWNrcyAjIG9mIGJhdGNoZXMgcXVldWVkIGFuZCBwZW5kaW5nXG4gIH0sXG4gIF9Kb2JTdGF0dXM6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc291cmNlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbWVzc2FnZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhcmFtczogeyB0eXBlOiAnT2JqZWN0JyB9LCAvLyBwYXJhbXMgcmVjZWl2ZWQgd2hlbiBjYWxsaW5nIHRoZSBqb2JcbiAgICBmaW5pc2hlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICB9LFxuICBfSm9iU2NoZWR1bGU6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGVzY3JpcHRpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJhbXM6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBzdGFydEFmdGVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGF5c09mV2VlazogeyB0eXBlOiAnQXJyYXknIH0sXG4gICAgdGltZU9mRGF5OiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbGFzdFJ1bjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHJlcGVhdE1pbnV0ZXM6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgfSxcbiAgX0hvb2tzOiB7XG4gICAgZnVuY3Rpb25OYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2xhc3NOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdHJpZ2dlck5hbWU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICB1cmw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX0dsb2JhbENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgcGFyYW1zOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgbWFzdGVyS2V5T25seTogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfR3JhcGhRTENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY29uZmlnOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIF9BdWRpZW5jZToge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHF1ZXJ5OiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vc3RvcmluZyBxdWVyeSBhcyBKU09OIHN0cmluZyB0byBwcmV2ZW50IFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIiBlcnJvclxuICAgIGxhc3RVc2VkOiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIHRpbWVzVXNlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICB9LFxuICBfSWRlbXBvdGVuY3k6IHtcbiAgICByZXFJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZTogeyB0eXBlOiAnRGF0ZScgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3QuZnJlZXplKHtcbiAgX1Byb2R1Y3Q6IFsncHJvZHVjdElkZW50aWZpZXInLCAnaWNvbicsICdvcmRlcicsICd0aXRsZScsICdzdWJ0aXRsZSddLFxuICBfUm9sZTogWyduYW1lJywgJ0FDTCddLFxufSk7XG5cbmNvbnN0IHN5c3RlbUNsYXNzZXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ19Vc2VyJyxcbiAgJ19JbnN0YWxsYXRpb24nLFxuICAnX1JvbGUnLFxuICAnX1Nlc3Npb24nLFxuICAnX1Byb2R1Y3QnLFxuICAnX1B1c2hTdGF0dXMnLFxuICAnX0pvYlN0YXR1cycsXG4gICdfSm9iU2NoZWR1bGUnLFxuICAnX0F1ZGllbmNlJyxcbiAgJ19JZGVtcG90ZW5jeScsXG5dKTtcblxuY29uc3Qgdm9sYXRpbGVDbGFzc2VzID0gT2JqZWN0LmZyZWV6ZShbXG4gICdfSm9iU3RhdHVzJyxcbiAgJ19QdXNoU3RhdHVzJyxcbiAgJ19Ib29rcycsXG4gICdfR2xvYmFsQ29uZmlnJyxcbiAgJ19HcmFwaFFMQ29uZmlnJyxcbiAgJ19Kb2JTY2hlZHVsZScsXG4gICdfQXVkaWVuY2UnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl0pO1xuXG4vLyBBbnl0aGluZyB0aGF0IHN0YXJ0IHdpdGggcm9sZVxuY29uc3Qgcm9sZVJlZ2V4ID0gL15yb2xlOi4qLztcbi8vIEFueXRoaW5nIHRoYXQgc3RhcnRzIHdpdGggdXNlckZpZWxkIChhbGxvd2VkIGZvciBwcm90ZWN0ZWQgZmllbGRzIG9ubHkpXG5jb25zdCBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXggPSAvXnVzZXJGaWVsZDouKi87XG4vLyAqIHBlcm1pc3Npb25cbmNvbnN0IHB1YmxpY1JlZ2V4ID0gL15cXCokLztcblxuY29uc3QgYXV0aGVudGljYXRlZFJlZ2V4ID0gL15hdXRoZW50aWNhdGVkJC87XG5cbmNvbnN0IHJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCA9IC9ecmVxdWlyZXNBdXRoZW50aWNhdGlvbiQvO1xuXG5jb25zdCBjbHBQb2ludGVyUmVnZXggPSAvXnBvaW50ZXJGaWVsZHMkLztcblxuLy8gcmVnZXggZm9yIHZhbGlkYXRpbmcgZW50aXRpZXMgaW4gcHJvdGVjdGVkRmllbGRzIG9iamVjdFxuY29uc3QgcHJvdGVjdGVkRmllbGRzUmVnZXggPSBPYmplY3QuZnJlZXplKFtcbiAgcHJvdGVjdGVkRmllbGRzUG9pbnRlclJlZ2V4LFxuICBwdWJsaWNSZWdleCxcbiAgYXV0aGVudGljYXRlZFJlZ2V4LFxuICByb2xlUmVnZXgsXG5dKTtcblxuLy8gY2xwIHJlZ2V4XG5jb25zdCBjbHBGaWVsZHNSZWdleCA9IE9iamVjdC5mcmVlemUoW1xuICBjbHBQb2ludGVyUmVnZXgsXG4gIHB1YmxpY1JlZ2V4LFxuICByZXF1aXJlc0F1dGhlbnRpY2F0aW9uUmVnZXgsXG4gIHJvbGVSZWdleCxcbl0pO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVBlcm1pc3Npb25LZXkoa2V5LCB1c2VySWRSZWdFeHApIHtcbiAgbGV0IG1hdGNoZXNTb21lID0gZmFsc2U7XG4gIGZvciAoY29uc3QgcmVnRXggb2YgY2xwRmllbGRzUmVnZXgpIHtcbiAgICBpZiAoa2V5Lm1hdGNoKHJlZ0V4KSAhPT0gbnVsbCkge1xuICAgICAgbWF0Y2hlc1NvbWUgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLy8gdXNlcklkIGRlcGVuZHMgb24gc3RhcnR1cCBvcHRpb25zIHNvIGl0J3MgZHluYW1pY1xuICBjb25zdCB2YWxpZCA9IG1hdGNoZXNTb21lIHx8IGtleS5tYXRjaCh1c2VySWRSZWdFeHApICE9PSBudWxsO1xuICBpZiAoIXZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3RlY3RlZEZpZWxkc0tleShrZXksIHVzZXJJZFJlZ0V4cCkge1xuICBsZXQgbWF0Y2hlc1NvbWUgPSBmYWxzZTtcbiAgZm9yIChjb25zdCByZWdFeCBvZiBwcm90ZWN0ZWRGaWVsZHNSZWdleCkge1xuICAgIGlmIChrZXkubWF0Y2gocmVnRXgpICE9PSBudWxsKSB7XG4gICAgICBtYXRjaGVzU29tZSA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyB1c2VySWQgcmVnZXggZGVwZW5kcyBvbiBsYXVuY2ggb3B0aW9ucyBzbyBpdCdzIGR5bmFtaWNcbiAgY29uc3QgdmFsaWQgPSBtYXRjaGVzU29tZSB8fCBrZXkubWF0Y2godXNlcklkUmVnRXhwKSAhPT0gbnVsbDtcbiAgaWYgKCF2YWxpZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgIGAnJHtrZXl9JyBpcyBub3QgYSB2YWxpZCBrZXkgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zYFxuICAgICk7XG4gIH1cbn1cblxuY29uc3QgQ0xQVmFsaWRLZXlzID0gT2JqZWN0LmZyZWV6ZShbXG4gICdmaW5kJyxcbiAgJ2NvdW50JyxcbiAgJ2dldCcsXG4gICdjcmVhdGUnLFxuICAndXBkYXRlJyxcbiAgJ2RlbGV0ZScsXG4gICdhZGRGaWVsZCcsXG4gICdyZWFkVXNlckZpZWxkcycsXG4gICd3cml0ZVVzZXJGaWVsZHMnLFxuICAncHJvdGVjdGVkRmllbGRzJyxcbl0pO1xuXG4vLyB2YWxpZGF0aW9uIGJlZm9yZSBzZXR0aW5nIGNsYXNzLWxldmVsIHBlcm1pc3Npb25zIG9uIGNvbGxlY3Rpb25cbmZ1bmN0aW9uIHZhbGlkYXRlQ0xQKHBlcm1zOiBDbGFzc0xldmVsUGVybWlzc2lvbnMsIGZpZWxkczogU2NoZW1hRmllbGRzLCB1c2VySWRSZWdFeHA6IFJlZ0V4cCkge1xuICBpZiAoIXBlcm1zKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAoY29uc3Qgb3BlcmF0aW9uS2V5IGluIHBlcm1zKSB7XG4gICAgaWYgKENMUFZhbGlkS2V5cy5pbmRleE9mKG9wZXJhdGlvbktleSkgPT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJHtvcGVyYXRpb25LZXl9IGlzIG5vdCBhIHZhbGlkIG9wZXJhdGlvbiBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IHBlcm1zW29wZXJhdGlvbktleV07XG4gICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgb3BlcmF0aW9uS2V5XG5cbiAgICAvLyB0aHJvd3Mgd2hlbiByb290IGZpZWxkcyBhcmUgb2Ygd3JvbmcgdHlwZVxuICAgIHZhbGlkYXRlQ0xQanNvbihvcGVyYXRpb24sIG9wZXJhdGlvbktleSk7XG5cbiAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbktleSA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICAgIC8vIHZhbGlkYXRlIGdyb3VwZWQgcG9pbnRlciBwZXJtaXNzaW9uc1xuICAgICAgLy8gbXVzdCBiZSBhbiBhcnJheSB3aXRoIGZpZWxkIG5hbWVzXG4gICAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBvZiBvcGVyYXRpb24pIHtcbiAgICAgICAgdmFsaWRhdGVQb2ludGVyUGVybWlzc2lvbihmaWVsZE5hbWUsIGZpZWxkcywgb3BlcmF0aW9uS2V5KTtcbiAgICAgIH1cbiAgICAgIC8vIHJlYWRVc2VyRmllbGRzIGFuZCB3cml0ZXJVc2VyRmllbGRzIGRvIG5vdCBoYXZlIG5lc2R0ZWQgZmllbGRzXG4gICAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIHByb3RlY3RlZCBmaWVsZHNcbiAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAncHJvdGVjdGVkRmllbGRzJykge1xuICAgICAgZm9yIChjb25zdCBlbnRpdHkgaW4gb3BlcmF0aW9uKSB7XG4gICAgICAgIC8vIHRocm93cyBvbiB1bmV4cGVjdGVkIGtleVxuICAgICAgICB2YWxpZGF0ZVByb3RlY3RlZEZpZWxkc0tleShlbnRpdHksIHVzZXJJZFJlZ0V4cCk7XG5cbiAgICAgICAgY29uc3QgcHJvdGVjdGVkRmllbGRzID0gb3BlcmF0aW9uW2VudGl0eV07XG5cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHByb3RlY3RlZEZpZWxkcykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7cHJvdGVjdGVkRmllbGRzfScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHByb3RlY3RlZEZpZWxkc1ske2VudGl0eX1dIC0gZXhwZWN0ZWQgYW4gYXJyYXkuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGUgZmllbGQgaXMgaW4gZm9ybSBvZiBhcnJheVxuICAgICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgIC8vIGRvIG5vdCBhbGxvb3cgdG8gcHJvdGVjdCBkZWZhdWx0IGZpZWxkc1xuICAgICAgICAgIGlmIChkZWZhdWx0Q29sdW1ucy5fRGVmYXVsdFtmaWVsZF0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICBgRGVmYXVsdCBmaWVsZCAnJHtmaWVsZH0nIGNhbiBub3QgYmUgcHJvdGVjdGVkYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZmllbGQgc2hvdWxkIGV4aXN0IG9uIGNvbGxlY3Rpb25cbiAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmaWVsZHMsIGZpZWxkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIGBGaWVsZCAnJHtmaWVsZH0nIGluIHByb3RlY3RlZEZpZWxkczoke2VudGl0eX0gZG9lcyBub3QgZXhpc3RgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgb3BlcmF0aW9uS2V5XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBvdGhlciBmaWVsZHNcbiAgICAvLyBFbnRpdHkgY2FuIGJlOlxuICAgIC8vIFwiKlwiIC0gUHVibGljLFxuICAgIC8vIFwicmVxdWlyZXNBdXRoZW50aWNhdGlvblwiIC0gYXV0aGVudGljYXRlZCB1c2VycyxcbiAgICAvLyBcIm9iamVjdElkXCIgLSBfVXNlciBpZCxcbiAgICAvLyBcInJvbGU6cm9sZW5hbWVcIixcbiAgICAvLyBcInBvaW50ZXJGaWVsZHNcIiAtIGFycmF5IG9mIGZpZWxkIG5hbWVzIGNvbnRhaW5pbmcgcG9pbnRlcnMgdG8gdXNlcnNcbiAgICBmb3IgKGNvbnN0IGVudGl0eSBpbiBvcGVyYXRpb24pIHtcbiAgICAgIC8vIHRocm93cyBvbiB1bmV4cGVjdGVkIGtleVxuICAgICAgdmFsaWRhdGVQZXJtaXNzaW9uS2V5KGVudGl0eSwgdXNlcklkUmVnRXhwKTtcblxuICAgICAgLy8gZW50aXR5IGNhbiBiZSBlaXRoZXI6XG4gICAgICAvLyBcInBvaW50ZXJGaWVsZHNcIjogc3RyaW5nW11cbiAgICAgIGlmIChlbnRpdHkgPT09ICdwb2ludGVyRmllbGRzJykge1xuICAgICAgICBjb25zdCBwb2ludGVyRmllbGRzID0gb3BlcmF0aW9uW2VudGl0eV07XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnRlckZpZWxkcykpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHBvaW50ZXJGaWVsZCBvZiBwb2ludGVyRmllbGRzKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKHBvaW50ZXJGaWVsZCwgZmllbGRzLCBvcGVyYXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7cG9pbnRlckZpZWxkc30nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciAke29wZXJhdGlvbktleX1bJHtlbnRpdHl9XSAtIGV4cGVjdGVkIGFuIGFycmF5LmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb2NlZWQgd2l0aCBuZXh0IGVudGl0eSBrZXlcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIG9yIFtlbnRpdHldOiBib29sZWFuXG4gICAgICBjb25zdCBwZXJtaXQgPSBvcGVyYXRpb25bZW50aXR5XTtcblxuICAgICAgaWYgKHBlcm1pdCAhPT0gdHJ1ZSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGAnJHtwZXJtaXR9JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9OiR7ZW50aXR5fToke3Blcm1pdH1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ0xQanNvbihvcGVyYXRpb246IGFueSwgb3BlcmF0aW9uS2V5OiBzdHJpbmcpIHtcbiAgaWYgKG9wZXJhdGlvbktleSA9PT0gJ3JlYWRVc2VyRmllbGRzJyB8fCBvcGVyYXRpb25LZXkgPT09ICd3cml0ZVVzZXJGaWVsZHMnKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wZXJhdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJyR7b3BlcmF0aW9ufScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zICR7b3BlcmF0aW9uS2V5fSAtIG11c3QgYmUgYW4gYXJyYXlgXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIG9wZXJhdGlvbiA9PT0gJ29iamVjdCcgJiYgb3BlcmF0aW9uICE9PSBudWxsKSB7XG4gICAgICAvLyBvayB0byBwcm9jZWVkXG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJyR7b3BlcmF0aW9ufScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zICR7b3BlcmF0aW9uS2V5fSAtIG11c3QgYmUgYW4gb2JqZWN0YFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVQb2ludGVyUGVybWlzc2lvbihmaWVsZE5hbWU6IHN0cmluZywgZmllbGRzOiBPYmplY3QsIG9wZXJhdGlvbjogc3RyaW5nKSB7XG4gIC8vIFVzZXMgY29sbGVjdGlvbiBzY2hlbWEgdG8gZW5zdXJlIHRoZSBmaWVsZCBpcyBvZiB0eXBlOlxuICAvLyAtIFBvaW50ZXI8X1VzZXI+IChwb2ludGVycylcbiAgLy8gLSBBcnJheVxuICAvL1xuICAvLyAgICBJdCdzIG5vdCBwb3NzaWJsZSB0byBlbmZvcmNlIHR5cGUgb24gQXJyYXkncyBpdGVtcyBpbiBzY2hlbWFcbiAgLy8gIHNvIHdlIGFjY2VwdCBhbnkgQXJyYXkgZmllbGQsIGFuZCBsYXRlciB3aGVuIGFwcGx5aW5nIHBlcm1pc3Npb25zXG4gIC8vICBvbmx5IGl0ZW1zIHRoYXQgYXJlIHBvaW50ZXJzIHRvIF9Vc2VyIGFyZSBjb25zaWRlcmVkLlxuICBpZiAoXG4gICAgIShcbiAgICAgIGZpZWxkc1tmaWVsZE5hbWVdICYmXG4gICAgICAoKGZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT0gJ1BvaW50ZXInICYmIGZpZWxkc1tmaWVsZE5hbWVdLnRhcmdldENsYXNzID09ICdfVXNlcicpIHx8XG4gICAgICAgIGZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT0gJ0FycmF5JylcbiAgICApXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgIGAnJHtmaWVsZE5hbWV9JyBpcyBub3QgYSB2YWxpZCBjb2x1bW4gZm9yIGNsYXNzIGxldmVsIHBvaW50ZXIgcGVybWlzc2lvbnMgJHtvcGVyYXRpb259YFxuICAgICk7XG4gIH1cbn1cblxuY29uc3Qgam9pbkNsYXNzUmVnZXggPSAvXl9Kb2luOltBLVphLXowLTlfXSs6W0EtWmEtejAtOV9dKy87XG5jb25zdCBjbGFzc0FuZEZpZWxkUmVnZXggPSAvXltBLVphLXpdW0EtWmEtejAtOV9dKiQvO1xuZnVuY3Rpb24gY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAvLyBWYWxpZCBjbGFzc2VzIG11c3Q6XG4gIHJldHVybiAoXG4gICAgLy8gQmUgb25lIG9mIF9Vc2VyLCBfSW5zdGFsbGF0aW9uLCBfUm9sZSwgX1Nlc3Npb24gT1JcbiAgICBzeXN0ZW1DbGFzc2VzLmluZGV4T2YoY2xhc3NOYW1lKSA+IC0xIHx8XG4gICAgLy8gQmUgYSBqb2luIHRhYmxlIE9SXG4gICAgam9pbkNsYXNzUmVnZXgudGVzdChjbGFzc05hbWUpIHx8XG4gICAgLy8gSW5jbHVkZSBvbmx5IGFscGhhLW51bWVyaWMgYW5kIHVuZGVyc2NvcmVzLCBhbmQgbm90IHN0YXJ0IHdpdGggYW4gdW5kZXJzY29yZSBvciBudW1iZXJcbiAgICBmaWVsZE5hbWVJc1ZhbGlkKGNsYXNzTmFtZSlcbiAgKTtcbn1cblxuLy8gVmFsaWQgZmllbGRzIG11c3QgYmUgYWxwaGEtbnVtZXJpYywgYW5kIG5vdCBzdGFydCB3aXRoIGFuIHVuZGVyc2NvcmUgb3IgbnVtYmVyXG5mdW5jdGlvbiBmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBjbGFzc0FuZEZpZWxkUmVnZXgudGVzdChmaWVsZE5hbWUpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBpdCdzIG5vdCB0cnlpbmcgdG8gY2xvYmJlciBvbmUgb2YgdGhlIGRlZmF1bHQgZmllbGRzIG9mIHRoZSBjbGFzcy5cbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWU6IHN0cmluZywgY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0W2ZpZWxkTmFtZV0pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gJiYgZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXVtmaWVsZE5hbWVdKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiAoXG4gICAgJ0ludmFsaWQgY2xhc3NuYW1lOiAnICtcbiAgICBjbGFzc05hbWUgK1xuICAgICcsIGNsYXNzbmFtZXMgY2FuIG9ubHkgaGF2ZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgXywgYW5kIG11c3Qgc3RhcnQgd2l0aCBhbiBhbHBoYSBjaGFyYWN0ZXIgJ1xuICApO1xufVxuXG5jb25zdCBpbnZhbGlkSnNvbkVycm9yID0gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2ludmFsaWQgSlNPTicpO1xuY29uc3QgdmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzID0gW1xuICAnTnVtYmVyJyxcbiAgJ1N0cmluZycsXG4gICdCb29sZWFuJyxcbiAgJ0RhdGUnLFxuICAnT2JqZWN0JyxcbiAgJ0FycmF5JyxcbiAgJ0dlb1BvaW50JyxcbiAgJ0ZpbGUnLFxuICAnQnl0ZXMnLFxuICAnUG9seWdvbicsXG5dO1xuLy8gUmV0dXJucyBhbiBlcnJvciBzdWl0YWJsZSBmb3IgdGhyb3dpbmcgaWYgdGhlIHR5cGUgaXMgaW52YWxpZFxuY29uc3QgZmllbGRUeXBlSXNJbnZhbGlkID0gKHsgdHlwZSwgdGFyZ2V0Q2xhc3MgfSkgPT4ge1xuICBpZiAoWydQb2ludGVyJywgJ1JlbGF0aW9uJ10uaW5kZXhPZih0eXBlKSA+PSAwKSB7XG4gICAgaWYgKCF0YXJnZXRDbGFzcykge1xuICAgICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcigxMzUsIGB0eXBlICR7dHlwZX0gbmVlZHMgYSBjbGFzcyBuYW1lYCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGFyZ2V0Q2xhc3MgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gaW52YWxpZEpzb25FcnJvcjtcbiAgICB9IGVsc2UgaWYgKCFjbGFzc05hbWVJc1ZhbGlkKHRhcmdldENsYXNzKSkge1xuICAgICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsIGludmFsaWRDbGFzc05hbWVNZXNzYWdlKHRhcmdldENsYXNzKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gaW52YWxpZEpzb25FcnJvcjtcbiAgfVxuICBpZiAodmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzLmluZGV4T2YodHlwZSkgPCAwKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSwgYGludmFsaWQgZmllbGQgdHlwZTogJHt0eXBlfWApO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG5jb25zdCBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hID0gKHNjaGVtYTogYW55KSA9PiB7XG4gIHNjaGVtYSA9IGluamVjdERlZmF1bHRTY2hlbWEoc2NoZW1hKTtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuQUNMO1xuICBzY2hlbWEuZmllbGRzLl9ycGVybSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuICBzY2hlbWEuZmllbGRzLl93cGVybSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuXG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMucGFzc3dvcmQ7XG4gICAgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbmNvbnN0IGNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSA9ICh7IC4uLnNjaGVtYSB9KSA9PiB7XG4gIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9ycGVybTtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3dwZXJtO1xuXG4gIHNjaGVtYS5maWVsZHMuQUNMID0geyB0eXBlOiAnQUNMJyB9O1xuXG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuYXV0aERhdGE7IC8vQXV0aCBkYXRhIGlzIGltcGxpY2l0XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgICBzY2hlbWEuZmllbGRzLnBhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICB9XG5cbiAgaWYgKHNjaGVtYS5pbmRleGVzICYmIE9iamVjdC5rZXlzKHNjaGVtYS5pbmRleGVzKS5sZW5ndGggPT09IDApIHtcbiAgICBkZWxldGUgc2NoZW1hLmluZGV4ZXM7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY2xhc3MgU2NoZW1hRGF0YSB7XG4gIF9fZGF0YTogYW55O1xuICBfX3Byb3RlY3RlZEZpZWxkczogYW55O1xuICBjb25zdHJ1Y3RvcihhbGxTY2hlbWFzID0gW10sIHByb3RlY3RlZEZpZWxkcyA9IHt9KSB7XG4gICAgdGhpcy5fX2RhdGEgPSB7fTtcbiAgICB0aGlzLl9fcHJvdGVjdGVkRmllbGRzID0gcHJvdGVjdGVkRmllbGRzO1xuICAgIGFsbFNjaGVtYXMuZm9yRWFjaChzY2hlbWEgPT4ge1xuICAgICAgaWYgKHZvbGF0aWxlQ2xhc3Nlcy5pbmNsdWRlcyhzY2hlbWEuY2xhc3NOYW1lKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgc2NoZW1hLmNsYXNzTmFtZSwge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuX19kYXRhW3NjaGVtYS5jbGFzc05hbWVdKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgICAgICBkYXRhLmZpZWxkcyA9IGluamVjdERlZmF1bHRTY2hlbWEoc2NoZW1hKS5maWVsZHM7XG4gICAgICAgICAgICBkYXRhLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyA9IGRlZXBjb3B5KHNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMpO1xuICAgICAgICAgICAgZGF0YS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG5cbiAgICAgICAgICAgIGNvbnN0IGNsYXNzUHJvdGVjdGVkRmllbGRzID0gdGhpcy5fX3Byb3RlY3RlZEZpZWxkc1tzY2hlbWEuY2xhc3NOYW1lXTtcbiAgICAgICAgICAgIGlmIChjbGFzc1Byb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjbGFzc1Byb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVucSA9IG5ldyBTZXQoW1xuICAgICAgICAgICAgICAgICAgLi4uKGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLnByb3RlY3RlZEZpZWxkc1trZXldIHx8IFtdKSxcbiAgICAgICAgICAgICAgICAgIC4uLmNsYXNzUHJvdGVjdGVkRmllbGRzW2tleV0sXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMucHJvdGVjdGVkRmllbGRzW2tleV0gPSBBcnJheS5mcm9tKHVucSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV0gPSBkYXRhO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV07XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEluamVjdCB0aGUgaW4tbWVtb3J5IGNsYXNzZXNcbiAgICB2b2xhdGlsZUNsYXNzZXMuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGNsYXNzTmFtZSwge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuX19kYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGZpZWxkczoge30sXG4gICAgICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgICAgIGRhdGEuZmllbGRzID0gc2NoZW1hLmZpZWxkcztcbiAgICAgICAgICAgIGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICAgICAgICAgIGRhdGEuaW5kZXhlcyA9IHNjaGVtYS5pbmRleGVzO1xuICAgICAgICAgICAgdGhpcy5fX2RhdGFbY2xhc3NOYW1lXSA9IGRhdGE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLl9fZGF0YVtjbGFzc05hbWVdO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxuY29uc3QgaW5qZWN0RGVmYXVsdFNjaGVtYSA9ICh7IGNsYXNzTmFtZSwgZmllbGRzLCBjbGFzc0xldmVsUGVybWlzc2lvbnMsIGluZGV4ZXMgfTogU2NoZW1hKSA9PiB7XG4gIGNvbnN0IGRlZmF1bHRTY2hlbWE6IFNjaGVtYSA9IHtcbiAgICBjbGFzc05hbWUsXG4gICAgZmllbGRzOiB7XG4gICAgICAuLi5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgIC4uLihkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdIHx8IHt9KSxcbiAgICAgIC4uLmZpZWxkcyxcbiAgICB9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgfTtcbiAgaWYgKGluZGV4ZXMgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoICE9PSAwKSB7XG4gICAgZGVmYXVsdFNjaGVtYS5pbmRleGVzID0gaW5kZXhlcztcbiAgfVxuICByZXR1cm4gZGVmYXVsdFNjaGVtYTtcbn07XG5cbmNvbnN0IF9Ib29rc1NjaGVtYSA9IHsgY2xhc3NOYW1lOiAnX0hvb2tzJywgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fSG9va3MgfTtcbmNvbnN0IF9HbG9iYWxDb25maWdTY2hlbWEgPSB7XG4gIGNsYXNzTmFtZTogJ19HbG9iYWxDb25maWcnLFxuICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9HbG9iYWxDb25maWcsXG59O1xuY29uc3QgX0dyYXBoUUxDb25maWdTY2hlbWEgPSB7XG4gIGNsYXNzTmFtZTogJ19HcmFwaFFMQ29uZmlnJyxcbiAgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fR3JhcGhRTENvbmZpZyxcbn07XG5jb25zdCBfUHVzaFN0YXR1c1NjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19QdXNoU3RhdHVzJyxcbiAgICBmaWVsZHM6IHt9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgX0pvYlN0YXR1c1NjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19Kb2JTdGF0dXMnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSm9iU2NoZWR1bGVTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfSm9iU2NoZWR1bGUnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfQXVkaWVuY2VTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfQXVkaWVuY2UnLFxuICAgIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0F1ZGllbmNlLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgX0lkZW1wb3RlbmN5U2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX0lkZW1wb3RlbmN5JyxcbiAgICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9JZGVtcG90ZW5jeSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMgPSBbXG4gIF9Ib29rc1NjaGVtYSxcbiAgX0pvYlN0YXR1c1NjaGVtYSxcbiAgX0pvYlNjaGVkdWxlU2NoZW1hLFxuICBfUHVzaFN0YXR1c1NjaGVtYSxcbiAgX0dsb2JhbENvbmZpZ1NjaGVtYSxcbiAgX0dyYXBoUUxDb25maWdTY2hlbWEsXG4gIF9BdWRpZW5jZVNjaGVtYSxcbiAgX0lkZW1wb3RlbmN5U2NoZW1hLFxuXTtcblxuY29uc3QgZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUgPSAoZGJUeXBlOiBTY2hlbWFGaWVsZCB8IHN0cmluZywgb2JqZWN0VHlwZTogU2NoZW1hRmllbGQpID0+IHtcbiAgaWYgKGRiVHlwZS50eXBlICE9PSBvYmplY3RUeXBlLnR5cGUpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRiVHlwZS50YXJnZXRDbGFzcyAhPT0gb2JqZWN0VHlwZS50YXJnZXRDbGFzcykgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGJUeXBlID09PSBvYmplY3RUeXBlLnR5cGUpIHJldHVybiB0cnVlO1xuICBpZiAoZGJUeXBlLnR5cGUgPT09IG9iamVjdFR5cGUudHlwZSkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IHR5cGVUb1N0cmluZyA9ICh0eXBlOiBTY2hlbWFGaWVsZCB8IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuICBpZiAodHlwZS50YXJnZXRDbGFzcykge1xuICAgIHJldHVybiBgJHt0eXBlLnR5cGV9PCR7dHlwZS50YXJnZXRDbGFzc30+YDtcbiAgfVxuICByZXR1cm4gYCR7dHlwZS50eXBlfWA7XG59O1xuXG4vLyBTdG9yZXMgdGhlIGVudGlyZSBzY2hlbWEgb2YgdGhlIGFwcCBpbiBhIHdlaXJkIGh5YnJpZCBmb3JtYXQgc29tZXdoZXJlIGJldHdlZW5cbi8vIHRoZSBtb25nbyBmb3JtYXQgYW5kIHRoZSBQYXJzZSBmb3JtYXQuIFNvb24sIHRoaXMgd2lsbCBhbGwgYmUgUGFyc2UgZm9ybWF0LlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NoZW1hQ29udHJvbGxlciB7XG4gIF9kYkFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyO1xuICBzY2hlbWFEYXRhOiB7IFtzdHJpbmddOiBTY2hlbWEgfTtcbiAgX2NhY2hlOiBhbnk7XG4gIHJlbG9hZERhdGFQcm9taXNlOiA/UHJvbWlzZTxhbnk+O1xuICBwcm90ZWN0ZWRGaWVsZHM6IGFueTtcbiAgdXNlcklkUmVnRXg6IFJlZ0V4cDtcblxuICBjb25zdHJ1Y3RvcihkYXRhYmFzZUFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5fZGJBZGFwdGVyID0gZGF0YWJhc2VBZGFwdGVyO1xuICAgIHRoaXMuX2NhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoKTtcbiAgICB0aGlzLnByb3RlY3RlZEZpZWxkcyA9IENvbmZpZy5nZXQoUGFyc2UuYXBwbGljYXRpb25JZCkucHJvdGVjdGVkRmllbGRzO1xuXG4gICAgY29uc3QgY3VzdG9tSWRzID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKS5hbGxvd0N1c3RvbU9iamVjdElkO1xuXG4gICAgY29uc3QgY3VzdG9tSWRSZWdFeCA9IC9eLnsxLH0kL3U7IC8vIDErIGNoYXJzXG4gICAgY29uc3QgYXV0b0lkUmVnRXggPSAvXlthLXpBLVowLTldezEsfSQvO1xuXG4gICAgdGhpcy51c2VySWRSZWdFeCA9IGN1c3RvbUlkcyA/IGN1c3RvbUlkUmVnRXggOiBhdXRvSWRSZWdFeDtcbiAgfVxuXG4gIHJlbG9hZERhdGEob3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGlmICh0aGlzLnJlbG9hZERhdGFQcm9taXNlICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgIH1cbiAgICB0aGlzLnJlbG9hZERhdGFQcm9taXNlID0gdGhpcy5nZXRBbGxDbGFzc2VzKG9wdGlvbnMpXG4gICAgICAudGhlbihcbiAgICAgICAgYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoYWxsU2NoZW1hcywgdGhpcy5wcm90ZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHRoaXMuc2NoZW1hRGF0YSA9IG5ldyBTY2hlbWFEYXRhKCk7XG4gICAgICAgICAgZGVsZXRlIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB7fSk7XG4gICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gIH1cblxuICBnZXRBbGxDbGFzc2VzKG9wdGlvbnM6IExvYWRTY2hlbWFPcHRpb25zID0geyBjbGVhckNhY2hlOiBmYWxzZSB9KTogUHJvbWlzZTxBcnJheTxTY2hlbWE+PiB7XG4gICAgaWYgKG9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY2FjaGUuZ2V0QWxsQ2xhc3NlcygpLnRoZW4oYWxsQ2xhc3NlcyA9PiB7XG4gICAgICBpZiAoYWxsQ2xhc3NlcyAmJiBhbGxDbGFzc2VzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGFsbENsYXNzZXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0QWxsQ2xhc3NlcygpOiBQcm9taXNlPEFycmF5PFNjaGVtYT4+IHtcbiAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyXG4gICAgICAuZ2V0QWxsQ2xhc3NlcygpXG4gICAgICAudGhlbihhbGxTY2hlbWFzID0+IGFsbFNjaGVtYXMubWFwKGluamVjdERlZmF1bHRTY2hlbWEpKVxuICAgICAgLnRoZW4oYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgdGhpcy5fY2FjaGVcbiAgICAgICAgICAuc2V0QWxsQ2xhc3NlcyhhbGxTY2hlbWFzKVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiBjb25zb2xlLmVycm9yKCdFcnJvciBzYXZpbmcgc2NoZW1hIHRvIGNhY2hlOicsIGVycm9yKSk7XG4gICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuICAgICAgICByZXR1cm4gYWxsU2NoZW1hcztcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0T25lU2NoZW1hKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGFsbG93Vm9sYXRpbGVDbGFzc2VzOiBib29sZWFuID0gZmFsc2UsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWE+IHtcbiAgICBsZXQgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLl9jYWNoZS5jbGVhcigpO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChhbGxvd1ZvbGF0aWxlQ2xhc3NlcyAmJiB2b2xhdGlsZUNsYXNzZXMuaW5kZXhPZihjbGFzc05hbWUpID4gLTEpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGRzOiBkYXRhLmZpZWxkcyxcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgIGluZGV4ZXM6IGRhdGEuaW5kZXhlcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGUuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSkudGhlbihjYWNoZWQgPT4ge1xuICAgICAgICBpZiAoY2FjaGVkICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpLnRoZW4oYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgICAgY29uc3Qgb25lU2NoZW1hID0gYWxsU2NoZW1hcy5maW5kKHNjaGVtYSA9PiBzY2hlbWEuY2xhc3NOYW1lID09PSBjbGFzc05hbWUpO1xuICAgICAgICAgIGlmICghb25lU2NoZW1hKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodW5kZWZpbmVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG9uZVNjaGVtYTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIG5ldyBjbGFzcyB0aGF0IGluY2x1ZGVzIHRoZSB0aHJlZSBkZWZhdWx0IGZpZWxkcy5cbiAgLy8gQUNMIGlzIGFuIGltcGxpY2l0IGNvbHVtbiB0aGF0IGRvZXMgbm90IGdldCBhbiBlbnRyeSBpbiB0aGVcbiAgLy8gX1NDSEVNQVMgZGF0YWJhc2UuIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGVcbiAgLy8gY3JlYXRlZCBzY2hlbWEsIGluIG1vbmdvIGZvcm1hdC5cbiAgLy8gb24gc3VjY2VzcywgYW5kIHJlamVjdHMgd2l0aCBhbiBlcnJvciBvbiBmYWlsLiBFbnN1cmUgeW91XG4gIC8vIGhhdmUgYXV0aG9yaXphdGlvbiAobWFzdGVyIGtleSwgb3IgY2xpZW50IGNsYXNzIGNyZWF0aW9uXG4gIC8vIGVuYWJsZWQpIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gIGFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBTY2hlbWFGaWVsZHMgPSB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueSxcbiAgICBpbmRleGVzOiBhbnkgPSB7fVxuICApOiBQcm9taXNlPHZvaWQgfCBTY2hlbWE+IHtcbiAgICB2YXIgdmFsaWRhdGlvbkVycm9yID0gdGhpcy52YWxpZGF0ZU5ld0NsYXNzKGNsYXNzTmFtZSwgZmllbGRzLCBjbGFzc0xldmVsUGVybWlzc2lvbnMpO1xuICAgIGlmICh2YWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIH0gZWxzZSBpZiAodmFsaWRhdGlvbkVycm9yLmNvZGUgJiYgdmFsaWRhdGlvbkVycm9yLmVycm9yKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgUGFyc2UuRXJyb3IodmFsaWRhdGlvbkVycm9yLmNvZGUsIHZhbGlkYXRpb25FcnJvci5lcnJvcikpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHZhbGlkYXRpb25FcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmNyZWF0ZUNsYXNzKFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoe1xuICAgICAgICAgIGZpZWxkcyxcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgaW5kZXhlcyxcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAudGhlbihjb252ZXJ0QWRhcHRlclNjaGVtYVRvUGFyc2VTY2hlbWEpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGVDbGFzcyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzdWJtaXR0ZWRGaWVsZHM6IFNjaGVtYUZpZWxkcyxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueSxcbiAgICBpbmRleGVzOiBhbnksXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlclxuICApIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdGaWVsZHMgPSBzY2hlbWEuZmllbGRzO1xuICAgICAgICBPYmplY3Qua2V5cyhzdWJtaXR0ZWRGaWVsZHMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBzdWJtaXR0ZWRGaWVsZHNbbmFtZV07XG4gICAgICAgICAgaWYgKGV4aXN0aW5nRmllbGRzW25hbWVdICYmIGZpZWxkLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMjU1LCBgRmllbGQgJHtuYW1lfSBleGlzdHMsIGNhbm5vdCB1cGRhdGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZXhpc3RpbmdGaWVsZHNbbmFtZV0gJiYgZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nRmllbGRzLl9ycGVybTtcbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nRmllbGRzLl93cGVybTtcbiAgICAgICAgY29uc3QgbmV3U2NoZW1hID0gYnVpbGRNZXJnZWRTY2hlbWFPYmplY3QoZXhpc3RpbmdGaWVsZHMsIHN1Ym1pdHRlZEZpZWxkcyk7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRGaWVsZHMgPSBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdIHx8IGRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0O1xuICAgICAgICBjb25zdCBmdWxsTmV3U2NoZW1hID0gT2JqZWN0LmFzc2lnbih7fSwgbmV3U2NoZW1hLCBkZWZhdWx0RmllbGRzKTtcbiAgICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9yID0gdGhpcy52YWxpZGF0ZVNjaGVtYURhdGEoXG4gICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgIG5ld1NjaGVtYSxcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgT2JqZWN0LmtleXMoZXhpc3RpbmdGaWVsZHMpXG4gICAgICAgICk7XG4gICAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IodmFsaWRhdGlvbkVycm9yLmNvZGUsIHZhbGlkYXRpb25FcnJvci5lcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5hbGx5IHdlIGhhdmUgY2hlY2tlZCB0byBtYWtlIHN1cmUgdGhlIHJlcXVlc3QgaXMgdmFsaWQgYW5kIHdlIGNhbiBzdGFydCBkZWxldGluZyBmaWVsZHMuXG4gICAgICAgIC8vIERvIGFsbCBkZWxldGlvbnMgZmlyc3QsIHRoZW4gYSBzaW5nbGUgc2F2ZSB0byBfU0NIRU1BIGNvbGxlY3Rpb24gdG8gaGFuZGxlIGFsbCBhZGRpdGlvbnMuXG4gICAgICAgIGNvbnN0IGRlbGV0ZWRGaWVsZHM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGNvbnN0IGluc2VydGVkRmllbGRzID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgIGlmIChzdWJtaXR0ZWRGaWVsZHNbZmllbGROYW1lXS5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICAgICAgZGVsZXRlZEZpZWxkcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc2VydGVkRmllbGRzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGxldCBkZWxldGVQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIGlmIChkZWxldGVkRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBkZWxldGVQcm9taXNlID0gdGhpcy5kZWxldGVGaWVsZHMoZGVsZXRlZEZpZWxkcywgY2xhc3NOYW1lLCBkYXRhYmFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVuZm9yY2VGaWVsZHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBkZWxldGVQcm9taXNlIC8vIERlbGV0ZSBFdmVyeXRoaW5nXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pKSAvLyBSZWxvYWQgb3VyIFNjaGVtYSwgc28gd2UgaGF2ZSBhbGwgdGhlIG5ldyB2YWx1ZXNcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBpbnNlcnRlZEZpZWxkcy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0eXBlID0gc3VibWl0dGVkRmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5mb3JjZUZpZWxkRXhpc3RzKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgICAgIGVuZm9yY2VGaWVsZHMgPSByZXN1bHRzLmZpbHRlcihyZXN1bHQgPT4gISFyZXN1bHQpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRQZXJtaXNzaW9ucyhjbGFzc05hbWUsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbmV3U2NoZW1hKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PlxuICAgICAgICAgICAgICB0aGlzLl9kYkFkYXB0ZXIuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4ZXMsXG4gICAgICAgICAgICAgICAgc2NoZW1hLmluZGV4ZXMsXG4gICAgICAgICAgICAgICAgZnVsbE5ld1NjaGVtYVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pKVxuICAgICAgICAgICAgLy9UT0RPOiBNb3ZlIHRoaXMgbG9naWMgaW50byB0aGUgZGF0YWJhc2UgYWRhcHRlclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmVuc3VyZUZpZWxkcyhlbmZvcmNlRmllbGRzKTtcbiAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgICAgICAgICAgIGNvbnN0IHJlbG9hZGVkU2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgZmllbGRzOiBzY2hlbWEuZmllbGRzLFxuICAgICAgICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgaWYgKHNjaGVtYS5pbmRleGVzICYmIE9iamVjdC5rZXlzKHNjaGVtYS5pbmRleGVzKS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgICAgICByZWxvYWRlZFNjaGVtYS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlbG9hZGVkU2NoZW1hO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSxcbiAgICAgICAgICAgIGBDbGFzcyAke2NsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3QuYFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgdG8gdGhlIG5ldyBzY2hlbWFcbiAgLy8gb2JqZWN0IG9yIGZhaWxzIHdpdGggYSByZWFzb24uXG4gIGVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8U2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG4gICAgLy8gV2UgZG9uJ3QgaGF2ZSB0aGlzIGNsYXNzLiBVcGRhdGUgdGhlIHNjaGVtYVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmFkZENsYXNzSWZOb3RFeGlzdHMoY2xhc3NOYW1lKVxuICAgICAgICAvLyBUaGUgc2NoZW1hIHVwZGF0ZSBzdWNjZWVkZWQuIFJlbG9hZCB0aGUgc2NoZW1hXG4gICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHRcbiAgICAgICAgICAvLyBoYXZlIGZhaWxlZCBiZWNhdXNlIHRoZXJlJ3MgYSByYWNlIGNvbmRpdGlvbiBhbmQgYSBkaWZmZXJlbnRcbiAgICAgICAgICAvLyBjbGllbnQgaXMgbWFraW5nIHRoZSBleGFjdCBzYW1lIHNjaGVtYSB1cGRhdGUgdGhhdCB3ZSB3YW50LlxuICAgICAgICAgIC8vIFNvIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWEuXG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc2NoZW1hIG5vdyB2YWxpZGF0ZXNcbiAgICAgICAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgRmFpbGVkIHRvIGFkZCAke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBzdGlsbCBkb2Vzbid0IHZhbGlkYXRlLiBHaXZlIHVwXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ3NjaGVtYSBjbGFzcyBuYW1lIGRvZXMgbm90IHJldmFsaWRhdGUnKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVOZXdDbGFzcyhjbGFzc05hbWU6IHN0cmluZywgZmllbGRzOiBTY2hlbWFGaWVsZHMgPSB7fSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBhbnkpOiBhbnkge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gKTtcbiAgICB9XG4gICAgaWYgKCFjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSxcbiAgICAgICAgZXJyb3I6IGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZSksXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVNjaGVtYURhdGEoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgW10pO1xuICB9XG5cbiAgdmFsaWRhdGVTY2hlbWFEYXRhKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGZpZWxkczogU2NoZW1hRmllbGRzLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgIGV4aXN0aW5nRmllbGROYW1lczogQXJyYXk8c3RyaW5nPlxuICApIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBmaWVsZHMpIHtcbiAgICAgIGlmIChleGlzdGluZ0ZpZWxkTmFtZXMuaW5kZXhPZihmaWVsZE5hbWUpIDwgMCkge1xuICAgICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICAgZXJyb3I6ICdpbnZhbGlkIGZpZWxkIG5hbWU6ICcgKyBmaWVsZE5hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29kZTogMTM2LFxuICAgICAgICAgICAgZXJyb3I6ICdmaWVsZCAnICsgZmllbGROYW1lICsgJyBjYW5ub3QgYmUgYWRkZWQnLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmllbGRUeXBlID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAgIGNvbnN0IGVycm9yID0gZmllbGRUeXBlSXNJbnZhbGlkKGZpZWxkVHlwZSk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuIHsgY29kZTogZXJyb3IuY29kZSwgZXJyb3I6IGVycm9yLm1lc3NhZ2UgfTtcbiAgICAgICAgaWYgKGZpZWxkVHlwZS5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxldCBkZWZhdWx0VmFsdWVUeXBlID0gZ2V0VHlwZShmaWVsZFR5cGUuZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgICBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmYXVsdFZhbHVlVHlwZSA9PT0gJ29iamVjdCcgJiYgZmllbGRUeXBlLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICBlcnJvcjogYFRoZSAnZGVmYXVsdCB2YWx1ZScgb3B0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciAke3R5cGVUb1N0cmluZyhmaWVsZFR5cGUpfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKGZpZWxkVHlwZSwgZGVmYXVsdFZhbHVlVHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICBlcnJvcjogYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfSBkZWZhdWx0IHZhbHVlOyBleHBlY3RlZCAke3R5cGVUb1N0cmluZyhcbiAgICAgICAgICAgICAgICBmaWVsZFR5cGVcbiAgICAgICAgICAgICAgKX0gYnV0IGdvdCAke3R5cGVUb1N0cmluZyhkZWZhdWx0VmFsdWVUeXBlKX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGRUeXBlLnJlcXVpcmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFR5cGUgPT09ICdvYmplY3QnICYmIGZpZWxkVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBUaGUgJ3JlcXVpcmVkJyBvcHRpb24gaXMgbm90IGFwcGxpY2FibGUgZm9yICR7dHlwZVRvU3RyaW5nKGZpZWxkVHlwZSl9YCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXSkge1xuICAgICAgZmllbGRzW2ZpZWxkTmFtZV0gPSBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdW2ZpZWxkTmFtZV07XG4gICAgfVxuXG4gICAgY29uc3QgZ2VvUG9pbnRzID0gT2JqZWN0LmtleXMoZmllbGRzKS5maWx0ZXIoXG4gICAgICBrZXkgPT4gZmllbGRzW2tleV0gJiYgZmllbGRzW2tleV0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICk7XG4gICAgaWYgKGdlb1BvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgZXJyb3I6XG4gICAgICAgICAgJ2N1cnJlbnRseSwgb25seSBvbmUgR2VvUG9pbnQgZmllbGQgbWF5IGV4aXN0IGluIGFuIG9iamVjdC4gQWRkaW5nICcgK1xuICAgICAgICAgIGdlb1BvaW50c1sxXSArXG4gICAgICAgICAgJyB3aGVuICcgK1xuICAgICAgICAgIGdlb1BvaW50c1swXSArXG4gICAgICAgICAgJyBhbHJlYWR5IGV4aXN0cy4nLFxuICAgICAgfTtcbiAgICB9XG4gICAgdmFsaWRhdGVDTFAoY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBmaWVsZHMsIHRoaXMudXNlcklkUmVnRXgpO1xuICB9XG5cbiAgLy8gU2V0cyB0aGUgQ2xhc3MtbGV2ZWwgcGVybWlzc2lvbnMgZm9yIGEgZ2l2ZW4gY2xhc3NOYW1lLCB3aGljaCBtdXN0IGV4aXN0LlxuICBzZXRQZXJtaXNzaW9ucyhjbGFzc05hbWU6IHN0cmluZywgcGVybXM6IGFueSwgbmV3U2NoZW1hOiBTY2hlbWFGaWVsZHMpIHtcbiAgICBpZiAodHlwZW9mIHBlcm1zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICB2YWxpZGF0ZUNMUChwZXJtcywgbmV3U2NoZW1hLCB0aGlzLnVzZXJJZFJlZ0V4KTtcbiAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyLnNldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUsIHBlcm1zKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgc3VjY2Vzc2Z1bGx5IHRvIHRoZSBuZXcgc2NoZW1hXG4gIC8vIG9iamVjdCBpZiB0aGUgcHJvdmlkZWQgY2xhc3NOYW1lLWZpZWxkTmFtZS10eXBlIHR1cGxlIGlzIHZhbGlkLlxuICAvLyBUaGUgY2xhc3NOYW1lIG11c3QgYWxyZWFkeSBiZSB2YWxpZGF0ZWQuXG4gIC8vIElmICdmcmVlemUnIGlzIHRydWUsIHJlZnVzZSB0byB1cGRhdGUgdGhlIHNjaGVtYSBmb3IgdGhpcyBmaWVsZC5cbiAgZW5mb3JjZUZpZWxkRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nIHwgU2NoZW1hRmllbGQpIHtcbiAgICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA+IDApIHtcbiAgICAgIC8vIHN1YmRvY3VtZW50IGtleSAoeC55KSA9PiBvayBpZiB4IGlzIG9mIHR5cGUgJ29iamVjdCdcbiAgICAgIGZpZWxkTmFtZSA9IGZpZWxkTmFtZS5zcGxpdCgnLicpWzBdO1xuICAgICAgdHlwZSA9ICdPYmplY3QnO1xuICAgIH1cbiAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfS5gKTtcbiAgICB9XG5cbiAgICAvLyBJZiBzb21lb25lIHRyaWVzIHRvIGNyZWF0ZSBhIG5ldyBmaWVsZCB3aXRoIG51bGwvdW5kZWZpbmVkIGFzIHRoZSB2YWx1ZSwgcmV0dXJuO1xuICAgIGlmICghdHlwZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgdHlwZSA9ICh7IHR5cGUgfTogU2NoZW1hRmllbGQpO1xuICAgIH1cblxuICAgIGlmICh0eXBlLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBsZXQgZGVmYXVsdFZhbHVlVHlwZSA9IGdldFR5cGUodHlwZS5kZWZhdWx0VmFsdWUpO1xuICAgICAgaWYgKHR5cGVvZiBkZWZhdWx0VmFsdWVUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICB9XG4gICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKHR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICBgc2NoZW1hIG1pc21hdGNoIGZvciAke2NsYXNzTmFtZX0uJHtmaWVsZE5hbWV9IGRlZmF1bHQgdmFsdWU7IGV4cGVjdGVkICR7dHlwZVRvU3RyaW5nKFxuICAgICAgICAgICAgdHlwZVxuICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcoZGVmYXVsdFZhbHVlVHlwZSl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleHBlY3RlZFR5cGUpIHtcbiAgICAgIGlmICghZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUoZXhwZWN0ZWRUeXBlLCB0eXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICBleHBlY3RlZFR5cGVcbiAgICAgICAgICApfSBidXQgZ290ICR7dHlwZVRvU3RyaW5nKHR5cGUpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSkge1xuICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHdlIHRocm93IGVycm9ycyB3aGVuIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGRvIHNvLlxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHQgaGF2ZSBiZWVuIGEgcmFjZVxuICAgICAgICAvLyBjb25kaXRpb24gd2hlcmUgYW5vdGhlciBjbGllbnQgdXBkYXRlZCB0aGUgc2NoZW1hIGluIHRoZSBzYW1lXG4gICAgICAgIC8vIHdheSB0aGF0IHdlIHdhbnRlZCB0by4gU28sIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIGVuc3VyZUZpZWxkcyhmaWVsZHM6IGFueSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH0gPSBmaWVsZHNbaV07XG4gICAgICBsZXQgeyB0eXBlIH0gPSBmaWVsZHNbaV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHR5cGUgPSB7IHR5cGU6IHR5cGUgfTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWRUeXBlIHx8ICFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBDb3VsZCBub3QgYWRkIGZpZWxkICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG1haW50YWluIGNvbXBhdGliaWxpdHlcbiAgZGVsZXRlRmllbGQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nLCBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlRmllbGRzKFtmaWVsZE5hbWVdLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgfVxuXG4gIC8vIERlbGV0ZSBmaWVsZHMsIGFuZCByZW1vdmUgdGhhdCBkYXRhIGZyb20gYWxsIG9iamVjdHMuIFRoaXMgaXMgaW50ZW5kZWRcbiAgLy8gdG8gcmVtb3ZlIHVudXNlZCBmaWVsZHMsIGlmIG90aGVyIHdyaXRlcnMgYXJlIHdyaXRpbmcgb2JqZWN0cyB0aGF0IGluY2x1ZGVcbiAgLy8gdGhpcyBmaWVsZCwgdGhlIGZpZWxkIG1heSByZWFwcGVhci4gUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoXG4gIC8vIG5vIG9iamVjdCBvbiBzdWNjZXNzLCBvciByZWplY3RzIHdpdGggeyBjb2RlLCBlcnJvciB9IG9uIGZhaWx1cmUuXG4gIC8vIFBhc3NpbmcgdGhlIGRhdGFiYXNlIGFuZCBwcmVmaXggaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGRyb3AgcmVsYXRpb24gY29sbGVjdGlvbnNcbiAgLy8gYW5kIHJlbW92ZSBmaWVsZHMgZnJvbSBvYmplY3RzLiBJZGVhbGx5IHRoZSBkYXRhYmFzZSB3b3VsZCBiZWxvbmcgdG9cbiAgLy8gYSBkYXRhYmFzZSBhZGFwdGVyIGFuZCB0aGlzIGZ1bmN0aW9uIHdvdWxkIGNsb3NlIG92ZXIgaXQgb3IgYWNjZXNzIGl0IHZpYSBtZW1iZXIuXG4gIGRlbGV0ZUZpZWxkcyhmaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+LCBjbGFzc05hbWU6IHN0cmluZywgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIGlmICghY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWUpKTtcbiAgICB9XG5cbiAgICBmaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCBgaW52YWxpZCBmaWVsZCBuYW1lOiAke2ZpZWxkTmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIC8vRG9uJ3QgYWxsb3cgZGVsZXRpbmcgdGhlIGRlZmF1bHQgZmllbGRzLlxuICAgICAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MoZmllbGROYW1lLCBjbGFzc05hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxMzYsIGBmaWVsZCAke2ZpZWxkTmFtZX0gY2Fubm90IGJlIGNoYW5nZWRgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIGZhbHNlLCB7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICAgIGZpZWxkTmFtZXMuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgIGlmICghc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMjU1LCBgRmllbGQgJHtmaWVsZE5hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2NoZW1hRmllbGRzID0geyAuLi5zY2hlbWEuZmllbGRzIH07XG4gICAgICAgIHJldHVybiBkYXRhYmFzZS5hZGFwdGVyLmRlbGV0ZUZpZWxkcyhjbGFzc05hbWUsIHNjaGVtYSwgZmllbGROYW1lcykudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICAgICAgZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZmllbGQgPSBzY2hlbWFGaWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgICAgICAgICAvL0ZvciByZWxhdGlvbnMsIGRyb3AgdGhlIF9Kb2luIHRhYmxlXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlQ2xhc3MoYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX2NhY2hlLmNsZWFyKCkpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9iamVjdCBwcm92aWRlZCBpbiBSRVNUIGZvcm1hdC5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYSBpZiB0aGlzIG9iamVjdCBpc1xuICAvLyB2YWxpZC5cbiAgYXN5bmMgdmFsaWRhdGVPYmplY3QoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdDogYW55LCBxdWVyeTogYW55KSB7XG4gICAgbGV0IGdlb2NvdW50ID0gMDtcbiAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLmVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWUpO1xuICAgIGNvbnN0IHByb21pc2VzID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBnZXRUeXBlKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgIGlmIChleHBlY3RlZCA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBnZW9jb3VudCsrO1xuICAgICAgfVxuICAgICAgaWYgKGdlb2NvdW50ID4gMSkge1xuICAgICAgICAvLyBNYWtlIHN1cmUgYWxsIGZpZWxkIHZhbGlkYXRpb24gb3BlcmF0aW9ucyBydW4gYmVmb3JlIHdlIHJldHVybi5cbiAgICAgICAgLy8gSWYgbm90IC0gd2UgYXJlIGNvbnRpbnVpbmcgdG8gcnVuIGxvZ2ljLCBidXQgYWxyZWFkeSBwcm92aWRlZCByZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICd0aGVyZSBjYW4gb25seSBiZSBvbmUgZ2VvcG9pbnQgZmllbGQgaW4gYSBjbGFzcydcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIWV4cGVjdGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgLy8gRXZlcnkgb2JqZWN0IGhhcyBBQ0wgaW1wbGljaXRseS5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBwcm9taXNlcy5wdXNoKHNjaGVtYS5lbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIGV4cGVjdGVkKSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgY29uc3QgZW5mb3JjZUZpZWxkcyA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiAhIXJlc3VsdCk7XG5cbiAgICBpZiAoZW5mb3JjZUZpZWxkcy5sZW5ndGggIT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgfVxuICAgIHRoaXMuZW5zdXJlRmllbGRzKGVuZm9yY2VGaWVsZHMpO1xuXG4gICAgY29uc3QgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShzY2hlbWEpO1xuICAgIHJldHVybiB0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMocHJvbWlzZSwgY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGF0IGFsbCB0aGUgcHJvcGVydGllcyBhcmUgc2V0IGZvciB0aGUgb2JqZWN0XG4gIHZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zKGNsYXNzTmFtZTogc3RyaW5nLCBvYmplY3Q6IGFueSwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGNvbHVtbnMgPSByZXF1aXJlZENvbHVtbnNbY2xhc3NOYW1lXTtcbiAgICBpZiAoIWNvbHVtbnMgfHwgY29sdW1ucy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBtaXNzaW5nQ29sdW1ucyA9IGNvbHVtbnMuZmlsdGVyKGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgIGlmIChxdWVyeSAmJiBxdWVyeS5vYmplY3RJZCkge1xuICAgICAgICBpZiAob2JqZWN0W2NvbHVtbl0gJiYgdHlwZW9mIG9iamVjdFtjb2x1bW5dID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIC8vIFRyeWluZyB0byBkZWxldGUgYSByZXF1aXJlZCBjb2x1bW5cbiAgICAgICAgICByZXR1cm4gb2JqZWN0W2NvbHVtbl0uX19vcCA9PSAnRGVsZXRlJztcbiAgICAgICAgfVxuICAgICAgICAvLyBOb3QgdHJ5aW5nIHRvIGRvIGFueXRoaW5nIHRoZXJlXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAhb2JqZWN0W2NvbHVtbl07XG4gICAgfSk7XG5cbiAgICBpZiAobWlzc2luZ0NvbHVtbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBtaXNzaW5nQ29sdW1uc1swXSArICcgaXMgcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XG4gIH1cblxuICB0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUoY2xhc3NOYW1lOiBzdHJpbmcsIGFjbEdyb3VwOiBzdHJpbmdbXSwgb3BlcmF0aW9uOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gU2NoZW1hQ29udHJvbGxlci50ZXN0UGVybWlzc2lvbnMoXG4gICAgICB0aGlzLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpLFxuICAgICAgYWNsR3JvdXAsXG4gICAgICBvcGVyYXRpb25cbiAgICApO1xuICB9XG5cbiAgLy8gVGVzdHMgdGhhdCB0aGUgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbiBsZXQgcGFzcyB0aGUgb3BlcmF0aW9uIGZvciBhIGdpdmVuIGFjbEdyb3VwXG4gIHN0YXRpYyB0ZXN0UGVybWlzc2lvbnMoY2xhc3NQZXJtaXNzaW9uczogP2FueSwgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghY2xhc3NQZXJtaXNzaW9ucyB8fCAhY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl07XG4gICAgaWYgKHBlcm1zWycqJ10pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDaGVjayBwZXJtaXNzaW9ucyBhZ2FpbnN0IHRoZSBhY2xHcm91cCBwcm92aWRlZCAoYXJyYXkgb2YgdXNlcklkL3JvbGVzKVxuICAgIGlmIChcbiAgICAgIGFjbEdyb3VwLnNvbWUoYWNsID0+IHtcbiAgICAgICAgcmV0dXJuIHBlcm1zW2FjbF0gPT09IHRydWU7XG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyBhbiBvcGVyYXRpb24gcGFzc2VzIGNsYXNzLWxldmVsLXBlcm1pc3Npb25zIHNldCBpbiB0aGUgc2NoZW1hXG4gIHN0YXRpYyB2YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgY2xhc3NQZXJtaXNzaW9uczogP2FueSxcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBhY2xHcm91cDogc3RyaW5nW10sXG4gICAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gICAgYWN0aW9uPzogc3RyaW5nXG4gICkge1xuICAgIGlmIChTY2hlbWFDb250cm9sbGVyLnRlc3RQZXJtaXNzaW9ucyhjbGFzc1Blcm1pc3Npb25zLCBhY2xHcm91cCwgb3BlcmF0aW9uKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICghY2xhc3NQZXJtaXNzaW9ucyB8fCAhY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl07XG4gICAgLy8gSWYgb25seSBmb3IgYXV0aGVudGljYXRlZCB1c2Vyc1xuICAgIC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIGFjbEdyb3VwXG4gICAgaWYgKHBlcm1zWydyZXF1aXJlc0F1dGhlbnRpY2F0aW9uJ10pIHtcbiAgICAgIC8vIElmIGFjbEdyb3VwIGhhcyAqIChwdWJsaWMpXG4gICAgICBpZiAoIWFjbEdyb3VwIHx8IGFjbEdyb3VwLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdQZXJtaXNzaW9uIGRlbmllZCwgdXNlciBuZWVkcyB0byBiZSBhdXRoZW50aWNhdGVkLidcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoYWNsR3JvdXAuaW5kZXhPZignKicpID4gLTEgJiYgYWNsR3JvdXAubGVuZ3RoID09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1Blcm1pc3Npb24gZGVuaWVkLCB1c2VyIG5lZWRzIHRvIGJlIGF1dGhlbnRpY2F0ZWQuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gcmVxdWlyZXNBdXRoZW50aWNhdGlvbiBwYXNzZWQsIGp1c3QgbW92ZSBmb3J3YXJkXG4gICAgICAvLyBwcm9iYWJseSB3b3VsZCBiZSB3aXNlIGF0IHNvbWUgcG9pbnQgdG8gcmVuYW1lIHRvICdhdXRoZW50aWNhdGVkVXNlcidcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvLyBObyBtYXRjaGluZyBDTFAsIGxldCdzIGNoZWNrIHRoZSBQb2ludGVyIHBlcm1pc3Npb25zXG4gICAgLy8gQW5kIGhhbmRsZSB0aG9zZSBsYXRlclxuICAgIGNvbnN0IHBlcm1pc3Npb25GaWVsZCA9XG4gICAgICBbJ2dldCcsICdmaW5kJywgJ2NvdW50J10uaW5kZXhPZihvcGVyYXRpb24pID4gLTEgPyAncmVhZFVzZXJGaWVsZHMnIDogJ3dyaXRlVXNlckZpZWxkcyc7XG5cbiAgICAvLyBSZWplY3QgY3JlYXRlIHdoZW4gd3JpdGUgbG9ja2Rvd25cbiAgICBpZiAocGVybWlzc2lvbkZpZWxkID09ICd3cml0ZVVzZXJGaWVsZHMnICYmIG9wZXJhdGlvbiA9PSAnY3JlYXRlJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBgUGVybWlzc2lvbiBkZW5pZWQgZm9yIGFjdGlvbiAke29wZXJhdGlvbn0gb24gY2xhc3MgJHtjbGFzc05hbWV9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyB0aGUgcmVhZFVzZXJGaWVsZHMgbGF0ZXJcbiAgICBpZiAoXG4gICAgICBBcnJheS5pc0FycmF5KGNsYXNzUGVybWlzc2lvbnNbcGVybWlzc2lvbkZpZWxkXSkgJiZcbiAgICAgIGNsYXNzUGVybWlzc2lvbnNbcGVybWlzc2lvbkZpZWxkXS5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgcG9pbnRlckZpZWxkcyA9IGNsYXNzUGVybWlzc2lvbnNbb3BlcmF0aW9uXS5wb2ludGVyRmllbGRzO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHBvaW50ZXJGaWVsZHMpICYmIHBvaW50ZXJGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gYW55IG9wIGV4Y2VwdCAnYWRkRmllbGQgYXMgcGFydCBvZiBjcmVhdGUnIGlzIG9rLlxuICAgICAgaWYgKG9wZXJhdGlvbiAhPT0gJ2FkZEZpZWxkJyB8fCBhY3Rpb24gPT09ICd1cGRhdGUnKSB7XG4gICAgICAgIC8vIFdlIGNhbiBhbGxvdyBhZGRpbmcgZmllbGQgb24gdXBkYXRlIGZsb3cgb25seS5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICBgUGVybWlzc2lvbiBkZW5pZWQgZm9yIGFjdGlvbiAke29wZXJhdGlvbn0gb24gY2xhc3MgJHtjbGFzc05hbWV9LmBcbiAgICApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9wZXJhdGlvbiBwYXNzZXMgY2xhc3MtbGV2ZWwtcGVybWlzc2lvbnMgc2V0IGluIHRoZSBzY2hlbWFcbiAgdmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZTogc3RyaW5nLCBhY2xHcm91cDogc3RyaW5nW10sIG9wZXJhdGlvbjogc3RyaW5nLCBhY3Rpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gU2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgICB0aGlzLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgYWNsR3JvdXAsXG4gICAgICBvcGVyYXRpb24sXG4gICAgICBhY3Rpb25cbiAgICApO1xuICB9XG5cbiAgZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0gJiYgdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0uY2xhc3NMZXZlbFBlcm1pc3Npb25zO1xuICB9XG5cbiAgLy8gUmV0dXJucyB0aGUgZXhwZWN0ZWQgdHlwZSBmb3IgYSBjbGFzc05hbWUra2V5IGNvbWJpbmF0aW9uXG4gIC8vIG9yIHVuZGVmaW5lZCBpZiB0aGUgc2NoZW1hIGlzIG5vdCBzZXRcbiAgZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZyk6ID8oU2NoZW1hRmllbGQgfCBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgcmV0dXJuIGV4cGVjdGVkVHlwZSA9PT0gJ21hcCcgPyAnT2JqZWN0JyA6IGV4cGVjdGVkVHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIENoZWNrcyBpZiBhIGdpdmVuIGNsYXNzIGlzIGluIHRoZSBzY2hlbWEuXG4gIGhhc0NsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhKCkudGhlbigoKSA9PiAhIXRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBuZXcgU2NoZW1hLlxuY29uc3QgbG9hZCA9IChcbiAgZGJBZGFwdGVyOiBTdG9yYWdlQWRhcHRlcixcbiAgc2NoZW1hQ2FjaGU6IGFueSxcbiAgb3B0aW9uczogYW55XG4pOiBQcm9taXNlPFNjaGVtYUNvbnRyb2xsZXI+ID0+IHtcbiAgY29uc3Qgc2NoZW1hID0gbmV3IFNjaGVtYUNvbnRyb2xsZXIoZGJBZGFwdGVyLCBzY2hlbWFDYWNoZSk7XG4gIHJldHVybiBzY2hlbWEucmVsb2FkRGF0YShvcHRpb25zKS50aGVuKCgpID0+IHNjaGVtYSk7XG59O1xuXG4vLyBCdWlsZHMgYSBuZXcgc2NoZW1hIChpbiBzY2hlbWEgQVBJIHJlc3BvbnNlIGZvcm1hdCkgb3V0IG9mIGFuXG4vLyBleGlzdGluZyBtb25nbyBzY2hlbWEgKyBhIHNjaGVtYXMgQVBJIHB1dCByZXF1ZXN0LiBUaGlzIHJlc3BvbnNlXG4vLyBkb2VzIG5vdCBpbmNsdWRlIHRoZSBkZWZhdWx0IGZpZWxkcywgYXMgaXQgaXMgaW50ZW5kZWQgdG8gYmUgcGFzc2VkXG4vLyB0byBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWUuIE5vIHZhbGlkYXRpb24gaXMgZG9uZSBoZXJlLCBpdFxuLy8gaXMgZG9uZSBpbiBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWUuXG5mdW5jdGlvbiBidWlsZE1lcmdlZFNjaGVtYU9iamVjdChleGlzdGluZ0ZpZWxkczogU2NoZW1hRmllbGRzLCBwdXRSZXF1ZXN0OiBhbnkpOiBTY2hlbWFGaWVsZHMge1xuICBjb25zdCBuZXdTY2hlbWEgPSB7fTtcbiAgLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG4gIGNvbnN0IHN5c1NjaGVtYUZpZWxkID1cbiAgICBPYmplY3Qua2V5cyhkZWZhdWx0Q29sdW1ucykuaW5kZXhPZihleGlzdGluZ0ZpZWxkcy5faWQpID09PSAtMVxuICAgICAgPyBbXVxuICAgICAgOiBPYmplY3Qua2V5cyhkZWZhdWx0Q29sdW1uc1tleGlzdGluZ0ZpZWxkcy5faWRdKTtcbiAgZm9yIChjb25zdCBvbGRGaWVsZCBpbiBleGlzdGluZ0ZpZWxkcykge1xuICAgIGlmIChcbiAgICAgIG9sZEZpZWxkICE9PSAnX2lkJyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdBQ0wnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ3VwZGF0ZWRBdCcgJiZcbiAgICAgIG9sZEZpZWxkICE9PSAnY3JlYXRlZEF0JyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdvYmplY3RJZCdcbiAgICApIHtcbiAgICAgIGlmIChzeXNTY2hlbWFGaWVsZC5sZW5ndGggPiAwICYmIHN5c1NjaGVtYUZpZWxkLmluZGV4T2Yob2xkRmllbGQpICE9PSAtMSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpZWxkSXNEZWxldGVkID0gcHV0UmVxdWVzdFtvbGRGaWVsZF0gJiYgcHV0UmVxdWVzdFtvbGRGaWVsZF0uX19vcCA9PT0gJ0RlbGV0ZSc7XG4gICAgICBpZiAoIWZpZWxkSXNEZWxldGVkKSB7XG4gICAgICAgIG5ld1NjaGVtYVtvbGRGaWVsZF0gPSBleGlzdGluZ0ZpZWxkc1tvbGRGaWVsZF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgbmV3RmllbGQgaW4gcHV0UmVxdWVzdCkge1xuICAgIGlmIChuZXdGaWVsZCAhPT0gJ29iamVjdElkJyAmJiBwdXRSZXF1ZXN0W25ld0ZpZWxkXS5fX29wICE9PSAnRGVsZXRlJykge1xuICAgICAgaWYgKHN5c1NjaGVtYUZpZWxkLmxlbmd0aCA+IDAgJiYgc3lzU2NoZW1hRmllbGQuaW5kZXhPZihuZXdGaWVsZCkgIT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbmV3U2NoZW1hW25ld0ZpZWxkXSA9IHB1dFJlcXVlc3RbbmV3RmllbGRdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3U2NoZW1hO1xufVxuXG4vLyBHaXZlbiBhIHNjaGVtYSBwcm9taXNlLCBjb25zdHJ1Y3QgYW5vdGhlciBzY2hlbWEgcHJvbWlzZSB0aGF0XG4vLyB2YWxpZGF0ZXMgdGhpcyBmaWVsZCBvbmNlIHRoZSBzY2hlbWEgbG9hZHMuXG5mdW5jdGlvbiB0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoc2NoZW1hUHJvbWlzZSwgY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KSB7XG4gIHJldHVybiBzY2hlbWFQcm9taXNlLnRoZW4oc2NoZW1hID0+IHtcbiAgICByZXR1cm4gc2NoZW1hLnZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zKGNsYXNzTmFtZSwgb2JqZWN0LCBxdWVyeSk7XG4gIH0pO1xufVxuXG4vLyBHZXRzIHRoZSB0eXBlIGZyb20gYSBSRVNUIEFQSSBmb3JtYXR0ZWQgb2JqZWN0LCB3aGVyZSAndHlwZScgaXNcbi8vIGV4dGVuZGVkIHBhc3QgamF2YXNjcmlwdCB0eXBlcyB0byBpbmNsdWRlIHRoZSByZXN0IG9mIHRoZSBQYXJzZVxuLy8gdHlwZSBzeXN0ZW0uXG4vLyBUaGUgb3V0cHV0IHNob3VsZCBiZSBhIHZhbGlkIHNjaGVtYSB2YWx1ZS5cbi8vIFRPRE86IGVuc3VyZSB0aGF0IHRoaXMgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBmb3JtYXQgdXNlZCBpbiBPcGVuIERCXG5mdW5jdGlvbiBnZXRUeXBlKG9iajogYW55KTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICBjb25zdCB0eXBlID0gdHlwZW9mIG9iajtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICByZXR1cm4gJ0Jvb2xlYW4nO1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICByZXR1cm4gJ1N0cmluZyc7XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIHJldHVybiAnTnVtYmVyJztcbiAgICBjYXNlICdtYXAnOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoIW9iaikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGdldE9iamVjdFR5cGUob2JqKTtcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyAnYmFkIG9iajogJyArIG9iajtcbiAgfVxufVxuXG4vLyBUaGlzIGdldHMgdGhlIHR5cGUgZm9yIG5vbi1KU09OIHR5cGVzIGxpa2UgcG9pbnRlcnMgYW5kIGZpbGVzLCBidXRcbi8vIGFsc28gZ2V0cyB0aGUgYXBwcm9wcmlhdGUgdHlwZSBmb3IgJCBvcGVyYXRvcnMuXG4vLyBSZXR1cm5zIG51bGwgaWYgdGhlIHR5cGUgaXMgdW5rbm93bi5cbmZ1bmN0aW9uIGdldE9iamVjdFR5cGUob2JqKTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICByZXR1cm4gJ0FycmF5JztcbiAgfVxuICBpZiAob2JqLl9fdHlwZSkge1xuICAgIHN3aXRjaCAob2JqLl9fdHlwZSkge1xuICAgICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICAgIGlmIChvYmouY2xhc3NOYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICAgIHRhcmdldENsYXNzOiBvYmouY2xhc3NOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdSZWxhdGlvbic6XG4gICAgICAgIGlmIChvYmouY2xhc3NOYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICAgICAgICB0YXJnZXRDbGFzczogb2JqLmNsYXNzTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRmlsZSc6XG4gICAgICAgIGlmIChvYmoubmFtZSkge1xuICAgICAgICAgIHJldHVybiAnRmlsZSc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdEYXRlJzpcbiAgICAgICAgaWYgKG9iai5pc28pIHtcbiAgICAgICAgICByZXR1cm4gJ0RhdGUnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgICBpZiAob2JqLmxhdGl0dWRlICE9IG51bGwgJiYgb2JqLmxvbmdpdHVkZSAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuICdHZW9Qb2ludCc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdCeXRlcyc6XG4gICAgICAgIGlmIChvYmouYmFzZTY0KSB7XG4gICAgICAgICAgcmV0dXJuICdCeXRlcyc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgICAgaWYgKG9iai5jb29yZGluYXRlcykge1xuICAgICAgICAgIHJldHVybiAnUG9seWdvbic7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSwgJ1RoaXMgaXMgbm90IGEgdmFsaWQgJyArIG9iai5fX3R5cGUpO1xuICB9XG4gIGlmIChvYmpbJyRuZSddKSB7XG4gICAgcmV0dXJuIGdldE9iamVjdFR5cGUob2JqWyckbmUnXSk7XG4gIH1cbiAgaWYgKG9iai5fX29wKSB7XG4gICAgc3dpdGNoIChvYmouX19vcCkge1xuICAgICAgY2FzZSAnSW5jcmVtZW50JzpcbiAgICAgICAgcmV0dXJuICdOdW1iZXInO1xuICAgICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICBjYXNlICdBZGQnOlxuICAgICAgY2FzZSAnQWRkVW5pcXVlJzpcbiAgICAgIGNhc2UgJ1JlbW92ZSc6XG4gICAgICAgIHJldHVybiAnQXJyYXknO1xuICAgICAgY2FzZSAnQWRkUmVsYXRpb24nOlxuICAgICAgY2FzZSAnUmVtb3ZlUmVsYXRpb24nOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICAgICAgdGFyZ2V0Q2xhc3M6IG9iai5vYmplY3RzWzBdLmNsYXNzTmFtZSxcbiAgICAgICAgfTtcbiAgICAgIGNhc2UgJ0JhdGNoJzpcbiAgICAgICAgcmV0dXJuIGdldE9iamVjdFR5cGUob2JqLm9wc1swXSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyAndW5leHBlY3RlZCBvcDogJyArIG9iai5fX29wO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJ09iamVjdCc7XG59XG5cbmV4cG9ydCB7XG4gIGxvYWQsXG4gIGNsYXNzTmFtZUlzVmFsaWQsXG4gIGZpZWxkTmFtZUlzVmFsaWQsXG4gIGludmFsaWRDbGFzc05hbWVNZXNzYWdlLFxuICBidWlsZE1lcmdlZFNjaGVtYU9iamVjdCxcbiAgc3lzdGVtQ2xhc3NlcyxcbiAgZGVmYXVsdENvbHVtbnMsXG4gIGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEsXG4gIFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMsXG4gIFNjaGVtYUNvbnRyb2xsZXIsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/UserController.js b/lib/Controllers/UserController.js deleted file mode 100644 index 75b067b3f9..0000000000 --- a/lib/Controllers/UserController.js +++ /dev/null @@ -1,318 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.UserController = void 0; - -var _cryptoUtils = require("../cryptoUtils"); - -var _triggers = require("../triggers"); - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var RestQuery = require('../RestQuery'); - -var Auth = require('../Auth'); - -class UserController extends _AdaptableController.default { - constructor(adapter, appId, options = {}) { - super(adapter, appId, options); - } - - validateAdapter(adapter) { - // Allow no adapter - if (!adapter && !this.shouldVerifyEmails) { - return; - } - - super.validateAdapter(adapter); - } - - expectedAdapterType() { - return _MailAdapter.default; - } - - get shouldVerifyEmails() { - return this.options.verifyUserEmails; - } - - setEmailVerifyToken(user) { - if (this.shouldVerifyEmails) { - user._email_verify_token = (0, _cryptoUtils.randomString)(25); - user.emailVerified = false; - - if (this.config.emailVerifyTokenValidityDuration) { - user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt()); - } - } - } - - verifyEmail(username, token) { - if (!this.shouldVerifyEmails) { - // Trying to verify email when not enabled - // TODO: Better error here. - throw undefined; - } - - const query = { - username: username, - _email_verify_token: token - }; - const updateFields = { - emailVerified: true, - _email_verify_token: { - __op: 'Delete' - } - }; // if the email verify token needs to be validated then - // add additional query params and additional fields that need to be updated - - if (this.config.emailVerifyTokenValidityDuration) { - query.emailVerified = false; - query._email_verify_token_expires_at = { - $gt: _node.default._encode(new Date()) - }; - updateFields._email_verify_token_expires_at = { - __op: 'Delete' - }; - } - - const masterAuth = Auth.master(this.config); - var findUserForEmailVerification = new RestQuery(this.config, Auth.master(this.config), '_User', { - username: username - }); - return findUserForEmailVerification.execute().then(result => { - if (result.results.length && result.results[0].emailVerified) { - return Promise.resolve(result.results.length[0]); - } else if (result.results.length) { - query.objectId = result.results[0].objectId; - } - - return _rest.default.update(this.config, masterAuth, '_User', query, updateFields); - }); - } - - checkResetTokenValidity(username, token) { - return this.config.database.find('_User', { - username: username, - _perishable_token: token - }, { - limit: 1 - }).then(results => { - if (results.length != 1) { - throw 'Failed to reset password: username / email / token is invalid'; - } - - if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { - let expiresDate = results[0]._perishable_token_expires_at; - - if (expiresDate && expiresDate.__type == 'Date') { - expiresDate = new Date(expiresDate.iso); - } - - if (expiresDate < new Date()) throw 'The password reset link has expired'; - } - - return results[0]; - }); - } - - getUserIfNeeded(user) { - if (user.username && user.email) { - return Promise.resolve(user); - } - - var where = {}; - - if (user.username) { - where.username = user.username; - } - - if (user.email) { - where.email = user.email; - } - - var query = new RestQuery(this.config, Auth.master(this.config), '_User', where); - return query.execute().then(function (result) { - if (result.results.length != 1) { - throw undefined; - } - - return result.results[0]; - }); - } - - sendVerificationEmail(user) { - if (!this.shouldVerifyEmails) { - return; - } - - const token = encodeURIComponent(user._email_verify_token); // We may need to fetch the user in case of update email - - this.getUserIfNeeded(user).then(user => { - const username = encodeURIComponent(user.username); - const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config); - const options = { - appName: this.config.appName, - link: link, - user: (0, _triggers.inflate)('_User', user) - }; - - if (this.adapter.sendVerificationEmail) { - this.adapter.sendVerificationEmail(options); - } else { - this.adapter.sendMail(this.defaultVerificationEmail(options)); - } - }); - } - /** - * Regenerates the given user's email verification token - * - * @param user - * @returns {*} - */ - - - regenerateEmailVerifyToken(user) { - this.setEmailVerifyToken(user); - return this.config.database.update('_User', { - username: user.username - }, user); - } - - resendVerificationEmail(username) { - return this.getUserIfNeeded({ - username: username - }).then(aUser => { - if (!aUser || aUser.emailVerified) { - throw undefined; - } - - return this.regenerateEmailVerifyToken(aUser).then(() => { - this.sendVerificationEmail(aUser); - }); - }); - } - - setPasswordResetToken(email) { - const token = { - _perishable_token: (0, _cryptoUtils.randomString)(25) - }; - - if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { - token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt()); - } - - return this.config.database.update('_User', { - $or: [{ - email - }, { - username: email, - email: { - $exists: false - } - }] - }, token, {}, true); - } - - sendPasswordResetEmail(email) { - if (!this.adapter) { - throw 'Trying to send a reset password but no adapter is set'; // TODO: No adapter? - } - - return this.setPasswordResetToken(email).then(user => { - const token = encodeURIComponent(user._perishable_token); - const username = encodeURIComponent(user.username); - const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config); - const options = { - appName: this.config.appName, - link: link, - user: (0, _triggers.inflate)('_User', user) - }; - - if (this.adapter.sendPasswordResetEmail) { - this.adapter.sendPasswordResetEmail(options); - } else { - this.adapter.sendMail(this.defaultResetPasswordEmail(options)); - } - - return Promise.resolve(user); - }); - } - - updatePassword(username, token, password) { - return this.checkResetTokenValidity(username, token).then(user => updateUserPassword(user.objectId, password, this.config)).catch(error => { - if (error && error.message) { - // in case of Parse.Error, fail with the error message only - return Promise.reject(error.message); - } else { - return Promise.reject(error); - } - }); - } - - defaultVerificationEmail({ - link, - user, - appName - }) { - const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link; - const to = user.get('email'); - const subject = 'Please verify your e-mail for ' + appName; - return { - text, - to, - subject - }; - } - - defaultResetPasswordEmail({ - link, - user, - appName - }) { - const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link; - const to = user.get('email') || user.get('username'); - const subject = 'Password Reset for ' + appName; - return { - text, - to, - subject - }; - } - -} // Mark this private - - -exports.UserController = UserController; - -function updateUserPassword(userId, password, config) { - return _rest.default.update(config, Auth.master(config), '_User', { - objectId: userId - }, { - password: password - }); -} - -function buildEmailLink(destination, username, token, config) { - const usernameAndToken = `token=${token}&username=${username}`; - - if (config.parseFrameURL) { - const destinationWithoutHost = destination.replace(config.publicServerURL, ''); - return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`; - } else { - return `${destination}?${usernameAndToken}`; - } -} - -var _default = UserController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Vc2VyQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJSZXN0UXVlcnkiLCJyZXF1aXJlIiwiQXV0aCIsIlVzZXJDb250cm9sbGVyIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsInNob3VsZFZlcmlmeUVtYWlscyIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJNYWlsQWRhcHRlciIsInZlcmlmeVVzZXJFbWFpbHMiLCJzZXRFbWFpbFZlcmlmeVRva2VuIiwidXNlciIsIl9lbWFpbF92ZXJpZnlfdG9rZW4iLCJlbWFpbFZlcmlmaWVkIiwiY29uZmlnIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJQYXJzZSIsIl9lbmNvZGUiLCJnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQiLCJ2ZXJpZnlFbWFpbCIsInVzZXJuYW1lIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFzdGVyQXV0aCIsIm1hc3RlciIsImZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24iLCJleGVjdXRlIiwidGhlbiIsInJlc3VsdCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm9iamVjdElkIiwicmVzdCIsInVwZGF0ZSIsImNoZWNrUmVzZXRUb2tlblZhbGlkaXR5IiwiZGF0YWJhc2UiLCJmaW5kIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJsaW1pdCIsInBhc3N3b3JkUG9saWN5IiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJleHBpcmVzRGF0ZSIsIl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQiLCJfX3R5cGUiLCJpc28iLCJnZXRVc2VySWZOZWVkZWQiLCJlbWFpbCIsIndoZXJlIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwibGluayIsImJ1aWxkRW1haWxMaW5rIiwidmVyaWZ5RW1haWxVUkwiLCJhcHBOYW1lIiwic2VuZE1haWwiLCJkZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwiLCJyZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbiIsInJlc2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiYVVzZXIiLCJzZXRQYXNzd29yZFJlc2V0VG9rZW4iLCJnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCIsIiRvciIsIiRleGlzdHMiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwicmVxdWVzdFJlc2V0UGFzc3dvcmRVUkwiLCJkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsIiwidXBkYXRlUGFzc3dvcmQiLCJwYXNzd29yZCIsInVwZGF0ZVVzZXJQYXNzd29yZCIsImNhdGNoIiwiZXJyb3IiLCJtZXNzYWdlIiwicmVqZWN0IiwidGV4dCIsImdldCIsInRvIiwic3ViamVjdCIsInVzZXJJZCIsImRlc3RpbmF0aW9uIiwidXNlcm5hbWVBbmRUb2tlbiIsInBhcnNlRnJhbWVVUkwiLCJkZXN0aW5hdGlvbldpdGhvdXRIb3N0IiwicmVwbGFjZSIsInB1YmxpY1NlcnZlclVSTCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsSUFBSUEsU0FBUyxHQUFHQyxPQUFPLENBQUMsY0FBRCxDQUF2Qjs7QUFDQSxJQUFJQyxJQUFJLEdBQUdELE9BQU8sQ0FBQyxTQUFELENBQWxCOztBQUVPLE1BQU1FLGNBQU4sU0FBNkJDLDRCQUE3QixDQUFpRDtBQUN0REMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQU8sR0FBRyxFQUEzQixFQUErQjtBQUN4QyxVQUFNRixPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0Q7O0FB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LENBb1F4RDs7Ozs7QUFDQSxTQUFTUixrQkFBVCxDQUE0QlMsTUFBNUIsRUFBb0NWLFFBQXBDLEVBQThDN0QsTUFBOUMsRUFBc0Q7QUFDcEQsU0FBTzBCLGNBQUtDLE1BQUwsQ0FDTDNCLE1BREssRUFFTGhCLElBQUksQ0FBQ2dDLE1BQUwsQ0FBWWhCLE1BQVosQ0FGSyxFQUdMLE9BSEssRUFJTDtBQUFFeUIsSUFBQUEsUUFBUSxFQUFFOEM7QUFBWixHQUpLLEVBS0w7QUFDRVYsSUFBQUEsUUFBUSxFQUFFQTtBQURaLEdBTEssQ0FBUDtBQVNEOztBQUVELFNBQVNoQixjQUFULENBQXdCMkIsV0FBeEIsRUFBcUNqRSxRQUFyQyxFQUErQ0MsS0FBL0MsRUFBc0RSLE1BQXRELEVBQThEO0FBQzVELFFBQU15RSxnQkFBZ0IsR0FBSSxTQUFRakUsS0FBTSxhQUFZRCxRQUFTLEVBQTdEOztBQUVBLE1BQUlQLE1BQU0sQ0FBQzBFLGFBQVgsRUFBMEI7QUFDeEIsVUFBTUMsc0JBQXNCLEdBQUdILFdBQVcsQ0FBQ0ksT0FBWixDQUFvQjVFLE1BQU0sQ0FBQzZFLGVBQTNCLEVBQTRDLEVBQTVDLENBQS9CO0FBRUEsV0FBUSxHQUFFN0UsTUFBTSxDQUFDMEUsYUFBYyxTQUFRL0Isa0JBQWtCLENBQ3ZEZ0Msc0JBRHVELENBRXZELElBQUdGLGdCQUFpQixFQUZ0QjtBQUdELEdBTkQsTUFNTztBQUNMLFdBQVEsR0FBRUQsV0FBWSxJQUFHQyxnQkFBaUIsRUFBMUM7QUFDRDtBQUNGOztlQUVjeEYsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gJy4uL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGluZmxhdGUgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IE1haWxBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0VtYWlsL01haWxBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG52YXIgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi4vUmVzdFF1ZXJ5Jyk7XG52YXIgQXV0aCA9IHJlcXVpcmUoJy4uL0F1dGgnKTtcblxuZXhwb3J0IGNsYXNzIFVzZXJDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyk7XG4gIH1cblxuICB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcikge1xuICAgIC8vIEFsbG93IG5vIGFkYXB0ZXJcbiAgICBpZiAoIWFkYXB0ZXIgJiYgIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN1cGVyLnZhbGlkYXRlQWRhcHRlcihhZGFwdGVyKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIE1haWxBZGFwdGVyO1xuICB9XG5cbiAgZ2V0IHNob3VsZFZlcmlmeUVtYWlscygpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZlcmlmeVVzZXJFbWFpbHM7XG4gIH1cblxuICBzZXRFbWFpbFZlcmlmeVRva2VuKHVzZXIpIHtcbiAgICBpZiAodGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbiA9IHJhbmRvbVN0cmluZygyNSk7XG4gICAgICB1c2VyLmVtYWlsVmVyaWZpZWQgPSBmYWxzZTtcblxuICAgICAgaWYgKHRoaXMuY29uZmlnLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICAgIHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0gUGFyc2UuX2VuY29kZShcbiAgICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQoKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZlcmlmeUVtYWlsKHVzZXJuYW1lLCB0b2tlbikge1xuICAgIGlmICghdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIC8vIFRyeWluZyB0byB2ZXJpZnkgZW1haWwgd2hlbiBub3QgZW5hYmxlZFxuICAgICAgLy8gVE9ETzogQmV0dGVyIGVycm9yIGhlcmUuXG4gICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgcXVlcnkgPSB7IHVzZXJuYW1lOiB1c2VybmFtZSwgX2VtYWlsX3ZlcmlmeV90b2tlbjogdG9rZW4gfTtcbiAgICBjb25zdCB1cGRhdGVGaWVsZHMgPSB7XG4gICAgICBlbWFpbFZlcmlmaWVkOiB0cnVlLFxuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgIH07XG5cbiAgICAvLyBpZiB0aGUgZW1haWwgdmVyaWZ5IHRva2VuIG5lZWRzIHRvIGJlIHZhbGlkYXRlZCB0aGVuXG4gICAgLy8gYWRkIGFkZGl0aW9uYWwgcXVlcnkgcGFyYW1zIGFuZCBhZGRpdGlvbmFsIGZpZWxkcyB0aGF0IG5lZWQgdG8gYmUgdXBkYXRlZFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcXVlcnkuZW1haWxWZXJpZmllZCA9IGZhbHNlO1xuICAgICAgcXVlcnkuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0geyAkZ3Q6IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSkgfTtcblxuICAgICAgdXBkYXRlRmllbGRzLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHsgX19vcDogJ0RlbGV0ZScgfTtcbiAgICB9XG4gICAgY29uc3QgbWFzdGVyQXV0aCA9IEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKTtcbiAgICB2YXIgZmluZFVzZXJGb3JFbWFpbFZlcmlmaWNhdGlvbiA9IG5ldyBSZXN0UXVlcnkoXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSxcbiAgICAgICdfVXNlcicsXG4gICAgICB7IHVzZXJuYW1lOiB1c2VybmFtZSB9XG4gICAgKTtcbiAgICByZXR1cm4gZmluZFVzZXJGb3JFbWFpbFZlcmlmaWNhdGlvbi5leGVjdXRlKCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5yZXN1bHRzLmxlbmd0aCAmJiByZXN1bHQucmVzdWx0c1swXS5lbWFpbFZlcmlmaWVkKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0LnJlc3VsdHMubGVuZ3RoWzBdKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXJ5Lm9iamVjdElkID0gcmVzdWx0LnJlc3VsdHNbMF0ub2JqZWN0SWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdC51cGRhdGUodGhpcy5jb25maWcsIG1hc3RlckF1dGgsICdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICAgIH0pO1xuICB9XG5cbiAgY2hlY2tSZXNldFRva2VuVmFsaWRpdHkodXNlcm5hbWUsIHRva2VuKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJuYW1lOiB1c2VybmFtZSxcbiAgICAgICAgICBfcGVyaXNoYWJsZV90b2tlbjogdG9rZW4sXG4gICAgICAgIH0sXG4gICAgICAgIHsgbGltaXQ6IDEgfVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhyb3cgJ0ZhaWxlZCB0byByZXNldCBwYXNzd29yZDogdXNlcm5hbWUgLyBlbWFpbCAvIHRva2VuIGlzIGludmFsaWQnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICAgICAgbGV0IGV4cGlyZXNEYXRlID0gcmVzdWx0c1swXS5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0O1xuICAgICAgICAgIGlmIChleHBpcmVzRGF0ZSAmJiBleHBpcmVzRGF0ZS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgICBleHBpcmVzRGF0ZSA9IG5ldyBEYXRlKGV4cGlyZXNEYXRlLmlzbyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChleHBpcmVzRGF0ZSA8IG5ldyBEYXRlKCkpIHRocm93ICdUaGUgcGFzc3dvcmQgcmVzZXQgbGluayBoYXMgZXhwaXJlZCc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0c1swXTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklmTmVlZGVkKHVzZXIpIHtcbiAgICBpZiAodXNlci51c2VybmFtZSAmJiB1c2VyLmVtYWlsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICAgIH1cbiAgICB2YXIgd2hlcmUgPSB7fTtcbiAgICBpZiAodXNlci51c2VybmFtZSkge1xuICAgICAgd2hlcmUudXNlcm5hbWUgPSB1c2VyLnVzZXJuYW1lO1xuICAgIH1cbiAgICBpZiAodXNlci5lbWFpbCkge1xuICAgICAgd2hlcmUuZW1haWwgPSB1c2VyLmVtYWlsO1xuICAgIH1cblxuICAgIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSwgJ19Vc2VyJywgd2hlcmUpO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdC5yZXN1bHRzWzBdO1xuICAgIH0pO1xuICB9XG5cbiAgc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXIpIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRva2VuID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIuX2VtYWlsX3ZlcmlmeV90b2tlbik7XG4gICAgLy8gV2UgbWF5IG5lZWQgdG8gZmV0Y2ggdGhlIHVzZXIgaW4gY2FzZSBvZiB1cGRhdGUgZW1haWxcbiAgICB0aGlzLmdldFVzZXJJZk5lZWRlZCh1c2VyKS50aGVuKHVzZXIgPT4ge1xuICAgICAgY29uc3QgdXNlcm5hbWUgPSBlbmNvZGVVUklDb21wb25lbnQodXNlci51c2VybmFtZSk7XG5cbiAgICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy52ZXJpZnlFbWFpbFVSTCwgdXNlcm5hbWUsIHRva2VuLCB0aGlzLmNvbmZpZyk7XG4gICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICBhcHBOYW1lOiB0aGlzLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBsaW5rOiBsaW5rLFxuICAgICAgICB1c2VyOiBpbmZsYXRlKCdfVXNlcicsIHVzZXIpLFxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLmFkYXB0ZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwob3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFkYXB0ZXIuc2VuZE1haWwodGhpcy5kZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwob3B0aW9ucykpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2VuZXJhdGVzIHRoZSBnaXZlbiB1c2VyJ3MgZW1haWwgdmVyaWZpY2F0aW9uIHRva2VuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgcmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4odXNlcikge1xuICAgIHRoaXMuc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSwgdXNlcik7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkge1xuICAgIHJldHVybiB0aGlzLmdldFVzZXJJZk5lZWRlZCh7IHVzZXJuYW1lOiB1c2VybmFtZSB9KS50aGVuKGFVc2VyID0+IHtcbiAgICAgIGlmICghYVVzZXIgfHwgYVVzZXIuZW1haWxWZXJpZmllZCkge1xuICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbihhVXNlcikudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKGFVc2VyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0UGFzc3dvcmRSZXNldFRva2VuKGVtYWlsKSB7XG4gICAgY29uc3QgdG9rZW4gPSB7IF9wZXJpc2hhYmxlX3Rva2VuOiByYW5kb21TdHJpbmcoMjUpIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHRva2VuLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAnX1VzZXInLFxuICAgICAgeyAkb3I6IFt7IGVtYWlsIH0sIHsgdXNlcm5hbWU6IGVtYWlsLCBlbWFpbDogeyAkZXhpc3RzOiBmYWxzZSB9IH1dIH0sXG4gICAgICB0b2tlbixcbiAgICAgIHt9LFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBzZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdUcnlpbmcgdG8gc2VuZCBhIHJlc2V0IHBhc3N3b3JkIGJ1dCBubyBhZGFwdGVyIGlzIHNldCc7XG4gICAgICAvLyAgVE9ETzogTm8gYWRhcHRlcj9cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zZXRQYXNzd29yZFJlc2V0VG9rZW4oZW1haWwpLnRoZW4odXNlciA9PiB7XG4gICAgICBjb25zdCB0b2tlbiA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLl9wZXJpc2hhYmxlX3Rva2VuKTtcbiAgICAgIGNvbnN0IHVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIudXNlcm5hbWUpO1xuXG4gICAgICBjb25zdCBsaW5rID0gYnVpbGRFbWFpbExpbmsoXG4gICAgICAgIHRoaXMuY29uZmlnLnJlcXVlc3RSZXNldFBhc3N3b3JkVVJMLFxuICAgICAgICB1c2VybmFtZSxcbiAgICAgICAgdG9rZW4sXG4gICAgICAgIHRoaXMuY29uZmlnXG4gICAgICApO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgYXBwTmFtZTogdGhpcy5jb25maWcuYXBwTmFtZSxcbiAgICAgICAgbGluazogbGluayxcbiAgICAgICAgdXNlcjogaW5mbGF0ZSgnX1VzZXInLCB1c2VyKSxcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCkge1xuICAgICAgICB0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRSZXNldFBhc3N3b3JkRW1haWwob3B0aW9ucykpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlUGFzc3dvcmQodXNlcm5hbWUsIHRva2VuLCBwYXNzd29yZCkge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUmVzZXRUb2tlblZhbGlkaXR5KHVzZXJuYW1lLCB0b2tlbilcbiAgICAgIC50aGVuKHVzZXIgPT4gdXBkYXRlVXNlclBhc3N3b3JkKHVzZXIub2JqZWN0SWQsIHBhc3N3b3JkLCB0aGlzLmNvbmZpZykpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgIC8vIGluIGNhc2Ugb2YgUGFyc2UuRXJyb3IsIGZhaWwgd2l0aCB0aGUgZXJyb3IgbWVzc2FnZSBvbmx5XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgZGVmYXVsdFZlcmlmaWNhdGlvbkVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IGFyZSBiZWluZyBhc2tlZCB0byBjb25maXJtIHRoZSBlLW1haWwgYWRkcmVzcyAnICtcbiAgICAgIHVzZXIuZ2V0KCdlbWFpbCcpICtcbiAgICAgICcgd2l0aCAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgJ1xcblxcbicgK1xuICAgICAgJycgK1xuICAgICAgJ0NsaWNrIGhlcmUgdG8gY29uZmlybSBpdDpcXG4nICtcbiAgICAgIGxpbms7XG4gICAgY29uc3QgdG8gPSB1c2VyLmdldCgnZW1haWwnKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1BsZWFzZSB2ZXJpZnkgeW91ciBlLW1haWwgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cblxuICBkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IHJlcXVlc3RlZCB0byByZXNldCB5b3VyIHBhc3N3b3JkIGZvciAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgKHVzZXIuZ2V0KCd1c2VybmFtZScpID8gXCIgKHlvdXIgdXNlcm5hbWUgaXMgJ1wiICsgdXNlci5nZXQoJ3VzZXJuYW1lJykgKyBcIicpXCIgOiAnJykgK1xuICAgICAgJy5cXG5cXG4nICtcbiAgICAgICcnICtcbiAgICAgICdDbGljayBoZXJlIHRvIHJlc2V0IGl0OlxcbicgK1xuICAgICAgbGluaztcbiAgICBjb25zdCB0byA9IHVzZXIuZ2V0KCdlbWFpbCcpIHx8IHVzZXIuZ2V0KCd1c2VybmFtZScpO1xuICAgIGNvbnN0IHN1YmplY3QgPSAnUGFzc3dvcmQgUmVzZXQgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cbn1cblxuLy8gTWFyayB0aGlzIHByaXZhdGVcbmZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VySWQsIHBhc3N3b3JkLCBjb25maWcpIHtcbiAgcmV0dXJuIHJlc3QudXBkYXRlKFxuICAgIGNvbmZpZyxcbiAgICBBdXRoLm1hc3Rlcihjb25maWcpLFxuICAgICdfVXNlcicsXG4gICAgeyBvYmplY3RJZDogdXNlcklkIH0sXG4gICAge1xuICAgICAgcGFzc3dvcmQ6IHBhc3N3b3JkLFxuICAgIH1cbiAgKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRFbWFpbExpbmsoZGVzdGluYXRpb24sIHVzZXJuYW1lLCB0b2tlbiwgY29uZmlnKSB7XG4gIGNvbnN0IHVzZXJuYW1lQW5kVG9rZW4gPSBgdG9rZW49JHt0b2tlbn0mdXNlcm5hbWU9JHt1c2VybmFtZX1gO1xuXG4gIGlmIChjb25maWcucGFyc2VGcmFtZVVSTCkge1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uV2l0aG91dEhvc3QgPSBkZXN0aW5hdGlvbi5yZXBsYWNlKGNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwsICcnKTtcblxuICAgIHJldHVybiBgJHtjb25maWcucGFyc2VGcmFtZVVSTH0/bGluaz0ke2VuY29kZVVSSUNvbXBvbmVudChcbiAgICAgIGRlc3RpbmF0aW9uV2l0aG91dEhvc3RcbiAgICApfSYke3VzZXJuYW1lQW5kVG9rZW59YDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYCR7ZGVzdGluYXRpb259PyR7dXNlcm5hbWVBbmRUb2tlbn1gO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/index.js b/lib/Controllers/index.js deleted file mode 100644 index e3ace5883c..0000000000 --- a/lib/Controllers/index.js +++ /dev/null @@ -1,312 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getControllers = getControllers; -exports.getLoggerController = getLoggerController; -exports.getFilesController = getFilesController; -exports.getUserController = getUserController; -exports.getCacheController = getCacheController; -exports.getParseGraphQLController = getParseGraphQLController; -exports.getAnalyticsController = getAnalyticsController; -exports.getLiveQueryController = getLiveQueryController; -exports.getDatabaseController = getDatabaseController; -exports.getHooksController = getHooksController; -exports.getPushController = getPushController; -exports.getAuthDataManager = getAuthDataManager; -exports.getDatabaseAdapter = getDatabaseAdapter; - -var _Auth = _interopRequireDefault(require("../Adapters/Auth")); - -var _Options = require("../Options"); - -var _AdapterLoader = require("../Adapters/AdapterLoader"); - -var _defaults = _interopRequireDefault(require("../defaults")); - -var _url = _interopRequireDefault(require("url")); - -var _LoggerController = require("./LoggerController"); - -var _FilesController = require("./FilesController"); - -var _HooksController = require("./HooksController"); - -var _UserController = require("./UserController"); - -var _CacheController = require("./CacheController"); - -var _LiveQueryController = require("./LiveQueryController"); - -var _AnalyticsController = require("./AnalyticsController"); - -var _PushController = require("./PushController"); - -var _PushQueue = require("../Push/PushQueue"); - -var _PushWorker = require("../Push/PushWorker"); - -var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); - -var _SchemaCache = _interopRequireDefault(require("./SchemaCache")); - -var _GridFSBucketAdapter = require("../Adapters/Files/GridFSBucketAdapter"); - -var _WinstonLoggerAdapter = require("../Adapters/Logger/WinstonLoggerAdapter"); - -var _InMemoryCacheAdapter = require("../Adapters/Cache/InMemoryCacheAdapter"); - -var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); - -var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); - -var _PostgresStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Postgres/PostgresStorageAdapter")); - -var _pushAdapter = _interopRequireDefault(require("@parse/push-adapter")); - -var _ParseGraphQLController = _interopRequireDefault(require("./ParseGraphQLController")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function getControllers(options) { - const loggerController = getLoggerController(options); - const filesController = getFilesController(options); - const userController = getUserController(options); - const { - pushController, - hasPushScheduledSupport, - hasPushSupport, - pushControllerQueue, - pushWorker - } = getPushController(options); - const cacheController = getCacheController(options); - const analyticsController = getAnalyticsController(options); - const liveQueryController = getLiveQueryController(options); - const databaseController = getDatabaseController(options, cacheController); - const hooksController = getHooksController(options, databaseController); - const authDataManager = getAuthDataManager(options); - const parseGraphQLController = getParseGraphQLController(options, { - databaseController, - cacheController - }); - return { - loggerController, - filesController, - userController, - pushController, - hasPushScheduledSupport, - hasPushSupport, - pushWorker, - pushControllerQueue, - analyticsController, - cacheController, - parseGraphQLController, - liveQueryController, - databaseController, - hooksController, - authDataManager - }; -} - -function getLoggerController(options) { - const { - appId, - jsonLogs, - logsFolder, - verbose, - logLevel, - maxLogFiles, - silent, - loggerAdapter - } = options; - const loggerOptions = { - jsonLogs, - logsFolder, - verbose, - logLevel, - silent, - maxLogFiles - }; - const loggerControllerAdapter = (0, _AdapterLoader.loadAdapter)(loggerAdapter, _WinstonLoggerAdapter.WinstonLoggerAdapter, loggerOptions); - return new _LoggerController.LoggerController(loggerControllerAdapter, appId, loggerOptions); -} - -function getFilesController(options) { - const { - appId, - databaseURI, - filesAdapter, - databaseAdapter, - preserveFileName, - fileKey - } = options; - - if (!filesAdapter && databaseAdapter) { - throw 'When using an explicit database adapter, you must also use an explicit filesAdapter.'; - } - - const filesControllerAdapter = (0, _AdapterLoader.loadAdapter)(filesAdapter, () => { - return new _GridFSBucketAdapter.GridFSBucketAdapter(databaseURI, {}, fileKey); - }); - return new _FilesController.FilesController(filesControllerAdapter, appId, { - preserveFileName - }); -} - -function getUserController(options) { - const { - appId, - emailAdapter, - verifyUserEmails - } = options; - const emailControllerAdapter = (0, _AdapterLoader.loadAdapter)(emailAdapter); - return new _UserController.UserController(emailControllerAdapter, appId, { - verifyUserEmails - }); -} - -function getCacheController(options) { - const { - appId, - cacheAdapter, - cacheTTL, - cacheMaxSize - } = options; - const cacheControllerAdapter = (0, _AdapterLoader.loadAdapter)(cacheAdapter, _InMemoryCacheAdapter.InMemoryCacheAdapter, { - appId: appId, - ttl: cacheTTL, - maxSize: cacheMaxSize - }); - return new _CacheController.CacheController(cacheControllerAdapter, appId); -} - -function getParseGraphQLController(options, controllerDeps) { - return new _ParseGraphQLController.default(_objectSpread({ - mountGraphQL: options.mountGraphQL - }, controllerDeps)); -} - -function getAnalyticsController(options) { - const { - analyticsAdapter - } = options; - const analyticsControllerAdapter = (0, _AdapterLoader.loadAdapter)(analyticsAdapter, _AnalyticsAdapter.AnalyticsAdapter); - return new _AnalyticsController.AnalyticsController(analyticsControllerAdapter); -} - -function getLiveQueryController(options) { - return new _LiveQueryController.LiveQueryController(options.liveQuery); -} - -function getDatabaseController(options, cacheController) { - const { - databaseURI, - databaseOptions, - collectionPrefix, - schemaCacheTTL, - enableSingleSchemaCache - } = options; - let { - databaseAdapter - } = options; - - if ((databaseOptions || databaseURI && databaseURI !== _defaults.default.databaseURI || collectionPrefix !== _defaults.default.collectionPrefix) && databaseAdapter) { - throw 'You cannot specify both a databaseAdapter and a databaseURI/databaseOptions/collectionPrefix.'; - } else if (!databaseAdapter) { - databaseAdapter = getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions); - } else { - databaseAdapter = (0, _AdapterLoader.loadAdapter)(databaseAdapter); - } - - return new _DatabaseController.default(databaseAdapter, new _SchemaCache.default(cacheController, schemaCacheTTL, enableSingleSchemaCache)); -} - -function getHooksController(options, databaseController) { - const { - appId, - webhookKey - } = options; - return new _HooksController.HooksController(appId, databaseController, webhookKey); -} - -function getPushController(options) { - const { - scheduledPush, - push - } = options; - const pushOptions = Object.assign({}, push); - const pushQueueOptions = pushOptions.queueOptions || {}; - - if (pushOptions.queueOptions) { - delete pushOptions.queueOptions; - } // Pass the push options too as it works with the default - - - const pushAdapter = (0, _AdapterLoader.loadAdapter)(pushOptions && pushOptions.adapter, _pushAdapter.default, pushOptions); // We pass the options and the base class for the adatper, - // Note that passing an instance would work too - - const pushController = new _PushController.PushController(); - const hasPushSupport = !!(pushAdapter && push); - const hasPushScheduledSupport = hasPushSupport && scheduledPush === true; - const { - disablePushWorker - } = pushQueueOptions; - const pushControllerQueue = new _PushQueue.PushQueue(pushQueueOptions); - let pushWorker; - - if (!disablePushWorker) { - pushWorker = new _PushWorker.PushWorker(pushAdapter, pushQueueOptions); - } - - return { - pushController, - hasPushSupport, - hasPushScheduledSupport, - pushControllerQueue, - pushWorker - }; -} - -function getAuthDataManager(options) { - const { - auth, - enableAnonymousUsers - } = options; - return (0, _Auth.default)(auth, enableAnonymousUsers); -} - -function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions) { - let protocol; - - try { - const parsedURI = _url.default.parse(databaseURI); - - protocol = parsedURI.protocol ? parsedURI.protocol.toLowerCase() : null; - } catch (e) { - /* */ - } - - switch (protocol) { - case 'postgres:': - return new _PostgresStorageAdapter.default({ - uri: databaseURI, - collectionPrefix, - databaseOptions - }); - - default: - return new _MongoStorageAdapter.default({ - uri: databaseURI, - collectionPrefix, - mongoOptions: databaseOptions - }); - } -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9pbmRleC5qcyJdLCJuYW1lcyI6WyJnZXRDb250cm9sbGVycyIsIm9wdGlvbnMiLCJsb2dnZXJDb250cm9sbGVyIiwiZ2V0TG9nZ2VyQ29udHJvbGxlciIsImZpbGVzQ29udHJvbGxlciIsImdldEZpbGVzQ29udHJvbGxlciIsInVzZXJDb250cm9sbGVyIiwiZ2V0VXNlckNvbnRyb2xsZXIiLCJwdXNoQ29udHJvbGxlciIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwiaGFzUHVzaFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwicHVzaFdvcmtlciIsImdldFB1c2hDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiZ2V0Q2FjaGVDb250cm9sbGVyIiwiYW5hbHl0aWNzQ29udHJvbGxlciIsImdldEFuYWx5dGljc0NvbnRyb2xsZXIiLCJsaXZlUXVlcnlDb250cm9sbGVyIiwiZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImdldERhdGFiYXNlQ29udHJvbGxlciIsImhvb2tzQ29udHJvbGxlciIsImdldEhvb2tzQ29udHJvbGxlciIsImF1dGhEYXRhTWFuYWdlciIsImdldEF1dGhEYXRhTWFuYWdlciIsInBhcnNlR3JhcGhRTENvbnRyb2xsZXIiLCJnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwiYXBwSWQiLCJqc29uTG9ncyIsImxvZ3NGb2xkZXIiLCJ2ZXJib3NlIiwibG9nTGV2ZWwiLCJtYXhMb2dGaWxlcyIsInNpbGVudCIsImxvZ2dlckFkYXB0ZXIiLCJsb2dnZXJPcHRpb25zIiwibG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIiLCJXaW5zdG9uTG9nZ2VyQWRhcHRlciIsIkxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZVVSSSIsImZpbGVzQWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInByZXNlcnZlRmlsZU5hbWUiLCJmaWxlS2V5IiwiZmlsZXNDb250cm9sbGVyQWRhcHRlciIsIkdyaWRGU0J1Y2tldEFkYXB0ZXIiLCJGaWxlc0NvbnRyb2xsZXIiLCJlbWFpbEFkYXB0ZXIiLCJ2ZXJpZnlVc2VyRW1haWxzIiwiZW1haWxDb250cm9sbGVyQWRhcHRlciIsIlVzZXJDb250cm9sbGVyIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVUVEwiLCJjYWNoZU1heFNpemUiLCJjYWNoZUNvbnRyb2xsZXJBZGFwdGVyIiwiSW5NZW1vcnlDYWNoZUFkYXB0ZXIiLCJ0dGwiLCJtYXhTaXplIiwiQ2FjaGVDb250cm9sbGVyIiwiY29udHJvbGxlckRlcHMiLCJQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibW91bnRHcmFwaFFMIiwiYW5hbHl0aWNzQWRhcHRlciIsImFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyIiwiQW5hbHl0aWNzQWRhcHRlciIsIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJMaXZlUXVlcnlDb250cm9sbGVyIiwibGl2ZVF1ZXJ5IiwiZGF0YWJhc2VPcHRpb25zIiwiY29sbGVjdGlvblByZWZpeCIsInNjaGVtYUNhY2hlVFRMIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkZWZhdWx0cyIsImdldERhdGFiYXNlQWRhcHRlciIsIkRhdGFiYXNlQ29udHJvbGxlciIsIlNjaGVtYUNhY2hlIiwid2ViaG9va0tleSIsIkhvb2tzQ29udHJvbGxlciIsInNjaGVkdWxlZFB1c2giLCJwdXNoIiwicHVzaE9wdGlvbnMiLCJPYmplY3QiLCJhc3NpZ24iLCJwdXNoUXVldWVPcHRpb25zIiwicXVldWVPcHRpb25zIiwicHVzaEFkYXB0ZXIiLCJhZGFwdGVyIiwiUGFyc2VQdXNoQWRhcHRlciIsIlB1c2hDb250cm9sbGVyIiwiZGlzYWJsZVB1c2hXb3JrZXIiLCJQdXNoUXVldWUiLCJQdXNoV29ya2VyIiwiYXV0aCIsImVuYWJsZUFub255bW91c1VzZXJzIiwicHJvdG9jb2wiLCJwYXJzZWRVUkkiLCJ1cmwiLCJwYXJzZSIsInRvTG93ZXJDYXNlIiwiZSIsIlBvc3RncmVzU3RvcmFnZUFkYXB0ZXIiLCJ1cmkiLCJNb25nb1N0b3JhZ2VBZGFwdGVyIiwibW9uZ29PcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7QUFFTyxTQUFTQSxjQUFULENBQXdCQyxPQUF4QixFQUFxRDtBQUMxRCxRQUFNQyxnQkFBZ0IsR0FBR0MsbUJBQW1CLENBQUNGLE9BQUQsQ0FBNUM7QUFDQSxRQUFNRyxlQUFlLEdBQUdDLGtCQUFrQixDQUFDSixPQUFELENBQTFDO0FBQ0EsUUFBTUssY0FBYyxHQUFHQyxpQkFBaUIsQ0FBQ04sT0FBRCxDQUF4QztBQUNBLFFBQU07QUFDSk8sSUFBQUEsY0FESTtBQUVKQyxJQUFBQSx1QkFGSTtBQUdKQyxJQUFBQSxjQUhJO0FBSUpDLElBQUFBLG1CQUpJO0FBS0pDLElBQUFBO0FBTEksTUFNRkMsaUJBQWlCLENBQUNaLE9BQUQsQ0FOckI7QUFPQSxRQUFNYSxlQUFlLEdBQUdDLGtCQUFrQixDQUFDZCxPQUFELENBQTFDO0FBQ0EsUUFBTWUsbUJBQW1CLEdBQUdDLHNCQUFzQixDQUFDaEIsT0FBRCxDQUFsRDtBQUNBLFFBQU1pQixtQkFBbUIsR0FBR0Msc0JBQXNCLENBQUNsQixPQUFELENBQWxEO0FBQ0EsUUFBTW1CLGtCQUFrQixHQUFHQyxxQkFBcUIsQ0FBQ3BCLE9BQUQsRUFBVWEsZUFBVixDQUFoRDtBQUNBLFFBQU1RLGVBQWUsR0FBR0Msa0JBQWtCLENBQUN0QixPQUFELEVBQVVtQixrQkFBVixDQUExQztBQUNBLFFBQU1JLGVBQWUsR0FBR0Msa0JBQWtCLENBQUN4QixPQUFELENBQTFDO0FBQ0EsUUFBTXlCLHNCQUFzQixHQUFHQyx5QkFBeUIsQ0FBQzFCLE9BQUQsRUFBVTtBQUNoRW1CLElBQUFBLGtCQURnRTtBQUVoRU4sSUFBQUE7QUFGZ0UsR0FBVixDQUF4RDtBQUlBLFNBQU87QUFDTFosSUFBQUEsZ0JBREs7QUFFTEUsSUFBQUEsZUFGSztBQUdMRSxJQUFBQSxjQUhLO0FBSUxFLElBQUFBLGNBSks7QUFLTEMsSUFBQUEsdUJBTEs7QUFNTEMsSUFBQUEsY0FOSztBQU9MRSxJQUFBQSxVQVBLO0FBUUxELElBQUFBLG1CQVJLO0FBU0xLLElBQUFBLG1CQVRLO0FBVUxGLElBQUFBLGVBVks7QUFXTFksSUFBQUEsc0JBWEs7QUFZTFIsSUFBQUEsbUJBWks7QUFhTEUsSUFBQUEsa0JBYks7QUFjTEUsSUFBQUEsZUFkSztBQWVMRSxJQUFBQTtBQWZLLEdBQVA7QUFpQkQ7O0FBRU0sU0FBU3JCLG1CQUFULENBQTZCRixPQUE3QixFQUE0RTtBQUNqRixRQUFNO0FBQ0oyQixJQUFBQSxLQURJO0FBRUpDLElBQUFBLFFBRkk7QUFHSkMsSUFBQUEsVUFISTtBQUlKQyxJQUFBQSxPQUpJO0FBS0pDLElBQUFBLFFBTEk7QUFNSkMsSUFBQUEsV0FOSTtBQU9KQyxJQUFBQSxNQVBJO0FBUUpDLElBQUFBO0FBUkksTUFTRmxDLE9BVEo7QUFVQSxRQUFNbUMsYUFBYSxHQUFHO0FBQ3BCUCxJQUFBQSxRQURvQjtBQUVwQkMsSUFBQUEsVUFGb0I7QUFHcEJDLElBQUFBLE9BSG9CO0FBSXBCQyxJQUFBQSxRQUpvQjtBQUtwQkUsSUFBQUEsTUFMb0I7QUFNcEJELElBQUFBO0FBTm9CLEdBQXRCO0FBUUEsUUFBTUksdUJBQXVCLEdBQUcsZ0NBQVlGLGFBQVosRUFBMkJHLDBDQUEzQixFQUFpREYsYUFBakQsQ0FBaEM7QUFDQSxTQUFPLElBQUlHLGtDQUFKLENBQXFCRix1QkFBckIsRUFBOENULEtBQTlDLEVBQXFEUSxhQUFyRCxDQUFQO0FBQ0Q7O0FBRU0sU0FBUy9CLGtCQUFULENBQTRCSixPQUE1QixFQUEwRTtBQUMvRSxRQUFNO0FBQUUyQixJQUFBQSxLQUFGO0FBQVNZLElBQUFBLFdBQVQ7QUFBc0JDLElBQUFBLFlBQXRCO0FBQW9DQyxJQUFBQSxlQUFwQztBQUFxREMsSUFBQUEsZ0JBQXJEO0FBQXVFQyxJQUFBQTtBQUF2RSxNQUFtRjNDLE9BQXpGOztBQUNBLE1BQUksQ0FBQ3dDLFlBQUQsSUFBaUJDLGVBQXJCLEVBQXNDO0FBQ3BDLFVBQU0sc0ZBQU47QUFDRDs7QUFDRCxRQUFNRyxzQkFBc0IsR0FBRyxnQ0FBWUosWUFBWixFQUEwQixNQUFNO0FBQzdELFdBQU8sSUFBSUssd0NBQUosQ0FBd0JOLFdBQXhCLEVBQXFDLEVBQXJDLEVBQXlDSSxPQUF6QyxDQUFQO0FBQ0QsR0FGOEIsQ0FBL0I7QUFHQSxTQUFPLElBQUlHLGdDQUFKLENBQW9CRixzQkFBcEIsRUFBNENqQixLQUE1QyxFQUFtRDtBQUN4RGUsSUFBQUE7QUFEd0QsR0FBbkQsQ0FBUDtBQUdEOztBQUVNLFNBQVNwQyxpQkFBVCxDQUEyQk4sT0FBM0IsRUFBd0U7QUFDN0UsUUFBTTtBQUFFMkIsSUFBQUEsS0FBRjtBQUFTb0IsSUFBQUEsWUFBVDtBQUF1QkMsSUFBQUE7QUFBdkIsTUFBNENoRCxPQUFsRDtBQUNBLFFBQU1pRCxzQkFBc0IsR0FBRyxnQ0FBWUYsWUFBWixDQUEvQjtBQUNBLFNBQU8sSUFBSUcsOEJBQUosQ0FBbUJELHNCQUFuQixFQUEyQ3RCLEtBQTNDLEVBQWtEO0FBQ3ZEcUIsSUFBQUE7QUFEdUQsR0FBbEQsQ0FBUDtBQUdEOztBQUVNLFNBQVNsQyxrQkFBVCxDQUE0QmQsT0FBNUIsRUFBMEU7QUFDL0UsUUFBTTtBQUFFMkIsSUFBQUEsS0FBRjtBQUFTd0IsSUFBQUEsWUFBVDtBQUF1QkMsSUFBQUEsUUFBdkI7QUFBaUNDLElBQUFBO0FBQWpDLE1BQWtEckQsT0FBeEQ7QUFDQSxRQUFNc0Qsc0JBQXNCLEdBQUcsZ0NBQVlILFlBQVosRUFBMEJJLDBDQUExQixFQUFnRDtBQUM3RTVCLElBQUFBLEtBQUssRUFBRUEsS0FEc0U7QUFFN0U2QixJQUFBQSxHQUFHLEVBQUVKLFFBRndFO0FBRzdFSyxJQUFBQSxPQUFPLEVBQUVKO0FBSG9FLEdBQWhELENBQS9CO0FBS0EsU0FBTyxJQUFJSyxnQ0FBSixDQUFvQkosc0JBQXBCLEVBQTRDM0IsS0FBNUMsQ0FBUDtBQUNEOztBQUVNLFNBQVNELHlCQUFULENBQ0wxQixPQURLLEVBRUwyRCxjQUZLLEVBR21CO0FBQ3hCLFNBQU8sSUFBSUMsK0JBQUo7QUFDTEMsSUFBQUEsWUFBWSxFQUFFN0QsT0FBTyxDQUFDNkQ7QUFEakIsS0FFRkYsY0FGRSxFQUFQO0FBSUQ7O0FBRU0sU0FBUzNDLHNCQUFULENBQWdDaEIsT0FBaEMsRUFBa0Y7QUFDdkYsUUFBTTtBQUFFOEQsSUFBQUE7QUFBRixNQUF1QjlELE9BQTdCO0FBQ0EsUUFBTStELDBCQUEwQixHQUFHLGdDQUFZRCxnQkFBWixFQUE4QkUsa0NBQTlCLENBQW5DO0FBQ0EsU0FBTyxJQUFJQyx3Q0FBSixDQUF3QkYsMEJBQXhCLENBQVA7QUFDRDs7QUFFTSxTQUFTN0Msc0JBQVQsQ0FBZ0NsQixPQUFoQyxFQUFrRjtBQUN2RixTQUFPLElBQUlrRSx3Q0FBSixDQUF3QmxFLE9BQU8sQ0FBQ21FLFNBQWhDLENBQVA7QUFDRDs7QUFFTSxTQUFTL0MscUJBQVQsQ0FDTHBCLE9BREssRUFFTGEsZUFGSyxFQUdlO0FBQ3BCLFFBQU07QUFDSjBCLElBQUFBLFdBREk7QUFFSjZCLElBQUFBLGVBRkk7QUFHSkMsSUFBQUEsZ0JBSEk7QUFJSkMsSUFBQUEsY0FKSTtBQUtKQyxJQUFBQTtBQUxJLE1BTUZ2RSxPQU5KO0FBT0EsTUFBSTtBQUFFeUMsSUFBQUE7QUFBRixNQUFzQnpDLE9BQTFCOztBQUNBLE1BQ0UsQ0FBQ29FLGVBQWUsSUFDYjdCLFdBQVcsSUFBSUEsV0FBVyxLQUFLaUMsa0JBQVNqQyxXQUQxQyxJQUVDOEIsZ0JBQWdCLEtBQUtHLGtCQUFTSCxnQkFGaEMsS0FHQTVCLGVBSkYsRUFLRTtBQUNBLFVBQU0sK0ZBQU47QUFDRCxHQVBELE1BT08sSUFBSSxDQUFDQSxlQUFMLEVBQXNCO0FBQzNCQSxJQUFBQSxlQUFlLEdBQUdnQyxrQkFBa0IsQ0FBQ2xDLFdBQUQsRUFBYzhCLGdCQUFkLEVBQWdDRCxlQUFoQyxDQUFwQztBQUNELEdBRk0sTUFFQTtBQUNMM0IsSUFBQUEsZUFBZSxHQUFHLGdDQUFZQSxlQUFaLENBQWxCO0FBQ0Q7O0FBQ0QsU0FBTyxJQUFJaUMsMkJBQUosQ0FDTGpDLGVBREssRUFFTCxJQUFJa0Msb0JBQUosQ0FBZ0I5RCxlQUFoQixFQUFpQ3lELGNBQWpDLEVBQWlEQyx1QkFBakQsQ0FGSyxDQUFQO0FBSUQ7O0FBRU0sU0FBU2pELGtCQUFULENBQ0x0QixPQURLLEVBRUxtQixrQkFGSyxFQUdZO0FBQ2pCLFFBQU07QUFBRVEsSUFBQUEsS0FBRjtBQUFTaUQsSUFBQUE7QUFBVCxNQUF3QjVFLE9BQTlCO0FBQ0EsU0FBTyxJQUFJNkUsZ0NBQUosQ0FBb0JsRCxLQUFwQixFQUEyQlIsa0JBQTNCLEVBQStDeUQsVUFBL0MsQ0FBUDtBQUNEOztBQVNNLFNBQVNoRSxpQkFBVCxDQUEyQlosT0FBM0IsRUFBeUU7QUFDOUUsUUFBTTtBQUFFOEUsSUFBQUEsYUFBRjtBQUFpQkMsSUFBQUE7QUFBakIsTUFBMEIvRSxPQUFoQztBQUVBLFFBQU1nRixXQUFXLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLEVBQWQsRUFBa0JILElBQWxCLENBQXBCO0FBQ0EsUUFBTUksZ0JBQWdCLEdBQUdILFdBQVcsQ0FBQ0ksWUFBWixJQUE0QixFQUFyRDs7QUFDQSxNQUFJSixXQUFXLENBQUNJLFlBQWhCLEVBQThCO0FBQzVCLFdBQU9KLFdBQVcsQ0FBQ0ksWUFBbkI7QUFDRCxHQVA2RSxDQVM5RTs7O0FBQ0EsUUFBTUMsV0FBVyxHQUFHLGdDQUNsQkwsV0FBVyxJQUFJQSxXQUFXLENBQUNNLE9BRFQsRUFFbEJDLG9CQUZrQixFQUdsQlAsV0FIa0IsQ0FBcEIsQ0FWOEUsQ0FlOUU7QUFDQTs7QUFDQSxRQUFNekUsY0FBYyxHQUFHLElBQUlpRiw4QkFBSixFQUF2QjtBQUNBLFFBQU0vRSxjQUFjLEdBQUcsQ0FBQyxFQUFFNEUsV0FBVyxJQUFJTixJQUFqQixDQUF4QjtBQUNBLFFBQU12RSx1QkFBdUIsR0FBR0MsY0FBYyxJQUFJcUUsYUFBYSxLQUFLLElBQXBFO0FBRUEsUUFBTTtBQUFFVyxJQUFBQTtBQUFGLE1BQXdCTixnQkFBOUI7QUFFQSxRQUFNekUsbUJBQW1CLEdBQUcsSUFBSWdGLG9CQUFKLENBQWNQLGdCQUFkLENBQTVCO0FBQ0EsTUFBSXhFLFVBQUo7O0FBQ0EsTUFBSSxDQUFDOEUsaUJBQUwsRUFBd0I7QUFDdEI5RSxJQUFBQSxVQUFVLEdBQUcsSUFBSWdGLHNCQUFKLENBQWVOLFdBQWYsRUFBNEJGLGdCQUE1QixDQUFiO0FBQ0Q7O0FBQ0QsU0FBTztBQUNMNUUsSUFBQUEsY0FESztBQUVMRSxJQUFBQSxjQUZLO0FBR0xELElBQUFBLHVCQUhLO0FBSUxFLElBQUFBLG1CQUpLO0FBS0xDLElBQUFBO0FBTEssR0FBUDtBQU9EOztBQUVNLFNBQVNhLGtCQUFULENBQTRCeEIsT0FBNUIsRUFBeUQ7QUFDOUQsUUFBTTtBQUFFNEYsSUFBQUEsSUFBRjtBQUFRQyxJQUFBQTtBQUFSLE1BQWlDN0YsT0FBdkM7QUFDQSxTQUFPLG1CQUFnQjRGLElBQWhCLEVBQXNCQyxvQkFBdEIsQ0FBUDtBQUNEOztBQUVNLFNBQVNwQixrQkFBVCxDQUE0QmxDLFdBQTVCLEVBQXlDOEIsZ0JBQXpDLEVBQTJERCxlQUEzRCxFQUE0RTtBQUNqRixNQUFJMEIsUUFBSjs7QUFDQSxNQUFJO0FBQ0YsVUFBTUMsU0FBUyxHQUFHQyxhQUFJQyxLQUFKLENBQVUxRCxXQUFWLENBQWxCOztBQUNBdUQsSUFBQUEsUUFBUSxHQUFHQyxTQUFTLENBQUNELFFBQVYsR0FBcUJDLFNBQVMsQ0FBQ0QsUUFBVixDQUFtQkksV0FBbkIsRUFBckIsR0FBd0QsSUFBbkU7QUFDRCxHQUhELENBR0UsT0FBT0MsQ0FBUCxFQUFVO0FBQ1Y7QUFDRDs7QUFDRCxVQUFRTCxRQUFSO0FBQ0UsU0FBSyxXQUFMO0FBQ0UsYUFBTyxJQUFJTSwrQkFBSixDQUEyQjtBQUNoQ0MsUUFBQUEsR0FBRyxFQUFFOUQsV0FEMkI7QUFFaEM4QixRQUFBQSxnQkFGZ0M7QUFHaENELFFBQUFBO0FBSGdDLE9BQTNCLENBQVA7O0FBS0Y7QUFDRSxhQUFPLElBQUlrQyw0QkFBSixDQUF3QjtBQUM3QkQsUUFBQUEsR0FBRyxFQUFFOUQsV0FEd0I7QUFFN0I4QixRQUFBQSxnQkFGNkI7QUFHN0JrQyxRQUFBQSxZQUFZLEVBQUVuQztBQUhlLE9BQXhCLENBQVA7QUFSSjtBQWNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF1dGhEYXRhTWFuYWdlciBmcm9tICcuLi9BZGFwdGVycy9BdXRoJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4uL09wdGlvbnMnO1xuaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi9kZWZhdWx0cyc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG4vLyBDb250cm9sbGVyc1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vTG9nZ2VyQ29udHJvbGxlcic7XG5pbXBvcnQgeyBGaWxlc0NvbnRyb2xsZXIgfSBmcm9tICcuL0ZpbGVzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBIb29rc0NvbnRyb2xsZXIgfSBmcm9tICcuL0hvb2tzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBVc2VyQ29udHJvbGxlciB9IGZyb20gJy4vVXNlckNvbnRyb2xsZXInO1xuaW1wb3J0IHsgQ2FjaGVDb250cm9sbGVyIH0gZnJvbSAnLi9DYWNoZUNvbnRyb2xsZXInO1xuaW1wb3J0IHsgTGl2ZVF1ZXJ5Q29udHJvbGxlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5Q29udHJvbGxlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NDb250cm9sbGVyIH0gZnJvbSAnLi9BbmFseXRpY3NDb250cm9sbGVyJztcbmltcG9ydCB7IFB1c2hDb250cm9sbGVyIH0gZnJvbSAnLi9QdXNoQ29udHJvbGxlcic7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuLi9QdXNoL1B1c2hRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoV29ya2VyIH0gZnJvbSAnLi4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IFNjaGVtYUNhY2hlIGZyb20gJy4vU2NoZW1hQ2FjaGUnO1xuXG4vLyBBZGFwdGVyc1xuaW1wb3J0IHsgR3JpZEZTQnVja2V0QWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0ZpbGVzL0dyaWRGU0J1Y2tldEFkYXB0ZXInO1xuaW1wb3J0IHsgV2luc3RvbkxvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgSW5NZW1vcnlDYWNoZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvUG9zdGdyZXMvUG9zdGdyZXNTdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgUGFyc2VQdXNoQWRhcHRlciBmcm9tICdAcGFyc2UvcHVzaC1hZGFwdGVyJztcbmltcG9ydCBQYXJzZUdyYXBoUUxDb250cm9sbGVyIGZyb20gJy4vUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250cm9sbGVycyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlciA9IGdldExvZ2dlckNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGZpbGVzQ29udHJvbGxlciA9IGdldEZpbGVzQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSBnZXRVc2VyQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3Qge1xuICAgIHB1c2hDb250cm9sbGVyLFxuICAgIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0LFxuICAgIGhhc1B1c2hTdXBwb3J0LFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgcHVzaFdvcmtlcixcbiAgfSA9IGdldFB1c2hDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBjYWNoZUNvbnRyb2xsZXIgPSBnZXRDYWNoZUNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGFuYWx5dGljc0NvbnRyb2xsZXIgPSBnZXRBbmFseXRpY3NDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBsaXZlUXVlcnlDb250cm9sbGVyID0gZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgZGF0YWJhc2VDb250cm9sbGVyID0gZ2V0RGF0YWJhc2VDb250cm9sbGVyKG9wdGlvbnMsIGNhY2hlQ29udHJvbGxlcik7XG4gIGNvbnN0IGhvb2tzQ29udHJvbGxlciA9IGdldEhvb2tzQ29udHJvbGxlcihvcHRpb25zLCBkYXRhYmFzZUNvbnRyb2xsZXIpO1xuICBjb25zdCBhdXRoRGF0YU1hbmFnZXIgPSBnZXRBdXRoRGF0YU1hbmFnZXIob3B0aW9ucyk7XG4gIGNvbnN0IHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKG9wdGlvbnMsIHtcbiAgICBkYXRhYmFzZUNvbnRyb2xsZXIsXG4gICAgY2FjaGVDb250cm9sbGVyLFxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZXJDb250cm9sbGVyLFxuICAgIGZpbGVzQ29udHJvbGxlcixcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBwdXNoQ29udHJvbGxlcixcbiAgICBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICBoYXNQdXNoU3VwcG9ydCxcbiAgICBwdXNoV29ya2VyLFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgYW5hbHl0aWNzQ29udHJvbGxlcixcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICBsaXZlUXVlcnlDb250cm9sbGVyLFxuICAgIGRhdGFiYXNlQ29udHJvbGxlcixcbiAgICBob29rc0NvbnRyb2xsZXIsXG4gICAgYXV0aERhdGFNYW5hZ2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VyQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBMb2dnZXJDb250cm9sbGVyIHtcbiAgY29uc3Qge1xuICAgIGFwcElkLFxuICAgIGpzb25Mb2dzLFxuICAgIGxvZ3NGb2xkZXIsXG4gICAgdmVyYm9zZSxcbiAgICBsb2dMZXZlbCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgICBzaWxlbnQsXG4gICAgbG9nZ2VyQWRhcHRlcixcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxvZ2dlck9wdGlvbnMgPSB7XG4gICAganNvbkxvZ3MsXG4gICAgbG9nc0ZvbGRlcixcbiAgICB2ZXJib3NlLFxuICAgIGxvZ0xldmVsLFxuICAgIHNpbGVudCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgfTtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihsb2dnZXJBZGFwdGVyLCBXaW5zdG9uTG9nZ2VyQWRhcHRlciwgbG9nZ2VyT3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihsb2dnZXJDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIGxvZ2dlck9wdGlvbnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZXNDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IEZpbGVzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGRhdGFiYXNlVVJJLCBmaWxlc0FkYXB0ZXIsIGRhdGFiYXNlQWRhcHRlciwgcHJlc2VydmVGaWxlTmFtZSwgZmlsZUtleSB9ID0gb3B0aW9ucztcbiAgaWYgKCFmaWxlc0FkYXB0ZXIgJiYgZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgdGhyb3cgJ1doZW4gdXNpbmcgYW4gZXhwbGljaXQgZGF0YWJhc2UgYWRhcHRlciwgeW91IG11c3QgYWxzbyB1c2UgYW4gZXhwbGljaXQgZmlsZXNBZGFwdGVyLic7XG4gIH1cbiAgY29uc3QgZmlsZXNDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGZpbGVzQWRhcHRlciwgKCkgPT4ge1xuICAgIHJldHVybiBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihkYXRhYmFzZVVSSSwge30sIGZpbGVLZXkpO1xuICB9KTtcbiAgcmV0dXJuIG5ldyBGaWxlc0NvbnRyb2xsZXIoZmlsZXNDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIHtcbiAgICBwcmVzZXJ2ZUZpbGVOYW1lLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IFVzZXJDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgZW1haWxBZGFwdGVyLCB2ZXJpZnlVc2VyRW1haWxzIH0gPSBvcHRpb25zO1xuICBjb25zdCBlbWFpbENvbnRyb2xsZXJBZGFwdGVyID0gbG9hZEFkYXB0ZXIoZW1haWxBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBVc2VyQ29udHJvbGxlcihlbWFpbENvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCwge1xuICAgIHZlcmlmeVVzZXJFbWFpbHMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2FjaGVDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IENhY2hlQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGNhY2hlQWRhcHRlciwgY2FjaGVUVEwsIGNhY2hlTWF4U2l6ZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgY2FjaGVDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGNhY2hlQWRhcHRlciwgSW5NZW1vcnlDYWNoZUFkYXB0ZXIsIHtcbiAgICBhcHBJZDogYXBwSWQsXG4gICAgdHRsOiBjYWNoZVRUTCxcbiAgICBtYXhTaXplOiBjYWNoZU1heFNpemUsXG4gIH0pO1xuICByZXR1cm4gbmV3IENhY2hlQ29udHJvbGxlcihjYWNoZUNvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKFxuICBvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsXG4gIGNvbnRyb2xsZXJEZXBzXG4pOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyIHtcbiAgcmV0dXJuIG5ldyBQYXJzZUdyYXBoUUxDb250cm9sbGVyKHtcbiAgICBtb3VudEdyYXBoUUw6IG9wdGlvbnMubW91bnRHcmFwaFFMLFxuICAgIC4uLmNvbnRyb2xsZXJEZXBzLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFuYWx5dGljc0NvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogQW5hbHl0aWNzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYW5hbHl0aWNzQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihhbmFseXRpY3NBZGFwdGVyLCBBbmFseXRpY3NBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBBbmFseXRpY3NDb250cm9sbGVyKGFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExpdmVRdWVyeUNvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogTGl2ZVF1ZXJ5Q29udHJvbGxlciB7XG4gIHJldHVybiBuZXcgTGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zLmxpdmVRdWVyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhYmFzZUNvbnRyb2xsZXIoXG4gIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyxcbiAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXJcbik6IERhdGFiYXNlQ29udHJvbGxlciB7XG4gIGNvbnN0IHtcbiAgICBkYXRhYmFzZVVSSSxcbiAgICBkYXRhYmFzZU9wdGlvbnMsXG4gICAgY29sbGVjdGlvblByZWZpeCxcbiAgICBzY2hlbWFDYWNoZVRUTCxcbiAgICBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSxcbiAgfSA9IG9wdGlvbnM7XG4gIGxldCB7IGRhdGFiYXNlQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgaWYgKFxuICAgIChkYXRhYmFzZU9wdGlvbnMgfHxcbiAgICAgIChkYXRhYmFzZVVSSSAmJiBkYXRhYmFzZVVSSSAhPT0gZGVmYXVsdHMuZGF0YWJhc2VVUkkpIHx8XG4gICAgICBjb2xsZWN0aW9uUHJlZml4ICE9PSBkZWZhdWx0cy5jb2xsZWN0aW9uUHJlZml4KSAmJlxuICAgIGRhdGFiYXNlQWRhcHRlclxuICApIHtcbiAgICB0aHJvdyAnWW91IGNhbm5vdCBzcGVjaWZ5IGJvdGggYSBkYXRhYmFzZUFkYXB0ZXIgYW5kIGEgZGF0YWJhc2VVUkkvZGF0YWJhc2VPcHRpb25zL2NvbGxlY3Rpb25QcmVmaXguJztcbiAgfSBlbHNlIGlmICghZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgZGF0YWJhc2VBZGFwdGVyID0gZ2V0RGF0YWJhc2VBZGFwdGVyKGRhdGFiYXNlVVJJLCBjb2xsZWN0aW9uUHJlZml4LCBkYXRhYmFzZU9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIGRhdGFiYXNlQWRhcHRlciA9IGxvYWRBZGFwdGVyKGRhdGFiYXNlQWRhcHRlcik7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRhYmFzZUNvbnRyb2xsZXIoXG4gICAgZGF0YWJhc2VBZGFwdGVyLFxuICAgIG5ldyBTY2hlbWFDYWNoZShjYWNoZUNvbnRyb2xsZXIsIHNjaGVtYUNhY2hlVFRMLCBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tzQ29udHJvbGxlcihcbiAgb3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zLFxuICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlclxuKTogSG9va3NDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgd2ViaG9va0tleSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBIb29rc0NvbnRyb2xsZXIoYXBwSWQsIGRhdGFiYXNlQ29udHJvbGxlciwgd2ViaG9va0tleSk7XG59XG5cbmludGVyZmFjZSBQdXNoQ29udHJvbGxpbmcge1xuICBwdXNoQ29udHJvbGxlcjogUHVzaENvbnRyb2xsZXI7XG4gIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0OiBib29sZWFuO1xuICBwdXNoQ29udHJvbGxlclF1ZXVlOiBQdXNoUXVldWU7XG4gIHB1c2hXb3JrZXI6IFB1c2hXb3JrZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQdXNoQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBQdXNoQ29udHJvbGxpbmcge1xuICBjb25zdCB7IHNjaGVkdWxlZFB1c2gsIHB1c2ggfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgcHVzaE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBwdXNoKTtcbiAgY29uc3QgcHVzaFF1ZXVlT3B0aW9ucyA9IHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucyB8fCB7fTtcbiAgaWYgKHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucykge1xuICAgIGRlbGV0ZSBwdXNoT3B0aW9ucy5xdWV1ZU9wdGlvbnM7XG4gIH1cblxuICAvLyBQYXNzIHRoZSBwdXNoIG9wdGlvbnMgdG9vIGFzIGl0IHdvcmtzIHdpdGggdGhlIGRlZmF1bHRcbiAgY29uc3QgcHVzaEFkYXB0ZXIgPSBsb2FkQWRhcHRlcihcbiAgICBwdXNoT3B0aW9ucyAmJiBwdXNoT3B0aW9ucy5hZGFwdGVyLFxuICAgIFBhcnNlUHVzaEFkYXB0ZXIsXG4gICAgcHVzaE9wdGlvbnNcbiAgKTtcbiAgLy8gV2UgcGFzcyB0aGUgb3B0aW9ucyBhbmQgdGhlIGJhc2UgY2xhc3MgZm9yIHRoZSBhZGF0cGVyLFxuICAvLyBOb3RlIHRoYXQgcGFzc2luZyBhbiBpbnN0YW5jZSB3b3VsZCB3b3JrIHRvb1xuICBjb25zdCBwdXNoQ29udHJvbGxlciA9IG5ldyBQdXNoQ29udHJvbGxlcigpO1xuICBjb25zdCBoYXNQdXNoU3VwcG9ydCA9ICEhKHB1c2hBZGFwdGVyICYmIHB1c2gpO1xuICBjb25zdCBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCA9IGhhc1B1c2hTdXBwb3J0ICYmIHNjaGVkdWxlZFB1c2ggPT09IHRydWU7XG5cbiAgY29uc3QgeyBkaXNhYmxlUHVzaFdvcmtlciB9ID0gcHVzaFF1ZXVlT3B0aW9ucztcblxuICBjb25zdCBwdXNoQ29udHJvbGxlclF1ZXVlID0gbmV3IFB1c2hRdWV1ZShwdXNoUXVldWVPcHRpb25zKTtcbiAgbGV0IHB1c2hXb3JrZXI7XG4gIGlmICghZGlzYWJsZVB1c2hXb3JrZXIpIHtcbiAgICBwdXNoV29ya2VyID0gbmV3IFB1c2hXb3JrZXIocHVzaEFkYXB0ZXIsIHB1c2hRdWV1ZU9wdGlvbnMpO1xuICB9XG4gIHJldHVybiB7XG4gICAgcHVzaENvbnRyb2xsZXIsXG4gICAgaGFzUHVzaFN1cHBvcnQsXG4gICAgaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQsXG4gICAgcHVzaENvbnRyb2xsZXJRdWV1ZSxcbiAgICBwdXNoV29ya2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0aERhdGFNYW5hZ2VyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCB7IGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzIH0gPSBvcHRpb25zO1xuICByZXR1cm4gYXV0aERhdGFNYW5hZ2VyKGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERhdGFiYXNlQWRhcHRlcihkYXRhYmFzZVVSSSwgY29sbGVjdGlvblByZWZpeCwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBwcm90b2NvbDtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWRVUkkgPSB1cmwucGFyc2UoZGF0YWJhc2VVUkkpO1xuICAgIHByb3RvY29sID0gcGFyc2VkVVJJLnByb3RvY29sID8gcGFyc2VkVVJJLnByb3RvY29sLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICBzd2l0Y2ggKHByb3RvY29sKSB7XG4gICAgY2FzZSAncG9zdGdyZXM6JzpcbiAgICAgIHJldHVybiBuZXcgUG9zdGdyZXNTdG9yYWdlQWRhcHRlcih7XG4gICAgICAgIHVyaTogZGF0YWJhc2VVUkksXG4gICAgICAgIGNvbGxlY3Rpb25QcmVmaXgsXG4gICAgICAgIGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbmV3IE1vbmdvU3RvcmFnZUFkYXB0ZXIoe1xuICAgICAgICB1cmk6IGRhdGFiYXNlVVJJLFxuICAgICAgICBjb2xsZWN0aW9uUHJlZml4LFxuICAgICAgICBtb25nb09wdGlvbnM6IGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/types.js b/lib/Controllers/types.js deleted file mode 100644 index 4310b4ffac..0000000000 --- a/lib/Controllers/types.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLSchema.js b/lib/GraphQL/ParseGraphQLSchema.js deleted file mode 100644 index 254e6f3989..0000000000 --- a/lib/GraphQL/ParseGraphQLSchema.js +++ /dev/null @@ -1,446 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseGraphQLSchema = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphql = require("graphql"); - -var _stitch = require("@graphql-tools/stitch"); - -var _utils = require("@graphql-tools/utils"); - -var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./loaders/defaultGraphQLTypes")); - -var parseClassTypes = _interopRequireWildcard(require("./loaders/parseClassTypes")); - -var parseClassQueries = _interopRequireWildcard(require("./loaders/parseClassQueries")); - -var parseClassMutations = _interopRequireWildcard(require("./loaders/parseClassMutations")); - -var defaultGraphQLQueries = _interopRequireWildcard(require("./loaders/defaultGraphQLQueries")); - -var defaultGraphQLMutations = _interopRequireWildcard(require("./loaders/defaultGraphQLMutations")); - -var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); - -var _DatabaseController = _interopRequireDefault(require("../Controllers/DatabaseController")); - -var _parseGraphQLUtils = require("./parseGraphQLUtils"); - -var schemaDirectives = _interopRequireWildcard(require("./loaders/schemaDirectives")); - -var schemaTypes = _interopRequireWildcard(require("./loaders/schemaTypes")); - -var _triggers = require("../triggers"); - -var defaultRelaySchema = _interopRequireWildcard(require("./loaders/defaultRelaySchema")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const RESERVED_GRAPHQL_TYPE_NAMES = ['String', 'Boolean', 'Int', 'Float', 'ID', 'ArrayResult', 'Query', 'Mutation', 'Subscription', 'CreateFileInput', 'CreateFilePayload', 'Viewer', 'SignUpInput', 'SignUpPayload', 'LogInInput', 'LogInPayload', 'LogOutInput', 'LogOutPayload', 'CloudCodeFunction', 'CallCloudCodeInput', 'CallCloudCodePayload', 'CreateClassInput', 'CreateClassPayload', 'UpdateClassInput', 'UpdateClassPayload', 'DeleteClassInput', 'DeleteClassPayload', 'PageInfo']; -const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes']; -const RESERVED_GRAPHQL_MUTATION_NAMES = ['signUp', 'logIn', 'logOut', 'createFile', 'callCloudCode', 'createClass', 'updateClass', 'deleteClass']; - -class ParseGraphQLSchema { - constructor(params = {}) { - this.parseGraphQLController = params.parseGraphQLController || (0, _requiredParameter.default)('You must provide a parseGraphQLController instance!'); - this.databaseController = params.databaseController || (0, _requiredParameter.default)('You must provide a databaseController instance!'); - this.log = params.log || (0, _requiredParameter.default)('You must provide a log instance!'); - this.graphQLCustomTypeDefs = params.graphQLCustomTypeDefs; - this.appId = params.appId || (0, _requiredParameter.default)('You must provide the appId!'); - } - - async load() { - const { - parseGraphQLConfig - } = await this._initializeSchemaAndConfig(); - const parseClasses = await this._getClassesForSchema(parseGraphQLConfig); - const parseClassesString = JSON.stringify(parseClasses); - const functionNames = await this._getFunctionNames(); - const functionNamesString = JSON.stringify(functionNames); - - if (this.graphQLSchema && !this._hasSchemaInputChanged({ - parseClasses, - parseClassesString, - parseGraphQLConfig, - functionNamesString - })) { - return this.graphQLSchema; - } - - this.parseClasses = parseClasses; - this.parseClassesString = parseClassesString; - this.parseGraphQLConfig = parseGraphQLConfig; - this.functionNames = functionNames; - this.functionNamesString = functionNamesString; - this.parseClassTypes = {}; - this.viewerType = null; - this.graphQLAutoSchema = null; - this.graphQLSchema = null; - this.graphQLTypes = []; - this.graphQLQueries = {}; - this.graphQLMutations = {}; - this.graphQLSubscriptions = {}; - this.graphQLSchemaDirectivesDefinitions = null; - this.graphQLSchemaDirectives = {}; - this.relayNodeInterface = null; - defaultGraphQLTypes.load(this); - defaultRelaySchema.load(this); - schemaTypes.load(this); - - this._getParseClassesWithConfig(parseClasses, parseGraphQLConfig).forEach(([parseClass, parseClassConfig]) => { - parseClassTypes.load(this, parseClass, parseClassConfig); - parseClassQueries.load(this, parseClass, parseClassConfig); - parseClassMutations.load(this, parseClass, parseClassConfig); - }); - - defaultGraphQLTypes.loadArrayResult(this, parseClasses); - defaultGraphQLQueries.load(this); - defaultGraphQLMutations.load(this); - let graphQLQuery = undefined; - - if (Object.keys(this.graphQLQueries).length > 0) { - graphQLQuery = new _graphql.GraphQLObjectType({ - name: 'Query', - description: 'Query is the top level type for queries.', - fields: this.graphQLQueries - }); - this.addGraphQLType(graphQLQuery, true, true); - } - - let graphQLMutation = undefined; - - if (Object.keys(this.graphQLMutations).length > 0) { - graphQLMutation = new _graphql.GraphQLObjectType({ - name: 'Mutation', - description: 'Mutation is the top level type for mutations.', - fields: this.graphQLMutations - }); - this.addGraphQLType(graphQLMutation, true, true); - } - - let graphQLSubscription = undefined; - - if (Object.keys(this.graphQLSubscriptions).length > 0) { - graphQLSubscription = new _graphql.GraphQLObjectType({ - name: 'Subscription', - description: 'Subscription is the top level type for subscriptions.', - fields: this.graphQLSubscriptions - }); - this.addGraphQLType(graphQLSubscription, true, true); - } - - this.graphQLAutoSchema = new _graphql.GraphQLSchema({ - types: this.graphQLTypes, - query: graphQLQuery, - mutation: graphQLMutation, - subscription: graphQLSubscription - }); - - if (this.graphQLCustomTypeDefs) { - schemaDirectives.load(this); - - if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') { - const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs.getTypeMap(); - - const findAndReplaceLastType = (parent, key) => { - if (parent[key].name) { - if (this.graphQLAutoSchema.getType(parent[key].name) && this.graphQLAutoSchema.getType(parent[key].name) !== parent[key]) { - // To avoid unresolved field on overloaded schema - // replace the final type with the auto schema one - parent[key] = this.graphQLAutoSchema.getType(parent[key].name); - } - } else { - if (parent[key].ofType) { - findAndReplaceLastType(parent[key], 'ofType'); - } - } - }; - - Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { - if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { - return; - } - - const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); - - if (!autoGraphQLSchemaType) { - this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name] = customGraphQLSchemaType; - } - }); - Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { - if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { - return; - } - - const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); - - if (autoGraphQLSchemaType && typeof customGraphQLSchemaType.getFields === 'function') { - Object.values(customGraphQLSchemaType.getFields()).forEach(field => { - findAndReplaceLastType(field, 'type'); - }); - autoGraphQLSchemaType._fields = _objectSpread(_objectSpread({}, autoGraphQLSchemaType.getFields()), customGraphQLSchemaType.getFields()); - } - }); - this.graphQLSchema = (0, _stitch.stitchSchemas)({ - schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema], - mergeDirectives: true - }); - } else if (typeof this.graphQLCustomTypeDefs === 'function') { - this.graphQLSchema = await this.graphQLCustomTypeDefs({ - directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions, - autoSchema: this.graphQLAutoSchema, - stitchSchemas: _stitch.stitchSchemas - }); - } else { - this.graphQLSchema = (0, _stitch.stitchSchemas)({ - schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema, this.graphQLCustomTypeDefs], - mergeDirectives: true - }); - } - - const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap(); - Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => { - const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName]; - - if (typeof graphQLSchemaType.getFields === 'function' && this.graphQLCustomTypeDefs.definitions) { - const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(definition => definition.name.value === graphQLSchemaTypeName); - - if (graphQLCustomTypeDef) { - const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields(); - Object.keys(graphQLSchemaTypeFieldMap).forEach(graphQLSchemaTypeFieldName => { - const graphQLSchemaTypeField = graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName]; - - if (!graphQLSchemaTypeField.astNode) { - const astNode = graphQLCustomTypeDef.fields.find(field => field.name.value === graphQLSchemaTypeFieldName); - - if (astNode) { - graphQLSchemaTypeField.astNode = astNode; - } - } - }); - } - } - }); - - _utils.SchemaDirectiveVisitor.visitSchemaDirectives(this.graphQLSchema, this.graphQLSchemaDirectives); - } else { - this.graphQLSchema = this.graphQLAutoSchema; - } - - return this.graphQLSchema; - } - - addGraphQLType(type, throwError = false, ignoreReserved = false, ignoreConnection = false) { - if (!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name) || this.graphQLTypes.find(existingType => existingType.name === type.name) || !ignoreConnection && type.name.endsWith('Connection')) { - const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`; - - if (throwError) { - throw new Error(message); - } - - this.log.warn(message); - return undefined; - } - - this.graphQLTypes.push(type); - return type; - } - - addGraphQLQuery(fieldName, field, throwError = false, ignoreReserved = false) { - if (!ignoreReserved && RESERVED_GRAPHQL_QUERY_NAMES.includes(fieldName) || this.graphQLQueries[fieldName]) { - const message = `Query ${fieldName} could not be added to the auto schema because it collided with an existing field.`; - - if (throwError) { - throw new Error(message); - } - - this.log.warn(message); - return undefined; - } - - this.graphQLQueries[fieldName] = field; - return field; - } - - addGraphQLMutation(fieldName, field, throwError = false, ignoreReserved = false) { - if (!ignoreReserved && RESERVED_GRAPHQL_MUTATION_NAMES.includes(fieldName) || this.graphQLMutations[fieldName]) { - const message = `Mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`; - - if (throwError) { - throw new Error(message); - } - - this.log.warn(message); - return undefined; - } - - this.graphQLMutations[fieldName] = field; - return field; - } - - handleError(error) { - if (error instanceof _node.default.Error) { - this.log.error('Parse error: ', error); - } else { - this.log.error('Uncaught internal server error.', error, error.stack); - } - - throw (0, _parseGraphQLUtils.toGraphQLError)(error); - } - - async _initializeSchemaAndConfig() { - const [schemaController, parseGraphQLConfig] = await Promise.all([this.databaseController.loadSchema(), this.parseGraphQLController.getGraphQLConfig()]); - this.schemaController = schemaController; - return { - parseGraphQLConfig - }; - } - /** - * Gets all classes found by the `schemaController` - * minus those filtered out by the app's parseGraphQLConfig. - */ - - - async _getClassesForSchema(parseGraphQLConfig) { - const { - enabledForClasses, - disabledForClasses - } = parseGraphQLConfig; - const allClasses = await this.schemaController.getAllClasses(); - - if (Array.isArray(enabledForClasses) || Array.isArray(disabledForClasses)) { - let includedClasses = allClasses; - - if (enabledForClasses) { - includedClasses = allClasses.filter(clazz => { - return enabledForClasses.includes(clazz.className); - }); - } - - if (disabledForClasses) { - // Classes included in `enabledForClasses` that - // are also present in `disabledForClasses` will - // still be filtered out - includedClasses = includedClasses.filter(clazz => { - return !disabledForClasses.includes(clazz.className); - }); - } - - this.isUsersClassDisabled = !includedClasses.some(clazz => { - return clazz.className === '_User'; - }); - return includedClasses; - } else { - return allClasses; - } - } - /** - * This method returns a list of tuples - * that provide the parseClass along with - * its parseClassConfig where provided. - */ - - - _getParseClassesWithConfig(parseClasses, parseGraphQLConfig) { - const { - classConfigs - } = parseGraphQLConfig; // Make sures that the default classes and classes that - // starts with capitalized letter will be generated first. - - const sortClasses = (a, b) => { - a = a.className; - b = b.className; - - if (a[0] === '_') { - if (b[0] !== '_') { - return -1; - } - } - - if (b[0] === '_') { - if (a[0] !== '_') { - return 1; - } - } - - if (a === b) { - return 0; - } else if (a < b) { - return -1; - } else { - return 1; - } - }; - - return parseClasses.sort(sortClasses).map(parseClass => { - let parseClassConfig; - - if (classConfigs) { - parseClassConfig = classConfigs.find(c => c.className === parseClass.className); - } - - return [parseClass, parseClassConfig]; - }); - } - - async _getFunctionNames() { - return await (0, _triggers.getFunctionNames)(this.appId).filter(functionName => { - if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(functionName)) { - return true; - } else { - this.log.warn(`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`); - return false; - } - }); - } - /** - * Checks for changes to the parseClasses - * objects (i.e. database schema) or to - * the parseGraphQLConfig object. If no - * changes are found, return true; - */ - - - _hasSchemaInputChanged(params) { - const { - parseClasses, - parseClassesString, - parseGraphQLConfig, - functionNamesString - } = params; - - if (JSON.stringify(this.parseGraphQLConfig) === JSON.stringify(parseGraphQLConfig) && this.functionNamesString === functionNamesString) { - if (this.parseClasses === parseClasses) { - return false; - } - - if (this.parseClassesString === parseClassesString) { - this.parseClasses = parseClasses; - return false; - } - } - - return true; - } - -} - -exports.ParseGraphQLSchema = ParseGraphQLSchema; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMiLCJSRVNFUlZFRF9HUkFQSFFMX1FVRVJZX05BTUVTIiwiUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyIsIlBhcnNlR3JhcGhRTFNjaGVtYSIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwicGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImxvZyIsImdyYXBoUUxDdXN0b21UeXBlRGVmcyIsImFwcElkIiwibG9hZCIsInBhcnNlR3JhcGhRTENvbmZpZyIsIl9pbml0aWFsaXplU2NoZW1hQW5kQ29uZmlnIiwicGFyc2VDbGFzc2VzIiwiX2dldENsYXNzZXNGb3JTY2hlbWEiLCJwYXJzZUNsYXNzZXNTdHJpbmciLCJKU09OIiwic3RyaW5naWZ5IiwiZnVuY3Rpb25OYW1lcyIsIl9nZXRGdW5jdGlvbk5hbWVzIiwiZnVuY3Rpb25OYW1lc1N0cmluZyIsImdyYXBoUUxTY2hlbWEiLCJfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkIiwicGFyc2VDbGFzc1R5cGVzIiwidmlld2VyVHlwZSIsImdyYXBoUUxBdXRvU2NoZW1hIiwiZ3JhcGhRTFR5cGVzIiwiZ3JhcGhRTFF1ZXJpZXMiLCJncmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFN1YnNjcmlwdGlvbnMiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXMiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiZGVmYXVsdFJlbGF5U2NoZW1hIiwic2NoZW1hVHlwZXMiLCJfZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyIsImZvckVhY2giLCJwYXJzZUNsYXNzIiwicGFyc2VDbGFzc0NvbmZpZyIsInBhcnNlQ2xhc3NRdWVyaWVzIiwicGFyc2VDbGFzc011dGF0aW9ucyIsImxvYWRBcnJheVJlc3VsdCIsImRlZmF1bHRHcmFwaFFMUXVlcmllcyIsImRlZmF1bHRHcmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFF1ZXJ5IiwidW5kZWZpbmVkIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsIkdyYXBoUUxPYmplY3RUeXBlIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiZmllbGRzIiwiYWRkR3JhcGhRTFR5cGUiLCJncmFwaFFMTXV0YXRpb24iLCJncmFwaFFMU3Vic2NyaXB0aW9uIiwiR3JhcGhRTFNjaGVtYSIsInR5cGVzIiwicXVlcnkiLCJtdXRhdGlvbiIsInN1YnNjcmlwdGlvbiIsInNjaGVtYURpcmVjdGl2ZXMiLCJnZXRUeXBlTWFwIiwiY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJmaW5kQW5kUmVwbGFjZUxhc3RUeXBlIiwicGFyZW50Iiwia2V5IiwiZ2V0VHlwZSIsIm9mVHlwZSIsInZhbHVlcyIsImN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlIiwic3RhcnRzV2l0aCIsImF1dG9HcmFwaFFMU2NoZW1hVHlwZSIsIl90eXBlTWFwIiwiZ2V0RmllbGRzIiwiZmllbGQiLCJfZmllbGRzIiwic2NoZW1hcyIsIm1lcmdlRGlyZWN0aXZlcyIsImRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYSIsImF1dG9TY2hlbWEiLCJzdGl0Y2hTY2hlbWFzIiwiZ3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJncmFwaFFMU2NoZW1hVHlwZU5hbWUiLCJncmFwaFFMU2NoZW1hVHlwZSIsImRlZmluaXRpb25zIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWYiLCJmaW5kIiwiZGVmaW5pdGlvbiIsInZhbHVlIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE1hcCIsImdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCIsImFzdE5vZGUiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRTY2hlbWFEaXJlY3RpdmVzIiwidHlwZSIsInRocm93RXJyb3IiLCJpZ25vcmVSZXNlcnZlZCIsImlnbm9yZUNvbm5lY3Rpb24iLCJpbmNsdWRlcyIsImV4aXN0aW5nVHlwZSIsImVuZHNXaXRoIiwibWVzc2FnZSIsIkVycm9yIiwid2FybiIsInB1c2giLCJhZGRHcmFwaFFMUXVlcnkiLCJmaWVsZE5hbWUiLCJhZGRHcmFwaFFMTXV0YXRpb24iLCJoYW5kbGVFcnJvciIsImVycm9yIiwiUGFyc2UiLCJzdGFjayIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwiYWxsIiwibG9hZFNjaGVtYSIsImdldEdyYXBoUUxDb25maWciLCJlbmFibGVkRm9yQ2xhc3NlcyIsImRpc2FibGVkRm9yQ2xhc3NlcyIsImFsbENsYXNzZXMiLCJnZXRBbGxDbGFzc2VzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZWRDbGFzc2VzIiwiZmlsdGVyIiwiY2xhenoiLCJjbGFzc05hbWUiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNvbWUiLCJjbGFzc0NvbmZpZ3MiLCJzb3J0Q2xhc3NlcyIsImEiLCJiIiwic29ydCIsIm1hcCIsImMiLCJmdW5jdGlvbk5hbWUiLCJ0ZXN0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsMkJBQTJCLEdBQUcsQ0FDbEMsUUFEa0MsRUFFbEMsU0FGa0MsRUFHbEMsS0FIa0MsRUFJbEMsT0FKa0MsRUFLbEMsSUFMa0MsRUFNbEMsYUFOa0MsRUFPbEMsT0FQa0MsRUFRbEMsVUFSa0MsRUFTbEMsY0FUa0MsRUFVbEMsaUJBVmtDLEVBV2xDLG1CQVhrQyxFQVlsQyxRQVprQyxFQWFsQyxhQWJrQyxFQWNsQyxlQWRrQyxFQWVsQyxZQWZrQyxFQWdCbEMsY0FoQmtDLEVBaUJsQyxhQWpCa0MsRUFrQmxDLGVBbEJrQyxFQW1CbEMsbUJBbkJrQyxFQW9CbEMsb0JBcEJrQyxFQXFCbEMsc0JBckJrQyxFQXNCbEMsa0JBdEJrQyxFQXVCbEMsb0JBdkJrQyxFQXdCbEMsa0JBeEJrQyxFQXlCbEMsb0JBekJrQyxFQTBCbEMsa0JBMUJrQyxFQTJCbEMsb0JBM0JrQyxFQTRCbEMsVUE1QmtDLENBQXBDO0FBOEJBLE1BQU1DLDRCQUE0QixHQUFHLENBQUMsUUFBRCxFQUFXLFFBQVgsRUFBcUIsT0FBckIsRUFBOEIsU0FBOUIsQ0FBckM7QUFDQSxNQUFNQywrQkFBK0IsR0FBRyxDQUN0QyxRQURzQyxFQUV0QyxPQUZzQyxFQUd0QyxRQUhzQyxFQUl0QyxZQUpzQyxFQUt0QyxlQUxzQyxFQU10QyxhQU5zQyxFQU90QyxhQVBzQyxFQVF0QyxhQVJzQyxDQUF4Qzs7QUFXQSxNQUFNQyxrQkFBTixDQUF5QjtBQVF2QkMsRUFBQUEsV0FBVyxDQUNUQyxNQU1DLEdBQUcsRUFQSyxFQVFUO0FBQ0EsU0FBS0Msc0JBQUwsR0FDRUQsTUFBTSxDQUFDQyxzQkFBUCxJQUNBLGdDQUFrQixxREFBbEIsQ0FGRjtBQUdBLFNBQUtDLGtCQUFMLEdBQ0VGLE1BQU0sQ0FBQ0Usa0JBQVAsSUFDQSxnQ0FBa0IsaURBQWxCLENBRkY7QUFHQSxTQUFLQyxHQUFMLEdBQVdILE1BQU0sQ0FBQ0csR0FBUCxJQUFjLGdDQUFrQixrQ0FBbEIsQ0FBekI7QUFDQSxTQUFLQyxxQkFBTCxHQUE2QkosTUFBTSxDQUFDSSxxQkFBcEM7QUFDQSxTQUFLQyxLQUFMLEdBQWFMLE1BQU0sQ0FBQ0ssS0FBUCxJQUFnQixnQ0FBa0IsNkJBQWxCLENBQTdCO0FBQ0Q7O0FBRUQsUUFBTUMsSUFBTixHQUFhO0FBQ1gsVUFBTTtBQUFFQyxNQUFBQTtBQUFGLFFBQXlCLE1BQU0sS0FBS0MsMEJBQUwsRUFBckM7QUFDQSxVQUFNQyxZQUFZLEdBQUcsTUFBTSxLQUFLQyxvQkFBTCxDQUEwQkgsa0JBQTFCLENBQTNCO0FBQ0EsVUFBTUksa0JBQWtCLEdBQUdDLElBQUksQ0FBQ0MsU0FBTCxDQUFlSixZQUFmLENBQTNCO0FBQ0EsVUFBTUssYUFBYSxHQUFHLE1BQU0sS0FBS0MsaUJBQUwsRUFBNUI7QUFDQSxVQUFNQyxtQkFBbUIsR0FBR0osSUFBSSxDQUFDQyxTQUFMLENBQWVDLGFBQWYsQ0FBNUI7O0FBRUEsUUFDRSxLQUFLRyxhQUFMLElBQ0EsQ0FBQyxLQUFLQyxzQkFBTCxDQUE0QjtBQUMzQlQsTUFBQUEsWUFEMkI7QUFFM0JFLE1BQUFBLGtCQUYyQjtBQUczQkosTUFBQUEsa0JBSDJCO0FBSTNCUyxNQUFBQTtBQUoyQixLQUE1QixDQUZILEVBUUU7QUFDQSxhQUFPLEtBQUtDLGFBQVo7QUFDRDs7QUFFRCxTQUFLUixZQUFMLEdBQW9CQSxZQUFwQjtBQUNBLFNBQUtFLGtCQUFMLEdBQTBCQSxrQkFBMUI7QUFDQSxTQUFLSixrQkFBTCxHQUEwQkEsa0JBQTFCO0FBQ0EsU0FBS08sYUFBTCxHQUFxQkEsYUFBckI7QUFDQSxTQUFLRSxtQkFBTCxHQUEyQkEsbUJBQTNCO0FBQ0EsU0FBS0csZUFBTCxHQUF1QixFQUF2QjtBQUNBLFNBQUtDLFVBQUwsR0FBa0IsSUFBbEI7QUFDQSxTQUFLQyxpQkFBTCxHQUF5QixJQUF6QjtBQUNBLFNBQUtKLGFBQUwsR0FBcUIsSUFBckI7QUFDQSxTQUFLSyxZQUFMLEdBQW9CLEVBQXBCO0FBQ0EsU0FBS0MsY0FBTCxHQUFzQixFQUF0QjtBQUNBLFNBQUtDLGdCQUFMLEdBQXdCLEVBQXhCO0FBQ0EsU0FBS0Msb0JBQUwsR0FBNEIsRUFBNUI7QUFDQSxTQUFLQyxrQ0FBTCxHQUEwQyxJQUExQztBQUNBLFNBQUtDLHVCQUFMLEdBQStCLEVBQS9CO0FBQ0EsU0FBS0Msa0JBQUwsR0FBMEIsSUFBMUI7QUFFQUMsSUFBQUEsbUJBQW1CLENBQUN2QixJQUFwQixDQUF5QixJQUF6QjtBQUNBd0IsSUFBQUEsa0JBQWtCLENBQUN4QixJQUFuQixDQUF3QixJQUF4QjtBQUNBeUIsSUFBQUEsV0FBVyxDQUFDekIsSUFBWixDQUFpQixJQUFqQjs7QUFFQSxTQUFLMEIsMEJBQUwsQ0FBZ0N2QixZQUFoQyxFQUE4Q0Ysa0JBQTlDLEVBQWtFMEIsT0FBbEUsQ0FDRSxDQUFDLENBQUNDLFVBQUQsRUFBYUMsZ0JBQWIsQ0FBRCxLQUFvQztBQUNsQ2hCLE1BQUFBLGVBQWUsQ0FBQ2IsSUFBaEIsQ0FBcUIsSUFBckIsRUFBMkI0QixVQUEzQixFQUF1Q0MsZ0JBQXZDO0FBQ0FDLE1BQUFBLGlCQUFpQixDQUFDOUIsSUFBbEIsQ0FBdUIsSUFBdkIsRUFBNkI0QixVQUE3QixFQUF5Q0MsZ0JBQXpDO0FBQ0FFLE1BQUFBLG1CQUFtQixDQUFDL0IsSUFBcEIsQ0FBeUIsSUFBekIsRUFBK0I0QixVQUEvQixFQUEyQ0MsZ0JBQTNDO0FBQ0QsS0FMSDs7QUFRQU4sSUFBQUEsbUJBQW1CLENBQUNTLGVBQXBCLENBQW9DLElBQXBDLEVBQTBDN0IsWUFBMUM7QUFDQThCLElBQUFBLHFCQUFxQixDQUFDakMsSUFBdEIsQ0FBMkIsSUFBM0I7QUFDQWtDLElBQUFBLHVCQUF1QixDQUFDbEMsSUFBeEIsQ0FBNkIsSUFBN0I7QUFFQSxRQUFJbUMsWUFBWSxHQUFHQyxTQUFuQjs7QUFDQSxRQUFJQyxNQUFNLENBQUNDLElBQVAsQ0FBWSxLQUFLckIsY0FBakIsRUFBaUNzQixNQUFqQyxHQUEwQyxDQUE5QyxFQUFpRDtBQUMvQ0osTUFBQUEsWUFBWSxHQUFHLElBQUlLLDBCQUFKLENBQXNCO0FBQ25DQyxRQUFBQSxJQUFJLEVBQUUsT0FENkI7QUFFbkNDLFFBQUFBLFdBQVcsRUFBRSwwQ0FGc0I7QUFHbkNDLFFBQUFBLE1BQU0sRUFBRSxLQUFLMUI7QUFIc0IsT0FBdEIsQ0FBZjtBQUtBLFdBQUsyQixjQUFMLENBQW9CVCxZQUFwQixFQUFrQyxJQUFsQyxFQUF3QyxJQUF4QztBQUNEOztBQUVELFFBQUlVLGVBQWUsR0FBR1QsU0FBdEI7O0FBQ0EsUUFBSUMsTUFBTSxDQUFDQyxJQUFQLENBQVksS0FBS3BCLGdCQUFqQixFQUFtQ3FCLE1BQW5DLEdBQTRDLENBQWhELEVBQW1EO0FBQ2pETSxNQUFBQSxlQUFlLEdBQUcsSUFBSUwsMEJBQUosQ0FBc0I7QUFDdENDLFFBQUFBLElBQUksRUFBRSxVQURnQztBQUV0Q0MsUUFBQUEsV0FBVyxFQUFFLCtDQUZ5QjtBQUd0Q0MsUUFBQUEsTUFBTSxFQUFFLEtBQUt6QjtBQUh5QixPQUF0QixDQUFsQjtBQUtBLFdBQUswQixjQUFMLENBQW9CQyxlQUFwQixFQUFxQyxJQUFyQyxFQUEyQyxJQUEzQztBQUNEOztBQUVELFFBQUlDLG1CQUFtQixHQUFHVixTQUExQjs7QUFDQSxRQUFJQyxNQUFNLENBQUNDLElBQVAsQ0FBWSxLQUFLbkIsb0JBQWpCLEVBQXVDb0IsTUFBdkMsR0FBZ0QsQ0FBcEQsRUFBdUQ7QUFDckRPLE1BQUFBLG1CQUFtQixHQUFHLElBQUlOLDBCQUFKLENBQXNCO0FBQzFDQyxRQUFBQSxJQUFJLEVBQUUsY0FEb0M7QUFFMUNDLFFBQUFBLFdBQVcsRUFBRSx1REFGNkI7QUFHMUNDLFFBQUFBLE1BQU0sRUFBRSxLQUFLeEI7QUFINkIsT0FBdEIsQ0FBdEI7QUFLQSxXQUFLeUIsY0FBTCxDQUFvQkUsbUJBQXBCLEVBQXlDLElBQXpDLEVBQStDLElBQS9DO0FBQ0Q7O0FBRUQsU0FBSy9CLGlCQUFMLEdBQXlCLElBQUlnQyxzQkFBSixDQUFrQjtBQUN6Q0MsTUFBQUEsS0FBSyxFQUFFLEtBQUtoQyxZQUQ2QjtBQUV6Q2lDLE1BQUFBLEtBQUssRUFBRWQsWUFGa0M7QUFHekNlLE1BQUFBLFFBQVEsRUFBRUwsZUFIK0I7QUFJekNNLE1BQUFBLFlBQVksRUFBRUw7QUFKMkIsS0FBbEIsQ0FBekI7O0FBT0EsUUFBSSxLQUFLaEQscUJBQVQsRUFBZ0M7QUFDOUJzRCxNQUFBQSxnQkFBZ0IsQ0FBQ3BELElBQWpCLENBQXNCLElBQXRCOztBQUVBLFVBQUksT0FBTyxLQUFLRixxQkFBTCxDQUEyQnVELFVBQWxDLEtBQWlELFVBQXJELEVBQWlFO0FBQy9ELGNBQU1DLDBCQUEwQixHQUFHLEtBQUt4RCxxQkFBTCxDQUEyQnVELFVBQTNCLEVBQW5DOztBQUNBLGNBQU1FLHNCQUFzQixHQUFHLENBQUNDLE1BQUQsRUFBU0MsR0FBVCxLQUFpQjtBQUM5QyxjQUFJRCxNQUFNLENBQUNDLEdBQUQsQ0FBTixDQUFZaEIsSUFBaEIsRUFBc0I7QUFDcEIsZ0JBQ0UsS0FBSzFCLGlCQUFMLENBQXVCMkMsT0FBdkIsQ0FBK0JGLE1BQU0sQ0FBQ0MsR0FBRCxDQUFOLENBQVloQixJQUEzQyxLQUNBLEtBQUsxQixpQkFBTCxDQUF1QjJDLE9BQXZCLENBQStCRixNQUFNLENBQUNDLEdBQUQsQ0FBTixDQUFZaEIsSUFBM0MsTUFBcURlLE1BQU0sQ0FBQ0MsR0FBRCxDQUY3RCxFQUdFO0FBQ0E7QUFDQTtBQUNBRCxjQUFBQSxNQUFNLENBQUNDLEdBQUQsQ0FBTixHQUFjLEtBQUsxQyxpQkFBTCxDQUF1QjJDLE9BQXZCLENBQStCRixNQUFNLENBQUNDLEdBQUQsQ0FBTixDQUFZaEIsSUFBM0MsQ0FBZDtBQUNEO0FBQ0YsV0FURCxNQVNPO0FBQ0wsZ0JBQUllLE1BQU0sQ0FBQ0MsR0FBRCxDQUFOLENBQVlFLE1BQWhCLEVBQXdCO0FBQ3RCSixjQUFBQSxzQkFBc0IsQ0FBQ0MsTUFBTSxDQUFDQyxHQUFELENBQVAsRUFBYyxRQUFkLENBQXRCO0FBQ0Q7QUFDRjtBQUNGLFNBZkQ7O0FBZ0JBcEIsUUFBQUEsTUFBTSxDQUFDdUIsTUFBUCxDQUFjTiwwQkFBZCxFQUEwQzNCLE9BQTFDLENBQWtEa0MsdUJBQXVCLElBQUk7QUFDM0UsY0FDRSxDQUFDQSx1QkFBRCxJQUNBLENBQUNBLHVCQUF1QixDQUFDcEIsSUFEekIsSUFFQW9CLHVCQUF1QixDQUFDcEIsSUFBeEIsQ0FBNkJxQixVQUE3QixDQUF3QyxJQUF4QyxDQUhGLEVBSUU7QUFDQTtBQUNEOztBQUNELGdCQUFNQyxxQkFBcUIsR0FBRyxLQUFLaEQsaUJBQUwsQ0FBdUIyQyxPQUF2QixDQUM1QkcsdUJBQXVCLENBQUNwQixJQURJLENBQTlCOztBQUdBLGNBQUksQ0FBQ3NCLHFCQUFMLEVBQTRCO0FBQzFCLGlCQUFLaEQsaUJBQUwsQ0FBdUJpRCxRQUF2QixDQUFnQ0gsdUJBQXVCLENBQUNwQixJQUF4RCxJQUFnRW9CLHVCQUFoRTtBQUNEO0FBQ0YsU0FkRDtBQWVBeEIsUUFBQUEsTUFBTSxDQUFDdUIsTUFBUCxDQUFjTiwwQkFBZCxFQUEwQzNCLE9BQTFDLENBQWtEa0MsdUJBQXVCLElBQUk7QUFDM0UsY0FDRSxDQUFDQSx1QkFBRCxJQUNBLENBQUNBLHVCQUF1QixDQUFDcEIsSUFEekIsSUFFQW9CLHVCQUF1QixDQUFDcEIsSUFBeEIsQ0FBNkJxQixVQUE3QixDQUF3QyxJQUF4QyxDQUhGLEVBSUU7QUFDQTtBQUNEOztBQUNELGdCQUFNQyxxQkFBcUIsR0FBRyxLQUFLaEQsaUJBQUwsQ0FBdUIyQyxPQUF2QixDQUM1QkcsdUJBQXVCLENBQUNwQixJQURJLENBQTlCOztBQUlBLGNBQUlzQixxQkFBcUIsSUFBSSxPQUFPRix1QkFBdUIsQ0FBQ0ksU0FBL0IsS0FBNkMsVUFBMUUsRUFBc0Y7QUFDcEY1QixZQUFBQSxNQUFNLENBQUN1QixNQUFQLENBQWNDLHVCQUF1QixDQUFDSSxTQUF4QixFQUFkLEVBQW1EdEMsT0FBbkQsQ0FBMkR1QyxLQUFLLElBQUk7QUFDbEVYLGNBQUFBLHNCQUFzQixDQUFDVyxLQUFELEVBQVEsTUFBUixDQUF0QjtBQUNELGFBRkQ7QUFHQUgsWUFBQUEscUJBQXFCLENBQUNJLE9BQXRCLG1DQUNLSixxQkFBcUIsQ0FBQ0UsU0FBdEIsRUFETCxHQUVLSix1QkFBdUIsQ0FBQ0ksU0FBeEIsRUFGTDtBQUlEO0FBQ0YsU0FyQkQ7QUFzQkEsYUFBS3RELGFBQUwsR0FBcUIsMkJBQWM7QUFDakN5RCxVQUFBQSxPQUFPLEVBQUUsQ0FBQyxLQUFLaEQsa0NBQU4sRUFBMEMsS0FBS0wsaUJBQS9DLENBRHdCO0FBRWpDc0QsVUFBQUEsZUFBZSxFQUFFO0FBRmdCLFNBQWQsQ0FBckI7QUFJRCxPQTNERCxNQTJETyxJQUFJLE9BQU8sS0FBS3ZFLHFCQUFaLEtBQXNDLFVBQTFDLEVBQXNEO0FBQzNELGFBQUthLGFBQUwsR0FBcUIsTUFBTSxLQUFLYixxQkFBTCxDQUEyQjtBQUNwRHdFLFVBQUFBLDJCQUEyQixFQUFFLEtBQUtsRCxrQ0FEa0I7QUFFcERtRCxVQUFBQSxVQUFVLEVBQUUsS0FBS3hELGlCQUZtQztBQUdwRHlELFVBQUFBLGFBQWEsRUFBYkE7QUFIb0QsU0FBM0IsQ0FBM0I7QUFLRCxPQU5NLE1BTUE7QUFDTCxhQUFLN0QsYUFBTCxHQUFxQiwyQkFBYztBQUNqQ3lELFVBQUFBLE9BQU8sRUFBRSxDQUNQLEtBQUtoRCxrQ0FERSxFQUVQLEtBQUtMLGlCQUZFLEVBR1AsS0FBS2pCLHFCQUhFLENBRHdCO0FBTWpDdUUsVUFBQUEsZUFBZSxFQUFFO0FBTmdCLFNBQWQsQ0FBckI7QUFRRDs7QUFFRCxZQUFNSSxvQkFBb0IsR0FBRyxLQUFLOUQsYUFBTCxDQUFtQjBDLFVBQW5CLEVBQTdCO0FBQ0FoQixNQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWW1DLG9CQUFaLEVBQWtDOUMsT0FBbEMsQ0FBMEMrQyxxQkFBcUIsSUFBSTtBQUNqRSxjQUFNQyxpQkFBaUIsR0FBR0Ysb0JBQW9CLENBQUNDLHFCQUFELENBQTlDOztBQUNBLFlBQ0UsT0FBT0MsaUJBQWlCLENBQUNWLFNBQXpCLEtBQXVDLFVBQXZDLElBQ0EsS0FBS25FLHFCQUFMLENBQTJCOEUsV0FGN0IsRUFHRTtBQUNBLGdCQUFNQyxvQkFBb0IsR0FBRyxLQUFLL0UscUJBQUwsQ0FBMkI4RSxXQUEzQixDQUF1Q0UsSUFBdkMsQ0FDM0JDLFVBQVUsSUFBSUEsVUFBVSxDQUFDdEMsSUFBWCxDQUFnQnVDLEtBQWhCLEtBQTBCTixxQkFEYixDQUE3Qjs7QUFHQSxjQUFJRyxvQkFBSixFQUEwQjtBQUN4QixrQkFBTUkseUJBQXlCLEdBQUdOLGlCQUFpQixDQUFDVixTQUFsQixFQUFsQztBQUNBNUIsWUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVkyQyx5QkFBWixFQUF1Q3RELE9BQXZDLENBQStDdUQsMEJBQTBCLElBQUk7QUFDM0Usb0JBQU1DLHNCQUFzQixHQUFHRix5QkFBeUIsQ0FBQ0MsMEJBQUQsQ0FBeEQ7O0FBQ0Esa0JBQUksQ0FBQ0Msc0JBQXNCLENBQUNDLE9BQTVCLEVBQXFDO0FBQ25DLHNCQUFNQSxPQUFPLEdBQUdQLG9CQUFvQixDQUFDbEMsTUFBckIsQ0FBNEJtQyxJQUE1QixDQUNkWixLQUFLLElBQUlBLEtBQUssQ0FBQ3pCLElBQU4sQ0FBV3VDLEtBQVgsS0FBcUJFLDBCQURoQixDQUFoQjs7QUFHQSxvQkFBSUUsT0FBSixFQUFhO0FBQ1hELGtCQUFBQSxzQkFBc0IsQ0FBQ0MsT0FBdkIsR0FBaUNBLE9BQWpDO0FBQ0Q7QUFDRjtBQUNGLGFBVkQ7QUFXRDtBQUNGO0FBQ0YsT0F4QkQ7O0FBMEJBQyxvQ0FBdUJDLHFCQUF2QixDQUNFLEtBQUszRSxhQURQLEVBRUUsS0FBS1UsdUJBRlA7QUFJRCxLQTlHRCxNQThHTztBQUNMLFdBQUtWLGFBQUwsR0FBcUIsS0FBS0ksaUJBQTFCO0FBQ0Q7O0FBRUQsV0FBTyxLQUFLSixhQUFaO0FBQ0Q7O0FBRURpQyxFQUFBQSxjQUFjLENBQUMyQyxJQUFELEVBQU9DLFVBQVUsR0FBRyxLQUFwQixFQUEyQkMsY0FBYyxHQUFHLEtBQTVDLEVBQW1EQyxnQkFBZ0IsR0FBRyxLQUF0RSxFQUE2RTtBQUN6RixRQUNHLENBQUNELGNBQUQsSUFBbUJwRywyQkFBMkIsQ0FBQ3NHLFFBQTVCLENBQXFDSixJQUFJLENBQUM5QyxJQUExQyxDQUFwQixJQUNBLEtBQUt6QixZQUFMLENBQWtCOEQsSUFBbEIsQ0FBdUJjLFlBQVksSUFBSUEsWUFBWSxDQUFDbkQsSUFBYixLQUFzQjhDLElBQUksQ0FBQzlDLElBQWxFLENBREEsSUFFQyxDQUFDaUQsZ0JBQUQsSUFBcUJILElBQUksQ0FBQzlDLElBQUwsQ0FBVW9ELFFBQVYsQ0FBbUIsWUFBbkIsQ0FIeEIsRUFJRTtBQUNBLFlBQU1DLE9BQU8sR0FBSSxRQUFPUCxJQUFJLENBQUM5QyxJQUFLLG1GQUFsQzs7QUFDQSxVQUFJK0MsVUFBSixFQUFnQjtBQUNkLGNBQU0sSUFBSU8sS0FBSixDQUFVRCxPQUFWLENBQU47QUFDRDs7QUFDRCxXQUFLakcsR0FBTCxDQUFTbUcsSUFBVCxDQUFjRixPQUFkO0FBQ0EsYUFBTzFELFNBQVA7QUFDRDs7QUFDRCxTQUFLcEIsWUFBTCxDQUFrQmlGLElBQWxCLENBQXVCVixJQUF2QjtBQUNBLFdBQU9BLElBQVA7QUFDRDs7QUFFRFcsRUFBQUEsZUFBZSxDQUFDQyxTQUFELEVBQVlqQyxLQUFaLEVBQW1Cc0IsVUFBVSxHQUFHLEtBQWhDLEVBQXVDQyxjQUFjLEdBQUcsS0FBeEQsRUFBK0Q7QUFDNUUsUUFDRyxDQUFDQSxjQUFELElBQW1CbkcsNEJBQTRCLENBQUNxRyxRQUE3QixDQUFzQ1EsU0FBdEMsQ0FBcEIsSUFDQSxLQUFLbEYsY0FBTCxDQUFvQmtGLFNBQXBCLENBRkYsRUFHRTtBQUNBLFlBQU1MLE9BQU8sR0FBSSxTQUFRSyxTQUFVLG9GQUFuQzs7QUFDQSxVQUFJWCxVQUFKLEVBQWdCO0FBQ2QsY0FBTSxJQUFJTyxLQUFKLENBQVVELE9BQVYsQ0FBTjtBQUNEOztBQUNELFdBQUtqRyxHQUFMLENBQVNtRyxJQUFULENBQWNGLE9BQWQ7QUFDQSxhQUFPMUQsU0FBUDtBQUNEOztBQUNELFNBQUtuQixjQUFMLENBQW9Ca0YsU0FBcEIsSUFBaUNqQyxLQUFqQztBQUNBLFdBQU9BLEtBQVA7QUFDRDs7QUFFRGtDLEVBQUFBLGtCQUFrQixDQUFDRCxTQUFELEVBQVlqQyxLQUFaLEVBQW1Cc0IsVUFBVSxHQUFHLEtBQWhDLEVBQXVDQyxjQUFjLEdBQUcsS0FBeEQsRUFBK0Q7QUFDL0UsUUFDRyxDQUFDQSxjQUFELElBQW1CbEcsK0JBQStCLENBQUNvRyxRQUFoQyxDQUF5Q1EsU0FBekMsQ0FBcEIsSUFDQSxLQUFLakYsZ0JBQUwsQ0FBc0JpRixTQUF0QixDQUZGLEVBR0U7QUFDQSxZQUFNTCxPQUFPLEdBQUksWUFBV0ssU0FBVSxvRkFBdEM7O0FBQ0EsVUFBSVgsVUFBSixFQUFnQjtBQUNkLGNBQU0sSUFBSU8sS0FBSixDQUFVRCxPQUFWLENBQU47QUFDRDs7QUFDRCxXQUFLakcsR0FBTCxDQUFTbUcsSUFBVCxDQUFjRixPQUFkO0FBQ0EsYUFBTzFELFNBQVA7QUFDRDs7QUFDRCxTQUFLbEIsZ0JBQUwsQ0FBc0JpRixTQUF0QixJQUFtQ2pDLEtBQW5DO0FBQ0EsV0FBT0EsS0FBUDtBQUNEOztBQUVEbUMsRUFBQUEsV0FBVyxDQUFDQyxLQUFELEVBQVE7QUFDakIsUUFBSUEsS0FBSyxZQUFZQyxjQUFNUixLQUEzQixFQUFrQztBQUNoQyxXQUFLbEcsR0FBTCxDQUFTeUcsS0FBVCxDQUFlLGVBQWYsRUFBZ0NBLEtBQWhDO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsV0FBS3pHLEdBQUwsQ0FBU3lHLEtBQVQsQ0FBZSxpQ0FBZixFQUFrREEsS0FBbEQsRUFBeURBLEtBQUssQ0FBQ0UsS0FBL0Q7QUFDRDs7QUFDRCxVQUFNLHVDQUFlRixLQUFmLENBQU47QUFDRDs7QUFFRCxRQUFNcEcsMEJBQU4sR0FBbUM7QUFDakMsVUFBTSxDQUFDdUcsZ0JBQUQsRUFBbUJ4RyxrQkFBbkIsSUFBeUMsTUFBTXlHLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLENBQy9ELEtBQUsvRyxrQkFBTCxDQUF3QmdILFVBQXhCLEVBRCtELEVBRS9ELEtBQUtqSCxzQkFBTCxDQUE0QmtILGdCQUE1QixFQUYrRCxDQUFaLENBQXJEO0FBS0EsU0FBS0osZ0JBQUwsR0FBd0JBLGdCQUF4QjtBQUVBLFdBQU87QUFDTHhHLE1BQUFBO0FBREssS0FBUDtBQUdEO0FBRUQ7Ozs7OztBQUlBLFFBQU1HLG9CQUFOLENBQTJCSCxrQkFBM0IsRUFBbUU7QUFDakUsVUFBTTtBQUFFNkcsTUFBQUEsaUJBQUY7QUFBcUJDLE1BQUFBO0FBQXJCLFFBQTRDOUcsa0JBQWxEO0FBQ0EsVUFBTStHLFVBQVUsR0FBRyxNQUFNLEtBQUtQLGdCQUFMLENBQXNCUSxhQUF0QixFQUF6Qjs7QUFFQSxRQUFJQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0wsaUJBQWQsS0FBb0NJLEtBQUssQ0FBQ0MsT0FBTixDQUFjSixrQkFBZCxDQUF4QyxFQUEyRTtBQUN6RSxVQUFJSyxlQUFlLEdBQUdKLFVBQXRCOztBQUNBLFVBQUlGLGlCQUFKLEVBQXVCO0FBQ3JCTSxRQUFBQSxlQUFlLEdBQUdKLFVBQVUsQ0FBQ0ssTUFBWCxDQUFrQkMsS0FBSyxJQUFJO0FBQzNDLGlCQUFPUixpQkFBaUIsQ0FBQ25CLFFBQWxCLENBQTJCMkIsS0FBSyxDQUFDQyxTQUFqQyxDQUFQO0FBQ0QsU0FGaUIsQ0FBbEI7QUFHRDs7QUFDRCxVQUFJUixrQkFBSixFQUF3QjtBQUN0QjtBQUNBO0FBQ0E7QUFDQUssUUFBQUEsZUFBZSxHQUFHQSxlQUFlLENBQUNDLE1BQWhCLENBQXVCQyxLQUFLLElBQUk7QUFDaEQsaUJBQU8sQ0FBQ1Asa0JBQWtCLENBQUNwQixRQUFuQixDQUE0QjJCLEtBQUssQ0FBQ0MsU0FBbEMsQ0FBUjtBQUNELFNBRmlCLENBQWxCO0FBR0Q7O0FBRUQsV0FBS0Msb0JBQUwsR0FBNEIsQ0FBQ0osZUFBZSxDQUFDSyxJQUFoQixDQUFxQkgsS0FBSyxJQUFJO0FBQ3pELGVBQU9BLEtBQUssQ0FBQ0MsU0FBTixLQUFvQixPQUEzQjtBQUNELE9BRjRCLENBQTdCO0FBSUEsYUFBT0gsZUFBUDtBQUNELEtBckJELE1BcUJPO0FBQ0wsYUFBT0osVUFBUDtBQUNEO0FBQ0Y7QUFFRDs7Ozs7OztBQUtBdEYsRUFBQUEsMEJBQTBCLENBQUN2QixZQUFELEVBQWVGLGtCQUFmLEVBQXVEO0FBQy9FLFVBQU07QUFBRXlILE1BQUFBO0FBQUYsUUFBbUJ6SCxrQkFBekIsQ0FEK0UsQ0FHL0U7QUFDQTs7QUFDQSxVQUFNMEgsV0FBVyxHQUFHLENBQUNDLENBQUQsRUFBSUMsQ0FBSixLQUFVO0FBQzVCRCxNQUFBQSxDQUFDLEdBQUdBLENBQUMsQ0FBQ0wsU0FBTjtBQUNBTSxNQUFBQSxDQUFDLEdBQUdBLENBQUMsQ0FBQ04sU0FBTjs7QUFDQSxVQUFJSyxDQUFDLENBQUMsQ0FBRCxDQUFELEtBQVMsR0FBYixFQUFrQjtBQUNoQixZQUFJQyxDQUFDLENBQUMsQ0FBRCxDQUFELEtBQVMsR0FBYixFQUFrQjtBQUNoQixpQkFBTyxDQUFDLENBQVI7QUFDRDtBQUNGOztBQUNELFVBQUlBLENBQUMsQ0FBQyxDQUFELENBQUQsS0FBUyxHQUFiLEVBQWtCO0FBQ2hCLFlBQUlELENBQUMsQ0FBQyxDQUFELENBQUQsS0FBUyxHQUFiLEVBQWtCO0FBQ2hCLGlCQUFPLENBQVA7QUFDRDtBQUNGOztBQUNELFVBQUlBLENBQUMsS0FBS0MsQ0FBVixFQUFhO0FBQ1gsZUFBTyxDQUFQO0FBQ0QsT0FGRCxNQUVPLElBQUlELENBQUMsR0FBR0MsQ0FBUixFQUFXO0FBQ2hCLGVBQU8sQ0FBQyxDQUFSO0FBQ0QsT0FGTSxNQUVBO0FBQ0wsZUFBTyxDQUFQO0FBQ0Q7QUFDRixLQXBCRDs7QUFzQkEsV0FBTzFILFlBQVksQ0FBQzJILElBQWIsQ0FBa0JILFdBQWxCLEVBQStCSSxHQUEvQixDQUFtQ25HLFVBQVUsSUFBSTtBQUN0RCxVQUFJQyxnQkFBSjs7QUFDQSxVQUFJNkYsWUFBSixFQUFrQjtBQUNoQjdGLFFBQUFBLGdCQUFnQixHQUFHNkYsWUFBWSxDQUFDNUMsSUFBYixDQUFrQmtELENBQUMsSUFBSUEsQ0FBQyxDQUFDVCxTQUFGLEtBQWdCM0YsVUFBVSxDQUFDMkYsU0FBbEQsQ0FBbkI7QUFDRDs7QUFDRCxhQUFPLENBQUMzRixVQUFELEVBQWFDLGdCQUFiLENBQVA7QUFDRCxLQU5NLENBQVA7QUFPRDs7QUFFRCxRQUFNcEIsaUJBQU4sR0FBMEI7QUFDeEIsV0FBTyxNQUFNLGdDQUFpQixLQUFLVixLQUF0QixFQUE2QnNILE1BQTdCLENBQW9DWSxZQUFZLElBQUk7QUFDL0QsVUFBSSwyQkFBMkJDLElBQTNCLENBQWdDRCxZQUFoQyxDQUFKLEVBQW1EO0FBQ2pELGVBQU8sSUFBUDtBQUNELE9BRkQsTUFFTztBQUNMLGFBQUtwSSxHQUFMLENBQVNtRyxJQUFULENBQ0csWUFBV2lDLFlBQWEscUdBRDNCO0FBR0EsZUFBTyxLQUFQO0FBQ0Q7QUFDRixLQVRZLENBQWI7QUFVRDtBQUVEOzs7Ozs7OztBQU1BckgsRUFBQUEsc0JBQXNCLENBQUNsQixNQUFELEVBS1Y7QUFDVixVQUFNO0FBQUVTLE1BQUFBLFlBQUY7QUFBZ0JFLE1BQUFBLGtCQUFoQjtBQUFvQ0osTUFBQUEsa0JBQXBDO0FBQXdEUyxNQUFBQTtBQUF4RCxRQUFnRmhCLE1BQXRGOztBQUVBLFFBQ0VZLElBQUksQ0FBQ0MsU0FBTCxDQUFlLEtBQUtOLGtCQUFwQixNQUE0Q0ssSUFBSSxDQUFDQyxTQUFMLENBQWVOLGtCQUFmLENBQTVDLElBQ0EsS0FBS1MsbUJBQUwsS0FBNkJBLG1CQUYvQixFQUdFO0FBQ0EsVUFBSSxLQUFLUCxZQUFMLEtBQXNCQSxZQUExQixFQUF3QztBQUN0QyxlQUFPLEtBQVA7QUFDRDs7QUFFRCxVQUFJLEtBQUtFLGtCQUFMLEtBQTRCQSxrQkFBaEMsRUFBb0Q7QUFDbEQsYUFBS0YsWUFBTCxHQUFvQkEsWUFBcEI7QUFDQSxlQUFPLEtBQVA7QUFDRDtBQUNGOztBQUVELFdBQU8sSUFBUDtBQUNEOztBQXRhc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMU2NoZW1hLCBHcmFwaFFMT2JqZWN0VHlwZSwgRG9jdW1lbnROb2RlLCBHcmFwaFFMTmFtZWRUeXBlIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBzdGl0Y2hTY2hlbWFzIH0gZnJvbSAnQGdyYXBocWwtdG9vbHMvc3RpdGNoJztcbmltcG9ydCB7IFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IgfSBmcm9tICdAZ3JhcGhxbC10b29scy91dGlscyc7XG5pbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzVHlwZXMgZnJvbSAnLi9sb2FkZXJzL3BhcnNlQ2xhc3NUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzUXVlcmllcyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMnO1xuaW1wb3J0ICogYXMgcGFyc2VDbGFzc011dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMgZnJvbSAnLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0b0dyYXBoUUxFcnJvciB9IGZyb20gJy4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuaW1wb3J0ICogYXMgc2NoZW1hRGlyZWN0aXZlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFUeXBlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hVHlwZXMnO1xuaW1wb3J0IHsgZ2V0RnVuY3Rpb25OYW1lcyB9IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRSZWxheVNjaGVtYSBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hJztcblxuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9UWVBFX05BTUVTID0gW1xuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnSW50JyxcbiAgJ0Zsb2F0JyxcbiAgJ0lEJyxcbiAgJ0FycmF5UmVzdWx0JyxcbiAgJ1F1ZXJ5JyxcbiAgJ011dGF0aW9uJyxcbiAgJ1N1YnNjcmlwdGlvbicsXG4gICdDcmVhdGVGaWxlSW5wdXQnLFxuICAnQ3JlYXRlRmlsZVBheWxvYWQnLFxuICAnVmlld2VyJyxcbiAgJ1NpZ25VcElucHV0JyxcbiAgJ1NpZ25VcFBheWxvYWQnLFxuICAnTG9nSW5JbnB1dCcsXG4gICdMb2dJblBheWxvYWQnLFxuICAnTG9nT3V0SW5wdXQnLFxuICAnTG9nT3V0UGF5bG9hZCcsXG4gICdDbG91ZENvZGVGdW5jdGlvbicsXG4gICdDYWxsQ2xvdWRDb2RlSW5wdXQnLFxuICAnQ2FsbENsb3VkQ29kZVBheWxvYWQnLFxuICAnQ3JlYXRlQ2xhc3NJbnB1dCcsXG4gICdDcmVhdGVDbGFzc1BheWxvYWQnLFxuICAnVXBkYXRlQ2xhc3NJbnB1dCcsXG4gICdVcGRhdGVDbGFzc1BheWxvYWQnLFxuICAnRGVsZXRlQ2xhc3NJbnB1dCcsXG4gICdEZWxldGVDbGFzc1BheWxvYWQnLFxuICAnUGFnZUluZm8nLFxuXTtcbmNvbnN0IFJFU0VSVkVEX0dSQVBIUUxfUVVFUllfTkFNRVMgPSBbJ2hlYWx0aCcsICd2aWV3ZXInLCAnY2xhc3MnLCAnY2xhc3NlcyddO1xuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyA9IFtcbiAgJ3NpZ25VcCcsXG4gICdsb2dJbicsXG4gICdsb2dPdXQnLFxuICAnY3JlYXRlRmlsZScsXG4gICdjYWxsQ2xvdWRDb2RlJyxcbiAgJ2NyZWF0ZUNsYXNzJyxcbiAgJ3VwZGF0ZUNsYXNzJyxcbiAgJ2RlbGV0ZUNsYXNzJyxcbl07XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNjaGVtYSB7XG4gIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZztcbiAgbG9nOiBhbnk7XG4gIGFwcElkOiBzdHJpbmc7XG4gIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwYXJhbXM6IHtcbiAgICAgIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyLFxuICAgICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcjogUGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICAgIGxvZzogYW55LFxuICAgICAgYXBwSWQ6IHN0cmluZyxcbiAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKSxcbiAgICB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyID1cbiAgICAgIHBhcmFtcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyIHx8XG4gICAgICByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIgPVxuICAgICAgcGFyYW1zLmRhdGFiYXNlQ29udHJvbGxlciB8fFxuICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBkYXRhYmFzZUNvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5sb2cgPSBwYXJhbXMubG9nIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgbG9nIGluc3RhbmNlIScpO1xuICAgIHRoaXMuZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gcGFyYW1zLmdyYXBoUUxDdXN0b21UeXBlRGVmcztcbiAgICB0aGlzLmFwcElkID0gcGFyYW1zLmFwcElkIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIHRoZSBhcHBJZCEnKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgY29uc3QgeyBwYXJzZUdyYXBoUUxDb25maWcgfSA9IGF3YWl0IHRoaXMuX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKTtcbiAgICBjb25zdCBwYXJzZUNsYXNzZXMgPSBhd2FpdCB0aGlzLl9nZXRDbGFzc2VzRm9yU2NoZW1hKHBhcnNlR3JhcGhRTENvbmZpZyk7XG4gICAgY29uc3QgcGFyc2VDbGFzc2VzU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkocGFyc2VDbGFzc2VzKTtcbiAgICBjb25zdCBmdW5jdGlvbk5hbWVzID0gYXdhaXQgdGhpcy5fZ2V0RnVuY3Rpb25OYW1lcygpO1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZXNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShmdW5jdGlvbk5hbWVzKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSAmJlxuICAgICAgIXRoaXMuX2hhc1NjaGVtYUlucHV0Q2hhbmdlZCh7XG4gICAgICAgIHBhcnNlQ2xhc3NlcyxcbiAgICAgICAgcGFyc2VDbGFzc2VzU3RyaW5nLFxuICAgICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgICAgIGZ1bmN0aW9uTmFtZXNTdHJpbmcsXG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgICB9XG5cbiAgICB0aGlzLnBhcnNlQ2xhc3NlcyA9IHBhcnNlQ2xhc3NlcztcbiAgICB0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9IHBhcnNlQ2xhc3Nlc1N0cmluZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbmZpZyA9IHBhcnNlR3JhcGhRTENvbmZpZztcbiAgICB0aGlzLmZ1bmN0aW9uTmFtZXMgPSBmdW5jdGlvbk5hbWVzO1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lc1N0cmluZyA9IGZ1bmN0aW9uTmFtZXNTdHJpbmc7XG4gICAgdGhpcy5wYXJzZUNsYXNzVHlwZXMgPSB7fTtcbiAgICB0aGlzLnZpZXdlclR5cGUgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMVHlwZXMgPSBbXTtcbiAgICB0aGlzLmdyYXBoUUxRdWVyaWVzID0ge307XG4gICAgdGhpcy5ncmFwaFFMTXV0YXRpb25zID0ge307XG4gICAgdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyA9IHt9O1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNEZWZpbml0aW9ucyA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyA9IHt9O1xuICAgIHRoaXMucmVsYXlOb2RlSW50ZXJmYWNlID0gbnVsbDtcblxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0UmVsYXlTY2hlbWEubG9hZCh0aGlzKTtcbiAgICBzY2hlbWFUeXBlcy5sb2FkKHRoaXMpO1xuXG4gICAgdGhpcy5fZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyhwYXJzZUNsYXNzZXMsIHBhcnNlR3JhcGhRTENvbmZpZykuZm9yRWFjaChcbiAgICAgIChbcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZ10pID0+IHtcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NRdWVyaWVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NNdXRhdGlvbnMubG9hZCh0aGlzLCBwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5sb2FkQXJyYXlSZXN1bHQodGhpcywgcGFyc2VDbGFzc2VzKTtcbiAgICBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucy5sb2FkKHRoaXMpO1xuXG4gICAgbGV0IGdyYXBoUUxRdWVyeSA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMUXVlcmllcykubGVuZ3RoID4gMCkge1xuICAgICAgZ3JhcGhRTFF1ZXJ5ID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICAgICAgbmFtZTogJ1F1ZXJ5JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdRdWVyeSBpcyB0aGUgdG9wIGxldmVsIHR5cGUgZm9yIHF1ZXJpZXMuJyxcbiAgICAgICAgZmllbGRzOiB0aGlzLmdyYXBoUUxRdWVyaWVzLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxRdWVyeSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxNdXRhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMTXV0YXRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBncmFwaFFMTXV0YXRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnTXV0YXRpb24nLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ011dGF0aW9uIGlzIHRoZSB0b3AgbGV2ZWwgdHlwZSBmb3IgbXV0YXRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMTXV0YXRpb25zLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZ3JhcGhRTFN1YnNjcmlwdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGdyYXBoUUxTdWJzY3JpcHRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnU3Vic2NyaXB0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdTdWJzY3JpcHRpb24gaXMgdGhlIHRvcCBsZXZlbCB0eXBlIGZvciBzdWJzY3JpcHRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRHcmFwaFFMVHlwZShncmFwaFFMU3Vic2NyaXB0aW9uLCB0cnVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hID0gbmV3IEdyYXBoUUxTY2hlbWEoe1xuICAgICAgdHlwZXM6IHRoaXMuZ3JhcGhRTFR5cGVzLFxuICAgICAgcXVlcnk6IGdyYXBoUUxRdWVyeSxcbiAgICAgIG11dGF0aW9uOiBncmFwaFFMTXV0YXRpb24sXG4gICAgICBzdWJzY3JpcHRpb246IGdyYXBoUUxTdWJzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMpIHtcbiAgICAgIHNjaGVtYURpcmVjdGl2ZXMubG9hZCh0aGlzKTtcblxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5nZXRUeXBlTWFwID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlTWFwID0gdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZ2V0VHlwZU1hcCgpO1xuICAgICAgICBjb25zdCBmaW5kQW5kUmVwbGFjZUxhc3RUeXBlID0gKHBhcmVudCwga2V5KSA9PiB7XG4gICAgICAgICAgaWYgKHBhcmVudFtrZXldLm5hbWUpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpICYmXG4gICAgICAgICAgICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEuZ2V0VHlwZShwYXJlbnRba2V5XS5uYW1lKSAhPT0gcGFyZW50W2tleV1cbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAvLyBUbyBhdm9pZCB1bnJlc29sdmVkIGZpZWxkIG9uIG92ZXJsb2FkZWQgc2NoZW1hXG4gICAgICAgICAgICAgIC8vIHJlcGxhY2UgdGhlIGZpbmFsIHR5cGUgd2l0aCB0aGUgYXV0byBzY2hlbWEgb25lXG4gICAgICAgICAgICAgIHBhcmVudFtrZXldID0gdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocGFyZW50W2tleV0ub2ZUeXBlKSB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUocGFyZW50W2tleV0sICdvZlR5cGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIWF1dG9HcmFwaFFMU2NoZW1hVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5fdHlwZU1hcFtjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXSA9IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChhdXRvR3JhcGhRTFNjaGVtYVR5cGUgJiYgdHlwZW9mIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyhjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5nZXRGaWVsZHMoKSkuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUoZmllbGQsICd0eXBlJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF1dG9HcmFwaFFMU2NoZW1hVHlwZS5fZmllbGRzID0ge1xuICAgICAgICAgICAgICAuLi5hdXRvR3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCksXG4gICAgICAgICAgICAgIC4uLmN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcygpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLCB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5ncmFwaFFMU2NoZW1hID0gYXdhaXQgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMoe1xuICAgICAgICAgIGRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYTogdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLFxuICAgICAgICAgIGF1dG9TY2hlbWE6IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEsXG4gICAgICAgICAgc3RpdGNoU2NoZW1hcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzRGVmaW5pdGlvbnMsXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLFxuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZU1hcCA9IHRoaXMuZ3JhcGhRTFNjaGVtYS5nZXRUeXBlTWFwKCk7XG4gICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZU1hcCkuZm9yRWFjaChncmFwaFFMU2NoZW1hVHlwZU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZSA9IGdyYXBoUUxTY2hlbWFUeXBlTWFwW2dyYXBoUUxTY2hlbWFUeXBlTmFtZV07XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZGVmaW5pdGlvbnNcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZ3JhcGhRTEN1c3RvbVR5cGVEZWYgPSB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5kZWZpbml0aW9ucy5maW5kKFxuICAgICAgICAgICAgZGVmaW5pdGlvbiA9PiBkZWZpbml0aW9uLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlTmFtZVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGdyYXBoUUxDdXN0b21UeXBlRGVmKSB7XG4gICAgICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwID0gZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCk7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwKS5mb3JFYWNoKGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCA9IGdyYXBoUUxTY2hlbWFUeXBlRmllbGRNYXBbZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoIWdyYXBoUUxTY2hlbWFUeXBlRmllbGQuYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzdE5vZGUgPSBncmFwaFFMQ3VzdG9tVHlwZURlZi5maWVsZHMuZmluZChcbiAgICAgICAgICAgICAgICAgIGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZC5hc3ROb2RlID0gYXN0Tm9kZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IudmlzaXRTY2hlbWFEaXJlY3RpdmVzKFxuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEsXG4gICAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgfVxuXG4gIGFkZEdyYXBoUUxUeXBlKHR5cGUsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSwgaWdub3JlQ29ubmVjdGlvbiA9IGZhbHNlKSB7XG4gICAgaWYgKFxuICAgICAgKCFpZ25vcmVSZXNlcnZlZCAmJiBSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMuaW5jbHVkZXModHlwZS5uYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTFR5cGVzLmZpbmQoZXhpc3RpbmdUeXBlID0+IGV4aXN0aW5nVHlwZS5uYW1lID09PSB0eXBlLm5hbWUpIHx8XG4gICAgICAoIWlnbm9yZUNvbm5lY3Rpb24gJiYgdHlwZS5uYW1lLmVuZHNXaXRoKCdDb25uZWN0aW9uJykpXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFR5cGUgJHt0eXBlLm5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBpdCBjb2xsaWRlZCB3aXRoIGFuIGV4aXN0aW5nIHR5cGUuYDtcbiAgICAgIGlmICh0aHJvd0Vycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLndhcm4obWVzc2FnZSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLmdyYXBoUUxUeXBlcy5wdXNoKHR5cGUpO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgYWRkR3JhcGhRTFF1ZXJ5KGZpZWxkTmFtZSwgZmllbGQsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSkge1xuICAgIGlmIChcbiAgICAgICghaWdub3JlUmVzZXJ2ZWQgJiYgUkVTRVJWRURfR1JBUEhRTF9RVUVSWV9OQU1FUy5pbmNsdWRlcyhmaWVsZE5hbWUpKSB8fFxuICAgICAgdGhpcy5ncmFwaFFMUXVlcmllc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFF1ZXJ5ICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTFF1ZXJpZXNbZmllbGROYW1lXSA9IGZpZWxkO1xuICAgIHJldHVybiBmaWVsZDtcbiAgfVxuXG4gIGFkZEdyYXBoUUxNdXRhdGlvbihmaWVsZE5hbWUsIGZpZWxkLCB0aHJvd0Vycm9yID0gZmFsc2UsIGlnbm9yZVJlc2VydmVkID0gZmFsc2UpIHtcbiAgICBpZiAoXG4gICAgICAoIWlnbm9yZVJlc2VydmVkICYmIFJFU0VSVkVEX0dSQVBIUUxfTVVUQVRJT05fTkFNRVMuaW5jbHVkZXMoZmllbGROYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYE11dGF0aW9uICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdID0gZmllbGQ7XG4gICAgcmV0dXJuIGZpZWxkO1xuICB9XG5cbiAgaGFuZGxlRXJyb3IoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoJ1BhcnNlIGVycm9yOiAnLCBlcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKCdVbmNhdWdodCBpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJywgZXJyb3IsIGVycm9yLnN0YWNrKTtcbiAgICB9XG4gICAgdGhyb3cgdG9HcmFwaFFMRXJyb3IoZXJyb3IpO1xuICB9XG5cbiAgYXN5bmMgX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKSB7XG4gICAgY29uc3QgW3NjaGVtYUNvbnRyb2xsZXIsIHBhcnNlR3JhcGhRTENvbmZpZ10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci5sb2FkU2NoZW1hKCksXG4gICAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIuZ2V0R3JhcGhRTENvbmZpZygpLFxuICAgIF0pO1xuXG4gICAgdGhpcy5zY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB7XG4gICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFsbCBjbGFzc2VzIGZvdW5kIGJ5IHRoZSBgc2NoZW1hQ29udHJvbGxlcmBcbiAgICogbWludXMgdGhvc2UgZmlsdGVyZWQgb3V0IGJ5IHRoZSBhcHAncyBwYXJzZUdyYXBoUUxDb25maWcuXG4gICAqL1xuICBhc3luYyBfZ2V0Q2xhc3Nlc0ZvclNjaGVtYShwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZykge1xuICAgIGNvbnN0IHsgZW5hYmxlZEZvckNsYXNzZXMsIGRpc2FibGVkRm9yQ2xhc3NlcyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuICAgIGNvbnN0IGFsbENsYXNzZXMgPSBhd2FpdCB0aGlzLnNjaGVtYUNvbnRyb2xsZXIuZ2V0QWxsQ2xhc3NlcygpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZW5hYmxlZEZvckNsYXNzZXMpIHx8IEFycmF5LmlzQXJyYXkoZGlzYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgbGV0IGluY2x1ZGVkQ2xhc3NlcyA9IGFsbENsYXNzZXM7XG4gICAgICBpZiAoZW5hYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgaW5jbHVkZWRDbGFzc2VzID0gYWxsQ2xhc3Nlcy5maWx0ZXIoY2xhenogPT4ge1xuICAgICAgICAgIHJldHVybiBlbmFibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChkaXNhYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgLy8gQ2xhc3NlcyBpbmNsdWRlZCBpbiBgZW5hYmxlZEZvckNsYXNzZXNgIHRoYXRcbiAgICAgICAgLy8gYXJlIGFsc28gcHJlc2VudCBpbiBgZGlzYWJsZWRGb3JDbGFzc2VzYCB3aWxsXG4gICAgICAgIC8vIHN0aWxsIGJlIGZpbHRlcmVkIG91dFxuICAgICAgICBpbmNsdWRlZENsYXNzZXMgPSBpbmNsdWRlZENsYXNzZXMuZmlsdGVyKGNsYXp6ID0+IHtcbiAgICAgICAgICByZXR1cm4gIWRpc2FibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc1VzZXJzQ2xhc3NEaXNhYmxlZCA9ICFpbmNsdWRlZENsYXNzZXMuc29tZShjbGF6eiA9PiB7XG4gICAgICAgIHJldHVybiBjbGF6ei5jbGFzc05hbWUgPT09ICdfVXNlcic7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGluY2x1ZGVkQ2xhc3NlcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFsbENsYXNzZXM7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBsaXN0IG9mIHR1cGxlc1xuICAgKiB0aGF0IHByb3ZpZGUgdGhlIHBhcnNlQ2xhc3MgYWxvbmcgd2l0aFxuICAgKiBpdHMgcGFyc2VDbGFzc0NvbmZpZyB3aGVyZSBwcm92aWRlZC5cbiAgICovXG4gIF9nZXRQYXJzZUNsYXNzZXNXaXRoQ29uZmlnKHBhcnNlQ2xhc3NlcywgcGFyc2VHcmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpIHtcbiAgICBjb25zdCB7IGNsYXNzQ29uZmlncyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuXG4gICAgLy8gTWFrZSBzdXJlcyB0aGF0IHRoZSBkZWZhdWx0IGNsYXNzZXMgYW5kIGNsYXNzZXMgdGhhdFxuICAgIC8vIHN0YXJ0cyB3aXRoIGNhcGl0YWxpemVkIGxldHRlciB3aWxsIGJlIGdlbmVyYXRlZCBmaXJzdC5cbiAgICBjb25zdCBzb3J0Q2xhc3NlcyA9IChhLCBiKSA9PiB7XG4gICAgICBhID0gYS5jbGFzc05hbWU7XG4gICAgICBiID0gYi5jbGFzc05hbWU7XG4gICAgICBpZiAoYVswXSA9PT0gJ18nKSB7XG4gICAgICAgIGlmIChiWzBdICE9PSAnXycpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChiWzBdID09PSAnXycpIHtcbiAgICAgICAgaWYgKGFbMF0gIT09ICdfJykge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0gZWxzZSBpZiAoYSA8IGIpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBwYXJzZUNsYXNzZXMuc29ydChzb3J0Q2xhc3NlcykubWFwKHBhcnNlQ2xhc3MgPT4ge1xuICAgICAgbGV0IHBhcnNlQ2xhc3NDb25maWc7XG4gICAgICBpZiAoY2xhc3NDb25maWdzKSB7XG4gICAgICAgIHBhcnNlQ2xhc3NDb25maWcgPSBjbGFzc0NvbmZpZ3MuZmluZChjID0+IGMuY2xhc3NOYW1lID09PSBwYXJzZUNsYXNzLmNsYXNzTmFtZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW3BhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWddO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgX2dldEZ1bmN0aW9uTmFtZXMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IGdldEZ1bmN0aW9uTmFtZXModGhpcy5hcHBJZCkuZmlsdGVyKGZ1bmN0aW9uTmFtZSA9PiB7XG4gICAgICBpZiAoL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8udGVzdChmdW5jdGlvbk5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2cud2FybihcbiAgICAgICAgICBgRnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBHcmFwaFFMIG5hbWVzIG11c3QgbWF0Y2ggL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8uYFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBjaGFuZ2VzIHRvIHRoZSBwYXJzZUNsYXNzZXNcbiAgICogb2JqZWN0cyAoaS5lLiBkYXRhYmFzZSBzY2hlbWEpIG9yIHRvXG4gICAqIHRoZSBwYXJzZUdyYXBoUUxDb25maWcgb2JqZWN0LiBJZiBub1xuICAgKiBjaGFuZ2VzIGFyZSBmb3VuZCwgcmV0dXJuIHRydWU7XG4gICAqL1xuICBfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkKHBhcmFtczoge1xuICAgIHBhcnNlQ2xhc3NlczogYW55LFxuICAgIHBhcnNlQ2xhc3Nlc1N0cmluZzogc3RyaW5nLFxuICAgIHBhcnNlR3JhcGhRTENvbmZpZzogP1BhcnNlR3JhcGhRTENvbmZpZyxcbiAgICBmdW5jdGlvbk5hbWVzU3RyaW5nOiBzdHJpbmcsXG4gIH0pOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHBhcnNlQ2xhc3NlcywgcGFyc2VDbGFzc2VzU3RyaW5nLCBwYXJzZUdyYXBoUUxDb25maWcsIGZ1bmN0aW9uTmFtZXNTdHJpbmcgfSA9IHBhcmFtcztcblxuICAgIGlmIChcbiAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyc2VHcmFwaFFMQ29uZmlnKSA9PT0gSlNPTi5zdHJpbmdpZnkocGFyc2VHcmFwaFFMQ29uZmlnKSAmJlxuICAgICAgdGhpcy5mdW5jdGlvbk5hbWVzU3RyaW5nID09PSBmdW5jdGlvbk5hbWVzU3RyaW5nXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5wYXJzZUNsYXNzZXMgPT09IHBhcnNlQ2xhc3Nlcykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9PT0gcGFyc2VDbGFzc2VzU3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGFyc2VDbGFzc2VzID0gcGFyc2VDbGFzc2VzO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLServer.js b/lib/GraphQL/ParseGraphQLServer.js deleted file mode 100644 index 3025e6ae74..0000000000 --- a/lib/GraphQL/ParseGraphQLServer.js +++ /dev/null @@ -1,140 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseGraphQLServer = void 0; - -var _cors = _interopRequireDefault(require("cors")); - -var _bodyParser = _interopRequireDefault(require("body-parser")); - -var _graphqlUpload = require("graphql-upload"); - -var _expressApollo = require("apollo-server-express/dist/expressApollo"); - -var _graphqlPlaygroundHtml = require("@apollographql/graphql-playground-html"); - -var _graphql = require("graphql"); - -var _subscriptionsTransportWs = require("subscriptions-transport-ws"); - -var _middlewares = require("../middlewares"); - -var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); - -var _logger = _interopRequireDefault(require("../logger")); - -var _ParseGraphQLSchema = require("./ParseGraphQLSchema"); - -var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseGraphQLServer { - constructor(parseServer, config) { - this.parseServer = parseServer || (0, _requiredParameter.default)('You must provide a parseServer instance!'); - - if (!config || !config.graphQLPath) { - (0, _requiredParameter.default)('You must provide a config.graphQLPath!'); - } - - this.config = config; - this.parseGraphQLController = this.parseServer.config.parseGraphQLController; - this.log = this.parseServer.config && this.parseServer.config.loggerController || _logger.default; - this.parseGraphQLSchema = new _ParseGraphQLSchema.ParseGraphQLSchema({ - parseGraphQLController: this.parseGraphQLController, - databaseController: this.parseServer.config.databaseController, - log: this.log, - graphQLCustomTypeDefs: this.config.graphQLCustomTypeDefs, - appId: this.parseServer.config.appId - }); - } - - async _getGraphQLOptions(req) { - try { - return { - schema: await this.parseGraphQLSchema.load(), - context: { - info: req.info, - config: req.config, - auth: req.auth - }, - formatError: error => { - // Allow to console.log here to debug - return error; - } - }; - } catch (e) { - this.log.error(e.stack || typeof e.toString === 'function' && e.toString() || e); - throw e; - } - } - - _transformMaxUploadSizeToBytes(maxUploadSize) { - const unitMap = { - kb: 1, - mb: 2, - gb: 3 - }; - return Number(maxUploadSize.slice(0, -2)) * Math.pow(1024, unitMap[maxUploadSize.slice(-2).toLowerCase()]); - } - - applyGraphQL(app) { - if (!app || !app.use) { - (0, _requiredParameter.default)('You must provide an Express.js app instance!'); - } - - app.use(this.config.graphQLPath, (0, _graphqlUpload.graphqlUploadExpress)({ - maxFileSize: this._transformMaxUploadSizeToBytes(this.parseServer.config.maxUploadSize || '20mb') - })); - app.use(this.config.graphQLPath, (0, _cors.default)()); - app.use(this.config.graphQLPath, _bodyParser.default.json()); - app.use(this.config.graphQLPath, _middlewares.handleParseHeaders); - app.use(this.config.graphQLPath, _middlewares.handleParseErrors); - app.use(this.config.graphQLPath, (0, _expressApollo.graphqlExpress)(async req => await this._getGraphQLOptions(req))); - } - - applyPlayground(app) { - if (!app || !app.get) { - (0, _requiredParameter.default)('You must provide an Express.js app instance!'); - } - - app.get(this.config.playgroundPath || (0, _requiredParameter.default)('You must provide a config.playgroundPath to applyPlayground!'), (_req, res) => { - res.setHeader('Content-Type', 'text/html'); - res.write((0, _graphqlPlaygroundHtml.renderPlaygroundPage)({ - endpoint: this.config.graphQLPath, - version: '1.7.25', - subscriptionEndpoint: this.config.subscriptionsPath, - headers: { - 'X-Parse-Application-Id': this.parseServer.config.appId, - 'X-Parse-Master-Key': this.parseServer.config.masterKey - } - })); - res.end(); - }); - } - - createSubscriptions(server) { - _subscriptionsTransportWs.SubscriptionServer.create({ - execute: _graphql.execute, - subscribe: _graphql.subscribe, - onOperation: async (_message, params, webSocket) => Object.assign({}, params, await this._getGraphQLOptions(webSocket.upgradeReq)) - }, { - server, - path: this.config.subscriptionsPath || (0, _requiredParameter.default)('You must provide a config.subscriptionsPath to createSubscriptions!') - }); - } - - setGraphQLConfig(graphQLConfig) { - return this.parseGraphQLController.updateGraphQLConfig(graphQLConfig); - } - -} - -exports.ParseGraphQLServer = ParseGraphQLServer; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlci5qcyJdLCJuYW1lcyI6WyJQYXJzZUdyYXBoUUxTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInBhcnNlU2VydmVyIiwiY29uZmlnIiwiZ3JhcGhRTFBhdGgiLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImRlZmF1bHRMb2dnZXIiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJQYXJzZUdyYXBoUUxTY2hlbWEiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJncmFwaFFMQ3VzdG9tVHlwZURlZnMiLCJhcHBJZCIsIl9nZXRHcmFwaFFMT3B0aW9ucyIsInJlcSIsInNjaGVtYSIsImxvYWQiLCJjb250ZXh0IiwiaW5mbyIsImF1dGgiLCJmb3JtYXRFcnJvciIsImVycm9yIiwiZSIsInN0YWNrIiwidG9TdHJpbmciLCJfdHJhbnNmb3JtTWF4VXBsb2FkU2l6ZVRvQnl0ZXMiLCJtYXhVcGxvYWRTaXplIiwidW5pdE1hcCIsImtiIiwibWIiLCJnYiIsIk51bWJlciIsInNsaWNlIiwiTWF0aCIsInBvdyIsInRvTG93ZXJDYXNlIiwiYXBwbHlHcmFwaFFMIiwiYXBwIiwidXNlIiwibWF4RmlsZVNpemUiLCJib2R5UGFyc2VyIiwianNvbiIsImhhbmRsZVBhcnNlSGVhZGVycyIsImhhbmRsZVBhcnNlRXJyb3JzIiwiYXBwbHlQbGF5Z3JvdW5kIiwiZ2V0IiwicGxheWdyb3VuZFBhdGgiLCJfcmVxIiwicmVzIiwic2V0SGVhZGVyIiwid3JpdGUiLCJlbmRwb2ludCIsInZlcnNpb24iLCJzdWJzY3JpcHRpb25FbmRwb2ludCIsInN1YnNjcmlwdGlvbnNQYXRoIiwiaGVhZGVycyIsIm1hc3RlcktleSIsImVuZCIsImNyZWF0ZVN1YnNjcmlwdGlvbnMiLCJzZXJ2ZXIiLCJTdWJzY3JpcHRpb25TZXJ2ZXIiLCJjcmVhdGUiLCJleGVjdXRlIiwic3Vic2NyaWJlIiwib25PcGVyYXRpb24iLCJfbWVzc2FnZSIsInBhcmFtcyIsIndlYlNvY2tldCIsIk9iamVjdCIsImFzc2lnbiIsInVwZ3JhZGVSZXEiLCJwYXRoIiwic2V0R3JhcGhRTENvbmZpZyIsImdyYXBoUUxDb25maWciLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsa0JBQU4sQ0FBeUI7QUFHdkJDLEVBQUFBLFdBQVcsQ0FBQ0MsV0FBRCxFQUFjQyxNQUFkLEVBQXNCO0FBQy9CLFNBQUtELFdBQUwsR0FBbUJBLFdBQVcsSUFBSSxnQ0FBa0IsMENBQWxCLENBQWxDOztBQUNBLFFBQUksQ0FBQ0MsTUFBRCxJQUFXLENBQUNBLE1BQU0sQ0FBQ0MsV0FBdkIsRUFBb0M7QUFDbEMsc0NBQWtCLHdDQUFsQjtBQUNEOztBQUNELFNBQUtELE1BQUwsR0FBY0EsTUFBZDtBQUNBLFNBQUtFLHNCQUFMLEdBQThCLEtBQUtILFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdCRSxzQkFBdEQ7QUFDQSxTQUFLQyxHQUFMLEdBQ0csS0FBS0osV0FBTCxDQUFpQkMsTUFBakIsSUFBMkIsS0FBS0QsV0FBTCxDQUFpQkMsTUFBakIsQ0FBd0JJLGdCQUFwRCxJQUF5RUMsZUFEM0U7QUFFQSxTQUFLQyxrQkFBTCxHQUEwQixJQUFJQyxzQ0FBSixDQUF1QjtBQUMvQ0wsTUFBQUEsc0JBQXNCLEVBQUUsS0FBS0Esc0JBRGtCO0FBRS9DTSxNQUFBQSxrQkFBa0IsRUFBRSxLQUFLVCxXQUFMLENBQWlCQyxNQUFqQixDQUF3QlEsa0JBRkc7QUFHL0NMLE1BQUFBLEdBQUcsRUFBRSxLQUFLQSxHQUhxQztBQUkvQ00sTUFBQUEscUJBQXFCLEVBQUUsS0FBS1QsTUFBTCxDQUFZUyxxQkFKWTtBQUsvQ0MsTUFBQUEsS0FBSyxFQUFFLEtBQUtYLFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdC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QixDQUFnREQsYUFBaEQsQ0FBUDtBQUNEOztBQXpIc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29yc01pZGRsZXdhcmUgZnJvbSAnY29ycyc7XG5pbXBvcnQgYm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQgeyBncmFwaHFsVXBsb2FkRXhwcmVzcyB9IGZyb20gJ2dyYXBocWwtdXBsb2FkJztcbmltcG9ydCB7IGdyYXBocWxFeHByZXNzIH0gZnJvbSAnYXBvbGxvLXNlcnZlci1leHByZXNzL2Rpc3QvZXhwcmVzc0Fwb2xsbyc7XG5pbXBvcnQgeyByZW5kZXJQbGF5Z3JvdW5kUGFnZSB9IGZyb20gJ0BhcG9sbG9ncmFwaHFsL2dyYXBocWwtcGxheWdyb3VuZC1odG1sJztcbmltcG9ydCB7IGV4ZWN1dGUsIHN1YnNjcmliZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uU2VydmVyIH0gZnJvbSAnc3Vic2NyaXB0aW9ucy10cmFuc3BvcnQtd3MnO1xuaW1wb3J0IHsgaGFuZGxlUGFyc2VFcnJvcnMsIGhhbmRsZVBhcnNlSGVhZGVycyB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuLi9yZXF1aXJlZFBhcmFtZXRlcic7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH0gZnJvbSAnLi9QYXJzZUdyYXBoUUxTY2hlbWEnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNlcnZlciB7XG4gIHBhcnNlR3JhcGhRTENvbnRyb2xsZXI6IFBhcnNlR3JhcGhRTENvbnRyb2xsZXI7XG5cbiAgY29uc3RydWN0b3IocGFyc2VTZXJ2ZXIsIGNvbmZpZykge1xuICAgIHRoaXMucGFyc2VTZXJ2ZXIgPSBwYXJzZVNlcnZlciB8fCByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlU2VydmVyIGluc3RhbmNlIScpO1xuICAgIGlmICghY29uZmlnIHx8ICFjb25maWcuZ3JhcGhRTFBhdGgpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgY29uZmlnLmdyYXBoUUxQYXRoIScpO1xuICAgIH1cbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICAgIHRoaXMubG9nID1cbiAgICAgICh0aGlzLnBhcnNlU2VydmVyLmNvbmZpZyAmJiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB8fCBkZWZhdWx0TG9nZ2VyO1xuICAgIHRoaXMucGFyc2VHcmFwaFFMU2NoZW1hID0gbmV3IFBhcnNlR3JhcGhRTFNjaGVtYSh7XG4gICAgICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIsXG4gICAgICBkYXRhYmFzZUNvbnRyb2xsZXI6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLmRhdGFiYXNlQ29udHJvbGxlcixcbiAgICAgIGxvZzogdGhpcy5sb2csXG4gICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnM6IHRoaXMuY29uZmlnLmdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIGFwcElkOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIF9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2NoZW1hOiBhd2FpdCB0aGlzLnBhcnNlR3JhcGhRTFNjaGVtYS5sb2FkKCksXG4gICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICBpbmZvOiByZXEuaW5mbyxcbiAgICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgICAgYXV0aDogcmVxLmF1dGgsXG4gICAgICAgIH0sXG4gICAgICAgIGZvcm1hdEVycm9yOiBlcnJvciA9PiB7XG4gICAgICAgICAgLy8gQWxsb3cgdG8gY29uc29sZS5sb2cgaGVyZSB0byBkZWJ1Z1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoZS5zdGFjayB8fCAodHlwZW9mIGUudG9TdHJpbmcgPT09ICdmdW5jdGlvbicgJiYgZS50b1N0cmluZygpKSB8fCBlKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKG1heFVwbG9hZFNpemUpIHtcbiAgICBjb25zdCB1bml0TWFwID0ge1xuICAgICAga2I6IDEsXG4gICAgICBtYjogMixcbiAgICAgIGdiOiAzLFxuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgTnVtYmVyKG1heFVwbG9hZFNpemUuc2xpY2UoMCwgLTIpKSAqXG4gICAgICBNYXRoLnBvdygxMDI0LCB1bml0TWFwW21heFVwbG9hZFNpemUuc2xpY2UoLTIpLnRvTG93ZXJDYXNlKCldKVxuICAgICk7XG4gIH1cblxuICBhcHBseUdyYXBoUUwoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC51c2UpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cblxuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxVcGxvYWRFeHByZXNzKHtcbiAgICAgICAgbWF4RmlsZVNpemU6IHRoaXMuX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKFxuICAgICAgICAgIHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1heFVwbG9hZFNpemUgfHwgJzIwbWInXG4gICAgICAgICksXG4gICAgICB9KVxuICAgICk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgY29yc01pZGRsZXdhcmUoKSk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgYm9keVBhcnNlci5qc29uKCkpO1xuICAgIGFwcC51c2UodGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsIGhhbmRsZVBhcnNlSGVhZGVycyk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgaGFuZGxlUGFyc2VFcnJvcnMpO1xuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxFeHByZXNzKGFzeW5jIHJlcSA9PiBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpKVxuICAgICk7XG4gIH1cblxuICBhcHBseVBsYXlncm91bmQoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC5nZXQpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cbiAgICBhcHAuZ2V0KFxuICAgICAgdGhpcy5jb25maWcucGxheWdyb3VuZFBhdGggfHxcbiAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcucGxheWdyb3VuZFBhdGggdG8gYXBwbHlQbGF5Z3JvdW5kIScpLFxuICAgICAgKF9yZXEsIHJlcykgPT4ge1xuICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgIHJlcy53cml0ZShcbiAgICAgICAgICByZW5kZXJQbGF5Z3JvdW5kUGFnZSh7XG4gICAgICAgICAgICBlbmRwb2ludDogdGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS43LjI1JyxcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbkVuZHBvaW50OiB0aGlzLmNvbmZpZy5zdWJzY3JpcHRpb25zUGF0aCxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtTWFzdGVyLUtleSc6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1hc3RlcktleSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBjcmVhdGVTdWJzY3JpcHRpb25zKHNlcnZlcikge1xuICAgIFN1YnNjcmlwdGlvblNlcnZlci5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIGV4ZWN1dGUsXG4gICAgICAgIHN1YnNjcmliZSxcbiAgICAgICAgb25PcGVyYXRpb246IGFzeW5jIChfbWVzc2FnZSwgcGFyYW1zLCB3ZWJTb2NrZXQpID0+XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgcGFyYW1zLCBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyh3ZWJTb2NrZXQudXBncmFkZVJlcSkpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBwYXRoOlxuICAgICAgICAgIHRoaXMuY29uZmlnLnN1YnNjcmlwdGlvbnNQYXRoIHx8XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcuc3Vic2NyaXB0aW9uc1BhdGggdG8gY3JlYXRlU3Vic2NyaXB0aW9ucyEnKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgc2V0R3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpOiBQcm9taXNlIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZyk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsMutations.js b/lib/GraphQL/helpers/objectsMutations.js deleted file mode 100644 index 4d10d2fb4a..0000000000 --- a/lib/GraphQL/helpers/objectsMutations.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.deleteObject = exports.updateObject = exports.createObject = void 0; - -var _rest = _interopRequireDefault(require("../../rest")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const createObject = async (className, fields, config, auth, info) => { - if (!fields) { - fields = {}; - } - - return (await _rest.default.create(config, auth, className, fields, info.clientSDK, info.context)).response; -}; - -exports.createObject = createObject; - -const updateObject = async (className, objectId, fields, config, auth, info) => { - if (!fields) { - fields = {}; - } - - return (await _rest.default.update(config, auth, className, { - objectId - }, fields, info.clientSDK, info.context)).response; -}; - -exports.updateObject = updateObject; - -const deleteObject = async (className, objectId, config, auth, info) => { - await _rest.default.del(config, auth, className, objectId, info.context); - return true; -}; - -exports.deleteObject = deleteObject; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJjcmVhdGVPYmplY3QiLCJjbGFzc05hbWUiLCJmaWVsZHMiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInJlc3QiLCJjcmVhdGUiLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzcG9uc2UiLCJ1cGRhdGVPYmplY3QiLCJvYmplY3RJZCIsInVwZGF0ZSIsImRlbGV0ZU9iamVjdCIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsTUFBTUEsWUFBWSxHQUFHLE9BQU9DLFNBQVAsRUFBa0JDLE1BQWxCLEVBQTBCQyxNQUExQixFQUFrQ0MsSUFBbEMsRUFBd0NDLElBQXhDLEtBQWlEO0FBQ3BFLE1BQUksQ0FBQ0gsTUFBTCxFQUFhO0FBQ1hBLElBQUFBLE1BQU0sR0FBRyxFQUFUO0FBQ0Q7O0FBRUQsU0FBTyxDQUNMLE1BQU1JLGNBQUtDLE1BQUwsQ0FDSkosTUFESSxFQUVKQyxJQUZJLEVBR0pILFNBSEksRUFJSkMsTUFKSSxFQUtKRyxJQUFJLENBQUNHLFNBTEQsRUFNSkgsSUFBSSxDQUFDSSxPQU5ELENBREQsRUFTTEMsUUFURjtBQVVELENBZkQ7Ozs7QUFpQkEsTUFBTUMsWUFBWSxHQUFHLE9BQ25CVixTQURtQixFQUVuQlcsUUFGbUIsRUFHbkJWLE1BSG1CLEVBSW5CQyxNQUptQixFQUtuQkMsSUFMbUIsRUFNbkJDLElBTm1CLEtBT2hCO0FBQ0gsTUFBSSxDQUFDSCxNQUFMLEVBQWE7QUFDWEEsSUFBQUEsTUFBTSxHQUFHLEVBQVQ7QUFDRDs7QUFFRCxTQUFPLENBQ0wsTUFBTUksY0FBS08sTUFBTCxDQUNKVixNQURJLEVBRUpDLElBRkksRUFHSkgsU0FISSxFQUlKO0FBQUVXLElBQUFBO0FBQUYsR0FKSSxFQUtKVixNQUxJLEVBTUpHLElBQUksQ0FBQ0csU0FORCxFQU9KSCxJQUFJLENBQUNJLE9BUEQsQ0FERCxFQVVMQyxRQVZGO0FBV0QsQ0F2QkQ7Ozs7QUF5QkEsTUFBTUksWUFBWSxHQUFHLE9BQU9iLFNBQVAsRUFBa0JXLFFBQWxCLEVBQTRCVCxNQUE1QixFQUFvQ0MsSUFBcEMsRUFBMENDLElBQTFDLEtBQW1EO0FBQ3RFLFFBQU1DLGNBQUtTLEdBQUwsQ0FBU1osTUFBVCxFQUFpQkMsSUFBakIsRUFBdUJILFNBQXZCLEVBQWtDVyxRQUFsQyxFQUE0Q1AsSUFBSSxDQUFDSSxPQUFqRCxDQUFOO0FBQ0EsU0FBTyxJQUFQO0FBQ0QsQ0FIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuXG5jb25zdCBjcmVhdGVPYmplY3QgPSBhc3luYyAoY2xhc3NOYW1lLCBmaWVsZHMsIGNvbmZpZywgYXV0aCwgaW5mbykgPT4ge1xuICBpZiAoIWZpZWxkcykge1xuICAgIGZpZWxkcyA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICBhd2FpdCByZXN0LmNyZWF0ZShcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBmaWVsZHMsXG4gICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgIGluZm8uY29udGV4dFxuICAgIClcbiAgKS5yZXNwb25zZTtcbn07XG5cbmNvbnN0IHVwZGF0ZU9iamVjdCA9IGFzeW5jIChcbiAgY2xhc3NOYW1lLFxuICBvYmplY3RJZCxcbiAgZmllbGRzLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm9cbikgPT4ge1xuICBpZiAoIWZpZWxkcykge1xuICAgIGZpZWxkcyA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICBhd2FpdCByZXN0LnVwZGF0ZShcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB7IG9iamVjdElkIH0sXG4gICAgICBmaWVsZHMsXG4gICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgIGluZm8uY29udGV4dFxuICAgIClcbiAgKS5yZXNwb25zZTtcbn07XG5cbmNvbnN0IGRlbGV0ZU9iamVjdCA9IGFzeW5jIChjbGFzc05hbWUsIG9iamVjdElkLCBjb25maWcsIGF1dGgsIGluZm8pID0+IHtcbiAgYXdhaXQgcmVzdC5kZWwoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCBpbmZvLmNvbnRleHQpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmV4cG9ydCB7IGNyZWF0ZU9iamVjdCwgdXBkYXRlT2JqZWN0LCBkZWxldGVPYmplY3QgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsQueries.js b/lib/GraphQL/helpers/objectsQueries.js deleted file mode 100644 index b62de58245..0000000000 --- a/lib/GraphQL/helpers/objectsQueries.js +++ /dev/null @@ -1,307 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.needToGetAllKeys = exports.calculateSkipAndLimit = exports.findObjects = exports.getObject = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphqlRelay = require("graphql-relay"); - -var _rest = _interopRequireDefault(require("../../rest")); - -var _query = require("../transformers/query"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Eslint/Prettier conflict - -/* eslint-disable*/ -const needToGetAllKeys = (fields, keys, parseClasses) => keys ? keys.split(',').some(keyName => { - const key = keyName.split('.'); - - if (fields[key[0]]) { - if (fields[key[0]].type === 'Pointer') { - const subClass = parseClasses.find(({ - className: parseClassName - }) => fields[key[0]].targetClass === parseClassName); - - if (subClass && subClass.fields[key[1]]) { - // Current sub key is not custom - return false; - } - } else if (!key[1] || fields[key[0]].type === 'Array' || fields[key[0]].type === 'Object') { - // current key is not custom - return false; - } - } // Key not found into Parse Schema so it's custom - - - return true; -}) : true; -/* eslint-enable*/ - - -exports.needToGetAllKeys = needToGetAllKeys; - -const getObject = async (className, objectId, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses) => { - const options = {}; - - try { - if (!needToGetAllKeys(parseClasses.find(({ - className: parseClassName - }) => className === parseClassName).fields, keys, parseClasses)) { - options.keys = keys; - } - } catch (e) { - console.log(e); - } - - if (include) { - options.include = include; - - if (includeReadPreference) { - options.includeReadPreference = includeReadPreference; - } - } - - if (readPreference) { - options.readPreference = readPreference; - } - - const response = await _rest.default.get(config, auth, className, objectId, options, info.clientSDK, info.context); - - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - const object = response.results[0]; - - if (className === '_User') { - delete object.sessionToken; - } - - return object; -}; - -exports.getObject = getObject; - -const findObjects = async (className, where, order, skipInput, first, after, last, before, keys, include, includeAll, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseClasses) => { - if (!where) { - where = {}; - } - - (0, _query.transformQueryInputToParse)(where, className, parseClasses); - const skipAndLimitCalculation = calculateSkipAndLimit(skipInput, first, after, last, before, config.maxLimit); - let { - skip - } = skipAndLimitCalculation; - const { - limit, - needToPreCount - } = skipAndLimitCalculation; - let preCount = undefined; - - if (needToPreCount) { - const preCountOptions = { - limit: 0, - count: true - }; - - if (readPreference) { - preCountOptions.readPreference = readPreference; - } - - if (Object.keys(where).length > 0 && subqueryReadPreference) { - preCountOptions.subqueryReadPreference = subqueryReadPreference; - } - - preCount = (await _rest.default.find(config, auth, className, where, preCountOptions, info.clientSDK, info.context)).count; - - if ((skip || 0) + limit < preCount) { - skip = preCount - limit; - } - } - - const options = {}; - - if (selectedFields.find(field => field.startsWith('edges.') || field.startsWith('pageInfo.'))) { - if (limit || limit === 0) { - options.limit = limit; - } else { - options.limit = 100; - } - - if (options.limit !== 0) { - if (order) { - options.order = order; - } - - if (skip) { - options.skip = skip; - } - - if (config.maxLimit && options.limit > config.maxLimit) { - // Silently replace the limit on the query with the max configured - options.limit = config.maxLimit; - } - - if (!needToGetAllKeys(parseClasses.find(({ - className: parseClassName - }) => className === parseClassName).fields, keys, parseClasses)) { - options.keys = keys; - } - - if (includeAll === true) { - options.includeAll = includeAll; - } - - if (!options.includeAll && include) { - options.include = include; - } - - if ((options.includeAll || options.include) && includeReadPreference) { - options.includeReadPreference = includeReadPreference; - } - } - } else { - options.limit = 0; - } - - if ((selectedFields.includes('count') || selectedFields.includes('pageInfo.hasPreviousPage') || selectedFields.includes('pageInfo.hasNextPage')) && !needToPreCount) { - options.count = true; - } - - if (readPreference) { - options.readPreference = readPreference; - } - - if (Object.keys(where).length > 0 && subqueryReadPreference) { - options.subqueryReadPreference = subqueryReadPreference; - } - - let results, count; - - if (options.count || !options.limit || options.limit && options.limit > 0) { - const findResult = await _rest.default.find(config, auth, className, where, options, info.clientSDK, info.context); - results = findResult.results; - count = findResult.count; - } - - let edges = null; - let pageInfo = null; - - if (results) { - edges = results.map((result, index) => ({ - cursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + index), - node: result - })); - pageInfo = { - hasPreviousPage: (preCount && preCount > 0 || count && count > 0) && skip !== undefined && skip > 0, - startCursor: (0, _graphqlRelay.offsetToCursor)(skip || 0), - endCursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + (results.length || 1) - 1), - hasNextPage: (preCount || count) > (skip || 0) + results.length - }; - } - - return { - edges, - pageInfo, - count: preCount || count - }; -}; - -exports.findObjects = findObjects; - -const calculateSkipAndLimit = (skipInput, first, after, last, before, maxLimit) => { - let skip = undefined; - let limit = undefined; - let needToPreCount = false; // Validates the skip input - - if (skipInput || skipInput === 0) { - if (skipInput < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Skip should be a positive number'); - } - - skip = skipInput; - } // Validates the after param - - - if (after) { - after = (0, _graphqlRelay.cursorToOffset)(after); - - if (!after && after !== 0 || after < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'After is not a valid cursor'); - } // If skip and after are passed, a new skip is calculated by adding them - - - skip = (skip || 0) + (after + 1); - } // Validates the first param - - - if (first || first === 0) { - if (first < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'First should be a positive number'); - } // The first param is translated to the limit param of the Parse legacy API - - - limit = first; - } // Validates the before param - - - if (before || before === 0) { - // This method converts the cursor to the index of the object - before = (0, _graphqlRelay.cursorToOffset)(before); - - if (!before && before !== 0 || before < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Before is not a valid cursor'); - } - - if ((skip || 0) >= before) { - // If the before index is less then the skip, no objects will be returned - limit = 0; - } else if (!limit && limit !== 0 || (skip || 0) + limit > before) { - // If there is no limit set, the limit is calculated. Or, if the limit (plus skip) is bigger than the before index, the new limit is set. - limit = before - (skip || 0); - } - } // Validates the last param - - - if (last || last === 0) { - if (last < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Last should be a positive number'); - } - - if (last > maxLimit) { - // Last can't be bigger than Parse server maxLimit config. - last = maxLimit; - } - - if (limit || limit === 0) { - // If there is a previous limit set, it may be adjusted - if (last < limit) { - // if last is less than the current limit - skip = (skip || 0) + (limit - last); // The skip is adjusted - - limit = last; // the limit is adjusted - } - } else if (last === 0) { - // No objects will be returned - limit = 0; - } else { - // No previous limit set, the limit will be equal to last and pre count is needed. - limit = last; - needToPreCount = true; - } - } - - return { - skip, - limit, - needToPreCount - }; -}; - -exports.calculateSkipAndLimit = calculateSkipAndLimit; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMuanMiXSwibmFtZXMiOlsibmVlZFRvR2V0QWxsS2V5cyIsImZpZWxkcyIsImtleXMiLCJwYXJzZUNsYXNzZXMiLCJzcGxpdCIsInNvbWUiLCJrZXlOYW1lIiwia2V5IiwidHlwZSIsInN1YkNsYXNzIiwiZmluZCIsImNsYXNzTmFtZSIsInBhcnNlQ2xhc3NOYW1lIiwidGFyZ2V0Q2xhc3MiLCJnZXRPYmplY3QiLCJvYmplY3RJZCIsImluY2x1ZGUiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwib3B0aW9ucyIsImUiLCJjb25zb2xlIiwibG9nIiwicmVzcG9uc2UiLCJyZXN0IiwiZ2V0IiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIm9iamVjdCIsInNlc3Npb25Ub2tlbiIsImZpbmRPYmplY3RzIiwid2hlcmUiLCJvcmRlciIsInNraXBJbnB1dCIsImZpcnN0IiwiYWZ0ZXIiLCJsYXN0IiwiYmVmb3JlIiwiaW5jbHVkZUFsbCIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJzZWxlY3RlZEZpZWxkcyIsInNraXBBbmRMaW1pdENhbGN1bGF0aW9uIiwiY2FsY3VsYXRlU2tpcEFuZExpbWl0IiwibWF4TGltaXQiLCJza2lwIiwibGltaXQiLCJuZWVkVG9QcmVDb3VudCIsInByZUNvdW50IiwidW5kZWZpbmVkIiwicHJlQ291bnRPcHRpb25zIiwiY291bnQiLCJPYmplY3QiLCJmaWVsZCIsInN0YXJ0c1dpdGgiLCJpbmNsdWRlcyIsImZpbmRSZXN1bHQiLCJlZGdlcyIsInBhZ2VJbmZvIiwibWFwIiwicmVzdWx0IiwiaW5kZXgiLCJjdXJzb3IiLCJub2RlIiwiaGFzUHJldmlvdXNQYWdlIiwic3RhcnRDdXJzb3IiLCJl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Q0YsS0FQRCxNQU9PLElBQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ3JCO0FBQ0FTLE1BQUFBLEtBQUssR0FBRyxDQUFSO0FBQ0QsS0FITSxNQUdBO0FBQ0w7QUFDQUEsTUFBQUEsS0FBSyxHQUFHVCxJQUFSO0FBQ0FVLE1BQUFBLGNBQWMsR0FBRyxJQUFqQjtBQUNEO0FBQ0Y7O0FBQ0QsU0FBTztBQUNMRixJQUFBQSxJQURLO0FBRUxDLElBQUFBLEtBRks7QUFHTEMsSUFBQUE7QUFISyxHQUFQO0FBS0QsQ0F6R0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBvZmZzZXRUb0N1cnNvciwgY3Vyc29yVG9PZmZzZXQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuaW1wb3J0IHsgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvcXVlcnknO1xuXG4vLyBFc2xpbnQvUHJldHRpZXIgY29uZmxpY3Rcbi8qIGVzbGludC1kaXNhYmxlKi9cbmNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSAoZmllbGRzLCBrZXlzLCBwYXJzZUNsYXNzZXMpID0+XG4gIGtleXNcbiAgICA/IGtleXMuc3BsaXQoJywnKS5zb21lKGtleU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlOYW1lLnNwbGl0KCcuJyk7XG4gICAgICAgIGlmIChmaWVsZHNba2V5WzBdXSkge1xuICAgICAgICAgIGlmIChmaWVsZHNba2V5WzBdXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1YkNsYXNzID0gcGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgICAgICAgICAgICh7IGNsYXNzTmFtZTogcGFyc2VDbGFzc05hbWUgfSkgPT5cbiAgICAgICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50YXJnZXRDbGFzcyA9PT0gcGFyc2VDbGFzc05hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoc3ViQ2xhc3MgJiYgc3ViQ2xhc3MuZmllbGRzW2tleVsxXV0pIHtcbiAgICAgICAgICAgICAgLy8gQ3VycmVudCBzdWIga2V5IGlzIG5vdCBjdXN0b21cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAha2V5WzFdIHx8XG4gICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50eXBlID09PSAnQXJyYXknIHx8XG4gICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50eXBlID09PSAnT2JqZWN0J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gY3VycmVudCBrZXkgaXMgbm90IGN1c3RvbVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBLZXkgbm90IGZvdW5kIGludG8gUGFyc2UgU2NoZW1hIHNvIGl0J3MgY3VzdG9tXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSlcbiAgICA6IHRydWU7XG4vKiBlc2xpbnQtZW5hYmxlKi9cblxuY29uc3QgZ2V0T2JqZWN0ID0gYXN5bmMgKFxuICBjbGFzc05hbWUsXG4gIG9iamVjdElkLFxuICBrZXlzLFxuICBpbmNsdWRlLFxuICByZWFkUHJlZmVyZW5jZSxcbiAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm8sXG4gIHBhcnNlQ2xhc3Nlc1xuKSA9PiB7XG4gIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgdHJ5IHtcbiAgICBpZiAoXG4gICAgICAhbmVlZFRvR2V0QWxsS2V5cyhcbiAgICAgICAgcGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgICAgICAgKHsgY2xhc3NOYW1lOiBwYXJzZUNsYXNzTmFtZSB9KSA9PiBjbGFzc05hbWUgPT09IHBhcnNlQ2xhc3NOYW1lXG4gICAgICAgICkuZmllbGRzLFxuICAgICAgICBrZXlzLFxuICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgIClcbiAgICApIHtcbiAgICAgIG9wdGlvbnMua2V5cyA9IGtleXM7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5sb2coZSk7XG4gIH1cbiAgaWYgKGluY2x1ZGUpIHtcbiAgICBvcHRpb25zLmluY2x1ZGUgPSBpbmNsdWRlO1xuICAgIGlmIChpbmNsdWRlUmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgfVxuICBpZiAocmVhZFByZWZlcmVuY2UpIHtcbiAgICBvcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlc3QuZ2V0KFxuICAgIGNvbmZpZyxcbiAgICBhdXRoLFxuICAgIGNsYXNzTmFtZSxcbiAgICBvYmplY3RJZCxcbiAgICBvcHRpb25zLFxuICAgIGluZm8uY2xpZW50U0RLLFxuICAgIGluZm8uY29udGV4dFxuICApO1xuXG4gIGlmICghcmVzcG9uc2UucmVzdWx0cyB8fCByZXNwb25zZS5yZXN1bHRzLmxlbmd0aCA9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICB9XG5cbiAgY29uc3Qgb2JqZWN0ID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCBmaW5kT2JqZWN0cyA9IGFzeW5jIChcbiAgY2xhc3NOYW1lLFxuICB3aGVyZSxcbiAgb3JkZXIsXG4gIHNraXBJbnB1dCxcbiAgZmlyc3QsXG4gIGFmdGVyLFxuICBsYXN0LFxuICBiZWZvcmUsXG4gIGtleXMsXG4gIGluY2x1ZGUsXG4gIGluY2x1ZGVBbGwsXG4gIHJlYWRQcmVmZXJlbmNlLFxuICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgaW5mbyxcbiAgc2VsZWN0ZWRGaWVsZHMsXG4gIHBhcnNlQ2xhc3Nlc1xuKSA9PiB7XG4gIGlmICghd2hlcmUpIHtcbiAgICB3aGVyZSA9IHt9O1xuICB9XG4gIHRyYW5zZm9ybVF1ZXJ5SW5wdXRUb1BhcnNlKHdoZXJlLCBjbGFzc05hbWUsIHBhcnNlQ2xhc3Nlcyk7XG4gIGNvbnN0IHNraXBBbmRMaW1pdENhbGN1bGF0aW9uID0gY2FsY3VsYXRlU2tpcEFuZExpbWl0KFxuICAgIHNraXBJbnB1dCxcbiAgICBmaXJzdCxcbiAgICBhZnRlcixcbiAgICBsYXN0LFxuICAgIGJlZm9yZSxcbiAgICBjb25maWcubWF4TGltaXRcbiAgKTtcbiAgbGV0IHsgc2tpcCB9ID0gc2tpcEFuZExpbWl0Q2FsY3VsYXRpb247XG4gIGNvbnN0IHsgbGltaXQsIG5lZWRUb1ByZUNvdW50IH0gPSBza2lwQW5kTGltaXRDYWxjdWxhdGlvbjtcbiAgbGV0IHByZUNvdW50ID0gdW5kZWZpbmVkO1xuICBpZiAobmVlZFRvUHJlQ291bnQpIHtcbiAgICBjb25zdCBwcmVDb3VudE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMCxcbiAgICAgIGNvdW50OiB0cnVlLFxuICAgIH07XG4gICAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBwcmVDb3VudE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5rZXlzKHdoZXJlKS5sZW5ndGggPiAwICYmIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHByZUNvdW50T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgcHJlQ291bnQgPSAoXG4gICAgICBhd2FpdCByZXN0LmZpbmQoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICB3aGVyZSxcbiAgICAgICAgcHJlQ291bnRPcHRpb25zLFxuICAgICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgICAgaW5mby5jb250ZXh0XG4gICAgICApXG4gICAgKS5jb3VudDtcbiAgICBpZiAoKHNraXAgfHwgMCkgKyBsaW1pdCA8IHByZUNvdW50KSB7XG4gICAgICBza2lwID0gcHJlQ291bnQgLSBsaW1pdDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0ge307XG5cbiAgaWYgKFxuICAgIHNlbGVjdGVkRmllbGRzLmZpbmQoXG4gICAgICBmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKCdlZGdlcy4nKSB8fCBmaWVsZC5zdGFydHNXaXRoKCdwYWdlSW5mby4nKVxuICAgIClcbiAgKSB7XG4gICAgaWYgKGxpbWl0IHx8IGxpbWl0ID09PSAwKSB7XG4gICAgICBvcHRpb25zLmxpbWl0ID0gbGltaXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSAxMDA7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxpbWl0ICE9PSAwKSB7XG4gICAgICBpZiAob3JkZXIpIHtcbiAgICAgICAgb3B0aW9ucy5vcmRlciA9IG9yZGVyO1xuICAgICAgfVxuICAgICAgaWYgKHNraXApIHtcbiAgICAgICAgb3B0aW9ucy5za2lwID0gc2tpcDtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcubWF4TGltaXQgJiYgb3B0aW9ucy5saW1pdCA+IGNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgICAvLyBTaWxlbnRseSByZXBsYWNlIHRoZSBsaW1pdCBvbiB0aGUgcXVlcnkgd2l0aCB0aGUgbWF4IGNvbmZpZ3VyZWRcbiAgICAgICAgb3B0aW9ucy5saW1pdCA9IGNvbmZpZy5tYXhMaW1pdDtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIW5lZWRUb0dldEFsbEtleXMoXG4gICAgICAgICAgcGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgICAgICAgICAoeyBjbGFzc05hbWU6IHBhcnNlQ2xhc3NOYW1lIH0pID0+IGNsYXNzTmFtZSA9PT0gcGFyc2VDbGFzc05hbWVcbiAgICAgICAgICApLmZpZWxkcyxcbiAgICAgICAgICBrZXlzLFxuICAgICAgICAgIHBhcnNlQ2xhc3Nlc1xuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgb3B0aW9ucy5rZXlzID0ga2V5cztcbiAgICAgIH1cbiAgICAgIGlmIChpbmNsdWRlQWxsID09PSB0cnVlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IGluY2x1ZGVBbGw7XG4gICAgICB9XG4gICAgICBpZiAoIW9wdGlvbnMuaW5jbHVkZUFsbCAmJiBpbmNsdWRlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZSA9IGluY2x1ZGU7XG4gICAgICB9XG4gICAgICBpZiAoKG9wdGlvbnMuaW5jbHVkZUFsbCB8fCBvcHRpb25zLmluY2x1ZGUpICYmIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgb3B0aW9ucy5saW1pdCA9IDA7XG4gIH1cblxuICBpZiAoXG4gICAgKHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdjb3VudCcpIHx8XG4gICAgICBzZWxlY3RlZEZpZWxkcy5pbmNsdWRlcygncGFnZUluZm8uaGFzUHJldmlvdXNQYWdlJykgfHxcbiAgICAgIHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdwYWdlSW5mby5oYXNOZXh0UGFnZScpKSAmJlxuICAgICFuZWVkVG9QcmVDb3VudFxuICApIHtcbiAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChyZWFkUHJlZmVyZW5jZSkge1xuICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZWFkUHJlZmVyZW5jZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMod2hlcmUpLmxlbmd0aCA+IDAgJiYgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBsZXQgcmVzdWx0cywgY291bnQ7XG4gIGlmIChvcHRpb25zLmNvdW50IHx8ICFvcHRpb25zLmxpbWl0IHx8IChvcHRpb25zLmxpbWl0ICYmIG9wdGlvbnMubGltaXQgPiAwKSkge1xuICAgIGNvbnN0IGZpbmRSZXN1bHQgPSBhd2FpdCByZXN0LmZpbmQoXG4gICAgICBjb25maWcsXG4gICAgICBhdXRoLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgd2hlcmUsXG4gICAgICBvcHRpb25zLFxuICAgICAgaW5mby5jbGllbnRTREssXG4gICAgICBpbmZvLmNvbnRleHRcbiAgICApO1xuICAgIHJlc3VsdHMgPSBmaW5kUmVzdWx0LnJlc3VsdHM7XG4gICAgY291bnQgPSBmaW5kUmVzdWx0LmNvdW50O1xuICB9XG5cbiAgbGV0IGVkZ2VzID0gbnVsbDtcbiAgbGV0IHBhZ2VJbmZvID0gbnVsbDtcbiAgaWYgKHJlc3VsdHMpIHtcbiAgICBlZGdlcyA9IHJlc3VsdHMubWFwKChyZXN1bHQsIGluZGV4KSA9PiAoe1xuICAgICAgY3Vyc29yOiBvZmZzZXRUb0N1cnNvcigoc2tpcCB8fCAwKSArIGluZGV4KSxcbiAgICAgIG5vZGU6IHJlc3VsdCxcbiAgICB9KSk7XG5cbiAgICBwYWdlSW5mbyA9IHtcbiAgICAgIGhhc1ByZXZpb3VzUGFnZTpcbiAgICAgICAgKChwcmVDb3VudCAmJiBwcmVDb3VudCA+IDApIHx8IChjb3VudCAmJiBjb3VudCA+IDApKSAmJlxuICAgICAgICBza2lwICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgc2tpcCA+IDAsXG4gICAgICBzdGFydEN1cnNvcjogb2Zmc2V0VG9DdXJzb3Ioc2tpcCB8fCAwKSxcbiAgICAgIGVuZEN1cnNvcjogb2Zmc2V0VG9DdXJzb3IoKHNraXAgfHwgMCkgKyAocmVzdWx0cy5sZW5ndGggfHwgMSkgLSAxKSxcbiAgICAgIGhhc05leHRQYWdlOiAocHJlQ291bnQgfHwgY291bnQpID4gKHNraXAgfHwgMCkgKyByZXN1bHRzLmxlbmd0aCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlZGdlcyxcbiAgICBwYWdlSW5mbyxcbiAgICBjb3VudDogcHJlQ291bnQgfHwgY291bnQsXG4gIH07XG59O1xuXG5jb25zdCBjYWxjdWxhdGVTa2lwQW5kTGltaXQgPSAoXG4gIHNraXBJbnB1dCxcbiAgZmlyc3QsXG4gIGFmdGVyLFxuICBsYXN0LFxuICBiZWZvcmUsXG4gIG1heExpbWl0XG4pID0+IHtcbiAgbGV0IHNraXAgPSB1bmRlZmluZWQ7XG4gIGxldCBsaW1pdCA9IHVuZGVmaW5lZDtcbiAgbGV0IG5lZWRUb1ByZUNvdW50ID0gZmFsc2U7XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBza2lwIGlucHV0XG4gIGlmIChza2lwSW5wdXQgfHwgc2tpcElucHV0ID09PSAwKSB7XG4gICAgaWYgKHNraXBJbnB1dCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgJ1NraXAgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyJ1xuICAgICAgKTtcbiAgICB9XG4gICAgc2tpcCA9IHNraXBJbnB1dDtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgYWZ0ZXIgcGFyYW1cbiAgaWYgKGFmdGVyKSB7XG4gICAgYWZ0ZXIgPSBjdXJzb3JUb09mZnNldChhZnRlcik7XG4gICAgaWYgKCghYWZ0ZXIgJiYgYWZ0ZXIgIT09IDApIHx8IGFmdGVyIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnQWZ0ZXIgaXMgbm90IGEgdmFsaWQgY3Vyc29yJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJZiBza2lwIGFuZCBhZnRlciBhcmUgcGFzc2VkLCBhIG5ldyBza2lwIGlzIGNhbGN1bGF0ZWQgYnkgYWRkaW5nIHRoZW1cbiAgICBza2lwID0gKHNraXAgfHwgMCkgKyAoYWZ0ZXIgKyAxKTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgZmlyc3QgcGFyYW1cbiAgaWYgKGZpcnN0IHx8IGZpcnN0ID09PSAwKSB7XG4gICAgaWYgKGZpcnN0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnRmlyc3Qgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgZmlyc3QgcGFyYW0gaXMgdHJhbnNsYXRlZCB0byB0aGUgbGltaXQgcGFyYW0gb2YgdGhlIFBhcnNlIGxlZ2FjeSBBUElcbiAgICBsaW1pdCA9IGZpcnN0O1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBiZWZvcmUgcGFyYW1cbiAgaWYgKGJlZm9yZSB8fCBiZWZvcmUgPT09IDApIHtcbiAgICAvLyBUaGlzIG1ldGhvZCBjb252ZXJ0cyB0aGUgY3Vyc29yIHRvIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0XG4gICAgYmVmb3JlID0gY3Vyc29yVG9PZmZzZXQoYmVmb3JlKTtcbiAgICBpZiAoKCFiZWZvcmUgJiYgYmVmb3JlICE9PSAwKSB8fCBiZWZvcmUgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICdCZWZvcmUgaXMgbm90IGEgdmFsaWQgY3Vyc29yJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoKHNraXAgfHwgMCkgPj0gYmVmb3JlKSB7XG4gICAgICAvLyBJZiB0aGUgYmVmb3JlIGluZGV4IGlzIGxlc3MgdGhlbiB0aGUgc2tpcCwgbm8gb2JqZWN0cyB3aWxsIGJlIHJldHVybmVkXG4gICAgICBsaW1pdCA9IDA7XG4gICAgfSBlbHNlIGlmICgoIWxpbWl0ICYmIGxpbWl0ICE9PSAwKSB8fCAoc2tpcCB8fCAwKSArIGxpbWl0ID4gYmVmb3JlKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBubyBsaW1pdCBzZXQsIHRoZSBsaW1pdCBpcyBjYWxjdWxhdGVkLiBPciwgaWYgdGhlIGxpbWl0IChwbHVzIHNraXApIGlzIGJpZ2dlciB0aGFuIHRoZSBiZWZvcmUgaW5kZXgsIHRoZSBuZXcgbGltaXQgaXMgc2V0LlxuICAgICAgbGltaXQgPSBiZWZvcmUgLSAoc2tpcCB8fCAwKTtcbiAgICB9XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgdGhlIGxhc3QgcGFyYW1cbiAgaWYgKGxhc3QgfHwgbGFzdCA9PT0gMCkge1xuICAgIGlmIChsYXN0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnTGFzdCBzaG91bGQgYmUgYSBwb3NpdGl2ZSBudW1iZXInXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChsYXN0ID4gbWF4TGltaXQpIHtcbiAgICAgIC8vIExhc3QgY2FuJ3QgYmUgYmlnZ2VyIHRoYW4gUGFyc2Ugc2VydmVyIG1heExpbWl0IGNvbmZpZy5cbiAgICAgIGxhc3QgPSBtYXhMaW1pdDtcbiAgICB9XG5cbiAgICBpZiAobGltaXQgfHwgbGltaXQgPT09IDApIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgcHJldmlvdXMgbGltaXQgc2V0LCBpdCBtYXkgYmUgYWRqdXN0ZWRcbiAgICAgIGlmIChsYXN0IDwgbGltaXQpIHtcbiAgICAgICAgLy8gaWYgbGFzdCBpcyBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgbGltaXRcbiAgICAgICAgc2tpcCA9IChza2lwIHx8IDApICsgKGxpbWl0IC0gbGFzdCk7IC8vIFRoZSBza2lwIGlzIGFkanVzdGVkXG4gICAgICAgIGxpbWl0ID0gbGFzdDsgLy8gdGhlIGxpbWl0IGlzIGFkanVzdGVkXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAwKSB7XG4gICAgICAvLyBObyBvYmplY3RzIHdpbGwgYmUgcmV0dXJuZWRcbiAgICAgIGxpbWl0ID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gcHJldmlvdXMgbGltaXQgc2V0LCB0aGUgbGltaXQgd2lsbCBiZSBlcXVhbCB0byBsYXN0IGFuZCBwcmUgY291bnQgaXMgbmVlZGVkLlxuICAgICAgbGltaXQgPSBsYXN0O1xuICAgICAgbmVlZFRvUHJlQ291bnQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIHNraXAsXG4gICAgbGltaXQsXG4gICAgbmVlZFRvUHJlQ291bnQsXG4gIH07XG59O1xuXG5leHBvcnQgeyBnZXRPYmplY3QsIGZpbmRPYmplY3RzLCBjYWxjdWxhdGVTa2lwQW5kTGltaXQsIG5lZWRUb0dldEFsbEtleXMgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLMutations.js b/lib/GraphQL/loaders/defaultGraphQLMutations.js deleted file mode 100644 index afe32cc4fb..0000000000 --- a/lib/GraphQL/loaders/defaultGraphQLMutations.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var filesMutations = _interopRequireWildcard(require("./filesMutations")); - -var usersMutations = _interopRequireWildcard(require("./usersMutations")); - -var functionsMutations = _interopRequireWildcard(require("./functionsMutations")); - -var schemaMutations = _interopRequireWildcard(require("./schemaMutations")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const load = parseGraphQLSchema => { - filesMutations.load(parseGraphQLSchema); - usersMutations.load(parseGraphQLSchema); - functionsMutations.load(parseGraphQLSchema); - schemaMutations.load(parseGraphQLSchema); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImZpbGVzTXV0YXRpb25zIiwidXNlcnNNdXRhdGlvbnMiLCJmdW5jdGlvbnNNdXRhdGlvbnMiLCJzY2hlbWFNdXRhdGlvbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0MsRUFBQUEsY0FBYyxDQUFDRixJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUUsRUFBQUEsY0FBYyxDQUFDSCxJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUcsRUFBQUEsa0JBQWtCLENBQUNKLElBQW5CLENBQXdCQyxrQkFBeEI7QUFDQUksRUFBQUEsZUFBZSxDQUFDTCxJQUFoQixDQUFxQkMsa0JBQXJCO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZpbGVzTXV0YXRpb25zIGZyb20gJy4vZmlsZXNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgdXNlcnNNdXRhdGlvbnMgZnJvbSAnLi91c2Vyc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBmdW5jdGlvbnNNdXRhdGlvbnMgZnJvbSAnLi9mdW5jdGlvbnNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgc2NoZW1hTXV0YXRpb25zIGZyb20gJy4vc2NoZW1hTXV0YXRpb25zJztcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGZpbGVzTXV0YXRpb25zLmxvYWQocGFyc2VHcmFwaFFMU2NoZW1hKTtcbiAgdXNlcnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBmdW5jdGlvbnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBzY2hlbWFNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLQueries.js b/lib/GraphQL/loaders/defaultGraphQLQueries.js deleted file mode 100644 index b8935f3ab1..0000000000 --- a/lib/GraphQL/loaders/defaultGraphQLQueries.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var usersQueries = _interopRequireWildcard(require("./usersQueries")); - -var schemaQueries = _interopRequireWildcard(require("./schemaQueries")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLQuery('health', { - description: 'The health query can be used to check if the server is up and running.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean), - resolve: () => true - }, true, true); - usersQueries.load(parseGraphQLSchema); - schemaQueries.load(parseGraphQLSchema); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkdyYXBoUUxCb29sZWFuIiwicmVzb2x2ZSIsInVzZXJzUXVlcmllcyIsInNjaGVtYVF1ZXJpZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0EsRUFBQUEsa0JBQWtCLENBQUNDLGVBQW5CLENBQ0UsUUFERixFQUVFO0FBQ0VDLElBQUFBLFdBQVcsRUFDVCx3RUFGSjtBQUdFQyxJQUFBQSxJQUFJLEVBQUUsSUFBSUMsdUJBQUosQ0FBbUJDLHVCQUFuQixDQUhSO0FBSUVDLElBQUFBLE9BQU8sRUFBRSxNQUFNO0FBSmpCLEdBRkYsRUFRRSxJQVJGLEVBU0UsSUFURjtBQVlBQyxFQUFBQSxZQUFZLENBQUNSLElBQWIsQ0FBa0JDLGtCQUFsQjtBQUNBUSxFQUFBQSxhQUFhLENBQUNULElBQWQsQ0FBbUJDLGtCQUFuQjtBQUNELENBZkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCwgR3JhcGhRTEJvb2xlYW4gfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCAqIGFzIHVzZXJzUXVlcmllcyBmcm9tICcuL3VzZXJzUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFRdWVyaWVzIGZyb20gJy4vc2NoZW1hUXVlcmllcyc7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdoZWFsdGgnLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGhlYWx0aCBxdWVyeSBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiB0aGUgc2VydmVyIGlzIHVwIGFuZCBydW5uaW5nLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgcmVzb2x2ZTogKCkgPT4gdHJ1ZSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIHVzZXJzUXVlcmllcy5sb2FkKHBhcnNlR3JhcGhRTFNjaGVtYSk7XG4gIHNjaGVtYVF1ZXJpZXMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLTypes.js b/lib/GraphQL/loaders/defaultGraphQLTypes.js deleted file mode 100644 index 913aa114ce..0000000000 --- a/lib/GraphQL/loaders/defaultGraphQLTypes.js +++ /dev/null @@ -1,1271 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.loadArrayResult = exports.load = exports.PUBLIC_ACL = exports.ROLE_ACL = exports.USER_ACL = exports.ACL = exports.PUBLIC_ACL_INPUT = exports.ROLE_ACL_INPUT = exports.USER_ACL_INPUT = exports.ACL_INPUT = exports.ELEMENT = exports.ARRAY_RESULT = exports.POLYGON_WHERE_INPUT = exports.GEO_POINT_WHERE_INPUT = exports.FILE_WHERE_INPUT = exports.BYTES_WHERE_INPUT = exports.DATE_WHERE_INPUT = exports.OBJECT_WHERE_INPUT = exports.KEY_VALUE_INPUT = exports.ARRAY_WHERE_INPUT = exports.BOOLEAN_WHERE_INPUT = exports.NUMBER_WHERE_INPUT = exports.STRING_WHERE_INPUT = exports.ID_WHERE_INPUT = exports.notInQueryKey = exports.inQueryKey = exports.options = exports.matchesRegex = exports.exists = exports.notIn = exports.inOp = exports.greaterThanOrEqualTo = exports.greaterThan = exports.lessThanOrEqualTo = exports.lessThan = exports.notEqualTo = exports.equalTo = exports.GEO_INTERSECTS_INPUT = exports.GEO_WITHIN_INPUT = exports.CENTER_SPHERE_INPUT = exports.WITHIN_INPUT = exports.BOX_INPUT = exports.TEXT_INPUT = exports.SEARCH_INPUT = exports.COUNT_ATT = exports.LIMIT_ATT = exports.SKIP_ATT = exports.WHERE_ATT = exports.READ_OPTIONS_ATT = exports.READ_OPTIONS_INPUT = exports.SUBQUERY_READ_PREFERENCE_ATT = exports.INCLUDE_READ_PREFERENCE_ATT = exports.READ_PREFERENCE_ATT = exports.READ_PREFERENCE = exports.SESSION_TOKEN_ATT = exports.PARSE_OBJECT = exports.PARSE_OBJECT_FIELDS = exports.UPDATE_RESULT_FIELDS = exports.CREATE_RESULT_FIELDS = exports.INPUT_FIELDS = exports.CREATED_AT_ATT = exports.UPDATED_AT_ATT = exports.OBJECT_ID_ATT = exports.GLOBAL_OR_OBJECT_ID_ATT = exports.CLASS_NAME_ATT = exports.OBJECT_ID = exports.POLYGON = exports.POLYGON_INPUT = exports.GEO_POINT = exports.GEO_POINT_INPUT = exports.GEO_POINT_FIELDS = exports.FILE_INPUT = exports.FILE_INFO = exports.FILE = exports.SELECT_INPUT = exports.SUBQUERY_INPUT = exports.parseFileValue = exports.BYTES = exports.DATE = exports.serializeDateIso = exports.parseDateIsoValue = exports.OBJECT = exports.ANY = exports.parseObjectFields = exports.parseListValues = exports.parseValue = exports.parseBooleanValue = exports.parseFloatValue = exports.parseIntValue = exports.parseStringValue = exports.TypeValidationError = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _links = require("@graphql-tools/links"); - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -class TypeValidationError extends Error { - constructor(value, type) { - super(`${value} is not a valid ${type}`); - } - -} - -exports.TypeValidationError = TypeValidationError; - -const parseStringValue = value => { - if (typeof value === 'string') { - return value; - } - - throw new TypeValidationError(value, 'String'); -}; - -exports.parseStringValue = parseStringValue; - -const parseIntValue = value => { - if (typeof value === 'string') { - const int = Number(value); - - if (Number.isInteger(int)) { - return int; - } - } - - throw new TypeValidationError(value, 'Int'); -}; - -exports.parseIntValue = parseIntValue; - -const parseFloatValue = value => { - if (typeof value === 'string') { - const float = Number(value); - - if (!isNaN(float)) { - return float; - } - } - - throw new TypeValidationError(value, 'Float'); -}; - -exports.parseFloatValue = parseFloatValue; - -const parseBooleanValue = value => { - if (typeof value === 'boolean') { - return value; - } - - throw new TypeValidationError(value, 'Boolean'); -}; - -exports.parseBooleanValue = parseBooleanValue; - -const parseValue = value => { - switch (value.kind) { - case _graphql.Kind.STRING: - return parseStringValue(value.value); - - case _graphql.Kind.INT: - return parseIntValue(value.value); - - case _graphql.Kind.FLOAT: - return parseFloatValue(value.value); - - case _graphql.Kind.BOOLEAN: - return parseBooleanValue(value.value); - - case _graphql.Kind.LIST: - return parseListValues(value.values); - - case _graphql.Kind.OBJECT: - return parseObjectFields(value.fields); - - default: - return value.value; - } -}; - -exports.parseValue = parseValue; - -const parseListValues = values => { - if (Array.isArray(values)) { - return values.map(value => parseValue(value)); - } - - throw new TypeValidationError(values, 'List'); -}; - -exports.parseListValues = parseListValues; - -const parseObjectFields = fields => { - if (Array.isArray(fields)) { - return fields.reduce((object, field) => _objectSpread(_objectSpread({}, object), {}, { - [field.name.value]: parseValue(field.value) - }), {}); - } - - throw new TypeValidationError(fields, 'Object'); -}; - -exports.parseObjectFields = parseObjectFields; -const ANY = new _graphql.GraphQLScalarType({ - name: 'Any', - description: 'The Any scalar type is used in operations and types that involve any type of value.', - parseValue: value => value, - serialize: value => value, - parseLiteral: ast => parseValue(ast) -}); -exports.ANY = ANY; -const OBJECT = new _graphql.GraphQLScalarType({ - name: 'Object', - description: 'The Object scalar type is used in operations and types that involve objects.', - - parseValue(value) { - if (typeof value === 'object') { - return value; - } - - throw new TypeValidationError(value, 'Object'); - }, - - serialize(value) { - if (typeof value === 'object') { - return value; - } - - throw new TypeValidationError(value, 'Object'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.OBJECT) { - return parseObjectFields(ast.fields); - } - - throw new TypeValidationError(ast.kind, 'Object'); - } - -}); -exports.OBJECT = OBJECT; - -const parseDateIsoValue = value => { - if (typeof value === 'string') { - const date = new Date(value); - - if (!isNaN(date)) { - return date; - } - } else if (value instanceof Date) { - return value; - } - - throw new TypeValidationError(value, 'Date'); -}; - -exports.parseDateIsoValue = parseDateIsoValue; - -const serializeDateIso = value => { - if (typeof value === 'string') { - return value; - } - - if (value instanceof Date) { - return value.toISOString(); - } - - throw new TypeValidationError(value, 'Date'); -}; - -exports.serializeDateIso = serializeDateIso; - -const parseDateIsoLiteral = ast => { - if (ast.kind === _graphql.Kind.STRING) { - return parseDateIsoValue(ast.value); - } - - throw new TypeValidationError(ast.kind, 'Date'); -}; - -const DATE = new _graphql.GraphQLScalarType({ - name: 'Date', - description: 'The Date scalar type is used in operations and types that involve dates.', - - parseValue(value) { - if (typeof value === 'string' || value instanceof Date) { - return { - __type: 'Date', - iso: parseDateIsoValue(value) - }; - } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { - return { - __type: value.__type, - iso: parseDateIsoValue(value.iso) - }; - } - - throw new TypeValidationError(value, 'Date'); - }, - - serialize(value) { - if (typeof value === 'string' || value instanceof Date) { - return serializeDateIso(value); - } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { - return serializeDateIso(value.iso); - } - - throw new TypeValidationError(value, 'Date'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.STRING) { - return { - __type: 'Date', - iso: parseDateIsoLiteral(ast) - }; - } else if (ast.kind === _graphql.Kind.OBJECT) { - const __type = ast.fields.find(field => field.name.value === '__type'); - - const iso = ast.fields.find(field => field.name.value === 'iso'); - - if (__type && __type.value && __type.value.value === 'Date' && iso) { - return { - __type: __type.value.value, - iso: parseDateIsoLiteral(iso.value) - }; - } - } - - throw new TypeValidationError(ast.kind, 'Date'); - } - -}); -exports.DATE = DATE; -const BYTES = new _graphql.GraphQLScalarType({ - name: 'Bytes', - description: 'The Bytes scalar type is used in operations and types that involve base 64 binary data.', - - parseValue(value) { - if (typeof value === 'string') { - return { - __type: 'Bytes', - base64: value - }; - } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { - return value; - } - - throw new TypeValidationError(value, 'Bytes'); - }, - - serialize(value) { - if (typeof value === 'string') { - return value; - } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { - return value.base64; - } - - throw new TypeValidationError(value, 'Bytes'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.STRING) { - return { - __type: 'Bytes', - base64: ast.value - }; - } else if (ast.kind === _graphql.Kind.OBJECT) { - const __type = ast.fields.find(field => field.name.value === '__type'); - - const base64 = ast.fields.find(field => field.name.value === 'base64'); - - if (__type && __type.value && __type.value.value === 'Bytes' && base64 && base64.value && typeof base64.value.value === 'string') { - return { - __type: __type.value.value, - base64: base64.value.value - }; - } - } - - throw new TypeValidationError(ast.kind, 'Bytes'); - } - -}); -exports.BYTES = BYTES; - -const parseFileValue = value => { - if (typeof value === 'string') { - return { - __type: 'File', - name: value - }; - } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { - return value; - } - - throw new TypeValidationError(value, 'File'); -}; - -exports.parseFileValue = parseFileValue; -const FILE = new _graphql.GraphQLScalarType({ - name: 'File', - description: 'The File scalar type is used in operations and types that involve files.', - parseValue: parseFileValue, - serialize: value => { - if (typeof value === 'string') { - return value; - } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { - return value.name; - } - - throw new TypeValidationError(value, 'File'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.STRING) { - return parseFileValue(ast.value); - } else if (ast.kind === _graphql.Kind.OBJECT) { - const __type = ast.fields.find(field => field.name.value === '__type'); - - const name = ast.fields.find(field => field.name.value === 'name'); - const url = ast.fields.find(field => field.name.value === 'url'); - - if (__type && __type.value && name && name.value) { - return parseFileValue({ - __type: __type.value.value, - name: name.value.value, - url: url && url.value ? url.value.value : undefined - }); - } - } - - throw new TypeValidationError(ast.kind, 'File'); - } - -}); -exports.FILE = FILE; -const FILE_INFO = new _graphql.GraphQLObjectType({ - name: 'FileInfo', - description: 'The FileInfo object type is used to return the information about files.', - fields: { - name: { - description: 'This is the file name.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - url: { - description: 'This is the url in which the file can be downloaded.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - } -}); -exports.FILE_INFO = FILE_INFO; -const FILE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'FileInput', - fields: { - file: { - description: 'A File Scalar can be an url or a FileInfo object. If this field is set to null the file will be unlinked.', - type: FILE - }, - upload: { - description: 'Use this field if you want to create a new file.', - type: _links.GraphQLUpload - }, - unlink: { - description: 'Use this field if you want to unlink the file (the file will not be deleted on cloud storage)', - type: _graphql.GraphQLBoolean - } - } -}); -exports.FILE_INPUT = FILE_INPUT; -const GEO_POINT_FIELDS = { - latitude: { - description: 'This is the latitude.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) - }, - longitude: { - description: 'This is the longitude.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) - } -}; -exports.GEO_POINT_FIELDS = GEO_POINT_FIELDS; -const GEO_POINT_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoPointInput', - description: 'The GeoPointInput type is used in operations that involve inputting fields of type geo point.', - fields: GEO_POINT_FIELDS -}); -exports.GEO_POINT_INPUT = GEO_POINT_INPUT; -const GEO_POINT = new _graphql.GraphQLObjectType({ - name: 'GeoPoint', - description: 'The GeoPoint object type is used to return the information about geo point fields.', - fields: GEO_POINT_FIELDS -}); -exports.GEO_POINT = GEO_POINT; -const POLYGON_INPUT = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT_INPUT)); -exports.POLYGON_INPUT = POLYGON_INPUT; -const POLYGON = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT)); -exports.POLYGON = POLYGON; -const USER_ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'UserACLInput', - description: 'Allow to manage users in ACL.', - fields: { - userId: { - description: 'ID of the targetted User.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) - }, - read: { - description: 'Allow the user to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow the user to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.USER_ACL_INPUT = USER_ACL_INPUT; -const ROLE_ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'RoleACLInput', - description: 'Allow to manage roles in ACL.', - fields: { - roleName: { - description: 'Name of the targetted Role.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - read: { - description: 'Allow users who are members of the role to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow users who are members of the role to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.ROLE_ACL_INPUT = ROLE_ACL_INPUT; -const PUBLIC_ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'PublicACLInput', - description: 'Allow to manage public rights.', - fields: { - read: { - description: 'Allow anyone to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow anyone to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.PUBLIC_ACL_INPUT = PUBLIC_ACL_INPUT; -const ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ACLInput', - description: 'Allow to manage access rights. If not provided object will be publicly readable and writable', - fields: { - users: { - description: 'Access control list for users.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL_INPUT)) - }, - roles: { - description: 'Access control list for roles.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL_INPUT)) - }, - public: { - description: 'Public access control list.', - type: PUBLIC_ACL_INPUT - } - } -}); -exports.ACL_INPUT = ACL_INPUT; -const USER_ACL = new _graphql.GraphQLObjectType({ - name: 'UserACL', - description: 'Allow to manage users in ACL. If read and write are null the users have read and write rights.', - fields: { - userId: { - description: 'ID of the targetted User.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) - }, - read: { - description: 'Allow the user to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow the user to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.USER_ACL = USER_ACL; -const ROLE_ACL = new _graphql.GraphQLObjectType({ - name: 'RoleACL', - description: 'Allow to manage roles in ACL. If read and write are null the role have read and write rights.', - fields: { - roleName: { - description: 'Name of the targetted Role.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) - }, - read: { - description: 'Allow users who are members of the role to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow users who are members of the role to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.ROLE_ACL = ROLE_ACL; -const PUBLIC_ACL = new _graphql.GraphQLObjectType({ - name: 'PublicACL', - description: 'Allow to manage public rights.', - fields: { - read: { - description: 'Allow anyone to read the current object.', - type: _graphql.GraphQLBoolean - }, - write: { - description: 'Allow anyone to write on the current object.', - type: _graphql.GraphQLBoolean - } - } -}); -exports.PUBLIC_ACL = PUBLIC_ACL; -const ACL = new _graphql.GraphQLObjectType({ - name: 'ACL', - description: 'Current access control list of the current object.', - fields: { - users: { - description: 'Access control list for users.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL)), - - resolve(p) { - const users = []; - Object.keys(p).forEach(rule => { - if (rule !== '*' && rule.indexOf('role:') !== 0) { - users.push({ - userId: (0, _graphqlRelay.toGlobalId)('_User', rule), - read: p[rule].read ? true : false, - write: p[rule].write ? true : false - }); - } - }); - return users.length ? users : null; - } - - }, - roles: { - description: 'Access control list for roles.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL)), - - resolve(p) { - const roles = []; - Object.keys(p).forEach(rule => { - if (rule.indexOf('role:') === 0) { - roles.push({ - roleName: rule.replace('role:', ''), - read: p[rule].read ? true : false, - write: p[rule].write ? true : false - }); - } - }); - return roles.length ? roles : null; - } - - }, - public: { - description: 'Public access control list.', - type: PUBLIC_ACL, - - resolve(p) { - /* eslint-disable */ - return p['*'] ? { - read: p['*'].read ? true : false, - write: p['*'].write ? true : false - } : null; - } - - } - } -}); -exports.ACL = ACL; -const OBJECT_ID = new _graphql.GraphQLNonNull(_graphql.GraphQLID); -exports.OBJECT_ID = OBJECT_ID; -const CLASS_NAME_ATT = { - description: 'This is the class name of the object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.CLASS_NAME_ATT = CLASS_NAME_ATT; -const GLOBAL_OR_OBJECT_ID_ATT = { - description: 'This is the object id. You can use either the global or the object id.', - type: OBJECT_ID -}; -exports.GLOBAL_OR_OBJECT_ID_ATT = GLOBAL_OR_OBJECT_ID_ATT; -const OBJECT_ID_ATT = { - description: 'This is the object id.', - type: OBJECT_ID -}; -exports.OBJECT_ID_ATT = OBJECT_ID_ATT; -const CREATED_AT_ATT = { - description: 'This is the date in which the object was created.', - type: new _graphql.GraphQLNonNull(DATE) -}; -exports.CREATED_AT_ATT = CREATED_AT_ATT; -const UPDATED_AT_ATT = { - description: 'This is the date in which the object was las updated.', - type: new _graphql.GraphQLNonNull(DATE) -}; -exports.UPDATED_AT_ATT = UPDATED_AT_ATT; -const INPUT_FIELDS = { - ACL: { - type: ACL - } -}; -exports.INPUT_FIELDS = INPUT_FIELDS; -const CREATE_RESULT_FIELDS = { - objectId: OBJECT_ID_ATT, - createdAt: CREATED_AT_ATT -}; -exports.CREATE_RESULT_FIELDS = CREATE_RESULT_FIELDS; -const UPDATE_RESULT_FIELDS = { - updatedAt: UPDATED_AT_ATT -}; -exports.UPDATE_RESULT_FIELDS = UPDATE_RESULT_FIELDS; - -const PARSE_OBJECT_FIELDS = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, CREATE_RESULT_FIELDS), UPDATE_RESULT_FIELDS), INPUT_FIELDS), {}, { - ACL: { - type: new _graphql.GraphQLNonNull(ACL), - resolve: ({ - ACL - }) => ACL ? ACL : { - '*': { - read: true, - write: true - } - } - } -}); - -exports.PARSE_OBJECT_FIELDS = PARSE_OBJECT_FIELDS; -const PARSE_OBJECT = new _graphql.GraphQLInterfaceType({ - name: 'ParseObject', - description: 'The ParseObject interface type is used as a base type for the auto generated object types.', - fields: PARSE_OBJECT_FIELDS -}); -exports.PARSE_OBJECT = PARSE_OBJECT; -const SESSION_TOKEN_ATT = { - description: 'The current user session token.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.SESSION_TOKEN_ATT = SESSION_TOKEN_ATT; -const READ_PREFERENCE = new _graphql.GraphQLEnumType({ - name: 'ReadPreference', - description: 'The ReadPreference enum type is used in queries in order to select in which database replica the operation must run.', - values: { - PRIMARY: { - value: 'PRIMARY' - }, - PRIMARY_PREFERRED: { - value: 'PRIMARY_PREFERRED' - }, - SECONDARY: { - value: 'SECONDARY' - }, - SECONDARY_PREFERRED: { - value: 'SECONDARY_PREFERRED' - }, - NEAREST: { - value: 'NEAREST' - } - } -}); -exports.READ_PREFERENCE = READ_PREFERENCE; -const READ_PREFERENCE_ATT = { - description: 'The read preference for the main query to be executed.', - type: READ_PREFERENCE -}; -exports.READ_PREFERENCE_ATT = READ_PREFERENCE_ATT; -const INCLUDE_READ_PREFERENCE_ATT = { - description: 'The read preference for the queries to be executed to include fields.', - type: READ_PREFERENCE -}; -exports.INCLUDE_READ_PREFERENCE_ATT = INCLUDE_READ_PREFERENCE_ATT; -const SUBQUERY_READ_PREFERENCE_ATT = { - description: 'The read preference for the subqueries that may be required.', - type: READ_PREFERENCE -}; -exports.SUBQUERY_READ_PREFERENCE_ATT = SUBQUERY_READ_PREFERENCE_ATT; -const READ_OPTIONS_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ReadOptionsInput', - description: 'The ReadOptionsInputt type is used in queries in order to set the read preferences.', - fields: { - readPreference: READ_PREFERENCE_ATT, - includeReadPreference: INCLUDE_READ_PREFERENCE_ATT, - subqueryReadPreference: SUBQUERY_READ_PREFERENCE_ATT - } -}); -exports.READ_OPTIONS_INPUT = READ_OPTIONS_INPUT; -const READ_OPTIONS_ATT = { - description: 'The read options for the query to be executed.', - type: READ_OPTIONS_INPUT -}; -exports.READ_OPTIONS_ATT = READ_OPTIONS_ATT; -const WHERE_ATT = { - description: 'These are the conditions that the objects need to match in order to be found', - type: OBJECT -}; -exports.WHERE_ATT = WHERE_ATT; -const SKIP_ATT = { - description: 'This is the number of objects that must be skipped to return.', - type: _graphql.GraphQLInt -}; -exports.SKIP_ATT = SKIP_ATT; -const LIMIT_ATT = { - description: 'This is the limit number of objects that must be returned.', - type: _graphql.GraphQLInt -}; -exports.LIMIT_ATT = LIMIT_ATT; -const COUNT_ATT = { - description: 'This is the total matched objecs count that is returned when the count flag is set.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLInt) -}; -exports.COUNT_ATT = COUNT_ATT; -const SEARCH_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SearchInput', - description: 'The SearchInput type is used to specifiy a search operation on a full text search.', - fields: { - term: { - description: 'This is the term to be searched.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - language: { - description: 'This is the language to tetermine the list of stop words and the rules for tokenizer.', - type: _graphql.GraphQLString - }, - caseSensitive: { - description: 'This is the flag to enable or disable case sensitive search.', - type: _graphql.GraphQLBoolean - }, - diacriticSensitive: { - description: 'This is the flag to enable or disable diacritic sensitive search.', - type: _graphql.GraphQLBoolean - } - } -}); -exports.SEARCH_INPUT = SEARCH_INPUT; -const TEXT_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'TextInput', - description: 'The TextInput type is used to specify a text operation on a constraint.', - fields: { - search: { - description: 'This is the search to be executed.', - type: new _graphql.GraphQLNonNull(SEARCH_INPUT) - } - } -}); -exports.TEXT_INPUT = TEXT_INPUT; -const BOX_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'BoxInput', - description: 'The BoxInput type is used to specifiy a box operation on a within geo query.', - fields: { - bottomLeft: { - description: 'This is the bottom left coordinates of the box.', - type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) - }, - upperRight: { - description: 'This is the upper right coordinates of the box.', - type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) - } - } -}); -exports.BOX_INPUT = BOX_INPUT; -const WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'WithinInput', - description: 'The WithinInput type is used to specify a within operation on a constraint.', - fields: { - box: { - description: 'This is the box to be specified.', - type: new _graphql.GraphQLNonNull(BOX_INPUT) - } - } -}); -exports.WITHIN_INPUT = WITHIN_INPUT; -const CENTER_SPHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'CenterSphereInput', - description: 'The CenterSphereInput type is used to specifiy a centerSphere operation on a geoWithin query.', - fields: { - center: { - description: 'This is the center of the sphere.', - type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) - }, - distance: { - description: 'This is the radius of the sphere.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) - } - } -}); -exports.CENTER_SPHERE_INPUT = CENTER_SPHERE_INPUT; -const GEO_WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoWithinInput', - description: 'The GeoWithinInput type is used to specify a geoWithin operation on a constraint.', - fields: { - polygon: { - description: 'This is the polygon to be specified.', - type: POLYGON_INPUT - }, - centerSphere: { - description: 'This is the sphere to be specified.', - type: CENTER_SPHERE_INPUT - } - } -}); -exports.GEO_WITHIN_INPUT = GEO_WITHIN_INPUT; -const GEO_INTERSECTS_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoIntersectsInput', - description: 'The GeoIntersectsInput type is used to specify a geoIntersects operation on a constraint.', - fields: { - point: { - description: 'This is the point to be specified.', - type: GEO_POINT_INPUT - } - } -}); -exports.GEO_INTERSECTS_INPUT = GEO_INTERSECTS_INPUT; - -const equalTo = type => ({ - description: 'This is the equalTo operator to specify a constraint to select the objects where the value of a field equals to a specified value.', - type -}); - -exports.equalTo = equalTo; - -const notEqualTo = type => ({ - description: 'This is the notEqualTo operator to specify a constraint to select the objects where the value of a field do not equal to a specified value.', - type -}); - -exports.notEqualTo = notEqualTo; - -const lessThan = type => ({ - description: 'This is the lessThan operator to specify a constraint to select the objects where the value of a field is less than a specified value.', - type -}); - -exports.lessThan = lessThan; - -const lessThanOrEqualTo = type => ({ - description: 'This is the lessThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is less than or equal to a specified value.', - type -}); - -exports.lessThanOrEqualTo = lessThanOrEqualTo; - -const greaterThan = type => ({ - description: 'This is the greaterThan operator to specify a constraint to select the objects where the value of a field is greater than a specified value.', - type -}); - -exports.greaterThan = greaterThan; - -const greaterThanOrEqualTo = type => ({ - description: 'This is the greaterThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is greater than or equal to a specified value.', - type -}); - -exports.greaterThanOrEqualTo = greaterThanOrEqualTo; - -const inOp = type => ({ - description: 'This is the in operator to specify a constraint to select the objects where the value of a field equals any value in the specified array.', - type: new _graphql.GraphQLList(type) -}); - -exports.inOp = inOp; - -const notIn = type => ({ - description: 'This is the notIn operator to specify a constraint to select the objects where the value of a field do not equal any value in the specified array.', - type: new _graphql.GraphQLList(type) -}); - -exports.notIn = notIn; -const exists = { - description: 'This is the exists operator to specify a constraint to select the objects where a field exists (or do not exist).', - type: _graphql.GraphQLBoolean -}; -exports.exists = exists; -const matchesRegex = { - description: 'This is the matchesRegex operator to specify a constraint to select the objects where the value of a field matches a specified regular expression.', - type: _graphql.GraphQLString -}; -exports.matchesRegex = matchesRegex; -const options = { - description: 'This is the options operator to specify optional flags (such as "i" and "m") to be added to a matchesRegex operation in the same set of constraints.', - type: _graphql.GraphQLString -}; -exports.options = options; -const SUBQUERY_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SubqueryInput', - description: 'The SubqueryInput type is used to specify a sub query to another class.', - fields: { - className: CLASS_NAME_ATT, - where: Object.assign({}, WHERE_ATT, { - type: new _graphql.GraphQLNonNull(WHERE_ATT.type) - }) - } -}); -exports.SUBQUERY_INPUT = SUBQUERY_INPUT; -const SELECT_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SelectInput', - description: 'The SelectInput type is used to specify an inQueryKey or a notInQueryKey operation on a constraint.', - fields: { - query: { - description: 'This is the subquery to be executed.', - type: new _graphql.GraphQLNonNull(SUBQUERY_INPUT) - }, - key: { - description: 'This is the key in the result of the subquery that must match (not match) the field.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - } -}); -exports.SELECT_INPUT = SELECT_INPUT; -const inQueryKey = { - description: 'This is the inQueryKey operator to specify a constraint to select the objects where a field equals to a key in the result of a different query.', - type: SELECT_INPUT -}; -exports.inQueryKey = inQueryKey; -const notInQueryKey = { - description: 'This is the notInQueryKey operator to specify a constraint to select the objects where a field do not equal to a key in the result of a different query.', - type: SELECT_INPUT -}; -exports.notInQueryKey = notInQueryKey; -const ID_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'IdWhereInput', - description: 'The IdWhereInput input type is used in operations that involve filtering objects by an id.', - fields: { - equalTo: equalTo(_graphql.GraphQLID), - notEqualTo: notEqualTo(_graphql.GraphQLID), - lessThan: lessThan(_graphql.GraphQLID), - lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLID), - greaterThan: greaterThan(_graphql.GraphQLID), - greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLID), - in: inOp(_graphql.GraphQLID), - notIn: notIn(_graphql.GraphQLID), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.ID_WHERE_INPUT = ID_WHERE_INPUT; -const STRING_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'StringWhereInput', - description: 'The StringWhereInput input type is used in operations that involve filtering objects by a field of type String.', - fields: { - equalTo: equalTo(_graphql.GraphQLString), - notEqualTo: notEqualTo(_graphql.GraphQLString), - lessThan: lessThan(_graphql.GraphQLString), - lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLString), - greaterThan: greaterThan(_graphql.GraphQLString), - greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLString), - in: inOp(_graphql.GraphQLString), - notIn: notIn(_graphql.GraphQLString), - exists, - matchesRegex, - options, - text: { - description: 'This is the $text operator to specify a full text search constraint.', - type: TEXT_INPUT - }, - inQueryKey, - notInQueryKey - } -}); -exports.STRING_WHERE_INPUT = STRING_WHERE_INPUT; -const NUMBER_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'NumberWhereInput', - description: 'The NumberWhereInput input type is used in operations that involve filtering objects by a field of type Number.', - fields: { - equalTo: equalTo(_graphql.GraphQLFloat), - notEqualTo: notEqualTo(_graphql.GraphQLFloat), - lessThan: lessThan(_graphql.GraphQLFloat), - lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLFloat), - greaterThan: greaterThan(_graphql.GraphQLFloat), - greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLFloat), - in: inOp(_graphql.GraphQLFloat), - notIn: notIn(_graphql.GraphQLFloat), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.NUMBER_WHERE_INPUT = NUMBER_WHERE_INPUT; -const BOOLEAN_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'BooleanWhereInput', - description: 'The BooleanWhereInput input type is used in operations that involve filtering objects by a field of type Boolean.', - fields: { - equalTo: equalTo(_graphql.GraphQLBoolean), - notEqualTo: notEqualTo(_graphql.GraphQLBoolean), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.BOOLEAN_WHERE_INPUT = BOOLEAN_WHERE_INPUT; -const ARRAY_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ArrayWhereInput', - description: 'The ArrayWhereInput input type is used in operations that involve filtering objects by a field of type Array.', - fields: { - equalTo: equalTo(ANY), - notEqualTo: notEqualTo(ANY), - lessThan: lessThan(ANY), - lessThanOrEqualTo: lessThanOrEqualTo(ANY), - greaterThan: greaterThan(ANY), - greaterThanOrEqualTo: greaterThanOrEqualTo(ANY), - in: inOp(ANY), - notIn: notIn(ANY), - exists, - containedBy: { - description: 'This is the containedBy operator to specify a constraint to select the objects where the values of an array field is contained by another specified array.', - type: new _graphql.GraphQLList(ANY) - }, - contains: { - description: 'This is the contains operator to specify a constraint to select the objects where the values of an array field contain all elements of another specified array.', - type: new _graphql.GraphQLList(ANY) - }, - inQueryKey, - notInQueryKey - } -}); -exports.ARRAY_WHERE_INPUT = ARRAY_WHERE_INPUT; -const KEY_VALUE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'KeyValueInput', - description: 'An entry from an object, i.e., a pair of key and value.', - fields: { - key: { - description: 'The key used to retrieve the value of this entry.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - value: { - description: 'The value of the entry. Could be any type of scalar data.', - type: new _graphql.GraphQLNonNull(ANY) - } - } -}); -exports.KEY_VALUE_INPUT = KEY_VALUE_INPUT; -const OBJECT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ObjectWhereInput', - description: 'The ObjectWhereInput input type is used in operations that involve filtering result by a field of type Object.', - fields: { - equalTo: equalTo(KEY_VALUE_INPUT), - notEqualTo: notEqualTo(KEY_VALUE_INPUT), - in: inOp(KEY_VALUE_INPUT), - notIn: notIn(KEY_VALUE_INPUT), - lessThan: lessThan(KEY_VALUE_INPUT), - lessThanOrEqualTo: lessThanOrEqualTo(KEY_VALUE_INPUT), - greaterThan: greaterThan(KEY_VALUE_INPUT), - greaterThanOrEqualTo: greaterThanOrEqualTo(KEY_VALUE_INPUT), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.OBJECT_WHERE_INPUT = OBJECT_WHERE_INPUT; -const DATE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'DateWhereInput', - description: 'The DateWhereInput input type is used in operations that involve filtering objects by a field of type Date.', - fields: { - equalTo: equalTo(DATE), - notEqualTo: notEqualTo(DATE), - lessThan: lessThan(DATE), - lessThanOrEqualTo: lessThanOrEqualTo(DATE), - greaterThan: greaterThan(DATE), - greaterThanOrEqualTo: greaterThanOrEqualTo(DATE), - in: inOp(DATE), - notIn: notIn(DATE), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.DATE_WHERE_INPUT = DATE_WHERE_INPUT; -const BYTES_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'BytesWhereInput', - description: 'The BytesWhereInput input type is used in operations that involve filtering objects by a field of type Bytes.', - fields: { - equalTo: equalTo(BYTES), - notEqualTo: notEqualTo(BYTES), - lessThan: lessThan(BYTES), - lessThanOrEqualTo: lessThanOrEqualTo(BYTES), - greaterThan: greaterThan(BYTES), - greaterThanOrEqualTo: greaterThanOrEqualTo(BYTES), - in: inOp(BYTES), - notIn: notIn(BYTES), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.BYTES_WHERE_INPUT = BYTES_WHERE_INPUT; -const FILE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'FileWhereInput', - description: 'The FileWhereInput input type is used in operations that involve filtering objects by a field of type File.', - fields: { - equalTo: equalTo(FILE), - notEqualTo: notEqualTo(FILE), - lessThan: lessThan(FILE), - lessThanOrEqualTo: lessThanOrEqualTo(FILE), - greaterThan: greaterThan(FILE), - greaterThanOrEqualTo: greaterThanOrEqualTo(FILE), - in: inOp(FILE), - notIn: notIn(FILE), - exists, - matchesRegex, - options, - inQueryKey, - notInQueryKey - } -}); -exports.FILE_WHERE_INPUT = FILE_WHERE_INPUT; -const GEO_POINT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoPointWhereInput', - description: 'The GeoPointWhereInput input type is used in operations that involve filtering objects by a field of type GeoPoint.', - fields: { - exists, - nearSphere: { - description: 'This is the nearSphere operator to specify a constraint to select the objects where the values of a geo point field is near to another geo point.', - type: GEO_POINT_INPUT - }, - maxDistance: { - description: 'This is the maxDistance operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - maxDistanceInRadians: { - description: 'This is the maxDistanceInRadians operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - maxDistanceInMiles: { - description: 'This is the maxDistanceInMiles operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in miles) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - maxDistanceInKilometers: { - description: 'This is the maxDistanceInKilometers operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in kilometers) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - within: { - description: 'This is the within operator to specify a constraint to select the objects where the values of a geo point field is within a specified box.', - type: WITHIN_INPUT - }, - geoWithin: { - description: 'This is the geoWithin operator to specify a constraint to select the objects where the values of a geo point field is within a specified polygon or sphere.', - type: GEO_WITHIN_INPUT - } - } -}); -exports.GEO_POINT_WHERE_INPUT = GEO_POINT_WHERE_INPUT; -const POLYGON_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'PolygonWhereInput', - description: 'The PolygonWhereInput input type is used in operations that involve filtering objects by a field of type Polygon.', - fields: { - exists, - geoIntersects: { - description: 'This is the geoIntersects operator to specify a constraint to select the objects where the values of a polygon field intersect a specified point.', - type: GEO_INTERSECTS_INPUT - } - } -}); -exports.POLYGON_WHERE_INPUT = POLYGON_WHERE_INPUT; -const ELEMENT = new _graphql.GraphQLObjectType({ - name: 'Element', - description: "The Element object type is used to return array items' value.", - fields: { - value: { - description: 'Return the value of the element in the array', - type: new _graphql.GraphQLNonNull(ANY) - } - } -}); // Default static union type, we update types and resolveType function later - -exports.ELEMENT = ELEMENT; -let ARRAY_RESULT; -exports.ARRAY_RESULT = ARRAY_RESULT; - -const loadArrayResult = (parseGraphQLSchema, parseClasses) => { - const classTypes = parseClasses.filter(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType ? true : false).map(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType); - exports.ARRAY_RESULT = ARRAY_RESULT = new _graphql.GraphQLUnionType({ - name: 'ArrayResult', - description: 'Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments', - types: () => [ELEMENT, ...classTypes], - resolveType: value => { - if (value.__type === 'Object' && value.className && value.objectId) { - if (parseGraphQLSchema.parseClassTypes[value.className]) { - return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType; - } else { - return ELEMENT; - } - } else { - return ELEMENT; - } - } - }); - parseGraphQLSchema.graphQLTypes.push(ARRAY_RESULT); -}; - -exports.loadArrayResult = loadArrayResult; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLType(_links.GraphQLUpload, true); - parseGraphQLSchema.addGraphQLType(ANY, true); - parseGraphQLSchema.addGraphQLType(OBJECT, true); - parseGraphQLSchema.addGraphQLType(DATE, true); - parseGraphQLSchema.addGraphQLType(BYTES, true); - parseGraphQLSchema.addGraphQLType(FILE, true); - parseGraphQLSchema.addGraphQLType(FILE_INFO, true); - parseGraphQLSchema.addGraphQLType(FILE_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_POINT_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_POINT, true); - parseGraphQLSchema.addGraphQLType(PARSE_OBJECT, true); - parseGraphQLSchema.addGraphQLType(READ_PREFERENCE, true); - parseGraphQLSchema.addGraphQLType(READ_OPTIONS_INPUT, true); - parseGraphQLSchema.addGraphQLType(SEARCH_INPUT, true); - parseGraphQLSchema.addGraphQLType(TEXT_INPUT, true); - parseGraphQLSchema.addGraphQLType(BOX_INPUT, true); - parseGraphQLSchema.addGraphQLType(WITHIN_INPUT, true); - parseGraphQLSchema.addGraphQLType(CENTER_SPHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_WITHIN_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_INTERSECTS_INPUT, true); - parseGraphQLSchema.addGraphQLType(ID_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(STRING_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(NUMBER_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(BOOLEAN_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(ARRAY_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(KEY_VALUE_INPUT, true); - parseGraphQLSchema.addGraphQLType(OBJECT_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(DATE_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(BYTES_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(FILE_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_POINT_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(POLYGON_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(ELEMENT, true); - parseGraphQLSchema.addGraphQLType(ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(USER_ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(ROLE_ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(PUBLIC_ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(ACL, true); - parseGraphQLSchema.addGraphQLType(USER_ACL, true); - parseGraphQLSchema.addGraphQLType(ROLE_ACL, true); - parseGraphQLSchema.addGraphQLType(PUBLIC_ACL, true); - parseGraphQLSchema.addGraphQLType(SUBQUERY_INPUT, true); - parseGraphQLSchema.addGraphQLType(SELECT_INPUT, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcy5qcyJdLCJuYW1lcyI6WyJUeXBlVmFsaWRhdGlvbkVycm9yIiwiRXJyb3IiLCJjb25zdHJ1Y3RvciIsInZhbHVlIiwidHlwZSIsInBhcnNlU3RyaW5nVmFsdWUiLCJwYXJzZUludFZhbHVlIiwiaW50IiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwicGFyc2VGbG9hdFZhbHVlIiwiZmxvYXQiLCJpc05hTiIsInBhcnNlQm9vbGVhblZhbHVlIiwicGFyc2VWYWx1ZSIsImtpbmQiLCJLaW5kIiwiU1RSSU5HIiwiSU5UIiwiRkxPQVQiLCJCT09MRUFOIiwiTElTVCIsInBhcnNlTGlzdFZhbHVlcyIsInZhbHVlcyIsIk9CSkVDVCIsInBhcnNlT2JqZWN0RmllbGRzIiwiZmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwicmVkdWNlIiwib2JqZWN0IiwiZmllbGQiLCJuYW1lIiwiQU5ZIiwiR3JhcGhRTFNjYWxhclR5cGUiLCJkZXNjcmlwdGlvbiIsInNlcmlhbGl6ZSIsInBhcnNlTGl0ZXJhbCIsImFzdCIsInBhcnNlRGF0ZUlzb1ZhbHVlIiwiZGF0ZSIsIkRhdGUiLCJzZXJpYWxpemVEYXRlSXNvIiwidG9JU09TdHJpbmciLCJwYXJzZURhdGVJc29MaXRlcmFsIiwiREFURSIsIl9fdHlwZSIsImlzbyIsImZpbmQiLCJCWVRFUyIsImJhc2U2NCIsInBhcnNlRmlsZVZhbHVlIiwidXJsIiwidW5kZWZpbmVkIiwiRklMRSIsIkZJTEVfSU5GTyIsIkdyYXBoUUxPYmplY3RUeXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiRklMRV9JTlBVVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJmaWxlIiwidXBsb2FkIiwiR3JhcGhRTFVwbG9hZCIsInVubGluayIsIkdyYXBoUUxCb29sZWFuIiwiR0VPX1BPSU5UX0ZJRUxEUyIsImxhdGl0dWRlIiwiR3JhcGhRTEZsb2F0IiwibG9uZ2l0dWRlIiwiR0VPX1BPSU5UX0lOUFVUIiwiR0VPX1BPSU5UIiwiUE9MWUdPTl9JTlBVVCIsIkdyYXBoUUxMaXN0IiwiUE9MWUdPTiIsIlVTRVJfQUNMX0lOUFVUIiwidXNlcklkIiwiR3JhcGhRTElEIiwicmVhZCIsIndyaXRlIiwiUk9MRV9BQ0xfSU5QVVQiLCJyb2xlTmFtZSIsIlBVQkxJQ19BQ0xfSU5QVVQiLCJBQ0xfSU5QVVQiLCJ1c2VycyIsInJvbGVzIiwicHVibGljIiwiVVNFUl9BQ0wiLCJST0xFX0FDTCIsIlBVQkxJQ19BQ0wiLCJBQ0wiLCJyZXNvbHZlIiwicCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwicnVsZSIsImluZGV4T2YiLCJwdXNoIiwibGVuZ3RoIiwicmVwbGFjZSIsIk9CSkVDVF9JRCIsIkNMQVNTX05BTUVfQVRUIiwiR0xPQkFMX09SX09CSkVDVF9JRF9BVFQiLCJPQkpFQ1RfSURfQVRUIiwiQ1JFQVRFRF9BVF9BVFQiLCJVUERBVEVEX0FUX0FUVCIsIklOUFVUX0ZJRUxEUyIsIkNSRUFURV9SRVNVTFRfRklFTERTIiwib2JqZWN0SWQiLCJjcmVhdGVkQXQiLCJVUERBVEVfUkVTVUxUX0ZJRUxEUyIsInVwZGF0ZWRBdCIsIlBBUlNFX09CSkVDVF9GSUVMRFMiLCJQQVJTRV9PQkpFQ1QiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsIlNFU1NJT05fVE9LRU5fQVRUIiwiUkVBRF9QUkVGRVJFTkNFIiwiR3JhcGhRTEVudW1UeXBlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJSRUFEX1BSRUZFUkVOQ0VfQVRUIiwiSU5DTFVERV9SRUFEX1BSRUZFUkVOQ0VfQVRUIiwiU1VCUVVFUllfUkVBRF9QUkVGRVJFTkNFX0FUVCIsIlJFQURfT1BUSU9OU19JTlBVVCIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsIlJFQURfT1BUSU9OU19BVFQiLCJXSEVSRV9BVFQiLCJTS0lQX0FUVCIsIkdyYXBoUUxJbnQiLCJMSU1JVF9BVFQiLCJDT1VOVF9BVFQiLCJTRUFSQ0hfSU5QVVQiLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwiVEVYVF9JTlBVVCIsInNlYXJjaCIsIkJPWF9JTlBVVCIsImJvdHRvbUxlZnQiLCJ1cHBlclJpZ2h0IiwiV0lUSElOX0lOUFVUIiwiYm94IiwiQ0VOVEVSX1NQSEVSRV9JTlBVVCIsImNlbnRlciIsImRpc3RhbmNlIiwiR0VPX1dJVEhJTl9JTlBVVCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJHRU9fSU5URVJTRUNUU19JTlBVVCIsInBvaW50IiwiZXF1YWxUbyIsIm5vdEVxdWFsVG8iLCJsZXNzVGhhbiIsImxlc3NUaGFuT3JFcXVhbFRvIiwiZ3JlYXRlclRoYW4iLCJncmVhdGVyVGhhbk9yRXF1YWxUbyIsImluT3AiLCJub3RJbiIsImV4aXN0cyIsIm1hdGNoZXNSZWdleCIsIm9wdGlvbnMiLCJTVUJRVUVSWV9JTlBVVCIsImNsYXNzTmFtZSIsIndoZXJlIiwiYXNzaWduIiwiU0VMRUNUX0lOUFVUIiwicXVlcnkiLCJrZXkiLCJpblF1ZXJ5S2V5Iiwibm90SW5RdWVyeUtleSIsIklEX1dIRVJFX0lOUFVUIiwiaW4iLCJTVFJJTkdfV0hFUkVfSU5QVVQiLCJ0ZXh0IiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiY29udGFpbmVkQnkiLCJjb250YWlucyIsIktFWV9WQUxVRV9JTlBVVCIsIk9CSkVDVF9XSEVSRV9JTlBVVCIsIkRBVEVfV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsIkZJTEVfV0hFUkVfSU5QVVQiLCJHRU9fUE9JTlRfV0hFUkVfSU5QVVQiLCJuZWFyU3BoZXJlIiwibWF4RGlzdGFuY2UiLCJtYXhEaXN0YW5jZUluUmFkaWFucyIsIm1heERpc3RhbmNlSW5NaWxlcyIsIm1heERpc3RhbmNlSW5LaWxvbWV0ZXJzIiwid2l0aGluIiwiZ2VvV2l0aGluIiwiUE9MWUdPTl9XSEVSRV9JTlBVVCIsImdlb0ludGVyc2VjdHMiLCJFTEVNRU5UIiwiQVJSQVlfUkVTVUxUIiwibG9hZEFycmF5UmVzdWx0IiwicGFyc2VHcmFwaFFMU2NoZW1hIiwicGFyc2VDbGFzc2VzIiwiY2xhc3NUeXBlcyIsImZpbHRlciIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiR3JhcGhRTFVuaW9uVHlwZSIsInR5cGVzIiwicmVzb2x2ZVR5cGUiLCJncmFwaFFMVHlwZXMiLCJsb2FkIiwiYWRkR3JhcGhRTFR5cGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFnQkE7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsbUJBQU4sU0FBa0NDLEtBQWxDLENBQXdDO0FBQ3RDQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUUMsSUFBUixFQUFjO0FBQ3ZCLFVBQU8sR0FBRUQsS0FBTSxtQkFBa0JDLElBQUssRUFBdEM7QUFDRDs7QUFIcUM7Ozs7QUFNeEMsTUFBTUMsZ0JBQWdCLEdBQUlGLEtBQUQsSUFBVztBQUNsQyxNQUFJLE9BQU9BLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsV0FBT0EsS0FBUDtBQUNEOztBQUVELFFBQU0sSUFBSUgsbUJBQUosQ0FBd0JHLEtBQXhCLEVBQStCLFFBQS9CLENBQU47QUFDRCxDQU5EOzs7O0FBUUEsTUFBTUcsYUFBYSxHQUFJSCxLQUFELElBQVc7QUFDL0IsTUFBSSxPQUFPQSxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLFVBQU1JLEdBQUcsR0FBR0MsTUFBTSxDQUFDTCxLQUFELENBQWxCOztBQUNBLFFBQUlLLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkYsR0FBakIsQ0FBSixFQUEyQjtBQUN6QixhQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7QUFF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WSxjQUFuQixDQUFrQy9ILFVBQWxDLEVBQThDLElBQTlDO0FBQ0FtSCxFQUFBQSxrQkFBa0IsQ0FBQ1ksY0FBbkIsQ0FBa0NoRCxjQUFsQyxFQUFrRCxJQUFsRDtBQUNBb0MsRUFBQUEsa0JBQWtCLENBQUNZLGNBQW5CLENBQWtDNUMsWUFBbEMsRUFBZ0QsSUFBaEQ7QUFDRCxDQTVDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEtpbmQsXG4gIEdyYXBoUUxOb25OdWxsLFxuICBHcmFwaFFMU2NhbGFyVHlwZSxcbiAgR3JhcGhRTElELFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMT2JqZWN0VHlwZSxcbiAgR3JhcGhRTEludGVyZmFjZVR5cGUsXG4gIEdyYXBoUUxFbnVtVHlwZSxcbiAgR3JhcGhRTEludCxcbiAgR3JhcGhRTEZsb2F0LFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTEJvb2xlYW4sXG4gIEdyYXBoUUxVbmlvblR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgdG9HbG9iYWxJZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgR3JhcGhRTFVwbG9hZCB9IGZyb20gJ0BncmFwaHFsLXRvb2xzL2xpbmtzJztcblxuY2xhc3MgVHlwZVZhbGlkYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IodmFsdWUsIHR5cGUpIHtcbiAgICBzdXBlcihgJHt2YWx1ZX0gaXMgbm90IGEgdmFsaWQgJHt0eXBlfWApO1xuICB9XG59XG5cbmNvbnN0IHBhcnNlU3RyaW5nVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ1N0cmluZycpO1xufTtcblxuY29uc3QgcGFyc2VJbnRWYWx1ZSA9ICh2YWx1ZSkgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGludCA9IE51bWJlcih2YWx1ZSk7XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIoaW50KSkge1xuICAgICAgcmV0dXJuIGludDtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0ludCcpO1xufTtcblxuY29uc3QgcGFyc2VGbG9hdFZhbHVlID0gKHZhbHVlKSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgZmxvYXQgPSBOdW1iZXIodmFsdWUpO1xuICAgIGlmICghaXNOYU4oZmxvYXQpKSB7XG4gICAgICByZXR1cm4gZmxvYXQ7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdGbG9hdCcpO1xufTtcblxuY29uc3QgcGFyc2VCb29sZWFuVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdCb29sZWFuJyk7XG59O1xuXG5jb25zdCBwYXJzZVZhbHVlID0gKHZhbHVlKSA9PiB7XG4gIHN3aXRjaCAodmFsdWUua2luZCkge1xuICAgIGNhc2UgS2luZC5TVFJJTkc6XG4gICAgICByZXR1cm4gcGFyc2VTdHJpbmdWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuSU5UOlxuICAgICAgcmV0dXJuIHBhcnNlSW50VmFsdWUodmFsdWUudmFsdWUpO1xuXG4gICAgY2FzZSBLaW5kLkZMT0FUOlxuICAgICAgcmV0dXJuIHBhcnNlRmxvYXRWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuQk9PTEVBTjpcbiAgICAgIHJldHVybiBwYXJzZUJvb2xlYW5WYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuTElTVDpcbiAgICAgIHJldHVybiBwYXJzZUxpc3RWYWx1ZXModmFsdWUudmFsdWVzKTtcblxuICAgIGNhc2UgS2luZC5PQkpFQ1Q6XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RGaWVsZHModmFsdWUuZmllbGRzKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdmFsdWUudmFsdWU7XG4gIH1cbn07XG5cbmNvbnN0IHBhcnNlTGlzdFZhbHVlcyA9ICh2YWx1ZXMpID0+IHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xuICAgIHJldHVybiB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4gcGFyc2VWYWx1ZSh2YWx1ZSkpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWVzLCAnTGlzdCcpO1xufTtcblxuY29uc3QgcGFyc2VPYmplY3RGaWVsZHMgPSAoZmllbGRzKSA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KGZpZWxkcykpIHtcbiAgICByZXR1cm4gZmllbGRzLnJlZHVjZShcbiAgICAgIChvYmplY3QsIGZpZWxkKSA9PiAoe1xuICAgICAgICAuLi5vYmplY3QsXG4gICAgICAgIFtmaWVsZC5uYW1lLnZhbHVlXTogcGFyc2VWYWx1ZShmaWVsZC52YWx1ZSksXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGZpZWxkcywgJ09iamVjdCcpO1xufTtcblxuY29uc3QgQU5ZID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0FueScsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQW55IHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGFueSB0eXBlIG9mIHZhbHVlLicsXG4gIHBhcnNlVmFsdWU6ICh2YWx1ZSkgPT4gdmFsdWUsXG4gIHNlcmlhbGl6ZTogKHZhbHVlKSA9PiB2YWx1ZSxcbiAgcGFyc2VMaXRlcmFsOiAoYXN0KSA9PiBwYXJzZVZhbHVlKGFzdCksXG59KTtcblxuY29uc3QgT0JKRUNUID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ09iamVjdCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgT2JqZWN0IHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIG9iamVjdHMuJyxcbiAgcGFyc2VWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdPYmplY3QnKTtcbiAgfSxcbiAgc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ09iamVjdCcpO1xuICB9LFxuICBwYXJzZUxpdGVyYWwoYXN0KSB7XG4gICAgaWYgKGFzdC5raW5kID09PSBLaW5kLk9CSkVDVCkge1xuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0RmllbGRzKGFzdC5maWVsZHMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnT2JqZWN0Jyk7XG4gIH0sXG59KTtcblxuY29uc3QgcGFyc2VEYXRlSXNvVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUodmFsdWUpO1xuICAgIGlmICghaXNOYU4oZGF0ZSkpIHtcbiAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cbiAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0RhdGUnKTtcbn07XG5cbmNvbnN0IHNlcmlhbGl6ZURhdGVJc28gPSAodmFsdWUpID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG59O1xuXG5jb25zdCBwYXJzZURhdGVJc29MaXRlcmFsID0gKGFzdCkgPT4ge1xuICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgcmV0dXJuIHBhcnNlRGF0ZUlzb1ZhbHVlKGFzdC52YWx1ZSk7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ0RhdGUnKTtcbn07XG5cbmNvbnN0IERBVEUgPSBuZXcgR3JhcGhRTFNjYWxhclR5cGUoe1xuICBuYW1lOiAnRGF0ZScsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRGF0ZSBzY2FsYXIgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgYW5kIHR5cGVzIHRoYXQgaW52b2x2ZSBkYXRlcy4nLFxuICBwYXJzZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29WYWx1ZSh2YWx1ZSksXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICB2YWx1ZS5fX3R5cGUgPT09ICdEYXRlJyAmJlxuICAgICAgdmFsdWUuaXNvXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6IHZhbHVlLl9fdHlwZSxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29WYWx1ZSh2YWx1ZS5pc28pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0RhdGUnKTtcbiAgfSxcbiAgc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4gc2VyaWFsaXplRGF0ZUlzbyh2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnICYmXG4gICAgICB2YWx1ZS5pc29cbiAgICApIHtcbiAgICAgIHJldHVybiBzZXJpYWxpemVEYXRlSXNvKHZhbHVlLmlzbyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG4gIH0sXG4gIHBhcnNlTGl0ZXJhbChhc3QpIHtcbiAgICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29MaXRlcmFsKGFzdCksXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYXN0LmtpbmQgPT09IEtpbmQuT0JKRUNUKSB7XG4gICAgICBjb25zdCBfX3R5cGUgPSBhc3QuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnX190eXBlJyk7XG4gICAgICBjb25zdCBpc28gPSBhc3QuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnaXNvJyk7XG4gICAgICBpZiAoX190eXBlICYmIF9fdHlwZS52YWx1ZSAmJiBfX3R5cGUudmFsdWUudmFsdWUgPT09ICdEYXRlJyAmJiBpc28pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBfX3R5cGU6IF9fdHlwZS52YWx1ZS52YWx1ZSxcbiAgICAgICAgICBpc286IHBhcnNlRGF0ZUlzb0xpdGVyYWwoaXNvLnZhbHVlKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ0RhdGUnKTtcbiAgfSxcbn0pO1xuXG5jb25zdCBCWVRFUyA9IG5ldyBHcmFwaFFMU2NhbGFyVHlwZSh7XG4gIG5hbWU6ICdCeXRlcycsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQnl0ZXMgc2NhbGFyIHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIGFuZCB0eXBlcyB0aGF0IGludm9sdmUgYmFzZSA2NCBiaW5hcnkgZGF0YS4nLFxuICBwYXJzZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ0J5dGVzJyxcbiAgICAgICAgYmFzZTY0OiB2YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJyAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmJhc2U2NCA9PT0gJ3N0cmluZydcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0J5dGVzJyk7XG4gIH0sXG4gIHNlcmlhbGl6ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJyAmJlxuICAgICAgdHlwZW9mIHZhbHVlLmJhc2U2NCA9PT0gJ3N0cmluZydcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZS5iYXNlNjQ7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdCeXRlcycpO1xuICB9LFxuICBwYXJzZUxpdGVyYWwoYXN0KSB7XG4gICAgaWYgKGFzdC5raW5kID09PSBLaW5kLlNUUklORykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnQnl0ZXMnLFxuICAgICAgICBiYXNlNjQ6IGFzdC52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChhc3Qua2luZCA9PT0gS2luZC5PQkpFQ1QpIHtcbiAgICAgIGNvbnN0IF9fdHlwZSA9IGFzdC5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdfX3R5cGUnKTtcbiAgICAgIGNvbnN0IGJhc2U2NCA9IGFzdC5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdiYXNlNjQnKTtcbiAgICAgIGlmIChcbiAgICAgICAgX190eXBlICYmXG4gICAgICAgIF9fdHlwZS52YWx1ZSAmJlxuICAgICAgICBfX3R5cGUudmFsdWUudmFsdWUgPT09ICdCeXRlcycgJiZcbiAgICAgICAgYmFzZTY0ICYmXG4gICAgICAgIGJhc2U2NC52YWx1ZSAmJlxuICAgICAgICB0eXBlb2YgYmFzZTY0LnZhbHVlLnZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgX190eXBlOiBfX3R5cGUudmFsdWUudmFsdWUsXG4gICAgICAgICAgYmFzZTY0OiBiYXNlNjQudmFsdWUudmFsdWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IoYXN0LmtpbmQsICdCeXRlcycpO1xuICB9LFxufSk7XG5cbmNvbnN0IHBhcnNlRmlsZVZhbHVlID0gKHZhbHVlKSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogJ0ZpbGUnLFxuICAgICAgbmFtZTogdmFsdWUsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUuX190eXBlID09PSAnRmlsZScgJiZcbiAgICB0eXBlb2YgdmFsdWUubmFtZSA9PT0gJ3N0cmluZycgJiZcbiAgICAodmFsdWUudXJsID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHZhbHVlLnVybCA9PT0gJ3N0cmluZycpXG4gICkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRmlsZScpO1xufTtcblxuY29uc3QgRklMRSA9IG5ldyBHcmFwaFFMU2NhbGFyVHlwZSh7XG4gIG5hbWU6ICdGaWxlJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBGaWxlIHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGZpbGVzLicsXG4gIHBhcnNlVmFsdWU6IHBhcnNlRmlsZVZhbHVlLFxuICBzZXJpYWxpemU6ICh2YWx1ZSkgPT4ge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHZhbHVlLl9fdHlwZSA9PT0gJ0ZpbGUnICYmXG4gICAgICB0eXBlb2YgdmFsdWUubmFtZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICh2YWx1ZS51cmwgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdmFsdWUudXJsID09PSAnc3RyaW5nJylcbiAgICApIHtcbiAgICAgIHJldHVybiB2YWx1ZS5uYW1lO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRmlsZScpO1xuICB9LFxuICBwYXJzZUxpdGVyYWwoYXN0KSB7XG4gICAgaWYgKGFzdC5raW5kID09PSBLaW5kLlNUUklORykge1xuICAgICAgcmV0dXJuIHBhcnNlRmlsZVZhbHVlKGFzdC52YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChhc3Qua2luZCA9PT0gS2luZC5PQkpFQ1QpIHtcbiAgICAgIGNvbnN0IF9fdHlwZSA9IGFzdC5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdfX3R5cGUnKTtcbiAgICAgIGNvbnN0IG5hbWUgPSBhc3QuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnbmFtZScpO1xuICAgICAgY29uc3QgdXJsID0gYXN0LmZpZWxkcy5maW5kKChmaWVsZCkgPT4gZmllbGQubmFtZS52YWx1ZSA9PT0gJ3VybCcpO1xuICAgICAgaWYgKF9fdHlwZSAmJiBfX3R5cGUudmFsdWUgJiYgbmFtZSAmJiBuYW1lLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUZpbGVWYWx1ZSh7XG4gICAgICAgICAgX190eXBlOiBfX3R5cGUudmFsdWUudmFsdWUsXG4gICAgICAgICAgbmFtZTogbmFtZS52YWx1ZS52YWx1ZSxcbiAgICAgICAgICB1cmw6IHVybCAmJiB1cmwudmFsdWUgPyB1cmwudmFsdWUudmFsdWUgOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnRmlsZScpO1xuICB9LFxufSk7XG5cbmNvbnN0IEZJTEVfSU5GTyA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdGaWxlSW5mbycsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRmlsZUluZm8gb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGZpbGVzLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZmlsZSBuYW1lLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICB1cmw6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgdXJsIGluIHdoaWNoIHRoZSBmaWxlIGNhbiBiZSBkb3dubG9hZGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBGSUxFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnRmlsZUlucHV0JyxcbiAgZmllbGRzOiB7XG4gICAgZmlsZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBIEZpbGUgU2NhbGFyIGNhbiBiZSBhbiB1cmwgb3IgYSBGaWxlSW5mbyBvYmplY3QuIElmIHRoaXMgZmllbGQgaXMgc2V0IHRvIG51bGwgdGhlIGZpbGUgd2lsbCBiZSB1bmxpbmtlZC4nLFxuICAgICAgdHlwZTogRklMRSxcbiAgICB9LFxuICAgIHVwbG9hZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdVc2UgdGhpcyBmaWVsZCBpZiB5b3Ugd2FudCB0byBjcmVhdGUgYSBuZXcgZmlsZS4nLFxuICAgICAgdHlwZTogR3JhcGhRTFVwbG9hZCxcbiAgICB9LFxuICAgIHVubGluazoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdVc2UgdGhpcyBmaWVsZCBpZiB5b3Ugd2FudCB0byB1bmxpbmsgdGhlIGZpbGUgKHRoZSBmaWxlIHdpbGwgbm90IGJlIGRlbGV0ZWQgb24gY2xvdWQgc3RvcmFnZSknLFxuICAgICAgdHlwZTogR3JhcGhRTEJvb2xlYW4sXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBHRU9fUE9JTlRfRklFTERTID0ge1xuICBsYXRpdHVkZToge1xuICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbGF0aXR1ZGUuJyxcbiAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEZsb2F0KSxcbiAgfSxcbiAgbG9uZ2l0dWRlOiB7XG4gICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBsb25naXR1ZGUuJyxcbiAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEZsb2F0KSxcbiAgfSxcbn07XG5cbmNvbnN0IEdFT19QT0lOVF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1BvaW50SW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEdlb1BvaW50SW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGlucHV0dGluZyBmaWVsZHMgb2YgdHlwZSBnZW8gcG9pbnQuJyxcbiAgZmllbGRzOiBHRU9fUE9JTlRfRklFTERTLFxufSk7XG5cbmNvbnN0IEdFT19QT0lOVCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdHZW9Qb2ludCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvUG9pbnQgb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGdlbyBwb2ludCBmaWVsZHMuJyxcbiAgZmllbGRzOiBHRU9fUE9JTlRfRklFTERTLFxufSk7XG5cbmNvbnN0IFBPTFlHT05fSU5QVVQgPSBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKEdFT19QT0lOVF9JTlBVVCkpO1xuXG5jb25zdCBQT0xZR09OID0gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlQpKTtcblxuY29uc3QgVVNFUl9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdVc2VyQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSB1c2VycyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgdXNlcklkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0lEIG9mIHRoZSB0YXJnZXR0ZWQgVXNlci4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxJRCksXG4gICAgfSxcbiAgICByZWFkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdGhlIHVzZXIgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUk9MRV9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdSb2xlQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSByb2xlcyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFBVQkxJQ19BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0xJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnQWxsb3cgdG8gbWFuYWdlIHB1YmxpYyByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIGFjY2VzcyByaWdodHMuIElmIG5vdCBwcm92aWRlZCBvYmplY3Qgd2lsbCBiZSBwdWJsaWNseSByZWFkYWJsZSBhbmQgd3JpdGFibGUnLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTF9JTlBVVCkpLFxuICAgIH0sXG4gICAgcm9sZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWNjZXNzIGNvbnRyb2wgbGlzdCBmb3Igcm9sZXMuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoUk9MRV9BQ0xfSU5QVVQpKSxcbiAgICB9LFxuICAgIHB1YmxpYzoge1xuICAgICAgZGVzY3JpcHRpb246ICdQdWJsaWMgYWNjZXNzIGNvbnRyb2wgbGlzdC4nLFxuICAgICAgdHlwZTogUFVCTElDX0FDTF9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFVTRVJfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1VzZXJBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHVzZXJzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHVzZXJzIGhhdmUgcmVhZCBhbmQgd3JpdGUgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHVzZXJJZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdJRCBvZiB0aGUgdGFyZ2V0dGVkIFVzZXIuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB0aGUgdXNlciB0byByZWFkIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFJPTEVfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1JvbGVBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHJvbGVzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHJvbGUgaGF2ZSByZWFkIGFuZCB3cml0ZSByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUFVCTElDX0FDTCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0wnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSBwdWJsaWMgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgYW55b25lIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IGFueW9uZSB0byB3cml0ZSBvbiB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0FDTCcsXG4gIGRlc2NyaXB0aW9uOiAnQ3VycmVudCBhY2Nlc3MgY29udHJvbCBsaXN0IG9mIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTCkpLFxuICAgICAgcmVzb2x2ZShwKSB7XG4gICAgICAgIGNvbnN0IHVzZXJzID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHApLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgICBpZiAocnVsZSAhPT0gJyonICYmIHJ1bGUuaW5kZXhPZigncm9sZTonKSAhPT0gMCkge1xuICAgICAgICAgICAgdXNlcnMucHVzaCh7XG4gICAgICAgICAgICAgIHVzZXJJZDogdG9HbG9iYWxJZCgnX1VzZXInLCBydWxlKSxcbiAgICAgICAgICAgICAgcmVhZDogcFtydWxlXS5yZWFkID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICB3cml0ZTogcFtydWxlXS53cml0ZSA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1c2Vycy5sZW5ndGggPyB1c2VycyA6IG51bGw7XG4gICAgICB9LFxuICAgIH0sXG4gICAgcm9sZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWNjZXNzIGNvbnRyb2wgbGlzdCBmb3Igcm9sZXMuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoUk9MRV9BQ0wpKSxcbiAgICAgIHJlc29sdmUocCkge1xuICAgICAgICBjb25zdCByb2xlcyA9IFtdO1xuICAgICAgICBPYmplY3Qua2V5cyhwKS5mb3JFYWNoKChydWxlKSA9PiB7XG4gICAgICAgICAgaWYgKHJ1bGUuaW5kZXhPZigncm9sZTonKSA9PT0gMCkge1xuICAgICAgICAgICAgcm9sZXMucHVzaCh7XG4gICAgICAgICAgICAgIHJvbGVOYW1lOiBydWxlLnJlcGxhY2UoJ3JvbGU6JywgJycpLFxuICAgICAgICAgICAgICByZWFkOiBwW3J1bGVdLnJlYWQgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICAgIHdyaXRlOiBwW3J1bGVdLndyaXRlID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJvbGVzLmxlbmd0aCA/IHJvbGVzIDogbnVsbDtcbiAgICAgIH0sXG4gICAgfSxcbiAgICBwdWJsaWM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnUHVibGljIGFjY2VzcyBjb250cm9sIGxpc3QuJyxcbiAgICAgIHR5cGU6IFBVQkxJQ19BQ0wsXG4gICAgICByZXNvbHZlKHApIHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgKi9cbiAgICAgICAgcmV0dXJuIHBbJyonXVxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICByZWFkOiBwWycqJ10ucmVhZCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgd3JpdGU6IHBbJyonXS53cml0ZSA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IG51bGw7XG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgT0JKRUNUX0lEID0gbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxJRCk7XG5cbmNvbnN0IENMQVNTX05BTUVfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNsYXNzIG5hbWUgb2YgdGhlIG9iamVjdC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBPQkpFQ1RfSURfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBDUkVBVEVEX0FUX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBkYXRlIGluIHdoaWNoIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKERBVEUpLFxufTtcblxuY29uc3QgVVBEQVRFRF9BVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZGF0ZSBpbiB3aGljaCB0aGUgb2JqZWN0IHdhcyBsYXMgdXBkYXRlZC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoREFURSksXG59O1xuXG5jb25zdCBJTlBVVF9GSUVMRFMgPSB7XG4gIEFDTDoge1xuICAgIHR5cGU6IEFDTCxcbiAgfSxcbn07XG5cbmNvbnN0IENSRUFURV9SRVNVTFRfRklFTERTID0ge1xuICBvYmplY3RJZDogT0JKRUNUX0lEX0FUVCxcbiAgY3JlYXRlZEF0OiBDUkVBVEVEX0FUX0FUVCxcbn07XG5cbmNvbnN0IFVQREFURV9SRVNVTFRfRklFTERTID0ge1xuICB1cGRhdGVkQXQ6IFVQREFURURfQVRfQVRULFxufTtcblxuY29uc3QgUEFSU0VfT0JKRUNUX0ZJRUxEUyA9IHtcbiAgLi4uQ1JFQVRFX1JFU1VMVF9GSUVMRFMsXG4gIC4uLlVQREFURV9SRVNVTFRfRklFTERTLFxuICAuLi5JTlBVVF9GSUVMRFMsXG4gIEFDTDoge1xuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBQ0wpLFxuICAgIHJlc29sdmU6ICh7IEFDTCB9KSA9PiAoQUNMID8gQUNMIDogeyAnKic6IHsgcmVhZDogdHJ1ZSwgd3JpdGU6IHRydWUgfSB9KSxcbiAgfSxcbn07XG5cbmNvbnN0IFBBUlNFX09CSkVDVCA9IG5ldyBHcmFwaFFMSW50ZXJmYWNlVHlwZSh7XG4gIG5hbWU6ICdQYXJzZU9iamVjdCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUGFyc2VPYmplY3QgaW50ZXJmYWNlIHR5cGUgaXMgdXNlZCBhcyBhIGJhc2UgdHlwZSBmb3IgdGhlIGF1dG8gZ2VuZXJhdGVkIG9iamVjdCB0eXBlcy4nLFxuICBmaWVsZHM6IFBBUlNFX09CSkVDVF9GSUVMRFMsXG59KTtcblxuY29uc3QgU0VTU0lPTl9UT0tFTl9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIGN1cnJlbnQgdXNlciBzZXNzaW9uIHRva2VuLicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IFJFQURfUFJFRkVSRU5DRSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICBuYW1lOiAnUmVhZFByZWZlcmVuY2UnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFJlYWRQcmVmZXJlbmNlIGVudW0gdHlwZSBpcyB1c2VkIGluIHF1ZXJpZXMgaW4gb3JkZXIgdG8gc2VsZWN0IGluIHdoaWNoIGRhdGFiYXNlIHJlcGxpY2EgdGhlIG9wZXJhdGlvbiBtdXN0IHJ1bi4nLFxuICB2YWx1ZXM6IHtcbiAgICBQUklNQVJZOiB7IHZhbHVlOiAnUFJJTUFSWScgfSxcbiAgICBQUklNQVJZX1BSRUZFUlJFRDogeyB2YWx1ZTogJ1BSSU1BUllfUFJFRkVSUkVEJyB9LFxuICAgIFNFQ09OREFSWTogeyB2YWx1ZTogJ1NFQ09OREFSWScgfSxcbiAgICBTRUNPTkRBUllfUFJFRkVSUkVEOiB7IHZhbHVlOiAnU0VDT05EQVJZX1BSRUZFUlJFRCcgfSxcbiAgICBORUFSRVNUOiB7IHZhbHVlOiAnTkVBUkVTVCcgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBSRUFEX1BSRUZFUkVOQ0VfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBtYWluIHF1ZXJ5IHRvIGJlIGV4ZWN1dGVkLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBxdWVyaWVzIHRvIGJlIGV4ZWN1dGVkIHRvIGluY2x1ZGUgZmllbGRzLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IFNVQlFVRVJZX1JFQURfUFJFRkVSRU5DRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIHJlYWQgcHJlZmVyZW5jZSBmb3IgdGhlIHN1YnF1ZXJpZXMgdGhhdCBtYXkgYmUgcmVxdWlyZWQuJyxcbiAgdHlwZTogUkVBRF9QUkVGRVJFTkNFLFxufTtcblxuY29uc3QgUkVBRF9PUFRJT05TX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUmVhZE9wdGlvbnNJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUmVhZE9wdGlvbnNJbnB1dHQgdHlwZSBpcyB1c2VkIGluIHF1ZXJpZXMgaW4gb3JkZXIgdG8gc2V0IHRoZSByZWFkIHByZWZlcmVuY2VzLicsXG4gIGZpZWxkczoge1xuICAgIHJlYWRQcmVmZXJlbmNlOiBSRUFEX1BSRUZFUkVOQ0VfQVRULFxuICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZTogSU5DTFVERV9SRUFEX1BSRUZFUkVOQ0VfQVRULFxuICAgIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U6IFNVQlFVRVJZX1JFQURfUFJFRkVSRU5DRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgUkVBRF9PUFRJT05TX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGUgcmVhZCBvcHRpb25zIGZvciB0aGUgcXVlcnkgdG8gYmUgZXhlY3V0ZWQuJyxcbiAgdHlwZTogUkVBRF9PUFRJT05TX0lOUFVULFxufTtcblxuY29uc3QgV0hFUkVfQVRUID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlc2UgYXJlIHRoZSBjb25kaXRpb25zIHRoYXQgdGhlIG9iamVjdHMgbmVlZCB0byBtYXRjaCBpbiBvcmRlciB0byBiZSBmb3VuZCcsXG4gIHR5cGU6IE9CSkVDVCxcbn07XG5cbmNvbnN0IFNLSVBfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG51bWJlciBvZiBvYmplY3RzIHRoYXQgbXVzdCBiZSBza2lwcGVkIHRvIHJldHVybi4nLFxuICB0eXBlOiBHcmFwaFFMSW50LFxufTtcblxuY29uc3QgTElNSVRfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGxpbWl0IG51bWJlciBvZiBvYmplY3RzIHRoYXQgbXVzdCBiZSByZXR1cm5lZC4nLFxuICB0eXBlOiBHcmFwaFFMSW50LFxufTtcblxuY29uc3QgQ09VTlRfQVRUID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgdG90YWwgbWF0Y2hlZCBvYmplY3MgY291bnQgdGhhdCBpcyByZXR1cm5lZCB3aGVuIHRoZSBjb3VudCBmbGFnIGlzIHNldC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEludCksXG59O1xuXG5jb25zdCBTRUFSQ0hfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTZWFyY2hJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2VhcmNoSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgc2VhcmNoIG9wZXJhdGlvbiBvbiBhIGZ1bGwgdGV4dCBzZWFyY2guJyxcbiAgZmllbGRzOiB7XG4gICAgdGVybToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB0ZXJtIHRvIGJlIHNlYXJjaGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICBsYW5ndWFnZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBsYW5ndWFnZSB0byB0ZXRlcm1pbmUgdGhlIGxpc3Qgb2Ygc3RvcCB3b3JkcyBhbmQgdGhlIHJ1bGVzIGZvciB0b2tlbml6ZXIuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBjYXNlU2Vuc2l0aXZlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGZsYWcgdG8gZW5hYmxlIG9yIGRpc2FibGUgY2FzZSBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIGRpYWNyaXRpY1NlbnNpdGl2ZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIGRpYWNyaXRpYyBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFRFWFRfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdUZXh0SW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFRleHRJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHRleHQgb3BlcmF0aW9uIG9uIGEgY29uc3RyYWludC4nLFxuICBmaWVsZHM6IHtcbiAgICBzZWFyY2g6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgc2VhcmNoIHRvIGJlIGV4ZWN1dGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoU0VBUkNIX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEJPWF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0JveElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBCb3hJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmaXkgYSBib3ggb3BlcmF0aW9uIG9uIGEgd2l0aGluIGdlbyBxdWVyeS4nLFxuICBmaWVsZHM6IHtcbiAgICBib3R0b21MZWZ0OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGJvdHRvbSBsZWZ0IGNvb3JkaW5hdGVzIG9mIHRoZSBib3guJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gICAgdXBwZXJSaWdodDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cHBlciByaWdodCBjb29yZGluYXRlcyBvZiB0aGUgYm94LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR0VPX1BPSU5UX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFdJVEhJTl9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1dpdGhpbklucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBXaXRoaW5JbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHdpdGhpbiBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIGJveDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBib3ggdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoQk9YX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IENFTlRFUl9TUEhFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdDZW50ZXJTcGhlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQ2VudGVyU3BoZXJlSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgY2VudGVyU3BoZXJlIG9wZXJhdGlvbiBvbiBhIGdlb1dpdGhpbiBxdWVyeS4nLFxuICBmaWVsZHM6IHtcbiAgICBjZW50ZXI6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY2VudGVyIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gICAgZGlzdGFuY2U6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcmFkaXVzIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgR0VPX1dJVEhJTl9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1dpdGhpbklucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBHZW9XaXRoaW5JbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIGdlb1dpdGhpbiBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIHBvbHlnb246IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcG9seWdvbiB0byBiZSBzcGVjaWZpZWQuJyxcbiAgICAgIHR5cGU6IFBPTFlHT05fSU5QVVQsXG4gICAgfSxcbiAgICBjZW50ZXJTcGhlcmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgc3BoZXJlIHRvIGJlIHNwZWNpZmllZC4nLFxuICAgICAgdHlwZTogQ0VOVEVSX1NQSEVSRV9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEdFT19JTlRFUlNFQ1RTX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnR2VvSW50ZXJzZWN0c0lucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBHZW9JbnRlcnNlY3RzSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSBnZW9JbnRlcnNlY3RzIG9wZXJhdGlvbiBvbiBhIGNvbnN0cmFpbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgcG9pbnQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcG9pbnQgdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBHRU9fUE9JTlRfSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBlcXVhbFRvID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBlcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBlcXVhbHMgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBub3RFcXVhbFRvID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBkbyBub3QgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBsZXNzVGhhbiA9ICh0eXBlKSA9PiAoe1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgbGVzc1RoYW4gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGlzIGxlc3MgdGhhbiBhIHNwZWNpZmllZCB2YWx1ZS4nLFxuICB0eXBlLFxufSk7XG5cbmNvbnN0IGxlc3NUaGFuT3JFcXVhbFRvID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBsZXNzVGhhbk9yRXF1YWxUbyBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlIG9mIGEgZmllbGQgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGEgc3BlY2lmaWVkIHZhbHVlLicsXG4gIHR5cGUsXG59KTtcblxuY29uc3QgZ3JlYXRlclRoYW4gPSAodHlwZSkgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGdyZWF0ZXJUaGFuIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBncmVhdGVyIHRoYW4gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBncmVhdGVyVGhhbk9yRXF1YWxUbyA9ICh0eXBlKSA9PiAoe1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgZ3JlYXRlclRoYW5PckVxdWFsVG8gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhIHNwZWNpZmllZCB2YWx1ZS4nLFxuICB0eXBlLFxufSk7XG5cbmNvbnN0IGluT3AgPSAodHlwZSkgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGluIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBlcXVhbHMgYW55IHZhbHVlIGluIHRoZSBzcGVjaWZpZWQgYXJyYXkuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KHR5cGUpLFxufSk7XG5cbmNvbnN0IG5vdEluID0gKHR5cGUpID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RJbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlIG9mIGEgZmllbGQgZG8gbm90IGVxdWFsIGFueSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIGFycmF5LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTGlzdCh0eXBlKSxcbn0pO1xuXG5jb25zdCBleGlzdHMgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBleGlzdHMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZXhpc3RzIChvciBkbyBub3QgZXhpc3QpLicsXG4gIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxufTtcblxuY29uc3QgbWF0Y2hlc1JlZ2V4ID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgbWF0Y2hlc1JlZ2V4IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBtYXRjaGVzIGEgc3BlY2lmaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbi4nLFxuICB0eXBlOiBHcmFwaFFMU3RyaW5nLFxufTtcblxuY29uc3Qgb3B0aW9ucyA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG9wdGlvbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBvcHRpb25hbCBmbGFncyAoc3VjaCBhcyBcImlcIiBhbmQgXCJtXCIpIHRvIGJlIGFkZGVkIHRvIGEgbWF0Y2hlc1JlZ2V4IG9wZXJhdGlvbiBpbiB0aGUgc2FtZSBzZXQgb2YgY29uc3RyYWludHMuJyxcbiAgdHlwZTogR3JhcGhRTFN0cmluZyxcbn07XG5cbmNvbnN0IFNVQlFVRVJZX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU3VicXVlcnlJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU3VicXVlcnlJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHN1YiBxdWVyeSB0byBhbm90aGVyIGNsYXNzLicsXG4gIGZpZWxkczoge1xuICAgIGNsYXNzTmFtZTogQ0xBU1NfTkFNRV9BVFQsXG4gICAgd2hlcmU6IE9iamVjdC5hc3NpZ24oe30sIFdIRVJFX0FUVCwge1xuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFdIRVJFX0FUVC50eXBlKSxcbiAgICB9KSxcbiAgfSxcbn0pO1xuXG5jb25zdCBTRUxFQ1RfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTZWxlY3RJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2VsZWN0SW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYW4gaW5RdWVyeUtleSBvciBhIG5vdEluUXVlcnlLZXkgb3BlcmF0aW9uIG9uIGEgY29uc3RyYWludC4nLFxuICBmaWVsZHM6IHtcbiAgICBxdWVyeToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBzdWJxdWVyeSB0byBiZSBleGVjdXRlZC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFNVQlFVRVJZX0lOUFVUKSxcbiAgICB9LFxuICAgIGtleToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBrZXkgaW4gdGhlIHJlc3VsdCBvZiB0aGUgc3VicXVlcnkgdGhhdCBtdXN0IG1hdGNoIChub3QgbWF0Y2gpIHRoZSBmaWVsZC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxTdHJpbmcpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgaW5RdWVyeUtleSA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGluUXVlcnlLZXkgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZXF1YWxzIHRvIGEga2V5IGluIHRoZSByZXN1bHQgb2YgYSBkaWZmZXJlbnQgcXVlcnkuJyxcbiAgdHlwZTogU0VMRUNUX0lOUFVULFxufTtcblxuY29uc3Qgbm90SW5RdWVyeUtleSA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG5vdEluUXVlcnlLZXkgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZG8gbm90IGVxdWFsIHRvIGEga2V5IGluIHRoZSByZXN1bHQgb2YgYSBkaWZmZXJlbnQgcXVlcnkuJyxcbiAgdHlwZTogU0VMRUNUX0lOUFVULFxufTtcblxuY29uc3QgSURfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdJZFdoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIElkV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYW4gaWQuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMSUQpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oR3JhcGhRTElEKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oR3JhcGhRTElEKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBpbjogaW5PcChHcmFwaFFMSUQpLFxuICAgIG5vdEluOiBub3RJbihHcmFwaFFMSUQpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgU1RSSU5HX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU3RyaW5nV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU3RyaW5nV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIFN0cmluZy4nLFxuICBmaWVsZHM6IHtcbiAgICBlcXVhbFRvOiBlcXVhbFRvKEdyYXBoUUxTdHJpbmcpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTFN0cmluZyksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEdyYXBoUUxTdHJpbmcpLFxuICAgIGxlc3NUaGFuT3JFcXVhbFRvOiBsZXNzVGhhbk9yRXF1YWxUbyhHcmFwaFFMU3RyaW5nKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oR3JhcGhRTFN0cmluZyksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEdyYXBoUUxTdHJpbmcpLFxuICAgIGluOiBpbk9wKEdyYXBoUUxTdHJpbmcpLFxuICAgIG5vdEluOiBub3RJbihHcmFwaFFMU3RyaW5nKSxcbiAgICBleGlzdHMsXG4gICAgbWF0Y2hlc1JlZ2V4LFxuICAgIG9wdGlvbnMsXG4gICAgdGV4dDoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSAkdGV4dCBvcGVyYXRvciB0byBzcGVjaWZ5IGEgZnVsbCB0ZXh0IHNlYXJjaCBjb25zdHJhaW50LicsXG4gICAgICB0eXBlOiBURVhUX0lOUFVULFxuICAgIH0sXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IE5VTUJFUl9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ051bWJlcldoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIE51bWJlcldoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBOdW1iZXIuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMRmxvYXQpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oR3JhcGhRTEZsb2F0KSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oR3JhcGhRTEZsb2F0KSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBpbjogaW5PcChHcmFwaFFMRmxvYXQpLFxuICAgIG5vdEluOiBub3RJbihHcmFwaFFMRmxvYXQpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgQk9PTEVBTl9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0Jvb2xlYW5XaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBCb29sZWFuV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIEJvb2xlYW4uJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMQm9vbGVhbiksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhHcmFwaFFMQm9vbGVhbiksXG4gICAgZXhpc3RzLFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBBUlJBWV9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0FycmF5V2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQXJyYXlXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgQXJyYXkuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhBTlkpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oQU5ZKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oQU5ZKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oQU5ZKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oQU5ZKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oQU5ZKSxcbiAgICBpbjogaW5PcChBTlkpLFxuICAgIG5vdEluOiBub3RJbihBTlkpLFxuICAgIGV4aXN0cyxcbiAgICBjb250YWluZWRCeToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBjb250YWluZWRCeSBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhbiBhcnJheSBmaWVsZCBpcyBjb250YWluZWQgYnkgYW5vdGhlciBzcGVjaWZpZWQgYXJyYXkuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChBTlkpLFxuICAgIH0sXG4gICAgY29udGFpbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgY29udGFpbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYW4gYXJyYXkgZmllbGQgY29udGFpbiBhbGwgZWxlbWVudHMgb2YgYW5vdGhlciBzcGVjaWZpZWQgYXJyYXkuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChBTlkpLFxuICAgIH0sXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEtFWV9WQUxVRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0tleVZhbHVlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FuIGVudHJ5IGZyb20gYW4gb2JqZWN0LCBpLmUuLCBhIHBhaXIgb2Yga2V5IGFuZCB2YWx1ZS4nLFxuICBmaWVsZHM6IHtcbiAgICBrZXk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGtleSB1c2VkIHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBvZiB0aGlzIGVudHJ5LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICB2YWx1ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdmFsdWUgb2YgdGhlIGVudHJ5LiBDb3VsZCBiZSBhbnkgdHlwZSBvZiBzY2FsYXIgZGF0YS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEFOWSksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBPQkpFQ1RfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdPYmplY3RXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBPYmplY3RXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgcmVzdWx0IGJ5IGEgZmllbGQgb2YgdHlwZSBPYmplY3QuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhLRVlfVkFMVUVfSU5QVVQpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBpbjogaW5PcChLRVlfVkFMVUVfSU5QVVQpLFxuICAgIG5vdEluOiBub3RJbihLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGxlc3NUaGFuT3JFcXVhbFRvOiBsZXNzVGhhbk9yRXF1YWxUbyhLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhLRVlfVkFMVUVfSU5QVVQpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgREFURV9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0RhdGVXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBEYXRlV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIERhdGUuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhEQVRFKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKERBVEUpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihEQVRFKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oREFURSksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKERBVEUpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhEQVRFKSxcbiAgICBpbjogaW5PcChEQVRFKSxcbiAgICBub3RJbjogbm90SW4oREFURSksXG4gICAgZXhpc3RzLFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBCWVRFU19XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0J5dGVzV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQnl0ZXNXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgQnl0ZXMuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhCWVRFUyksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhCWVRFUyksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEJZVEVTKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oQllURVMpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihCWVRFUyksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEJZVEVTKSxcbiAgICBpbjogaW5PcChCWVRFUyksXG4gICAgbm90SW46IG5vdEluKEJZVEVTKSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEZJTEVfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdGaWxlV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRmlsZVdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBGaWxlLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oRklMRSksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhGSUxFKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oRklMRSksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEZJTEUpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihGSUxFKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oRklMRSksXG4gICAgaW46IGluT3AoRklMRSksXG4gICAgbm90SW46IG5vdEluKEZJTEUpLFxuICAgIGV4aXN0cyxcbiAgICBtYXRjaGVzUmVnZXgsXG4gICAgb3B0aW9ucyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgR0VPX1BPSU5UX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnR2VvUG9pbnRXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBHZW9Qb2ludFdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBHZW9Qb2ludC4nLFxuICBmaWVsZHM6IHtcbiAgICBleGlzdHMsXG4gICAgbmVhclNwaGVyZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBuZWFyU3BoZXJlIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIG5lYXIgdG8gYW5vdGhlciBnZW8gcG9pbnQuJyxcbiAgICAgIHR5cGU6IEdFT19QT0lOVF9JTlBVVCxcbiAgICB9LFxuICAgIG1heERpc3RhbmNlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiByYWRpYW5zKSBmcm9tIHRoZSBnZW8gcG9pbnQgc3BlY2lmaWVkIGluIHRoZSAkbmVhclNwaGVyZSBvcGVyYXRvci4nLFxuICAgICAgdHlwZTogR3JhcGhRTEZsb2F0LFxuICAgIH0sXG4gICAgbWF4RGlzdGFuY2VJblJhZGlhbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgbWF4RGlzdGFuY2VJblJhZGlhbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYSBnZW8gcG9pbnQgZmllbGQgaXMgYXQgYSBtYXggZGlzdGFuY2UgKGluIHJhZGlhbnMpIGZyb20gdGhlIGdlbyBwb2ludCBzcGVjaWZpZWQgaW4gdGhlICRuZWFyU3BoZXJlIG9wZXJhdG9yLicsXG4gICAgICB0eXBlOiBHcmFwaFFMRmxvYXQsXG4gICAgfSxcbiAgICBtYXhEaXN0YW5jZUluTWlsZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgbWF4RGlzdGFuY2VJbk1pbGVzIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiBtaWxlcykgZnJvbSB0aGUgZ2VvIHBvaW50IHNwZWNpZmllZCBpbiB0aGUgJG5lYXJTcGhlcmUgb3BlcmF0b3IuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxGbG9hdCxcbiAgICB9LFxuICAgIG1heERpc3RhbmNlSW5LaWxvbWV0ZXJzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlSW5LaWxvbWV0ZXJzIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiBraWxvbWV0ZXJzKSBmcm9tIHRoZSBnZW8gcG9pbnQgc3BlY2lmaWVkIGluIHRoZSAkbmVhclNwaGVyZSBvcGVyYXRvci4nLFxuICAgICAgdHlwZTogR3JhcGhRTEZsb2F0LFxuICAgIH0sXG4gICAgd2l0aGluOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIHdpdGhpbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyB3aXRoaW4gYSBzcGVjaWZpZWQgYm94LicsXG4gICAgICB0eXBlOiBXSVRISU5fSU5QVVQsXG4gICAgfSxcbiAgICBnZW9XaXRoaW46IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgZ2VvV2l0aGluIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIHdpdGhpbiBhIHNwZWNpZmllZCBwb2x5Z29uIG9yIHNwaGVyZS4nLFxuICAgICAgdHlwZTogR0VPX1dJVEhJTl9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFBPTFlHT05fV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQb2x5Z29uV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUG9seWdvbldoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBQb2x5Z29uLicsXG4gIGZpZWxkczoge1xuICAgIGV4aXN0cyxcbiAgICBnZW9JbnRlcnNlY3RzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGdlb0ludGVyc2VjdHMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYSBwb2x5Z29uIGZpZWxkIGludGVyc2VjdCBhIHNwZWNpZmllZCBwb2ludC4nLFxuICAgICAgdHlwZTogR0VPX0lOVEVSU0VDVFNfSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBFTEVNRU5UID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0VsZW1lbnQnLFxuICBkZXNjcmlwdGlvbjogXCJUaGUgRWxlbWVudCBvYmplY3QgdHlwZSBpcyB1c2VkIHRvIHJldHVybiBhcnJheSBpdGVtcycgdmFsdWUuXCIsXG4gIGZpZWxkczoge1xuICAgIHZhbHVlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1JldHVybiB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgaW4gdGhlIGFycmF5JyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBTlkpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuLy8gRGVmYXVsdCBzdGF0aWMgdW5pb24gdHlwZSwgd2UgdXBkYXRlIHR5cGVzIGFuZCByZXNvbHZlVHlwZSBmdW5jdGlvbiBsYXRlclxubGV0IEFSUkFZX1JFU1VMVDtcblxuY29uc3QgbG9hZEFycmF5UmVzdWx0ID0gKHBhcnNlR3JhcGhRTFNjaGVtYSwgcGFyc2VDbGFzc2VzKSA9PiB7XG4gIGNvbnN0IGNsYXNzVHlwZXMgPSBwYXJzZUNsYXNzZXNcbiAgICAuZmlsdGVyKChwYXJzZUNsYXNzKSA9PlxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1twYXJzZUNsYXNzLmNsYXNzTmFtZV1cbiAgICAgICAgLmNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgICAgICAgPyB0cnVlXG4gICAgICAgIDogZmFsc2VcbiAgICApXG4gICAgLm1hcChcbiAgICAgIChwYXJzZUNsYXNzKSA9PlxuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW3BhcnNlQ2xhc3MuY2xhc3NOYW1lXVxuICAgICAgICAgIC5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlXG4gICAgKTtcbiAgQVJSQVlfUkVTVUxUID0gbmV3IEdyYXBoUUxVbmlvblR5cGUoe1xuICAgIG5hbWU6ICdBcnJheVJlc3VsdCcsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVXNlIElubGluZSBGcmFnbWVudCBvbiBBcnJheSB0byBnZXQgcmVzdWx0czogaHR0cHM6Ly9ncmFwaHFsLm9yZy9sZWFybi9xdWVyaWVzLyNpbmxpbmUtZnJhZ21lbnRzJyxcbiAgICB0eXBlczogKCkgPT4gW0VMRU1FTlQsIC4uLmNsYXNzVHlwZXNdLFxuICAgIHJlc29sdmVUeXBlOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICh2YWx1ZS5fX3R5cGUgPT09ICdPYmplY3QnICYmIHZhbHVlLmNsYXNzTmFtZSAmJiB2YWx1ZS5vYmplY3RJZCkge1xuICAgICAgICBpZiAocGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1t2YWx1ZS5jbGFzc05hbWVdKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbdmFsdWUuY2xhc3NOYW1lXVxuICAgICAgICAgICAgLmNsYXNzR3JhcGhRTE91dHB1dFR5cGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEVMRU1FTlQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBFTEVNRU5UO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuZ3JhcGhRTFR5cGVzLnB1c2goQVJSQVlfUkVTVUxUKTtcbn07XG5cbmNvbnN0IGxvYWQgPSAocGFyc2VHcmFwaFFMU2NoZW1hKSA9PiB7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShHcmFwaFFMVXBsb2FkLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEFOWSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShPQkpFQ1QsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoREFURSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCWVRFUywgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShGSUxFLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEVfSU5GTywgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShGSUxFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19QT0lOVF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShHRU9fUE9JTlQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUEFSU0VfT0JKRUNULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJFQURfUFJFRkVSRU5DRSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShSRUFEX09QVElPTlNfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0VBUkNIX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFRFWFRfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQk9YX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFdJVEhJTl9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShDRU5URVJfU1BIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19XSVRISU5fSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX0lOVEVSU0VDVFNfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoSURfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU1RSSU5HX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKE5VTUJFUl9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCT09MRUFOX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEFSUkFZX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEtFWV9WQUxVRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShPQkpFQ1RfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoREFURV9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCWVRFU19XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShGSUxFX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19QT0lOVF9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShQT0xZR09OX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEVMRU1FTlQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQUNMX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFVTRVJfQUNMX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJPTEVfQUNMX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFBVQkxJQ19BQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQUNMLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFVTRVJfQUNMLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJPTEVfQUNMLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFBVQkxJQ19BQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU1VCUVVFUllfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0VMRUNUX0lOUFVULCB0cnVlKTtcbn07XG5cbmV4cG9ydCB7XG4gIFR5cGVWYWxpZGF0aW9uRXJyb3IsXG4gIHBhcnNlU3RyaW5nVmFsdWUsXG4gIHBhcnNlSW50VmFsdWUsXG4gIHBhcnNlRmxvYXRWYWx1ZSxcbiAgcGFyc2VCb29sZWFuVmFsdWUsXG4gIHBhcnNlVmFsdWUsXG4gIHBhcnNlTGlzdFZhbHVlcyxcbiAgcGFyc2VPYmplY3RGaWVsZHMsXG4gIEFOWSxcbiAgT0JKRUNULFxuICBwYXJzZURhdGVJc29WYWx1ZSxcbiAgc2VyaWFsaXplRGF0ZUlzbyxcbiAgREFURSxcbiAgQllURVMsXG4gIHBhcnNlRmlsZVZhbHVlLFxuICBTVUJRVUVSWV9JTlBVVCxcbiAgU0VMRUNUX0lOUFVULFxuICBGSUxFLFxuICBGSUxFX0lORk8sXG4gIEZJTEVfSU5QVVQsXG4gIEdFT19QT0lOVF9GSUVMRFMsXG4gIEdFT19QT0lOVF9JTlBVVCxcbiAgR0VPX1BPSU5ULFxuICBQT0xZR09OX0lOUFVULFxuICBQT0xZR09OLFxuICBPQkpFQ1RfSUQsXG4gIENMQVNTX05BTUVfQVRULFxuICBHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgT0JKRUNUX0lEX0FUVCxcbiAgVVBEQVRFRF9BVF9BVFQsXG4gIENSRUFURURfQVRfQVRULFxuICBJTlBVVF9GSUVMRFMsXG4gIENSRUFURV9SRVNVTFRfRklFTERTLFxuICBVUERBVEVfUkVTVUxUX0ZJRUxEUyxcbiAgUEFSU0VfT0JKRUNUX0ZJRUxEUyxcbiAgUEFSU0VfT0JKRUNULFxuICBTRVNTSU9OX1RPS0VOX0FUVCxcbiAgUkVBRF9QUkVGRVJFTkNFLFxuICBSRUFEX1BSRUZFUkVOQ0VfQVRULFxuICBJTkNMVURFX1JFQURfUFJFRkVSRU5DRV9BVFQsXG4gIFNVQlFVRVJZX1JFQURfUFJFRkVSRU5DRV9BVFQsXG4gIFJFQURfT1BUSU9OU19JTlBVVCxcbiAgUkVBRF9PUFRJT05TX0FUVCxcbiAgV0hFUkVfQVRULFxuICBTS0lQX0FUVCxcbiAgTElNSVRfQVRULFxuICBDT1VOVF9BVFQsXG4gIFNFQVJDSF9JTlBVVCxcbiAgVEVYVF9JTlBVVCxcbiAgQk9YX0lOUFVULFxuICBXSVRISU5fSU5QVVQsXG4gIENFTlRFUl9TUEhFUkVfSU5QVVQsXG4gIEdFT19XSVRISU5fSU5QVVQsXG4gIEdFT19JTlRFUlNFQ1RTX0lOUFVULFxuICBlcXVhbFRvLFxuICBub3RFcXVhbFRvLFxuICBsZXNzVGhhbixcbiAgbGVzc1RoYW5PckVxdWFsVG8sXG4gIGdyZWF0ZXJUaGFuLFxuICBncmVhdGVyVGhhbk9yRXF1YWxUbyxcbiAgaW5PcCxcbiAgbm90SW4sXG4gIGV4aXN0cyxcbiAgbWF0Y2hlc1JlZ2V4LFxuICBvcHRpb25zLFxuICBpblF1ZXJ5S2V5LFxuICBub3RJblF1ZXJ5S2V5LFxuICBJRF9XSEVSRV9JTlBVVCxcbiAgU1RSSU5HX1dIRVJFX0lOUFVULFxuICBOVU1CRVJfV0hFUkVfSU5QVVQsXG4gIEJPT0xFQU5fV0hFUkVfSU5QVVQsXG4gIEFSUkFZX1dIRVJFX0lOUFVULFxuICBLRVlfVkFMVUVfSU5QVVQsXG4gIE9CSkVDVF9XSEVSRV9JTlBVVCxcbiAgREFURV9XSEVSRV9JTlBVVCxcbiAgQllURVNfV0hFUkVfSU5QVVQsXG4gIEZJTEVfV0hFUkVfSU5QVVQsXG4gIEdFT19QT0lOVF9XSEVSRV9JTlBVVCxcbiAgUE9MWUdPTl9XSEVSRV9JTlBVVCxcbiAgQVJSQVlfUkVTVUxULFxuICBFTEVNRU5ULFxuICBBQ0xfSU5QVVQsXG4gIFVTRVJfQUNMX0lOUFVULFxuICBST0xFX0FDTF9JTlBVVCxcbiAgUFVCTElDX0FDTF9JTlBVVCxcbiAgQUNMLFxuICBVU0VSX0FDTCxcbiAgUk9MRV9BQ0wsXG4gIFBVQkxJQ19BQ0wsXG4gIGxvYWQsXG4gIGxvYWRBcnJheVJlc3VsdCxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultRelaySchema.js b/lib/GraphQL/loaders/defaultRelaySchema.js deleted file mode 100644 index 7ad9579b75..0000000000 --- a/lib/GraphQL/loaders/defaultRelaySchema.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.GLOBAL_ID_ATT = void 0; - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _parseClassTypes = require("./parseClassTypes"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const GLOBAL_ID_ATT = { - description: 'This is the global id.', - type: defaultGraphQLTypes.OBJECT_ID -}; -exports.GLOBAL_ID_ATT = GLOBAL_ID_ATT; - -const load = parseGraphQLSchema => { - const { - nodeInterface, - nodeField - } = (0, _graphqlRelay.nodeDefinitions)(async (globalId, context, queryInfo) => { - try { - const { - type, - id - } = (0, _graphqlRelay.fromGlobalId)(globalId); - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const { - keys, - include - } = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); - return _objectSpread({ - className: type - }, await objectsQueries.getObject(type, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses)); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - }, obj => { - return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType; - }); - parseGraphQLSchema.addGraphQLType(nodeInterface, true); - parseGraphQLSchema.relayNodeInterface = nodeInterface; - parseGraphQLSchema.addGraphQLQuery('node', nodeField, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hLmpzIl0sIm5hbWVzIjpbIkdMT0JBTF9JRF9BVFQiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiT0JKRUNUX0lEIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsIm5vZGVJbnRlcmZhY2UiLCJub2RlRmllbGQiLCJnbG9iYWxJZCIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJpZCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJrZXlzIiwiaW5jbHVkZSIsImNsYXNzTmFtZSIsIm9iamVjdHNRdWVyaWVzIiwiZ2V0T2JqZWN0IiwidW5kZWZpbmVkIiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwib2JqIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsImFkZEdyYXBoUUxUeXBlIiwicmVsYXlOb2RlSW50ZXJmYWNlIiwiYWRkR3JhcGhRTFF1ZXJ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsYUFBYSxHQUFHO0FBQ3BCQyxFQUFBQSxXQUFXLEVBQUUsd0JBRE87QUFFcEJDLEVBQUFBLElBQUksRUFBRUMsbUJBQW1CLENBQUNDO0FBRk4sQ0FBdEI7OztBQUtBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsUUFBTTtBQUFFQyxJQUFBQSxhQUFGO0FBQWlCQyxJQUFBQTtBQUFqQixNQUErQixtQ0FDbkMsT0FBT0MsUUFBUCxFQUFpQkMsT0FBakIsRUFBMEJDLFNBQTFCLEtBQXdDO0FBQ3RDLFFBQUk7QUFDRixZQUFNO0FBQUVULFFBQUFBLElBQUY7QUFBUVUsUUFBQUE7QUFBUixVQUFlLGdDQUFhSCxRQUFiLENBQXJCO0FBQ0EsWUFBTTtBQUFFSSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCTCxPQUEvQjtBQUNBLFlBQU1NLGNBQWMsR0FBRyxnQ0FBY0wsU0FBZCxDQUF2QjtBQUVBLFlBQU07QUFBRU0sUUFBQUEsSUFBRjtBQUFRQyxRQUFBQTtBQUFSLFVBQW9CLDRDQUFzQkYsY0FBdEIsQ0FBMUI7QUFFQTtBQUNFRyxRQUFBQSxTQUFTLEVBQUVqQjtBQURiLFNBRU0sTUFBTWtCLGNBQWMsQ0FBQ0MsU0FBZixDQUNSbkIsSUFEUSxFQUVSVSxFQUZRLEVBR1JLLElBSFEsRUFJUkMsT0FKUSxFQUtSSSxTQUxRLEVBTVJBLFNBTlEsRUFPUlQsTUFQUSxFQVFSQyxJQVJRLEVBU1JDLElBVFEsRUFVUlQsa0JBQWtCLENBQUNpQixZQVZYLENBRlo7QUFlRCxLQXRCRCxDQXNCRSxPQUFPQyxDQUFQLEVBQVU7QUFDVmxCLE1BQUFBLGtCQUFrQixDQUFDbUIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRixHQTNCa0MsRUE0Qm5DRSxHQUFHLElBQUk7QUFDTCxXQUFPcEIsa0JBQWtCLENBQUNxQixlQUFuQixDQUFtQ0QsR0FBRyxDQUFDUCxTQUF2QyxFQUNKUyxzQkFESDtBQUVELEdBL0JrQyxDQUFyQztBQWtDQXRCLEVBQUFBLGtCQUFrQixDQUFDdUIsY0FBbkIsQ0FBa0N0QixhQUFsQyxFQUFpRCxJQUFqRDtBQUNBRCxFQUFBQSxrQkFBa0IsQ0FBQ3dCLGtCQUFuQixHQUF3Q3ZCLGFBQXhDO0FBQ0FELEVBQUFBLGtCQUFrQixDQUFDeUIsZUFBbkIsQ0FBbUMsTUFBbkMsRUFBMkN2QixTQUEzQyxFQUFzRCxJQUF0RDtBQUNELENBdENEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbm9kZURlZmluaXRpb25zLCBmcm9tR2xvYmFsSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCBnZXRGaWVsZE5hbWVzIGZyb20gJ2dyYXBocWwtbGlzdC1maWVsZHMnO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0ICogYXMgb2JqZWN0c1F1ZXJpZXMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzUXVlcmllcyc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUgfSBmcm9tICcuL3BhcnNlQ2xhc3NUeXBlcyc7XG5cbmNvbnN0IEdMT0JBTF9JRF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZ2xvYmFsIGlkLicsXG4gIHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUX0lELFxufTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGNvbnN0IHsgbm9kZUludGVyZmFjZSwgbm9kZUZpZWxkIH0gPSBub2RlRGVmaW5pdGlvbnMoXG4gICAgYXN5bmMgKGdsb2JhbElkLCBjb250ZXh0LCBxdWVyeUluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGZyb21HbG9iYWxJZChnbG9iYWxJZCk7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMocXVlcnlJbmZvKTtcblxuICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWU6IHR5cGUsXG4gICAgICAgICAgLi4uKGF3YWl0IG9iamVjdHNRdWVyaWVzLmdldE9iamVjdChcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgKSksXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9iaiA9PiB7XG4gICAgICByZXR1cm4gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tvYmouY2xhc3NOYW1lXVxuICAgICAgICAuY2xhc3NHcmFwaFFMT3V0cHV0VHlwZTtcbiAgICB9XG4gICk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKG5vZGVJbnRlcmZhY2UsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEucmVsYXlOb2RlSW50ZXJmYWNlID0gbm9kZUludGVyZmFjZTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxRdWVyeSgnbm9kZScsIG5vZGVGaWVsZCwgdHJ1ZSk7XG59O1xuXG5leHBvcnQgeyBHTE9CQUxfSURfQVRULCBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/filesMutations.js b/lib/GraphQL/loaders/filesMutations.js deleted file mode 100644 index 216b62d7d9..0000000000 --- a/lib/GraphQL/loaders/filesMutations.js +++ /dev/null @@ -1,103 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.handleUpload = exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _links = require("@graphql-tools/links"); - -var _node = _interopRequireDefault(require("parse/node")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var _logger = _interopRequireDefault(require("../../logger")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const handleUpload = async (upload, config) => { - const { - createReadStream, - filename, - mimetype - } = await upload; - let data = null; - - if (createReadStream) { - const stream = createReadStream(); - data = await new Promise((resolve, reject) => { - const chunks = []; - stream.on('error', reject).on('data', chunk => chunks.push(chunk)).on('end', () => resolve(Buffer.concat(chunks))); - }); - } - - if (!data || !data.length) { - throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); - } - - if (filename.length > 128) { - throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); - } - - if (!filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) { - throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); - } - - try { - return { - fileInfo: await config.filesController.createFile(config, filename, data, mimetype) - }; - } catch (e) { - _logger.default.error('Error creating a file: ', e); - - throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, `Could not store file: ${filename}.`); - } -}; - -exports.handleUpload = handleUpload; - -const load = parseGraphQLSchema => { - const createMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'CreateFile', - description: 'The createFile mutation can be used to create and upload a new file.', - inputFields: { - upload: { - description: 'This is the new file to be created and uploaded.', - type: new _graphql.GraphQLNonNull(_links.GraphQLUpload) - } - }, - outputFields: { - fileInfo: { - description: 'This is the created file info.', - type: new _graphql.GraphQLNonNull(defaultGraphQLTypes.FILE_INFO) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - upload - } = args; - const { - config - } = context; - return handleUpload(upload, config); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(createMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(createMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('createFile', createMutation, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZmlsZXNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsiaGFuZGxlVXBsb2FkIiwidXBsb2FkIiwiY29uZmlnIiwiY3JlYXRlUmVhZFN0cmVhbSIsImZpbGVuYW1lIiwibWltZXR5cGUiLCJkYXRhIiwic3RyZWFtIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsImxlbmd0aCIsIlBhcnNlIiwiRXJyb3IiLCJGSUxFX1NBVkVfRVJST1IiLCJJTlZBTElEX0ZJTEVfTkFNRSIsIm1hdGNoIiwiZmlsZUluZm8iLCJmaWxlc0NvbnRyb2xsZXIiLCJjcmVhdGVGaWxlIiwiZSIsImxvZ2dlciIsImVycm9yIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImNyZWF0ZU11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMVXBsb2FkIiwib3V0cHV0RmllbGRzIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkZJTEVfSU5GTyIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFlBQVksR0FBRyxPQUFPQyxNQUFQLEVBQWVDLE1BQWYsS0FBMEI7QUFDN0MsUUFBTTtBQUFFQyxJQUFBQSxnQkFBRjtBQUFvQkMsSUFBQUEsUUFBcEI7QUFBOEJDLElBQUFBO0FBQTlCLE1BQTJDLE1BQU1KLE1BQXZEO0FBQ0EsTUFBSUssSUFBSSxHQUFHLElBQVg7O0FBQ0EsTUFBSUgsZ0JBQUos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QkFBa0IsQ0FBQ2UsY0FBbkIsQ0FDRWQsY0FBYyxDQUFDVyxJQUFmLENBQW9CSSxLQUFwQixDQUEwQlgsSUFBMUIsQ0FBK0JZLE1BRGpDLEVBRUUsSUFGRixFQUdFLElBSEY7QUFLQWpCLEVBQUFBLGtCQUFrQixDQUFDZSxjQUFuQixDQUFrQ2QsY0FBYyxDQUFDSSxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBTCxFQUFBQSxrQkFBa0IsQ0FBQ2tCLGtCQUFuQixDQUNFLFlBREYsRUFFRWpCLGNBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU1ELENBeENEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCB7IEdyYXBoUUxVcGxvYWQgfSBmcm9tICdAZ3JhcGhxbC10b29scy9saW5rcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5cbmNvbnN0IGhhbmRsZVVwbG9hZCA9IGFzeW5jICh1cGxvYWQsIGNvbmZpZykgPT4ge1xuICBjb25zdCB7IGNyZWF0ZVJlYWRTdHJlYW0sIGZpbGVuYW1lLCBtaW1ldHlwZSB9ID0gYXdhaXQgdXBsb2FkO1xuICBsZXQgZGF0YSA9IG51bGw7XG4gIGlmIChjcmVhdGVSZWFkU3RyZWFtKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY3JlYXRlUmVhZFN0cmVhbSgpO1xuICAgIGRhdGEgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIHN0cmVhbVxuICAgICAgICAub24oJ2Vycm9yJywgcmVqZWN0KVxuICAgICAgICAub24oJ2RhdGEnLCAoY2h1bmspID0+IGNodW5rcy5wdXNoKGNodW5rKSlcbiAgICAgICAgLm9uKCdlbmQnLCAoKSA9PiByZXNvbHZlKEJ1ZmZlci5jb25jYXQoY2h1bmtzKSkpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKCFkYXRhIHx8ICFkYXRhLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsICdJbnZhbGlkIGZpbGUgdXBsb2FkLicpO1xuICB9XG5cbiAgaWYgKGZpbGVuYW1lLmxlbmd0aCA+IDEyOCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSwgJ0ZpbGVuYW1lIHRvbyBsb25nLicpO1xuICB9XG5cbiAgaWYgKCFmaWxlbmFtZS5tYXRjaCgvXltfYS16QS1aMC05XVthLXpBLVowLTlAXFwuXFwgfl8tXSokLykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSxcbiAgICAgICdGaWxlbmFtZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJ1xuICAgICk7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiB7XG4gICAgICBmaWxlSW5mbzogYXdhaXQgY29uZmlnLmZpbGVzQ29udHJvbGxlci5jcmVhdGVGaWxlKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGZpbGVuYW1lLFxuICAgICAgICBkYXRhLFxuICAgICAgICBtaW1ldHlwZVxuICAgICAgKSxcbiAgICB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdFcnJvciBjcmVhdGluZyBhIGZpbGU6ICcsIGUpO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUixcbiAgICAgIGBDb3VsZCBub3Qgc3RvcmUgZmlsZTogJHtmaWxlbmFtZX0uYFxuICAgICk7XG4gIH1cbn07XG5cbmNvbnN0IGxvYWQgPSAocGFyc2VHcmFwaFFMU2NoZW1hKSA9PiB7XG4gIGNvbnN0IGNyZWF0ZU11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0NyZWF0ZUZpbGUnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBjcmVhdGVGaWxlIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhbmQgdXBsb2FkIGEgbmV3IGZpbGUuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgdXBsb2FkOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbmV3IGZpbGUgdG8gYmUgY3JlYXRlZCBhbmQgdXBsb2FkZWQuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxVcGxvYWQpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgZmlsZUluZm86IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjcmVhdGVkIGZpbGUgaW5mby4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoZGVmYXVsdEdyYXBoUUxUeXBlcy5GSUxFX0lORk8pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IHVwbG9hZCB9ID0gYXJncztcbiAgICAgICAgY29uc3QgeyBjb25maWcgfSA9IGNvbnRleHQ7XG4gICAgICAgIHJldHVybiBoYW5kbGVVcGxvYWQodXBsb2FkLCBjb25maWcpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNyZWF0ZU11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjcmVhdGVNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAnY3JlYXRlRmlsZScsXG4gICAgY3JlYXRlTXV0YXRpb24sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG59O1xuXG5leHBvcnQgeyBsb2FkLCBoYW5kbGVVcGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/functionsMutations.js b/lib/GraphQL/loaders/functionsMutations.js deleted file mode 100644 index 7c1aeeef0e..0000000000 --- a/lib/GraphQL/loaders/functionsMutations.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _FunctionsRouter = require("../../Routers/FunctionsRouter"); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const load = parseGraphQLSchema => { - if (parseGraphQLSchema.functionNames.length > 0) { - const cloudCodeFunctionEnum = parseGraphQLSchema.addGraphQLType(new _graphql.GraphQLEnumType({ - name: 'CloudCodeFunction', - description: 'The CloudCodeFunction enum type contains a list of all available cloud code functions.', - values: parseGraphQLSchema.functionNames.reduce((values, functionName) => _objectSpread(_objectSpread({}, values), {}, { - [functionName]: { - value: functionName - } - }), {}) - }), true, true); - const callCloudCodeMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'CallCloudCode', - description: 'The callCloudCode mutation can be used to invoke a cloud code function.', - inputFields: { - functionName: { - description: 'This is the function to be called.', - type: new _graphql.GraphQLNonNull(cloudCodeFunctionEnum) - }, - params: { - description: 'These are the params to be passed to the function.', - type: defaultGraphQLTypes.OBJECT - } - }, - outputFields: { - result: { - description: 'This is the result value of the cloud code function execution.', - type: defaultGraphQLTypes.ANY - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - functionName, - params - } = args; - const { - config, - auth, - info - } = context; - return { - result: (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ - params: { - functionName - }, - config, - auth, - info, - body: params - })).response.result - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('callCloudCode', callCloudCodeMutation, true, true); - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZnVuY3Rpb25zTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJmdW5jdGlvbk5hbWVzIiwibGVuZ3RoIiwiY2xvdWRDb2RlRnVuY3Rpb25FbnVtIiwiYWRkR3JhcGhRTFR5cGUiLCJHcmFwaFFMRW51bVR5cGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJ2YWx1ZXMiLCJyZWR1Y2UiLCJmdW5jdGlvbk5hbWUiLCJ2YWx1ZSIsImNhbGxDbG91ZENvZGVNdXRhdGlvbiIsImlucHV0RmllbGRzIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwicGFyYW1zIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIk9CSkVDVCIsIm91dHB1dEZpZWxkcyIsInJlc3VsdCIsIkFOWSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwiRnVuY3Rpb25zUm91dGVyIiwiaGFuZGxlQ2xvdWRGdW5jdGlvbiIsImJvZHkiLCJyZXNwb25zZSIsImUiLCJoYW5kbGVFcnJvciIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsTUFBSUEsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDQyxNQUFqQyxHQUEwQyxDQUE5QyxFQUFpRDtBQUMvQyxVQUFNQyxxQkFBcUIsR0FBR0gsa0JBQWtCLENBQUNJLGNBQW5CLENBQzVCLElBQUlDLHdCQUFKLENBQW9CO0FBQ2xCQyxNQUFBQSxJQUFJLEVBQUUsbUJBRFk7QUFFbEJDLE1BQUFBLFdBQVcsRUFDVCx3RkFIZ0I7QUFJbEJDLE1BQUFBLE1BQU0sRUFBRVIsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDUSxNQUFqQyxDQUNOLENBQUNELE1BQUQsRUFBU0UsWUFBVCxxQ0FDS0YsTUFETDtBQUVFLFNBQUNFLFlBQUQsR0FBZ0I7QUFBRUMsVUFBQUEsS0FBSyxFQUFFRDtBQUFUO0FBRmxCLFFBRE0sRUFLTixFQUxNO0FBSlUsS0FBcEIsQ0FENEIsRUFhNUIsSUFiNEIsRUFjNUIsSUFkNEIsQ0FBOUI7QUFpQkEsVUFBTUUscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pETixNQUFBQSxJQUFJLEVBQUUsZUFEbUQ7QUFFekRDLE1BQUFBLFdBQVcsRUFDVCx5RUFIdUQ7QUFJekRNLE1BQUFBLFdBQVcsRUFBRTtBQUNYSCxRQUFBQSxZQUFZLEVBQUU7QUFDWkgsVUFBQUEsV0FBVyxFQUFFLG9DQUREO0FBRVpPLFVBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQloscUJBQW5CO0FBRk0sU0FESDtBQUtYYSxRQUFBQSxNQUFNLEVBQUU7QUFDTlQsVUFBQUEsV0FBVyxFQUFFLG9EQURQO0FBRU5PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNDO0FBRnBCO0FBTEcsT0FKNEM7QUFjekRDLE1BQUFBLFlBQVksRUFBRTtBQUNaQyxRQUFBQSxNQUFNLEVBQUU7QUFDTmIsVUFBQUEsV0FBVyxFQUNULGdFQUZJO0FBR05PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNJO0FBSHBCO0FBREksT0FkMkM7QUFxQnpEQyxNQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsS0FBeUI7QUFDNUMsWUFBSTtBQUNGLGdCQUFNO0FBQUVkLFlBQUFBLFlBQUY7QUFBZ0JNLFlBQUFBO0FBQWhCLGNBQTJCTyxJQUFqQztBQUNBLGdCQUFNO0FBQUVFLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEIsY0FBeUJILE9BQS9CO0FBRUEsaUJBQU87QUFDTEosWUFBQUEsTUFBTSxFQUFFLENBQUMsTUFBTVEsaUNBQWdCQyxtQkFBaEIsQ0FBb0M7QUFDakRiLGNBQUFBLE1BQU0sRUFBRTtBQUNOTixnQkFBQUE7QUFETSxlQUR5QztBQUlqRGUsY0FBQUEsTUFKaUQ7QUFLakRDLGNBQUFBLElBTGlEO0FBTWpEQyxjQUFBQSxJQU5pRDtBQU9qREcsY0FBQUEsSUFBSSxFQUFFZDtBQVAyQyxhQUFwQyxDQUFQLEVBUUplLFFBUkksQ0FRS1g7QUFUUixXQUFQO0FBV0QsU0FmRCxDQWVFLE9BQU9ZLENBQVAsRUFBVTtBQUNWaEMsVUFBQUEsa0JBQWtCLENBQUNpQyxXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBeEN3RCxLQUE3QixDQUE5QjtBQTJDQWhDLElBQUFBLGtCQUFrQixDQUFDSSxjQUFuQixDQUNFUSxxQkFBcUIsQ0FBQ1csSUFBdEIsQ0FBMkJXLEtBQTNCLENBQWlDcEIsSUFBakMsQ0FBc0NxQixNQUR4QyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FuQyxJQUFBQSxrQkFBa0IsQ0FBQ0ksY0FBbkIsQ0FBa0NRLHFCQUFxQixDQUFDRSxJQUF4RCxFQUE4RCxJQUE5RCxFQUFvRSxJQUFwRTtBQUNBZCxJQUFBQSxrQkFBa0IsQ0FBQ29DLGtCQUFuQixDQUNFLGVBREYsRUFFRXhCLHFCQUZGLEVBR0UsSUFIRixFQUlFLElBSkY7QUFNRDtBQUNGLENBM0VEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwsIEdyYXBoUUxFbnVtVHlwZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi4vLi4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgaWYgKHBhcnNlR3JhcGhRTFNjaGVtYS5mdW5jdGlvbk5hbWVzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjbG91ZENvZGVGdW5jdGlvbkVudW0gPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICBuZXcgR3JhcGhRTEVudW1UeXBlKHtcbiAgICAgICAgbmFtZTogJ0Nsb3VkQ29kZUZ1bmN0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoZSBDbG91ZENvZGVGdW5jdGlvbiBlbnVtIHR5cGUgY29udGFpbnMgYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY2xvdWQgY29kZSBmdW5jdGlvbnMuJyxcbiAgICAgICAgdmFsdWVzOiBwYXJzZUdyYXBoUUxTY2hlbWEuZnVuY3Rpb25OYW1lcy5yZWR1Y2UoXG4gICAgICAgICAgKHZhbHVlcywgZnVuY3Rpb25OYW1lKSA9PiAoe1xuICAgICAgICAgICAgLi4udmFsdWVzLFxuICAgICAgICAgICAgW2Z1bmN0aW9uTmFtZV06IHsgdmFsdWU6IGZ1bmN0aW9uTmFtZSB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHt9XG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIGNvbnN0IGNhbGxDbG91ZENvZGVNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogJ0NhbGxDbG91ZENvZGUnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgY2FsbENsb3VkQ29kZSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBpbnZva2UgYSBjbG91ZCBjb2RlIGZ1bmN0aW9uLicsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBmdW5jdGlvbk5hbWU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbG91ZENvZGVGdW5jdGlvbkVudW0pLFxuICAgICAgICB9LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgcGFyYW1zIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uJyxcbiAgICAgICAgICB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgcmVzdWx0OiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAnVGhpcyBpcyB0aGUgcmVzdWx0IHZhbHVlIG9mIHRoZSBjbG91ZCBjb2RlIGZ1bmN0aW9uIGV4ZWN1dGlvbi4nLFxuICAgICAgICAgIHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQU5ZLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBmdW5jdGlvbk5hbWUsIHBhcmFtcyB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHQ6IChhd2FpdCBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRGdW5jdGlvbih7XG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBib2R5OiBwYXJhbXMsXG4gICAgICAgICAgICB9KSkucmVzcG9uc2UucmVzdWx0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICBjYWxsQ2xvdWRDb2RlTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlXG4gICAgKTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2FsbENsb3VkQ29kZU11dGF0aW9uLnR5cGUsIHRydWUsIHRydWUpO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgICAnY2FsbENsb3VkQ29kZScsXG4gICAgICBjYWxsQ2xvdWRDb2RlTXV0YXRpb24sXG4gICAgICB0cnVlLFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassMutations.js b/lib/GraphQL/loaders/parseClassMutations.js deleted file mode 100644 index 775475a289..0000000000 --- a/lib/GraphQL/loaders/parseClassMutations.js +++ /dev/null @@ -1,288 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); - -var _className = require("../transformers/className"); - -var _mutation = require("../transformers/mutation"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const getOnlyRequiredFields = (updatedFields, selectedFieldsString, includedFieldsString, nativeObjectFields) => { - const includedFields = includedFieldsString ? includedFieldsString.split(',') : []; - const selectedFields = selectedFieldsString ? selectedFieldsString.split(',') : []; - const missingFields = selectedFields.filter(field => !nativeObjectFields.includes(field) || includedFields.includes(field)).join(','); - - if (!missingFields.length) { - return { - needGet: false, - keys: '' - }; - } else { - return { - needGet: true, - keys: missingFields - }; - } -}; - -const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { - const className = parseClass.className; - const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); - const getGraphQLQueryName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); - const { - create: isCreateEnabled = true, - update: isUpdateEnabled = true, - destroy: isDestroyEnabled = true, - createAlias = '', - updateAlias = '', - destroyAlias = '' - } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); - const { - classGraphQLCreateType, - classGraphQLUpdateType, - classGraphQLOutputType - } = parseGraphQLSchema.parseClassTypes[className]; - - if (isCreateEnabled) { - const createGraphQLMutationName = createAlias || `create${graphQLClassName}`; - const createGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: `Create${graphQLClassName}`, - description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`, - inputFields: { - fields: { - description: 'These are the fields that will be used to create the new object.', - type: classGraphQLCreateType || defaultGraphQLTypes.OBJECT - } - }, - outputFields: { - [getGraphQLQueryName]: { - description: 'This is the created object.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - let { - fields - } = args; - if (!fields) fields = {}; - const { - config, - auth, - info - } = context; - const parseFields = await (0, _mutation.transformTypes)('create', fields, { - className, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const createdObject = await objectsMutations.createObject(className, parseFields, config, auth, info); - const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - const { - keys: requiredKeys, - needGet - } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'createdAt', 'updatedAt']); - const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); - let optimizedObject = {}; - - if (needGet && !needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } else if (needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } - - return { - [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({}, createdObject), {}, { - updatedAt: createdObject.createdAt - }, parseFields), optimizedObject) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - - if (parseGraphQLSchema.addGraphQLType(createGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(createGraphQLMutation.type)) { - parseGraphQLSchema.addGraphQLMutation(createGraphQLMutationName, createGraphQLMutation); - } - } - - if (isUpdateEnabled) { - const updateGraphQLMutationName = updateAlias || `update${graphQLClassName}`; - const updateGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: `Update${graphQLClassName}`, - description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`, - inputFields: { - id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, - fields: { - description: 'These are the fields that will be used to update the object.', - type: classGraphQLUpdateType || defaultGraphQLTypes.OBJECT - } - }, - outputFields: { - [getGraphQLQueryName]: { - description: 'This is the updated object.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - let { - id, - fields - } = args; - if (!fields) fields = {}; - const { - config, - auth, - info - } = context; - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); - - if (globalIdObject.type === className) { - id = globalIdObject.id; - } - - const parseFields = await (0, _mutation.transformTypes)('update', fields, { - className, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const updatedObject = await objectsMutations.updateObject(className, id, parseFields, config, auth, info); - const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - const { - keys: requiredKeys, - needGet - } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'updatedAt']); - const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); - let optimizedObject = {}; - - if (needGet && !needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, id, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } else if (needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, id, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } - - return { - [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({ - objectId: id - }, updatedObject), parseFields), optimizedObject) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - - if (parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.type)) { - parseGraphQLSchema.addGraphQLMutation(updateGraphQLMutationName, updateGraphQLMutation); - } - } - - if (isDestroyEnabled) { - const deleteGraphQLMutationName = destroyAlias || `delete${graphQLClassName}`; - const deleteGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: `Delete${graphQLClassName}`, - description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`, - inputFields: { - id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT - }, - outputFields: { - [getGraphQLQueryName]: { - description: 'This is the deleted object.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - let { - id - } = args; - const { - config, - auth, - info - } = context; - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); - - if (globalIdObject.type === className) { - id = globalIdObject.id; - } - - const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - let optimizedObject = {}; - - if (keys && keys.split(',').filter(key => !['id', 'objectId'].includes(key)).length > 0) { - optimizedObject = await objectsQueries.getObject(className, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } - - await objectsMutations.deleteObject(className, id, config, auth, info); - return { - [getGraphQLQueryName]: _objectSpread({ - objectId: id - }, optimizedObject) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - - if (parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.type)) { - parseGraphQLSchema.addGraphQLMutation(deleteGraphQLMutationName, deleteGraphQLMutation); - } - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJnZXRPbmx5UmVxdWlyZWRGaWVsZHMiLCJ1cGRhdGVkRmllbGRzIiwic2VsZWN0ZWRGaWVsZHNTdHJpbmciLCJpbmNsdWRlZEZpZWxkc1N0cmluZyIsIm5hdGl2ZU9iamVjdEZpZWxkcyIsImluY2x1ZGVkRmllbGRzIiwic3BsaXQiLCJzZWxlY3RlZEZpZWxkcyIsIm1pc3NpbmdGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwiam9pbiIsImxlbmd0aCIsIm5lZWRHZXQiLCJrZXlzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiZ3JhcGhRTENsYXNzTmFtZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJjaGFyQXQiLCJ0b0xvd2VyQ2FzZSIsInNsaWNlIiwiY3JlYXRlIiwiaXNDcmVhdGVFbmFibGVkIiwidXBkYXRlIiwiaXNVcGRhdGVFbmFibGVkIiwiZGVzdHJveSIsImlzRGVzdHJveUVuYWJsZWQiLCJjcmVhdGVBbGlhcyIsInVwZGF0ZUFsaWFzIiwiZGVzdHJveUFsaWFzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsImNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY3JlYXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImNyZWF0ZUdyYXBoUUxNdXRhdGlvbiIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsImlucHV0RmllbGRzIiwiZmllbGRzIiwidHlwZSIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJPQkpFQ1QiLCJvdXRwdXRGaWVsZHMiLCJHcmFwaFFMTm9uTnVsbCIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJyZXEiLCJjcmVhdGVkT2JqZWN0Iiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsInN0YXJ0c1dpdGgiLCJtYXAiLCJyZXBsYWNlIiwiaW5jbHVkZSIsInJlcXVpcmVkS2V5cyIsIm5lZWRUb0dldEFsbEtleXMiLCJvYmplY3RzUXVlcmllcyIsInBhcnNlQ2xhc3NlcyIsIm9wdGltaXplZE9iamVjdCIsImdldE9iamVjdCIsIm9iamVjdElkIiwidW5kZWZpbmVkIiwidXBkYXRlZEF0IiwiY3JlYXRlZEF0IiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUiLCJ1cGRhdGVHcmFwaFFMTXV0YXRpb24iLCJpZCIsIkdMT0JBTF9PUl9PQkpFQ1RfSURfQVRUIiwiZ2xvYmFsSWRPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwidXBkYXRlT2JqZWN0IiwiZGVsZXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImRlbGV0ZUdyYXBoUUxNdXRhdGlvbiIsImtleSIsImRlbGV0ZU9iamVjdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUlBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLENBQzVCQyxhQUQ0QixFQUU1QkMsb0JBRjRCLEVBRzVCQyxvQkFINEIsRUFJNUJDLGtCQUo0QixLQUt6QjtBQUNILFFBQU1DLGNBQWMsR0FBR0Ysb0JBQW9CLEdBQ3ZDQSxvQkFBb0IsQ0FBQ0csS0FBckIsQ0FBMkIsR0FBM0IsQ0FEdUMsR0FFdkMsRUFGSjtBQUdBLFFBQU1DLGNBQWMsR0FBR0wsb0JBQW9CLEdBQ3ZDQSxvQkFBb0IsQ0FBQ0ksS0FBckIsQ0FBMkIsR0FBM0IsQ0FEdUMsR0FFdkMsRUFGSjtBQUdBLFFB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O0FBQ1YzRCxVQUFBQSxrQkFBa0IsQ0FBQzRELFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUFoRXdELEtBQTdCLENBQTlCOztBQW1FQSxRQUNFM0Qsa0JBQWtCLENBQUM2RCxjQUFuQixDQUNFWSxxQkFBcUIsQ0FBQ3ZDLElBQXRCLENBQTJCNEIsS0FBM0IsQ0FBaUNsQyxJQUFqQyxDQUFzQ21DLE1BRHhDLEtBR0EvRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDWSxxQkFBcUIsQ0FBQzdDLElBQXhELENBSkYsRUFLRTtBQUNBNUIsTUFBQUEsa0JBQWtCLENBQUNnRSxrQkFBbkIsQ0FDRVEseUJBREYsRUFFRUMscUJBRkY7QUFJRDtBQUNGO0FBQ0YsQ0FoVkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZnJvbUdsb2JhbElkLCBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCB7XG4gIGV4dHJhY3RLZXlzQW5kSW5jbHVkZSxcbiAgZ2V0UGFyc2VDbGFzc011dGF0aW9uQ29uZmlnLFxufSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzTXV0YXRpb25zIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY2xhc3NOYW1lJztcbmltcG9ydCB7IHRyYW5zZm9ybVR5cGVzIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL211dGF0aW9uJztcblxuY29uc3QgZ2V0T25seVJlcXVpcmVkRmllbGRzID0gKFxuICB1cGRhdGVkRmllbGRzLFxuICBzZWxlY3RlZEZpZWxkc1N0cmluZyxcbiAgaW5jbHVkZWRGaWVsZHNTdHJpbmcsXG4gIG5hdGl2ZU9iamVjdEZpZWxkc1xuKSA9PiB7XG4gIGNvbnN0IGluY2x1ZGVkRmllbGRzID0gaW5jbHVkZWRGaWVsZHNTdHJpbmdcbiAgICA/IGluY2x1ZGVkRmllbGRzU3RyaW5nLnNwbGl0KCcsJylcbiAgICA6IFtdO1xuICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IHNlbGVjdGVkRmllbGRzU3RyaW5nXG4gICAgPyBzZWxlY3RlZEZpZWxkc1N0cmluZy5zcGxpdCgnLCcpXG4gICAgOiBbXTtcbiAgY29uc3QgbWlzc2luZ0ZpZWxkcyA9IHNlbGVjdGVkRmllbGRzXG4gICAgLmZpbHRlcihcbiAgICAgIGZpZWxkID0+XG4gICAgICAgICFuYXRpdmVPYmplY3RGaWVsZHMuaW5jbHVkZXMoZmllbGQpIHx8IGluY2x1ZGVkRmllbGRzLmluY2x1ZGVzKGZpZWxkKVxuICAgIClcbiAgICAuam9pbignLCcpO1xuICBpZiAoIW1pc3NpbmdGaWVsZHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHsgbmVlZEdldDogZmFsc2UsIGtleXM6ICcnIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHsgbmVlZEdldDogdHJ1ZSwga2V5czogbWlzc2luZ0ZpZWxkcyB9O1xuICB9XG59O1xuXG5jb25zdCBsb2FkID0gZnVuY3Rpb24oXG4gIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgcGFyc2VDbGFzcyxcbiAgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnXG4pIHtcbiAgY29uc3QgY2xhc3NOYW1lID0gcGFyc2VDbGFzcy5jbGFzc05hbWU7XG4gIGNvbnN0IGdyYXBoUUxDbGFzc05hbWUgPSB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwoY2xhc3NOYW1lKTtcbiAgY29uc3QgZ2V0R3JhcGhRTFF1ZXJ5TmFtZSA9XG4gICAgZ3JhcGhRTENsYXNzTmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGdyYXBoUUxDbGFzc05hbWUuc2xpY2UoMSk7XG5cbiAgY29uc3Qge1xuICAgIGNyZWF0ZTogaXNDcmVhdGVFbmFibGVkID0gdHJ1ZSxcbiAgICB1cGRhdGU6IGlzVXBkYXRlRW5hYmxlZCA9IHRydWUsXG4gICAgZGVzdHJveTogaXNEZXN0cm95RW5hYmxlZCA9IHRydWUsXG4gICAgY3JlYXRlQWxpYXM6IGNyZWF0ZUFsaWFzID0gJycsXG4gICAgdXBkYXRlQWxpYXM6IHVwZGF0ZUFsaWFzID0gJycsXG4gICAgZGVzdHJveUFsaWFzOiBkZXN0cm95QWxpYXMgPSAnJyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG5cbiAgaWYgKGlzQ3JlYXRlRW5hYmxlZCkge1xuICAgIGNvbnN0IGNyZWF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUgPVxuICAgICAgY3JlYXRlQWxpYXMgfHwgYGNyZWF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gO1xuICAgIGNvbnN0IGNyZWF0ZUdyYXBoUUxNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogYENyZWF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtjcmVhdGVHcmFwaFFMTXV0YXRpb25OYW1lfSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICdUaGVzZSBhcmUgdGhlIGZpZWxkcyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjcmVhdGUgdGhlIG5ldyBvYmplY3QuJyxcbiAgICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNULFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgICBbZ2V0R3JhcGhRTFF1ZXJ5TmFtZV06IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNyZWF0ZWQgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICAgICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVFxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB7IGZpZWxkcyB9ID0gYXJncztcbiAgICAgICAgICBpZiAoIWZpZWxkcykgZmllbGRzID0ge307XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGNyZWF0ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm9cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhtdXRhdGlvbkluZm8pXG4gICAgICAgICAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCkpXG4gICAgICAgICAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2UoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCwgJycpKTtcbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG4gICAgICAgICAgY29uc3QgeyBrZXlzOiByZXF1aXJlZEtleXMsIG5lZWRHZXQgfSA9IGdldE9ubHlSZXF1aXJlZEZpZWxkcyhcbiAgICAgICAgICAgIGZpZWxkcyxcbiAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgWydpZCcsICdvYmplY3RJZCcsICdjcmVhdGVkQXQnLCAndXBkYXRlZEF0J11cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSBvYmplY3RzUXVlcmllcy5uZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHMsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChuZWVkR2V0ICYmICFuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgY3JlYXRlZE9iamVjdC5vYmplY3RJZCxcbiAgICAgICAgICAgICAgcmVxdWlyZWRLZXlzLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmVlZFRvR2V0QWxsS2V5cykge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGNyZWF0ZWRPYmplY3Qub2JqZWN0SWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICAuLi5jcmVhdGVkT2JqZWN0LFxuICAgICAgICAgICAgICB1cGRhdGVkQXQ6IGNyZWF0ZWRPYmplY3QuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAuLi5wYXJzZUZpZWxkcyxcbiAgICAgICAgICAgICAgLi4ub3B0aW1pemVkT2JqZWN0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKFxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgICAgICBjcmVhdGVHcmFwaFFMTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZVxuICAgICAgKSAmJlxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUdyYXBoUUxNdXRhdGlvbi50eXBlKVxuICAgICkge1xuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAgICAgY3JlYXRlR3JhcGhRTE11dGF0aW9uTmFtZSxcbiAgICAgICAgY3JlYXRlR3JhcGhRTE11dGF0aW9uXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc1VwZGF0ZUVuYWJsZWQpIHtcbiAgICBjb25zdCB1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lID1cbiAgICAgIHVwZGF0ZUFsaWFzIHx8IGB1cGRhdGUke2dyYXBoUUxDbGFzc05hbWV9YDtcbiAgICBjb25zdCB1cGRhdGVHcmFwaFFMTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICAgIG5hbWU6IGBVcGRhdGUke2dyYXBoUUxDbGFzc05hbWV9YCxcbiAgICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7dXBkYXRlR3JhcGhRTE11dGF0aW9uTmFtZX0gbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gdXBkYXRlIGFuIG9iamVjdCBvZiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgICAgaWQ6IGRlZmF1bHRHcmFwaFFMVHlwZXMuR0xPQkFMX09SX09CSkVDVF9JRF9BVFQsXG4gICAgICAgIGZpZWxkczoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgJ1RoZXNlIGFyZSB0aGUgZmllbGRzIHRoYXQgd2lsbCBiZSB1c2VkIHRvIHVwZGF0ZSB0aGUgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMVXBkYXRlVHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cGRhdGVkIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChcbiAgICAgICAgICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsZXQgeyBpZCwgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICAgIGlmICghZmllbGRzKSBmaWVsZHMgPSB7fTtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGlkKTtcblxuICAgICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIGlkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcGFyc2VGaWVsZHMgPSBhd2FpdCB0cmFuc2Zvcm1UeXBlcygndXBkYXRlJywgZmllbGRzLCB7XG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c011dGF0aW9ucy51cGRhdGVPYmplY3QoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm9cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKG11dGF0aW9uSW5mbylcbiAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aChgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gKSlcbiAgICAgICAgICAgIC5tYXAoZmllbGQgPT4gZmllbGQucmVwbGFjZShgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gLCAnJykpO1xuICAgICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKHNlbGVjdGVkRmllbGRzKTtcbiAgICAgICAgICBjb25zdCB7IGtleXM6IHJlcXVpcmVkS2V5cywgbmVlZEdldCB9ID0gZ2V0T25seVJlcXVpcmVkRmllbGRzKFxuICAgICAgICAgICAgZmllbGRzLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICBbJ2lkJywgJ29iamVjdElkJywgJ3VwZGF0ZWRBdCddXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBuZWVkVG9HZXRBbGxLZXlzID0gb2JqZWN0c1F1ZXJpZXMubmVlZFRvR2V0QWxsS2V5cyhcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGxldCBvcHRpbWl6ZWRPYmplY3QgPSB7fTtcbiAgICAgICAgICBpZiAobmVlZEdldCAmJiAhbmVlZFRvR2V0QWxsS2V5cykge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICByZXF1aXJlZEtleXMsXG4gICAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICBvYmplY3RJZDogaWQsXG4gICAgICAgICAgICAgIC4uLnVwZGF0ZWRPYmplY3QsXG4gICAgICAgICAgICAgIC4uLnBhcnNlRmllbGRzLFxuICAgICAgICAgICAgICAuLi5vcHRpbWl6ZWRPYmplY3QsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICAgIHVwZGF0ZUdyYXBoUUxNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlXG4gICAgICApICYmXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUodXBkYXRlR3JhcGhRTE11dGF0aW9uLnR5cGUpXG4gICAgKSB7XG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKFxuICAgICAgICB1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lLFxuICAgICAgICB1cGRhdGVHcmFwaFFMTXV0YXRpb25cbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzRGVzdHJveUVuYWJsZWQpIHtcbiAgICBjb25zdCBkZWxldGVHcmFwaFFMTXV0YXRpb25OYW1lID1cbiAgICAgIGRlc3Ryb3lBbGlhcyB8fCBgZGVsZXRlJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gICAgY29uc3QgZGVsZXRlR3JhcGhRTE11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgICBuYW1lOiBgRGVsZXRlJHtncmFwaFFMQ2xhc3NOYW1lfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSAke2RlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWV9IG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIGRlbGV0ZSBhbiBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICAgIGlucHV0RmllbGRzOiB7XG4gICAgICAgIGlkOiBkZWZhdWx0R3JhcGhRTFR5cGVzLkdMT0JBTF9PUl9PQkpFQ1RfSURfQVRULFxuICAgICAgfSxcbiAgICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgICBbZ2V0R3JhcGhRTFF1ZXJ5TmFtZV06IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGRlbGV0ZWQgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICAgICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVFxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB7IGlkIH0gPSBhcmdzO1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaWQpO1xuXG4gICAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IGNsYXNzTmFtZSkge1xuICAgICAgICAgICAgaWQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMobXV0YXRpb25JbmZvKVxuICAgICAgICAgICAgLmZpbHRlcihmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmApKVxuICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmAsICcnKSk7XG4gICAgICAgICAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGxldCBvcHRpbWl6ZWRPYmplY3QgPSB7fTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBrZXlzICYmXG4gICAgICAgICAgICBrZXlzLnNwbGl0KCcsJykuZmlsdGVyKGtleSA9PiAhWydpZCcsICdvYmplY3RJZCddLmluY2x1ZGVzKGtleSkpXG4gICAgICAgICAgICAgIC5sZW5ndGggPiAwXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuZGVsZXRlT2JqZWN0KFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mb1xuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICBvYmplY3RJZDogaWQsXG4gICAgICAgICAgICAgIC4uLm9wdGltaXplZE9iamVjdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICAgICAgZGVsZXRlR3JhcGhRTE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGVcbiAgICAgICkgJiZcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShkZWxldGVHcmFwaFFMTXV0YXRpb24udHlwZSlcbiAgICApIHtcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgICAgIGRlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWUsXG4gICAgICAgIGRlbGV0ZUdyYXBoUUxNdXRhdGlvblxuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassQueries.js b/lib/GraphQL/loaders/parseClassQueries.js deleted file mode 100644 index 2901f2cf06..0000000000 --- a/lib/GraphQL/loaders/parseClassQueries.js +++ /dev/null @@ -1,150 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var _pluralize = _interopRequireDefault(require("pluralize")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); - -var _className = require("../transformers/className"); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const getParseClassQueryConfig = function (parseClassConfig) { - return parseClassConfig && parseClassConfig.query || {}; -}; - -const getQuery = async (parseClass, _source, args, context, queryInfo, parseClasses) => { - let { - id - } = args; - const { - options - } = args; - const { - readPreference, - includeReadPreference - } = options || {}; - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); - - if (globalIdObject.type === parseClass.className) { - id = globalIdObject.id; - } - - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - return await objectsQueries.getObject(parseClass.className, id, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses); -}; - -const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { - const className = parseClass.className; - const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); - const { - get: isGetEnabled = true, - find: isFindEnabled = true, - getAlias = '', - findAlias = '' - } = getParseClassQueryConfig(parseClassConfig); - const { - classGraphQLOutputType, - classGraphQLFindArgs, - classGraphQLFindResultType - } = parseGraphQLSchema.parseClassTypes[className]; - - if (isGetEnabled) { - const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); - const getGraphQLQueryName = getAlias || lowerCaseClassName; - parseGraphQLSchema.addGraphQLQuery(getGraphQLQueryName, { - description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`, - args: { - id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, - options: defaultGraphQLTypes.READ_OPTIONS_ATT - }, - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT), - - async resolve(_source, args, context, queryInfo) { - try { - return await getQuery(parseClass, _source, args, context, queryInfo, parseGraphQLSchema.parseClasses); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - }); - } - - if (isFindEnabled) { - const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); - const findGraphQLQueryName = findAlias || (0, _pluralize.default)(lowerCaseClassName); - parseGraphQLSchema.addGraphQLQuery(findGraphQLQueryName, { - description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`, - args: classGraphQLFindArgs, - type: new _graphql.GraphQLNonNull(classGraphQLFindResultType || defaultGraphQLTypes.OBJECT), - - async resolve(_source, args, context, queryInfo) { - try { - const { - where, - order, - skip, - first, - after, - last, - before, - options - } = args; - const { - readPreference, - includeReadPreference, - subqueryReadPreference - } = options || {}; - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); - const parseOrder = order && order.join(','); - return await objectsQueries.findObjects(className, where, parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - }); - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMuanMiXSwibmFtZXMiOlsiZ2V0UGFyc2VDbGFzc1F1ZXJ5Q29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInF1ZXJ5IiwiZ2V0UXVlcnkiLCJwYXJzZUNsYXNzIiwiX3NvdXJjZSIsImFyZ3MiLCJjb250ZXh0IiwicXVlcnlJbmZvIiwicGFyc2VDbGFzc2VzIiwiaWQiLCJvcHRpb25zIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInNlbGVjdGVkRmllbGRzIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiY2xhc3NOYW1lIiwia2V5cyIsImluY2x1ZGUiLCJvYmplY3RzUXVlcmllcyIsImdldE9iamVjdCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiZ2V0IiwiaXNHZXRFbmFibGVkIiwiZmluZCIsImlzRmluZEVuYWJsZWQiLCJnZXRBbGlhcyIsImZpbmRBbGlhcyIsImNsYXNzR3JhcGhRTE91dHB1dFR5cGUiLCJjbGFzc0dyYXBoUUxGaW5kQXJncyIsImNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwibG93ZXJDYXNlQ2xhc3NOYW1lIiwiY2hhckF0IiwidG9Mb3dlckNhc2UiLCJzbGljZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCIsIlJFQURfT1BUSU9OU19BVFQiLCJHcmFwaFFMTm9uTnVsbCIsIk9CSkVDVCIsInJlc29sdmUiLCJlIiwiaGFuZGxlRXJyb3IiLCJmaW5kR3JhcGhRTFF1ZXJ5TmFtZSIsIndoZXJlIiwib3JkZXIiLCJza2lwIiwiZmlyc3QiLCJhZnRlciIsImxhc3QiLCJiZWZvcmUiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsInBhcnNlT3JkZXIiLCJqb2luIiwiZmluZE9iamVjdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSx3QkFBd0IsR0FBRyxVQUMvQkMsZ0JBRCtCLEVBRS9CO0FBQ0EsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxLQUF0QyxJQUFnRCxFQUF2RDtBQUNELENBSkQ7O0FBTUEsTUFBTUMsUUFBUSxHQUFHLE9BQ2ZDLFVBRGUsRUFFZkMsT0FGZSxFQUdmQyxJQUhlLEVBSWZDLE9BSmUsRUFLZkMsU0FMZSxFQU1mQyxZQU5lLEtBT1o7QUFDSCxNQUFJO0FBQUVDLElBQUFBO0FBQUYsTUFBU0osSUFBYjtBQUNBLFFBQU07QUFBRUssSUFBQUE7QUFBRixNQUFjTCxJQUFwQjtBQUNBLFFBQU07QUFBRU0sSUFBQUEsY0FBRjtBQUFrQkMsSUFBQUE7QUFBbEIsTUFBNENGLE9BQU8sSUFBSSxFQUE3RDtBQUNBLFFBQU07QUFBRUcsSUFBQUEsTUFBRjtBQUFVQyxJQUFBQSxJQUFWO0FBQWdCQyxJQUFBQTtBQUFoQixNQUF5QlQsT0FBL0I7QUFDQSxRQUFNVSxjQUFjLEdBQUcsZ0NBQWNULFNBQWQsQ0FBdkI7QUFFQSxRQUFNVSxjQUFjLEdBQUcsZ0NBQWFSLEVBQWIsQ0FBdkI7O0FBRUEsTUFBSVEsY0FBYyxDQUFDQyxJQUFmLEtBQXdCZixVQUFVLENBQUNnQixTQUF2QyxFQUFrRDtBQUNoRFYsSUFBQUEsRUFBRSxHQUFHUSxjQUFjLENBQUNSLEVBQXBCO0FBQ0Q7O0FBRUQsUUFBTTtBQUFFVyxJQUFBQSxJQUFGO0FBQVFDLElBQUFBO0FBQVIsTUFBb0IsOENBQXNCTCxjQUF0QixDQUExQjtBQUVBLFNBQU8sTUFBTU0sY0FBYyxDQUFDQyxT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YlcsRUFjWGdELHNCQWRXLEVBZVgvQyxNQWZXLEVBZ0JYQyxJQWhCVyxFQWlCWEMsSUFqQlcsRUFrQlhDLGNBbEJXLEVBbUJYUyxrQkFBa0IsQ0FBQ2pCLFlBbkJSLENBQWI7QUFxQkQsU0EvQ0QsQ0ErQ0UsT0FBTzBDLENBQVAsRUFBVTtBQUNWekIsVUFBQUEsa0JBQWtCLENBQUMwQixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGOztBQXpEc0QsS0FBekQ7QUEyREQ7QUFDRixDQXRIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEdyYXBoUUxOb25OdWxsIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBmcm9tR2xvYmFsSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCBnZXRGaWVsZE5hbWVzIGZyb20gJ2dyYXBocWwtbGlzdC1maWVsZHMnO1xuaW1wb3J0IHBsdXJhbGl6ZSBmcm9tICdwbHVyYWxpemUnO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0ICogYXMgb2JqZWN0c1F1ZXJpZXMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzUXVlcmllcyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxDbGFzc0NvbmZpZyB9IGZyb20gJy4uLy4uL0NvbnRyb2xsZXJzL1BhcnNlR3JhcGhRTENvbnRyb2xsZXInO1xuaW1wb3J0IHsgdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2NsYXNzTmFtZSc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUgfSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5cbmNvbnN0IGdldFBhcnNlQ2xhc3NRdWVyeUNvbmZpZyA9IGZ1bmN0aW9uIChcbiAgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnXG4pIHtcbiAgcmV0dXJuIChwYXJzZUNsYXNzQ29uZmlnICYmIHBhcnNlQ2xhc3NDb25maWcucXVlcnkpIHx8IHt9O1xufTtcblxuY29uc3QgZ2V0UXVlcnkgPSBhc3luYyAoXG4gIHBhcnNlQ2xhc3MsXG4gIF9zb3VyY2UsXG4gIGFyZ3MsXG4gIGNvbnRleHQsXG4gIHF1ZXJ5SW5mbyxcbiAgcGFyc2VDbGFzc2VzXG4pID0+IHtcbiAgbGV0IHsgaWQgfSA9IGFyZ3M7XG4gIGNvbnN0IHsgb3B0aW9ucyB9ID0gYXJncztcbiAgY29uc3QgeyByZWFkUHJlZmVyZW5jZSwgaW5jbHVkZVJlYWRQcmVmZXJlbmNlIH0gPSBvcHRpb25zIHx8IHt9O1xuICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcbiAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaWQpO1xuXG4gIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSBwYXJzZUNsYXNzLmNsYXNzTmFtZSkge1xuICAgIGlkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gIH1cblxuICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG5cbiAgcmV0dXJuIGF3YWl0IG9iamVjdHNRdWVyaWVzLmdldE9iamVjdChcbiAgICBwYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICBpZCxcbiAgICBrZXlzLFxuICAgIGluY2x1ZGUsXG4gICAgcmVhZFByZWZlcmVuY2UsXG4gICAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICAgIGNvbmZpZyxcbiAgICBhdXRoLFxuICAgIGluZm8sXG4gICAgcGFyc2VDbGFzc2VzXG4gICk7XG59O1xuXG5jb25zdCBsb2FkID0gZnVuY3Rpb24gKFxuICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gIHBhcnNlQ2xhc3MsXG4gIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZ1xuKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICBjb25zdCBncmFwaFFMQ2xhc3NOYW1lID0gdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMKGNsYXNzTmFtZSk7XG4gIGNvbnN0IHtcbiAgICBnZXQ6IGlzR2V0RW5hYmxlZCA9IHRydWUsXG4gICAgZmluZDogaXNGaW5kRW5hYmxlZCA9IHRydWUsXG4gICAgZ2V0QWxpYXM6IGdldEFsaWFzID0gJycsXG4gICAgZmluZEFsaWFzOiBmaW5kQWxpYXMgPSAnJyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NRdWVyeUNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSxcbiAgICBjbGFzc0dyYXBoUUxGaW5kQXJncyxcbiAgICBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSxcbiAgfSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbY2xhc3NOYW1lXTtcblxuICBpZiAoaXNHZXRFbmFibGVkKSB7XG4gICAgY29uc3QgbG93ZXJDYXNlQ2xhc3NOYW1lID1cbiAgICAgIGdyYXBoUUxDbGFzc05hbWUuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBncmFwaFFMQ2xhc3NOYW1lLnNsaWNlKDEpO1xuXG4gICAgY29uc3QgZ2V0R3JhcGhRTFF1ZXJ5TmFtZSA9IGdldEFsaWFzIHx8IGxvd2VyQ2FzZUNsYXNzTmFtZTtcblxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoZ2V0R3JhcGhRTFF1ZXJ5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfSBxdWVyeSBjYW4gYmUgdXNlZCB0byBnZXQgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGJ5IGl0cyBpZC5gLFxuICAgICAgYXJnczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgICAgb3B0aW9uczogZGVmYXVsdEdyYXBoUUxUeXBlcy5SRUFEX09QVElPTlNfQVRULFxuICAgICAgfSxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChcbiAgICAgICAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVFxuICAgICAgKSxcbiAgICAgIGFzeW5jIHJlc29sdmUoX3NvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGdldFF1ZXJ5KFxuICAgICAgICAgICAgcGFyc2VDbGFzcyxcbiAgICAgICAgICAgIF9zb3VyY2UsXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzRmluZEVuYWJsZWQpIHtcbiAgICBjb25zdCBsb3dlckNhc2VDbGFzc05hbWUgPVxuICAgICAgZ3JhcGhRTENsYXNzTmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGdyYXBoUUxDbGFzc05hbWUuc2xpY2UoMSk7XG5cbiAgICBjb25zdCBmaW5kR3JhcGhRTFF1ZXJ5TmFtZSA9IGZpbmRBbGlhcyB8fCBwbHVyYWxpemUobG93ZXJDYXNlQ2xhc3NOYW1lKTtcblxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoZmluZEdyYXBoUUxRdWVyeU5hbWUsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7ZmluZEdyYXBoUUxRdWVyeU5hbWV9IHF1ZXJ5IGNhbiBiZSB1c2VkIHRvIGZpbmQgb2JqZWN0cyBvZiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgYXJnczogY2xhc3NHcmFwaFFMRmluZEFyZ3MsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoXG4gICAgICAgIGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUXG4gICAgICApLFxuICAgICAgYXN5bmMgcmVzb2x2ZShfc291cmNlLCBhcmdzLCBjb250ZXh0LCBxdWVyeUluZm8pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgICAgc2tpcCxcbiAgICAgICAgICAgIGZpcnN0LFxuICAgICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgfSA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShcbiAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgIC5maWx0ZXIoKGZpZWxkKSA9PiBmaWVsZC5zdGFydHNXaXRoKCdlZGdlcy5ub2RlLicpKVxuICAgICAgICAgICAgICAubWFwKChmaWVsZCkgPT4gZmllbGQucmVwbGFjZSgnZWRnZXMubm9kZS4nLCAnJykpXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBwYXJzZU9yZGVyID0gb3JkZXIgJiYgb3JkZXIuam9pbignLCcpO1xuXG4gICAgICAgICAgcmV0dXJuIGF3YWl0IG9iamVjdHNRdWVyaWVzLmZpbmRPYmplY3RzKFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgd2hlcmUsXG4gICAgICAgICAgICBwYXJzZU9yZGVyLFxuICAgICAgICAgICAgc2tpcCxcbiAgICAgICAgICAgIGZpcnN0LFxuICAgICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgc2VsZWN0ZWRGaWVsZHMsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassTypes.js b/lib/GraphQL/loaders/parseClassTypes.js deleted file mode 100644 index 4c178368a4..0000000000 --- a/lib/GraphQL/loaders/parseClassTypes.js +++ /dev/null @@ -1,531 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "extractKeysAndInclude", { - enumerable: true, - get: function () { - return _parseGraphQLUtils.extractKeysAndInclude; - } -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); - -var _className = require("../transformers/className"); - -var _inputType = require("../transformers/inputType"); - -var _outputType = require("../transformers/outputType"); - -var _constraintType = require("../transformers/constraintType"); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const getParseClassTypeConfig = function (parseClassConfig) { - return parseClassConfig && parseClassConfig.type || {}; -}; - -const getInputFieldsAndConstraints = function (parseClass, parseClassConfig) { - const classFields = Object.keys(parseClass.fields).concat('id'); - const { - inputFields: allowedInputFields, - outputFields: allowedOutputFields, - constraintFields: allowedConstraintFields, - sortFields: allowedSortFields - } = getParseClassTypeConfig(parseClassConfig); - let classOutputFields; - let classCreateFields; - let classUpdateFields; - let classConstraintFields; - let classSortFields; // All allowed customs fields - - const classCustomFields = classFields.filter(field => { - return !Object.keys(defaultGraphQLTypes.PARSE_OBJECT_FIELDS).includes(field) && field !== 'id'; - }); - - if (allowedInputFields && allowedInputFields.create) { - classCreateFields = classCustomFields.filter(field => { - return allowedInputFields.create.includes(field); - }); - } else { - classCreateFields = classCustomFields; - } - - if (allowedInputFields && allowedInputFields.update) { - classUpdateFields = classCustomFields.filter(field => { - return allowedInputFields.update.includes(field); - }); - } else { - classUpdateFields = classCustomFields; - } - - if (allowedOutputFields) { - classOutputFields = classCustomFields.filter(field => { - return allowedOutputFields.includes(field); - }); - } else { - classOutputFields = classCustomFields; - } // Filters the "password" field from class _User - - - if (parseClass.className === '_User') { - classOutputFields = classOutputFields.filter(outputField => outputField !== 'password'); - } - - if (allowedConstraintFields) { - classConstraintFields = classCustomFields.filter(field => { - return allowedConstraintFields.includes(field); - }); - } else { - classConstraintFields = classFields; - } - - if (allowedSortFields) { - classSortFields = allowedSortFields; - - if (!classSortFields.length) { - // must have at least 1 order field - // otherwise the FindArgs Input Type will throw. - classSortFields.push({ - field: 'id', - asc: true, - desc: true - }); - } - } else { - classSortFields = classFields.map(field => { - return { - field, - asc: true, - desc: true - }; - }); - } - - return { - classCreateFields, - classUpdateFields, - classConstraintFields, - classOutputFields, - classSortFields - }; -}; - -const load = (parseGraphQLSchema, parseClass, parseClassConfig) => { - const className = parseClass.className; - const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); - const { - classCreateFields, - classUpdateFields, - classOutputFields, - classConstraintFields, - classSortFields - } = getInputFieldsAndConstraints(parseClass, parseClassConfig); - const { - create: isCreateEnabled = true, - update: isUpdateEnabled = true - } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); - const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`; - let classGraphQLCreateType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLCreateTypeName, - description: `The ${classGraphQLCreateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, - fields: () => classCreateFields.reduce((fields, field) => { - const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); - - if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type: className === '_User' && (field === 'username' || field === 'password') || parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type - } - }); - } else { - return fields; - } - }, { - ACL: { - type: defaultGraphQLTypes.ACL_INPUT - } - }) - }); - classGraphQLCreateType = parseGraphQLSchema.addGraphQLType(classGraphQLCreateType); - const classGraphQLUpdateTypeName = `Update${graphQLClassName}FieldsInput`; - let classGraphQLUpdateType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLUpdateTypeName, - description: `The ${classGraphQLUpdateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, - fields: () => classUpdateFields.reduce((fields, field) => { - const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); - - if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type - } - }); - } else { - return fields; - } - }, { - ACL: { - type: defaultGraphQLTypes.ACL_INPUT - } - }) - }); - classGraphQLUpdateType = parseGraphQLSchema.addGraphQLType(classGraphQLUpdateType); - const classGraphQLPointerTypeName = `${graphQLClassName}PointerInput`; - let classGraphQLPointerType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLPointerTypeName, - description: `Allow to link OR add and link an object of the ${graphQLClassName} class.`, - fields: () => { - const fields = { - link: { - description: `Link an existing object from ${graphQLClassName} class. You can use either the global or the object id.`, - type: _graphql.GraphQLID - } - }; - - if (isCreateEnabled) { - fields['createAndLink'] = { - description: `Create and link an object from ${graphQLClassName} class.`, - type: classGraphQLCreateType - }; - } - - return fields; - } - }); - classGraphQLPointerType = parseGraphQLSchema.addGraphQLType(classGraphQLPointerType) || defaultGraphQLTypes.OBJECT; - const classGraphQLRelationTypeName = `${graphQLClassName}RelationInput`; - let classGraphQLRelationType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLRelationTypeName, - description: `Allow to add, remove, createAndAdd objects of the ${graphQLClassName} class into a relation field.`, - fields: () => { - const fields = { - add: { - description: `Add existing objects from the ${graphQLClassName} class into the relation. You can use either the global or the object ids.`, - type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) - }, - remove: { - description: `Remove existing objects from the ${graphQLClassName} class out of the relation. You can use either the global or the object ids.`, - type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) - } - }; - - if (isCreateEnabled) { - fields['createAndAdd'] = { - description: `Create and add objects of the ${graphQLClassName} class into the relation.`, - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLCreateType)) - }; - } - - return fields; - } - }); - classGraphQLRelationType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationType) || defaultGraphQLTypes.OBJECT; - const classGraphQLConstraintsTypeName = `${graphQLClassName}WhereInput`; - let classGraphQLConstraintsType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLConstraintsTypeName, - description: `The ${classGraphQLConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, - fields: () => _objectSpread(_objectSpread({}, classConstraintFields.reduce((fields, field) => { - if (['OR', 'AND', 'NOR'].includes(field)) { - parseGraphQLSchema.log.warn(`Field ${field} could not be added to the auto schema ${classGraphQLConstraintsTypeName} because it collided with an existing one.`); - return fields; - } - - const parseField = field === 'id' ? 'objectId' : field; - const type = (0, _constraintType.transformConstraintTypeToGraphQL)(parseClass.fields[parseField].type, parseClass.fields[parseField].targetClass, parseGraphQLSchema.parseClassTypes, field); - - if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type - } - }); - } else { - return fields; - } - }, {})), {}, { - OR: { - description: 'This is the OR operator to compound constraints.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) - }, - AND: { - description: 'This is the AND operator to compound constraints.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) - }, - NOR: { - description: 'This is the NOR operator to compound constraints.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) - } - }) - }); - classGraphQLConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLConstraintsType) || defaultGraphQLTypes.OBJECT; - const classGraphQLRelationConstraintsTypeName = `${graphQLClassName}RelationWhereInput`; - let classGraphQLRelationConstraintsType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLRelationConstraintsTypeName, - description: `The ${classGraphQLRelationConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, - fields: () => ({ - have: { - description: 'Run a relational/pointer query where at least one child object can match.', - type: classGraphQLConstraintsType - }, - haveNot: { - description: 'Run an inverted relational/pointer query where at least one child object can match.', - type: classGraphQLConstraintsType - }, - exists: { - description: 'Check if the relation/pointer contains objects.', - type: _graphql.GraphQLBoolean - } - }) - }); - classGraphQLRelationConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationConstraintsType) || defaultGraphQLTypes.OBJECT; - const classGraphQLOrderTypeName = `${graphQLClassName}Order`; - let classGraphQLOrderType = new _graphql.GraphQLEnumType({ - name: classGraphQLOrderTypeName, - description: `The ${classGraphQLOrderTypeName} input type is used when sorting objects of the ${graphQLClassName} class.`, - values: classSortFields.reduce((sortFields, fieldConfig) => { - const { - field, - asc, - desc - } = fieldConfig; - - const updatedSortFields = _objectSpread({}, sortFields); - - const value = field === 'id' ? 'objectId' : field; - - if (asc) { - updatedSortFields[`${field}_ASC`] = { - value - }; - } - - if (desc) { - updatedSortFields[`${field}_DESC`] = { - value: `-${value}` - }; - } - - return updatedSortFields; - }, {}) - }); - classGraphQLOrderType = parseGraphQLSchema.addGraphQLType(classGraphQLOrderType); - - const classGraphQLFindArgs = _objectSpread(_objectSpread({ - where: { - description: 'These are the conditions that the objects need to match in order to be found.', - type: classGraphQLConstraintsType - }, - order: { - description: 'The fields to be used when sorting the data fetched.', - type: classGraphQLOrderType ? new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLOrderType)) : _graphql.GraphQLString - }, - skip: defaultGraphQLTypes.SKIP_ATT - }, _graphqlRelay.connectionArgs), {}, { - options: defaultGraphQLTypes.READ_OPTIONS_ATT - }); - - const classGraphQLOutputTypeName = `${graphQLClassName}`; - const interfaces = [defaultGraphQLTypes.PARSE_OBJECT, parseGraphQLSchema.relayNodeInterface]; - - const parseObjectFields = _objectSpread({ - id: (0, _graphqlRelay.globalIdField)(className, obj => obj.objectId) - }, defaultGraphQLTypes.PARSE_OBJECT_FIELDS); - - const outputFields = () => { - return classOutputFields.reduce((fields, field) => { - const type = (0, _outputType.transformOutputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); - - if (parseClass.fields[field].type === 'Relation') { - const targetParseClassTypes = parseGraphQLSchema.parseClassTypes[parseClass.fields[field].targetClass]; - const args = targetParseClassTypes ? targetParseClassTypes.classGraphQLFindArgs : undefined; - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - args, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, - - async resolve(source, args, context, queryInfo) { - try { - const { - where, - order, - skip, - first, - after, - last, - before, - options - } = args; - const { - readPreference, - includeReadPreference, - subqueryReadPreference - } = options || {}; - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); - const parseOrder = order && order.join(','); - return objectsQueries.findObjects(source[field].className, _objectSpread({ - $relatedTo: { - object: { - __type: 'Pointer', - className: className, - objectId: source.objectId - }, - key: field - } - }, where || {}), parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - } - }); - } else if (parseClass.fields[field].type === 'Polygon') { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, - - async resolve(source) { - if (source[field] && source[field].coordinates) { - return source[field].coordinates.map(coordinate => ({ - latitude: coordinate[0], - longitude: coordinate[1] - })); - } else { - return null; - } - } - - } - }); - } else if (parseClass.fields[field].type === 'Array') { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments`, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, - - async resolve(source) { - if (!source[field]) return null; - return source[field].map(async elem => { - if (elem.className && elem.objectId && elem.__type === 'Object') { - return elem; - } else { - return { - value: elem - }; - } - }); - } - - } - }); - } else if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type - } - }); - } else { - return fields; - } - }, parseObjectFields); - }; - - let classGraphQLOutputType = new _graphql.GraphQLObjectType({ - name: classGraphQLOutputTypeName, - description: `The ${classGraphQLOutputTypeName} object type is used in operations that involve outputting objects of ${graphQLClassName} class.`, - interfaces, - fields: outputFields - }); - classGraphQLOutputType = parseGraphQLSchema.addGraphQLType(classGraphQLOutputType); - const { - connectionType, - edgeType - } = (0, _graphqlRelay.connectionDefinitions)({ - name: graphQLClassName, - connectionFields: { - count: defaultGraphQLTypes.COUNT_ATT - }, - nodeType: classGraphQLOutputType || defaultGraphQLTypes.OBJECT - }); - let classGraphQLFindResultType = undefined; - - if (parseGraphQLSchema.addGraphQLType(edgeType) && parseGraphQLSchema.addGraphQLType(connectionType, false, false, true)) { - classGraphQLFindResultType = connectionType; - } - - parseGraphQLSchema.parseClassTypes[className] = { - classGraphQLPointerType, - classGraphQLRelationType, - classGraphQLCreateType, - classGraphQLUpdateType, - classGraphQLConstraintsType, - classGraphQLRelationConstraintsType, - classGraphQLFindArgs, - classGraphQLOutputType, - classGraphQLFindResultType, - config: { - parseClassConfig, - isCreateEnabled, - isUpdateEnabled - } - }; - - if (className === '_User') { - const viewerType = new _graphql.GraphQLObjectType({ - name: 'Viewer', - description: `The Viewer object type is used in operations that involve outputting the current user data.`, - fields: () => ({ - sessionToken: defaultGraphQLTypes.SESSION_TOKEN_ATT, - user: { - description: 'This is the current user.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType) - } - }) - }); - parseGraphQLSchema.addGraphQLType(viewerType, true, true); - parseGraphQLSchema.viewerType = viewerType; - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1R5cGVzLmpzIl0sIm5hbWVzIjpbImdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInR5cGUiLCJnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzIiwicGFyc2VDbGFzcyIsImNsYXNzRmllbGRzIiwiT2JqZWN0Iiwia2V5cyIsImZpZWxkcyIsImNvbmNhdCIsImlucHV0RmllbGRzIiwiYWxsb3dlZElucHV0RmllbGRzIiwib3V0cHV0RmllbGRzIiwiYWxsb3dlZE91dHB1dEZpZWxkcyIsImNvbnN0cmFpbnRGaWVsZHMiLCJhbGxvd2VkQ29uc3RyYWludEZpZWxkcyIsInNvcnRGaWVsZHMiLCJhbGxvd2VkU29ydEZpZWxkcyIsImNsYXNzT3V0cHV0RmllbGRzIiwiY2xhc3NDcmVhdGVGaWVsZHMiLCJjbGFzc1VwZGF0ZUZpZWxkcyIsImNsYXNzQ29uc3RyYWludEZpZWxkcyIsImNsYXNzU29ydEZpZWxkcyIsImNsYXNzQ3VzdG9tRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiUEFSU0VfT0JKRUNUX0ZJRUxEUyIsImluY2x1ZGVzIiwiY3JlYXRlIiwidXBkYXRlIiwiY2xhc3NOYW1lIiwib3V0cHV0RmllbGQiLCJsZW5ndGgiLCJwdXNoIiwiYXNjIiwiZGVzYyIsIm1hcCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxDcmVhdGVUeXBlIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsInJlZHVjZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwicmVxdWlyZWQiLCJHcmFwaFFMTm9uTnVsbCIsIkFDTCIsIkFDTF9JTlBVVCIsImFkZEdyYXBoUUxUeXBlIiwiY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJsaW5rIiwiR3JhcGhRTElEIiwiT0JKRUNUIiwiY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlTmFtZSIsImNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSIsImFkZCIsIkdyYXBoUUxMaXN0IiwiT0JKRUNUX0lEIiwicmVtb3ZlIiwiY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZSIsImNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSIsImxvZyIsIndhcm4iLCJwYXJzZUZpZWxkIiwiT1IiLCJBTkQiLCJOT1IiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSIsImhhdmUiLCJoYXZlTm90IiwiZXhpc3RzIiwiR3JhcGhRTEJvb2xlYW4iLCJjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMT3JkZXJUeXBlIiwiR3JhcGhRTEVudW1UeXBlIiwidmFsdWVzIiwiZmllbGRDb25maWciLCJ1cGRhdGVkU29ydEZpZWxkcyIsInZhbHVlIiwiY2xhc3NHcmFwaFFMRmluZEFyZ3MiLCJ3aGVyZSIsIm9yZGVyIiwiR3JhcGhRTFN0cmluZyIsInNraXAiLCJTS0lQX0FUVCIsImNvbm5lY3Rpb25BcmdzIiwib3B0aW9ucyIsIlJFQURfT1BUSU9OU19BVFQiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSIsImludGVyZmFjZXMiLCJQQVJTRV9PQkpFQ1QiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJwYXJzZU9iamVjdEZpZWxkcyIsImlkIiwib2JqIiwib2JqZWN0SWQiLCJ0YXJnZXRQYXJzZUNsYXNzVHlwZXMiLCJhcmdzIiwidW5kZWZpbmVkIiwicmVzb2x2ZSIsInNvdXJjZSIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJmaXJzdCIsImFmdGVyIiwibGFzdCIsImJlZm9yZSIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJpbmNsdWRlIiwic3RhcnRzV2l0aCIsInJlcGxhY2UiLCJwYXJzZU9yZGVyIiwiam9pbiIsIm9iamVjdHNRdWVyaWVzIiwiZmluZE9iamVjdHMiLCIkcmVsYXRlZFRvIiwib2JqZWN0IiwiX190eXBlIiwia2V5IiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwiY29vcmRpbmF0ZXMiLCJjb29yZGluYXRlIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJlbGVtIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsIkdyYXBoUUxPYmplY3RUeXBlIiwiY29ubmVjdGlvblR5cGUiLCJlZGdlVHlwZSIsImNvbm5lY3Rpb25GaWVsZHMiLCJjb3VudCIsIkNPVU5UX0FUVCIsIm5vZGVUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJ2aWV3ZXJUeXBlIiwic2Vzc2lvblRva2VuIiwiU0VTU0lPTl9UT0tFTl9BVFQiLCJ1c2VyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUE7O0FBVUE7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBS0EsTUFBTUEsdUJBQXVCLEdBQUcsVUFDOUJDLGdCQUQ4QixFQUU5QjtBQUNBLFNBQVFBLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ0MsSUFBdEMsSUFBK0MsRUFBdEQ7QUFDRCxDQUpEOztBQU1BLE1BQU1DLDRCQUE0QixHQUFHLFVBQ25DQyxVQURtQyxFQUVuQ0gsZ0JBRm1DLEVBR25DO0FBQ0EsUUFBTUksV0FBVyxHQUFHQyxNQUFN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dUJBRDhDO0FBRTlDSyxJQUFBQSx3QkFGOEM7QUFHOUNwQixJQUFBQSxzQkFIOEM7QUFJOUNhLElBQUFBLHNCQUo4QztBQUs5Q2EsSUFBQUEsMkJBTDhDO0FBTTlDUSxJQUFBQSxtQ0FOOEM7QUFPOUNZLElBQUFBLG9CQVA4QztBQVE5Q3NELElBQUFBLHNCQVI4QztBQVM5Q1EsSUFBQUEsMEJBVDhDO0FBVTlDL0IsSUFBQUEsTUFBTSxFQUFFO0FBQ054SCxNQUFBQSxnQkFETTtBQUVOd0MsTUFBQUEsZUFGTTtBQUdOQyxNQUFBQTtBQUhNO0FBVnNDLEdBQWhEOztBQWlCQSxNQUFJWCxTQUFTLEtBQUssT0FBbEIsRUFBMkI7QUFDekIsVUFBTTBILFVBQVUsR0FBRyxJQUFJUiwwQkFBSixDQUFzQjtBQUN2Q25HLE1BQUFBLElBQUksRUFBRSxRQURpQztBQUV2Q0MsTUFBQUEsV0FBVyxFQUFHLDZGQUZ5QjtBQUd2Q3ZDLE1BQUFBLE1BQU0sRUFBRSxPQUFPO0FBQ2JrSixRQUFBQSxZQUFZLEVBQUVoSSxtQkFBbUIsQ0FBQ2lJLGlCQURyQjtBQUViQyxRQUFBQSxJQUFJLEVBQUU7QUFDSjdHLFVBQUFBLFdBQVcsRUFBRSwyQkFEVDtBQUVKN0MsVUFBQUEsSUFBSSxFQUFFLElBQUlrRCx1QkFBSixDQUFtQjRGLHNCQUFuQjtBQUZGO0FBRk8sT0FBUDtBQUgrQixLQUF0QixDQUFuQjtBQVdBekcsSUFBQUEsa0JBQWtCLENBQUNnQixjQUFuQixDQUFrQ2tHLFVBQWxDLEVBQThDLElBQTlDLEVBQW9ELElBQXBEO0FBQ0FsSCxJQUFBQSxrQkFBa0IsQ0FBQ2tILFVBQW5CLEdBQWdDQSxVQUFoQztBQUNEO0FBQ0YsQ0FwZEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFFMSUQsXG4gIEdyYXBoUUxPYmplY3RUeXBlLFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMRW51bVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHtcbiAgZ2xvYmFsSWRGaWVsZCxcbiAgY29ubmVjdGlvbkFyZ3MsXG4gIGNvbm5lY3Rpb25EZWZpbml0aW9ucyxcbn0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCAqIGFzIG9iamVjdHNRdWVyaWVzIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcgfSBmcm9tICcuLi8uLi9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9jbGFzc05hbWUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2lucHV0VHlwZSc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL291dHB1dFR5cGUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY29uc3RyYWludFR5cGUnO1xuaW1wb3J0IHtcbiAgZXh0cmFjdEtleXNBbmRJbmNsdWRlLFxuICBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcsXG59IGZyb20gJy4uL3BhcnNlR3JhcGhRTFV0aWxzJztcblxuY29uc3QgZ2V0UGFyc2VDbGFzc1R5cGVDb25maWcgPSBmdW5jdGlvbiAoXG4gIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZ1xuKSB7XG4gIHJldHVybiAocGFyc2VDbGFzc0NvbmZpZyAmJiBwYXJzZUNsYXNzQ29uZmlnLnR5cGUpIHx8IHt9O1xufTtcblxuY29uc3QgZ2V0SW5wdXRGaWVsZHNBbmRDb25zdHJhaW50cyA9IGZ1bmN0aW9uIChcbiAgcGFyc2VDbGFzcyxcbiAgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnXG4pIHtcbiAgY29uc3QgY2xhc3NGaWVsZHMgPSBPYmplY3Qua2V5cyhwYXJzZUNsYXNzLmZpZWxkcykuY29uY2F0KCdpZCcpO1xuICBjb25zdCB7XG4gICAgaW5wdXRGaWVsZHM6IGFsbG93ZWRJbnB1dEZpZWxkcyxcbiAgICBvdXRwdXRGaWVsZHM6IGFsbG93ZWRPdXRwdXRGaWVsZHMsXG4gICAgY29uc3RyYWludEZpZWxkczogYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMsXG4gICAgc29ydEZpZWxkczogYWxsb3dlZFNvcnRGaWVsZHMsXG4gIH0gPSBnZXRQYXJzZUNsYXNzVHlwZUNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBsZXQgY2xhc3NPdXRwdXRGaWVsZHM7XG4gIGxldCBjbGFzc0NyZWF0ZUZpZWxkcztcbiAgbGV0IGNsYXNzVXBkYXRlRmllbGRzO1xuICBsZXQgY2xhc3NDb25zdHJhaW50RmllbGRzO1xuICBsZXQgY2xhc3NTb3J0RmllbGRzO1xuXG4gIC8vIEFsbCBhbGxvd2VkIGN1c3RvbXMgZmllbGRzXG4gIGNvbnN0IGNsYXNzQ3VzdG9tRmllbGRzID0gY2xhc3NGaWVsZHMuZmlsdGVyKChmaWVsZCkgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICAhT2JqZWN0LmtleXMoZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1RfRklFTERTKS5pbmNsdWRlcyhmaWVsZCkgJiZcbiAgICAgIGZpZWxkICE9PSAnaWQnXG4gICAgKTtcbiAgfSk7XG5cbiAgaWYgKGFsbG93ZWRJbnB1dEZpZWxkcyAmJiBhbGxvd2VkSW5wdXRGaWVsZHMuY3JlYXRlKSB7XG4gICAgY2xhc3NDcmVhdGVGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZElucHV0RmllbGRzLmNyZWF0ZS5pbmNsdWRlcyhmaWVsZCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NDcmVhdGVGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcztcbiAgfVxuICBpZiAoYWxsb3dlZElucHV0RmllbGRzICYmIGFsbG93ZWRJbnB1dEZpZWxkcy51cGRhdGUpIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcigoZmllbGQpID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMudXBkYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRPdXRwdXRGaWVsZHMpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcigoZmllbGQpID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkT3V0cHV0RmllbGRzLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG4gIC8vIEZpbHRlcnMgdGhlIFwicGFzc3dvcmRcIiBmaWVsZCBmcm9tIGNsYXNzIF9Vc2VyXG4gIGlmIChwYXJzZUNsYXNzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNsYXNzT3V0cHV0RmllbGRzID0gY2xhc3NPdXRwdXRGaWVsZHMuZmlsdGVyKFxuICAgICAgKG91dHB1dEZpZWxkKSA9PiBvdXRwdXRGaWVsZCAhPT0gJ3Bhc3N3b3JkJ1xuICAgICk7XG4gIH1cblxuICBpZiAoYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMpIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMuaW5jbHVkZXMoZmllbGQpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNsYXNzQ29uc3RyYWludEZpZWxkcyA9IGNsYXNzRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRTb3J0RmllbGRzKSB7XG4gICAgY2xhc3NTb3J0RmllbGRzID0gYWxsb3dlZFNvcnRGaWVsZHM7XG4gICAgaWYgKCFjbGFzc1NvcnRGaWVsZHMubGVuZ3RoKSB7XG4gICAgICAvLyBtdXN0IGhhdmUgYXQgbGVhc3QgMSBvcmRlciBmaWVsZFxuICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBGaW5kQXJncyBJbnB1dCBUeXBlIHdpbGwgdGhyb3cuXG4gICAgICBjbGFzc1NvcnRGaWVsZHMucHVzaCh7XG4gICAgICAgIGZpZWxkOiAnaWQnLFxuICAgICAgICBhc2M6IHRydWUsXG4gICAgICAgIGRlc2M6IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NTb3J0RmllbGRzID0gY2xhc3NGaWVsZHMubWFwKChmaWVsZCkgPT4ge1xuICAgICAgcmV0dXJuIHsgZmllbGQsIGFzYzogdHJ1ZSwgZGVzYzogdHJ1ZSB9O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyxcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyxcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMsXG4gICAgY2xhc3NPdXRwdXRGaWVsZHMsXG4gICAgY2xhc3NTb3J0RmllbGRzLFxuICB9O1xufTtcblxuY29uc3QgbG9hZCA9IChcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICBwYXJzZUNsYXNzLFxuICBwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWdcbikgPT4ge1xuICBjb25zdCBjbGFzc05hbWUgPSBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgY29uc3QgZ3JhcGhRTENsYXNzTmFtZSA9IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTChjbGFzc05hbWUpO1xuICBjb25zdCB7XG4gICAgY2xhc3NDcmVhdGVGaWVsZHMsXG4gICAgY2xhc3NVcGRhdGVGaWVsZHMsXG4gICAgY2xhc3NPdXRwdXRGaWVsZHMsXG4gICAgY2xhc3NDb25zdHJhaW50RmllbGRzLFxuICAgIGNsYXNzU29ydEZpZWxkcyxcbiAgfSA9IGdldElucHV0RmllbGRzQW5kQ29uc3RyYWludHMocGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG5cbiAgY29uc3Qge1xuICAgIGNyZWF0ZTogaXNDcmVhdGVFbmFibGVkID0gdHJ1ZSxcbiAgICB1cGRhdGU6IGlzVXBkYXRlRW5hYmxlZCA9IHRydWUsXG4gIH0gPSBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcocGFyc2VDbGFzc0NvbmZpZyk7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUgPSBgQ3JlYXRlJHtncmFwaFFMQ2xhc3NOYW1lfUZpZWxkc0lucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGNyZWF0aW9uIG9mIG9iamVjdHMgaW4gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+XG4gICAgICBjbGFzc0NyZWF0ZUZpZWxkcy5yZWR1Y2UoXG4gICAgICAgIChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlLFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgICAgdHlwZTpcbiAgICAgICAgICAgICAgICAgIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiZcbiAgICAgICAgICAgICAgICAgICAgKGZpZWxkID09PSAndXNlcm5hbWUnIHx8IGZpZWxkID09PSAncGFzc3dvcmQnKSkgfHxcbiAgICAgICAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKVxuICAgICAgICAgICAgICAgICAgICA6IHR5cGUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIEFDTDogeyB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLkFDTF9JTlBVVCB9LFxuICAgICAgICB9XG4gICAgICApLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlXG4gICk7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUgPSBgVXBkYXRlJHtncmFwaFFMQ2xhc3NOYW1lfUZpZWxkc0lucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxVcGRhdGVUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGNyZWF0aW9uIG9mIG9iamVjdHMgaW4gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+XG4gICAgICBjbGFzc1VwZGF0ZUZpZWxkcy5yZWR1Y2UoXG4gICAgICAgIChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlLFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgQUNMOiB7IHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUIH0sXG4gICAgICAgIH1cbiAgICAgICksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVcbiAgKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVBvaW50ZXJJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBsaW5rIE9SIGFkZCBhbmQgbGluayBhbiBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IHtcbiAgICAgICAgbGluazoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgTGluayBhbiBleGlzdGluZyBvYmplY3QgZnJvbSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLiBZb3UgY2FuIHVzZSBlaXRoZXIgdGhlIGdsb2JhbCBvciB0aGUgb2JqZWN0IGlkLmAsXG4gICAgICAgICAgdHlwZTogR3JhcGhRTElELFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRMaW5rJ10gPSB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW5kIGxpbmsgYW4gb2JqZWN0IGZyb20gJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRzO1xuICAgIH0sXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlKSB8fFxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVJlbGF0aW9uSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBhZGQsIHJlbW92ZSwgY3JlYXRlQW5kQWRkIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byBhIHJlbGF0aW9uIGZpZWxkLmAsXG4gICAgZmllbGRzOiAoKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZHMgPSB7XG4gICAgICAgIGFkZDoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgQWRkIGV4aXN0aW5nIG9iamVjdHMgZnJvbSB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcyBpbnRvIHRoZSByZWxhdGlvbi4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZHMuYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQpLFxuICAgICAgICB9LFxuICAgICAgICByZW1vdmU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYFJlbW92ZSBleGlzdGluZyBvYmplY3RzIGZyb20gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3Mgb3V0IG9mIHRoZSByZWxhdGlvbi4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZHMuYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRBZGQnXSA9IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZSBhbmQgYWRkIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byB0aGUgcmVsYXRpb24uYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUpKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgfSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSkgfHxcbiAgICBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1XaGVyZUlucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIG9mICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+ICh7XG4gICAgICAuLi5jbGFzc0NvbnN0cmFpbnRGaWVsZHMucmVkdWNlKChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgIGlmIChbJ09SJywgJ0FORCcsICdOT1InXS5pbmNsdWRlcyhmaWVsZCkpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEubG9nLndhcm4oXG4gICAgICAgICAgICBgRmllbGQgJHtmaWVsZH0gY291bGQgbm90IGJlIGFkZGVkIHRvIHRoZSBhdXRvIHNjaGVtYSAke2NsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWV9IGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBvbmUuYFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJzZUZpZWxkID0gZmllbGQgPT09ICdpZCcgPyAnb2JqZWN0SWQnIDogZmllbGQ7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1Db25zdHJhaW50VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1twYXJzZUZpZWxkXS50eXBlLFxuICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW3BhcnNlRmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXMsXG4gICAgICAgICAgZmllbGRcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgIH1cbiAgICAgIH0sIHt9KSxcbiAgICAgIE9SOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgT1Igb3BlcmF0b3IgdG8gY29tcG91bmQgY29uc3RyYWludHMuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpKSxcbiAgICAgIH0sXG4gICAgICBBTkQ6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBBTkQgb3BlcmF0b3IgdG8gY29tcG91bmQgY29uc3RyYWludHMuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpKSxcbiAgICAgIH0sXG4gICAgICBOT1I6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBOT1Igb3BlcmF0b3IgdG8gY29tcG91bmQgY29uc3RyYWludHMuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpKSxcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUgPVxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUpIHx8XG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1SZWxhdGlvbldoZXJlSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgIGhhdmU6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1J1biBhIHJlbGF0aW9uYWwvcG9pbnRlciBxdWVyeSB3aGVyZSBhdCBsZWFzdCBvbmUgY2hpbGQgb2JqZWN0IGNhbiBtYXRjaC4nLFxuICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUsXG4gICAgICB9LFxuICAgICAgaGF2ZU5vdDoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnUnVuIGFuIGludmVydGVkIHJlbGF0aW9uYWwvcG9pbnRlciBxdWVyeSB3aGVyZSBhdCBsZWFzdCBvbmUgY2hpbGQgb2JqZWN0IGNhbiBtYXRjaC4nLFxuICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUsXG4gICAgICB9LFxuICAgICAgZXhpc3RzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgaWYgdGhlIHJlbGF0aW9uL3BvaW50ZXIgY29udGFpbnMgb2JqZWN0cy4nLFxuICAgICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlKSB8fFxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTE9yZGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfU9yZGVyYDtcbiAgbGV0IGNsYXNzR3JhcGhRTE9yZGVyVHlwZSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTE9yZGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgd2hlbiBzb3J0aW5nIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICB2YWx1ZXM6IGNsYXNzU29ydEZpZWxkcy5yZWR1Y2UoKHNvcnRGaWVsZHMsIGZpZWxkQ29uZmlnKSA9PiB7XG4gICAgICBjb25zdCB7IGZpZWxkLCBhc2MsIGRlc2MgfSA9IGZpZWxkQ29uZmlnO1xuICAgICAgY29uc3QgdXBkYXRlZFNvcnRGaWVsZHMgPSB7XG4gICAgICAgIC4uLnNvcnRGaWVsZHMsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmFsdWUgPSBmaWVsZCA9PT0gJ2lkJyA/ICdvYmplY3RJZCcgOiBmaWVsZDtcbiAgICAgIGlmIChhc2MpIHtcbiAgICAgICAgdXBkYXRlZFNvcnRGaWVsZHNbYCR7ZmllbGR9X0FTQ2BdID0geyB2YWx1ZSB9O1xuICAgICAgfVxuICAgICAgaWYgKGRlc2MpIHtcbiAgICAgICAgdXBkYXRlZFNvcnRGaWVsZHNbYCR7ZmllbGR9X0RFU0NgXSA9IHsgdmFsdWU6IGAtJHt2YWx1ZX1gIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdXBkYXRlZFNvcnRGaWVsZHM7XG4gICAgfSwge30pLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMT3JkZXJUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNsYXNzR3JhcGhRTE9yZGVyVHlwZVxuICApO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTEZpbmRBcmdzID0ge1xuICAgIHdoZXJlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgY29uZGl0aW9ucyB0aGF0IHRoZSBvYmplY3RzIG5lZWQgdG8gbWF0Y2ggaW4gb3JkZXIgdG8gYmUgZm91bmQuJyxcbiAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSxcbiAgICB9LFxuICAgIG9yZGVyOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBmaWVsZHMgdG8gYmUgdXNlZCB3aGVuIHNvcnRpbmcgdGhlIGRhdGEgZmV0Y2hlZC4nLFxuICAgICAgdHlwZTogY2xhc3NHcmFwaFFMT3JkZXJUeXBlXG4gICAgICAgID8gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPcmRlclR5cGUpKVxuICAgICAgICA6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBza2lwOiBkZWZhdWx0R3JhcGhRTFR5cGVzLlNLSVBfQVRULFxuICAgIC4uLmNvbm5lY3Rpb25BcmdzLFxuICAgIG9wdGlvbnM6IGRlZmF1bHRHcmFwaFFMVHlwZXMuUkVBRF9PUFRJT05TX0FUVCxcbiAgfTtcbiAgY29uc3QgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gIGNvbnN0IGludGVyZmFjZXMgPSBbXG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1QsXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLnJlbGF5Tm9kZUludGVyZmFjZSxcbiAgXTtcbiAgY29uc3QgcGFyc2VPYmplY3RGaWVsZHMgPSB7XG4gICAgaWQ6IGdsb2JhbElkRmllbGQoY2xhc3NOYW1lLCAob2JqKSA9PiBvYmoub2JqZWN0SWQpLFxuICAgIC4uLmRlZmF1bHRHcmFwaFFMVHlwZXMuUEFSU0VfT0JKRUNUX0ZJRUxEUyxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0RmllbGRzID0gKCkgPT4ge1xuICAgIHJldHVybiBjbGFzc091dHB1dEZpZWxkcy5yZWR1Y2UoKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSxcbiAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICApO1xuICAgICAgaWYgKHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldFBhcnNlQ2xhc3NUeXBlcyA9XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzc1xuICAgICAgICAgIF07XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0YXJnZXRQYXJzZUNsYXNzVHlwZXNcbiAgICAgICAgICA/IHRhcmdldFBhcnNlQ2xhc3NUeXBlcy5jbGFzc0dyYXBoUUxGaW5kQXJnc1xuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZFxuICAgICAgICAgICAgICA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKVxuICAgICAgICAgICAgICA6IHR5cGUsXG4gICAgICAgICAgICBhc3luYyByZXNvbHZlKHNvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgICAgd2hlcmUsXG4gICAgICAgICAgICAgICAgICBvcmRlcixcbiAgICAgICAgICAgICAgICAgIHNraXAsXG4gICAgICAgICAgICAgICAgICBmaXJzdCxcbiAgICAgICAgICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgICAgICAgICAgbGFzdCxcbiAgICAgICAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICAgICAgfSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgIH0gPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhxdWVyeUluZm8pO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEZpZWxkc1xuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChmaWVsZCkgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMubm9kZS4nKSlcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoZmllbGQpID0+IGZpZWxkLnJlcGxhY2UoJ2VkZ2VzLm5vZGUuJywgJycpKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VPcmRlciA9IG9yZGVyICYmIG9yZGVyLmpvaW4oJywnKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3RzUXVlcmllcy5maW5kT2JqZWN0cyhcbiAgICAgICAgICAgICAgICAgIHNvdXJjZVtmaWVsZF0uY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAkcmVsYXRlZFRvOiB7XG4gICAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0SWQ6IHNvdXJjZS5vYmplY3RJZCxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIC4uLih3aGVyZSB8fCB7fSksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgcGFyc2VPcmRlcixcbiAgICAgICAgICAgICAgICAgIHNraXAsXG4gICAgICAgICAgICAgICAgICBmaXJzdCxcbiAgICAgICAgICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgICAgICAgICAgbGFzdCxcbiAgICAgICAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICAgICAgICAgIGtleXMsXG4gICAgICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzLFxuICAgICAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAocGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkXG4gICAgICAgICAgICAgID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpXG4gICAgICAgICAgICAgIDogdHlwZSxcbiAgICAgICAgICAgIGFzeW5jIHJlc29sdmUoc291cmNlKSB7XG4gICAgICAgICAgICAgIGlmIChzb3VyY2VbZmllbGRdICYmIHNvdXJjZVtmaWVsZF0uY29vcmRpbmF0ZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlW2ZpZWxkXS5jb29yZGluYXRlcy5tYXAoKGNvb3JkaW5hdGUpID0+ICh7XG4gICAgICAgICAgICAgICAgICBsYXRpdHVkZTogY29vcmRpbmF0ZVswXSxcbiAgICAgICAgICAgICAgICAgIGxvbmdpdHVkZTogY29vcmRpbmF0ZVsxXSxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAocGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBVc2UgSW5saW5lIEZyYWdtZW50IG9uIEFycmF5IHRvIGdldCByZXN1bHRzOiBodHRwczovL2dyYXBocWwub3JnL2xlYXJuL3F1ZXJpZXMvI2lubGluZS1mcmFnbWVudHNgLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkXG4gICAgICAgICAgICAgID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpXG4gICAgICAgICAgICAgIDogdHlwZSxcbiAgICAgICAgICAgIGFzeW5jIHJlc29sdmUoc291cmNlKSB7XG4gICAgICAgICAgICAgIGlmICghc291cmNlW2ZpZWxkXSkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIHJldHVybiBzb3VyY2VbZmllbGRdLm1hcChhc3luYyAoZWxlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgIGVsZW0uY2xhc3NOYW1lICYmXG4gICAgICAgICAgICAgICAgICBlbGVtLm9iamVjdElkICYmXG4gICAgICAgICAgICAgICAgICBlbGVtLl9fdHlwZSA9PT0gJ09iamVjdCdcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogZWxlbSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZFxuICAgICAgICAgICAgICA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKVxuICAgICAgICAgICAgICA6IHR5cGUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICB9XG4gICAgfSwgcGFyc2VPYmplY3RGaWVsZHMpO1xuICB9O1xuICBsZXQgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZX0gb2JqZWN0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBvdXRwdXR0aW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGludGVyZmFjZXMsXG4gICAgZmllbGRzOiBvdXRwdXRGaWVsZHMsXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgKTtcblxuICBjb25zdCB7IGNvbm5lY3Rpb25UeXBlLCBlZGdlVHlwZSB9ID0gY29ubmVjdGlvbkRlZmluaXRpb25zKHtcbiAgICBuYW1lOiBncmFwaFFMQ2xhc3NOYW1lLFxuICAgIGNvbm5lY3Rpb25GaWVsZHM6IHtcbiAgICAgIGNvdW50OiBkZWZhdWx0R3JhcGhRTFR5cGVzLkNPVU5UX0FUVCxcbiAgICB9LFxuICAgIG5vZGVUeXBlOiBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNULFxuICB9KTtcbiAgbGV0IGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlID0gdW5kZWZpbmVkO1xuICBpZiAoXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGVkZ2VUeXBlKSAmJlxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjb25uZWN0aW9uVHlwZSwgZmFsc2UsIGZhbHNlLCB0cnVlKVxuICApIHtcbiAgICBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSA9IGNvbm5lY3Rpb25UeXBlO1xuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tjbGFzc05hbWVdID0ge1xuICAgIGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUsXG4gICAgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlLFxuICAgIGNsYXNzR3JhcGhRTEZpbmRBcmdzLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUsXG4gICAgY29uZmlnOiB7XG4gICAgICBwYXJzZUNsYXNzQ29uZmlnLFxuICAgICAgaXNDcmVhdGVFbmFibGVkLFxuICAgICAgaXNVcGRhdGVFbmFibGVkLFxuICAgIH0sXG4gIH07XG5cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNvbnN0IHZpZXdlclR5cGUgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgbmFtZTogJ1ZpZXdlcicsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSBWaWV3ZXIgb2JqZWN0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBvdXRwdXR0aW5nIHRoZSBjdXJyZW50IHVzZXIgZGF0YS5gLFxuICAgICAgZmllbGRzOiAoKSA9PiAoe1xuICAgICAgICBzZXNzaW9uVG9rZW46IGRlZmF1bHRHcmFwaFFMVHlwZXMuU0VTU0lPTl9UT0tFTl9BVFQsXG4gICAgICAgIHVzZXI6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGN1cnJlbnQgdXNlci4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlKSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIH0pO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh2aWV3ZXJUeXBlLCB0cnVlLCB0cnVlKTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEudmlld2VyVHlwZSA9IHZpZXdlclR5cGU7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSwgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaDirectives.js b/lib/GraphQL/loaders/schemaDirectives.js deleted file mode 100644 index 6ddca35850..0000000000 --- a/lib/GraphQL/loaders/schemaDirectives.js +++ /dev/null @@ -1,72 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.definitions = void 0; - -var _graphqlTag = _interopRequireDefault(require("graphql-tag")); - -var _utils = require("@graphql-tools/utils"); - -var _FunctionsRouter = require("../../Routers/FunctionsRouter"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const definitions = (0, _graphqlTag.default)` - directive @resolve(to: String) on FIELD_DEFINITION - directive @mock(with: Any!) on FIELD_DEFINITION -`; -exports.definitions = definitions; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions; - - class ResolveDirectiveVisitor extends _utils.SchemaDirectiveVisitor { - visitFieldDefinition(field) { - field.resolve = async (_source, args, context) => { - try { - const { - config, - auth, - info - } = context; - let functionName = field.name; - - if (this.args.to) { - functionName = this.args.to; - } - - return (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ - params: { - functionName - }, - config, - auth, - info, - body: args - })).response.result; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - }; - } - - } - - parseGraphQLSchema.graphQLSchemaDirectives.resolve = ResolveDirectiveVisitor; - - class MockDirectiveVisitor extends _utils.SchemaDirectiveVisitor { - visitFieldDefinition(field) { - field.resolve = () => { - return this.args.with; - }; - } - - } - - parseGraphQLSchema.graphQLSchemaDirectives.mock = MockDirectiveVisitor; -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcy5qcyJdLCJuYW1lcyI6WyJkZWZpbml0aW9ucyIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiUmVzb2x2ZURpcmVjdGl2ZVZpc2l0b3IiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRGaWVsZERlZmluaXRpb24iLCJmaWVsZCIsInJlc29sdmUiLCJfc291cmNlIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsImZ1bmN0aW9uTmFtZSIsIm5hbWUiLCJ0byIsIkZ1bmN0aW9uc1JvdXRlciIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwYXJhbXMiLCJib2R5IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJlIiwiaGFuZGxlRXJyb3IiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyIsIk1vY2tEaXJlY3RpdmVWaXNpdG9yIiwid2l0aCIsIm1vY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVPLE1BQU1BLFdBQVcsR0FBRyx3QkFBSTs7O0NBQXhCOzs7QUFLUCxNQUFNQyxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDQSxFQUFBQSxrQkFBa0IsQ0FBQ0Msa0NBQW5CLEdBQXdESCxXQUF4RDs7QUFFQSxRQUFNSSx1QkFBTixTQUFzQ0MsNkJBQXRDLENBQTZEO0FBQzNEQyxJQUFBQSxvQkFBb0IsQ0FBQ0MsS0FBRCxFQUFRO0FBQzFCQSxNQUFBQSxLQUFLLENBQUNDLE9BQU4sR0FBZ0IsT0FBT0MsT0FBUCxFQUFnQkMsSUFBaEIsRUFBc0JDLE9BQXRCLEtBQWtDO0FBQ2hELFlBQUk7QUFDRixnQkFBTTtBQUFFQyxZQUFBQSxNQUFGO0FBQVVDLFlBQUFBLElBQVY7QUFBZ0JDLFlBQUFBO0FBQWhCLGNBQXlCSCxPQUEvQjtBQUVBLGNBQUlJLFlBQVksR0FBR1IsS0FBSyxDQUFDUyxJQUF6Qjs7QUFDQSxjQUFJLEtBQUtOLElBQUwsQ0FBVU8sRUFBZCxFQUFrQjtBQUNoQkYsWUFBQUEsWUFBWSxHQUFHLEtBQUtMLElBQUwsQ0FBVU8sRUFBekI7QUFDRDs7QUFFRCxpQkFBTyxDQUFDLE1BQU1DLGlDQUFnQkMsbUJBQWhCLENBQW9DO0FBQ2hEQyxZQUFBQSxNQUFNLEVBQUU7QUFDTkwsY0FBQUE7QUFETSxhQUR3QztBQUloREgsWUFBQUEsTUFKZ0Q7QUFLaERDLFlBQUFBLElBTGdEO0FBTWhEQyxZQUFBQSxJQU5nRDtBQU9oRE8sWUFBQUEsSUFBSSxFQUFFWDtBQVAwQyxXQUFwQyxDQUFQLEVBUUhZLFFBUkcsQ0FRTUMsTUFSYjtBQVNELFNBakJELENBaUJFLE9BQU9DLENBQVAsRUFBVTtBQUNWdEIsVUFBQUEsa0JBQWtCLENBQUN1QixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGLE9BckJEO0FBc0JEOztBQXhCMEQ7O0FBMkI3RHRCLEVBQUFBLGtCQUFrQixDQUFDd0IsdUJBQW5CLENBQTJDbEIsT0FBM0MsR0FBcURKLHVCQUFyRDs7QUFFQSxRQUFNdUIsb0JBQU4sU0FBbUN0Qiw2QkFBbkMsQ0FBMEQ7QUFDeERDLElBQUFBLG9CQUFvQixDQUFDQyxLQUFELEVBQVE7QUFDMUJBLE1BQUFBLEtBQUssQ0FBQ0MsT0FBTixHQUFnQixNQUFNO0FBQ3BCLGVBQU8sS0FBS0UsSUFBTCxDQUFVa0IsSUFBakI7QUFDRCxPQUZEO0FBR0Q7O0FBTHVEOztBQVExRDFCLEVBQUFBLGtCQUFrQixDQUFDd0IsdUJBQW5CLENBQTJDRyxJQUEzQyxHQUFrREYsb0JBQWxEO0FBQ0QsQ0F6Q0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZ3FsIGZyb20gJ2dyYXBocWwtdGFnJztcbmltcG9ydCB7IFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IgfSBmcm9tICdAZ3JhcGhxbC10b29scy91dGlscyc7XG5pbXBvcnQgeyBGdW5jdGlvbnNSb3V0ZXIgfSBmcm9tICcuLi8uLi9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlcic7XG5cbmV4cG9ydCBjb25zdCBkZWZpbml0aW9ucyA9IGdxbGBcbiAgZGlyZWN0aXZlIEByZXNvbHZlKHRvOiBTdHJpbmcpIG9uIEZJRUxEX0RFRklOSVRJT05cbiAgZGlyZWN0aXZlIEBtb2NrKHdpdGg6IEFueSEpIG9uIEZJRUxEX0RFRklOSVRJT05cbmA7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNEZWZpbml0aW9ucyA9IGRlZmluaXRpb25zO1xuXG4gIGNsYXNzIFJlc29sdmVEaXJlY3RpdmVWaXNpdG9yIGV4dGVuZHMgU2NoZW1hRGlyZWN0aXZlVmlzaXRvciB7XG4gICAgdmlzaXRGaWVsZERlZmluaXRpb24oZmllbGQpIHtcbiAgICAgIGZpZWxkLnJlc29sdmUgPSBhc3luYyAoX3NvdXJjZSwgYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgbGV0IGZ1bmN0aW9uTmFtZSA9IGZpZWxkLm5hbWU7XG4gICAgICAgICAgaWYgKHRoaXMuYXJncy50bykge1xuICAgICAgICAgICAgZnVuY3Rpb25OYW1lID0gdGhpcy5hcmdzLnRvO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiAoYXdhaXQgRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkRnVuY3Rpb24oe1xuICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgIGJvZHk6IGFyZ3MsXG4gICAgICAgICAgfSkpLnJlc3BvbnNlLnJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXMucmVzb2x2ZSA9IFJlc29sdmVEaXJlY3RpdmVWaXNpdG9yO1xuXG4gIGNsYXNzIE1vY2tEaXJlY3RpdmVWaXNpdG9yIGV4dGVuZHMgU2NoZW1hRGlyZWN0aXZlVmlzaXRvciB7XG4gICAgdmlzaXRGaWVsZERlZmluaXRpb24oZmllbGQpIHtcbiAgICAgIGZpZWxkLnJlc29sdmUgPSAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFyZ3Mud2l0aDtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzLm1vY2sgPSBNb2NrRGlyZWN0aXZlVmlzaXRvcjtcbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaMutations.js b/lib/GraphQL/loaders/schemaMutations.js deleted file mode 100644 index 2f948e3d7a..0000000000 --- a/lib/GraphQL/loaders/schemaMutations.js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); - -var _schemaFields = require("../transformers/schemaFields"); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -var _schemaQueries = require("./schemaQueries"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const load = parseGraphQLSchema => { - const createClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'CreateClass', - description: 'The createClass mutation can be used to create the schema for a new object class.', - inputFields: { - name: schemaTypes.CLASS_NAME_ATT, - schemaFields: { - description: "These are the schema's fields of the object class.", - type: schemaTypes.SCHEMA_FIELDS_INPUT - } - }, - outputFields: { - class: { - description: 'This is the created class.', - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - name, - schemaFields - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - - if (auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); - } - - const schema = await config.database.loadSchema({ - clearCache: true - }); - const parseClass = await schema.addClassIfNotExists(name, (0, _schemaFields.transformToParse)(schemaFields)); - return { - class: { - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - } - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(createClassMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(createClassMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('createClass', createClassMutation, true, true); - const updateClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'UpdateClass', - description: 'The updateClass mutation can be used to update the schema for an existing object class.', - inputFields: { - name: schemaTypes.CLASS_NAME_ATT, - schemaFields: { - description: "These are the schema's fields of the object class.", - type: schemaTypes.SCHEMA_FIELDS_INPUT - } - }, - outputFields: { - class: { - description: 'This is the updated class.', - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - name, - schemaFields - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - - if (auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); - } - - const schema = await config.database.loadSchema({ - clearCache: true - }); - const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); - const parseClass = await schema.updateClass(name, (0, _schemaFields.transformToParse)(schemaFields, existingParseClass.fields), undefined, undefined, config.database); - return { - class: { - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - } - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(updateClassMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(updateClassMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('updateClass', updateClassMutation, true, true); - const deleteClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'DeleteClass', - description: 'The deleteClass mutation can be used to delete an existing object class.', - inputFields: { - name: schemaTypes.CLASS_NAME_ATT - }, - outputFields: { - class: { - description: 'This is the deleted class.', - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - name - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - - if (auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); - } - - const schema = await config.database.loadSchema({ - clearCache: true - }); - const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); - await config.database.deleteSchema(name); - return { - class: { - name: existingParseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(existingParseClass.fields) - } - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(deleteClassMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(deleteClassMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('deleteClass', deleteClassMutation, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJjcmVhdGVDbGFzc011dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwic2NoZW1hRmllbGRzIiwidHlwZSIsIlNDSEVNQV9GSUVMRFNfSU5QVVQiLCJvdXRwdXRGaWVsZHMiLCJjbGFzcyIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJtdXRhdGVBbmRHZXRQYXlsb2FkIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaXNSZWFkT25seSIsIlBhcnNlIiwiRXJyb3IiLCJPUEVSQVRJT05fRk9SQklEREVOIiwic2NoZW1hIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJhZGRDbGFzc0lmTm90RXhpc3RzIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUNsYXNzTXV0YXRpb24iLCJleGlzdGluZ1BhcnNlQ2xhc3MiLCJ1cGRhdGVDbGFzcyIsInVuZGVmaW5lZCIsImRlbGV0ZUNsYXNzTXV0YXRpb24iLCJkZWxldGVTY2hlbWEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFJQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLFFBQU1DLG1CQUFtQixHQUFHLGdEQUE2QjtBQUN2REMsSUFBQUEsSUFBSSxFQUFFLGFBRGlEO0FBRXZEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHFEO0FBSXZEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWEYs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LDZCQUFTcEMsSUFBVCxFQUFlcUIsTUFBZixDQUFqQztBQUNBLGNBQU1OLE1BQU0sQ0FBQ08sUUFBUCxDQUFnQmtCLFlBQWhCLENBQTZCeEMsSUFBN0IsQ0FBTjtBQUNBLGVBQU87QUFDTFMsVUFBQUEsS0FBSyxFQUFFO0FBQ0xULFlBQUFBLElBQUksRUFBRW9DLGtCQUFrQixDQUFDVCxTQURwQjtBQUVMdEIsWUFBQUEsWUFBWSxFQUFFLHNDQUFtQitCLGtCQUFrQixDQUFDUixNQUF0QztBQUZUO0FBREYsU0FBUDtBQU1ELE9BdEJELENBc0JFLE9BQU9DLENBQVAsRUFBVTtBQUNWL0IsUUFBQUEsa0JBQWtCLENBQUNnQyxXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBdkNzRCxHQUE3QixDQUE1QjtBQTBDQS9CLEVBQUFBLGtCQUFrQixDQUFDaUMsY0FBbkIsQ0FDRVEsbUJBQW1CLENBQUMxQixJQUFwQixDQUF5Qm1CLEtBQXpCLENBQStCMUIsSUFBL0IsQ0FBb0MyQixNQUR0QyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FuQyxFQUFBQSxrQkFBa0IsQ0FBQ2lDLGNBQW5CLENBQWtDUSxtQkFBbUIsQ0FBQ2pDLElBQXRELEVBQTRELElBQTVELEVBQWtFLElBQWxFO0FBQ0FSLEVBQUFBLGtCQUFrQixDQUFDb0Msa0JBQW5CLENBQ0UsYUFERixFQUVFSyxtQkFGRixFQUdFLElBSEYsRUFJRSxJQUpGO0FBTUQsQ0FyTEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0ICogYXMgc2NoZW1hVHlwZXMgZnJvbSAnLi9zY2hlbWFUeXBlcyc7XG5pbXBvcnQge1xuICB0cmFuc2Zvcm1Ub1BhcnNlLFxuICB0cmFuc2Zvcm1Ub0dyYXBoUUwsXG59IGZyb20gJy4uL3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMnO1xuaW1wb3J0IHsgZW5mb3JjZU1hc3RlcktleUFjY2VzcyB9IGZyb20gJy4uL3BhcnNlR3JhcGhRTFV0aWxzJztcbmltcG9ydCB7IGdldENsYXNzIH0gZnJvbSAnLi9zY2hlbWFRdWVyaWVzJztcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGNvbnN0IGNyZWF0ZUNsYXNzTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnQ3JlYXRlQ2xhc3MnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBjcmVhdGVDbGFzcyBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBjcmVhdGUgdGhlIHNjaGVtYSBmb3IgYSBuZXcgb2JqZWN0IGNsYXNzLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgICAgc2NoZW1hRmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZXNlIGFyZSB0aGUgc2NoZW1hJ3MgZmllbGRzIG9mIHRoZSBvYmplY3QgY2xhc3MuXCIsXG4gICAgICAgIHR5cGU6IHNjaGVtYVR5cGVzLlNDSEVNQV9GSUVMRFNfSU5QVVQsXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBjbGFzczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGNyZWF0ZWQgY2xhc3MuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBuYW1lLCBzY2hlbWFGaWVsZHMgfSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MoYXV0aCk7XG5cbiAgICAgICAgaWYgKGF1dGguaXNSZWFkT25seSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBjcmVhdGUgYSBzY2hlbWEuXCJcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgY29uZmlnLmRhdGFiYXNlLmxvYWRTY2hlbWEoeyBjbGVhckNhY2hlOiB0cnVlIH0pO1xuICAgICAgICBjb25zdCBwYXJzZUNsYXNzID0gYXdhaXQgc2NoZW1hLmFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICB0cmFuc2Zvcm1Ub1BhcnNlKHNjaGVtYUZpZWxkcylcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBjcmVhdGVDbGFzc011dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjcmVhdGVDbGFzc011dGF0aW9uLnR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKFxuICAgICdjcmVhdGVDbGFzcycsXG4gICAgY3JlYXRlQ2xhc3NNdXRhdGlvbixcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcblxuICBjb25zdCB1cGRhdGVDbGFzc011dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ1VwZGF0ZUNsYXNzJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgdXBkYXRlQ2xhc3MgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gdXBkYXRlIHRoZSBzY2hlbWEgZm9yIGFuIGV4aXN0aW5nIG9iamVjdCBjbGFzcy4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBuYW1lOiBzY2hlbWFUeXBlcy5DTEFTU19OQU1FX0FUVCxcbiAgICAgIHNjaGVtYUZpZWxkczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGVzZSBhcmUgdGhlIHNjaGVtYSdzIGZpZWxkcyBvZiB0aGUgb2JqZWN0IGNsYXNzLlwiLFxuICAgICAgICB0eXBlOiBzY2hlbWFUeXBlcy5TQ0hFTUFfRklFTERTX0lOUFVULFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgY2xhc3M6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cGRhdGVkIGNsYXNzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgbmFtZSwgc2NoZW1hRmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gdXBkYXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdQYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgY29uc3QgcGFyc2VDbGFzcyA9IGF3YWl0IHNjaGVtYS51cGRhdGVDbGFzcyhcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIHRyYW5zZm9ybVRvUGFyc2Uoc2NoZW1hRmllbGRzLCBleGlzdGluZ1BhcnNlQ2xhc3MuZmllbGRzKSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIGNvbmZpZy5kYXRhYmFzZVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNsYXNzOiB7XG4gICAgICAgICAgICBuYW1lOiBwYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYUZpZWxkczogdHJhbnNmb3JtVG9HcmFwaFFMKHBhcnNlQ2xhc3MuZmllbGRzKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIHVwZGF0ZUNsYXNzTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHVwZGF0ZUNsYXNzTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgJ3VwZGF0ZUNsYXNzJyxcbiAgICB1cGRhdGVDbGFzc011dGF0aW9uLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIGNvbnN0IGRlbGV0ZUNsYXNzTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnRGVsZXRlQ2xhc3MnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBkZWxldGVDbGFzcyBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBkZWxldGUgYW4gZXhpc3Rpbmcgb2JqZWN0IGNsYXNzLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBjbGFzczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGRlbGV0ZWQgY2xhc3MuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gZGVsZXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdQYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgYXdhaXQgY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShuYW1lKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogZXhpc3RpbmdQYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYUZpZWxkczogdHJhbnNmb3JtVG9HcmFwaFFMKGV4aXN0aW5nUGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgZGVsZXRlQ2xhc3NNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlQ2xhc3NNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAnZGVsZXRlQ2xhc3MnLFxuICAgIGRlbGV0ZUNsYXNzTXV0YXRpb24sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaQueries.js b/lib/GraphQL/loaders/schemaQueries.js deleted file mode 100644 index e1df2aa6b3..0000000000 --- a/lib/GraphQL/loaders/schemaQueries.js +++ /dev/null @@ -1,93 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.getClass = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphql = require("graphql"); - -var _schemaFields = require("../transformers/schemaFields"); - -var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const getClass = async (name, schema) => { - try { - return await schema.getOneSchema(name, true); - } catch (e) { - if (e === undefined) { - throw new _node.default.Error(_node.default.Error.INVALID_CLASS_NAME, `Class ${name} does not exist.`); - } else { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); - } - } -}; - -exports.getClass = getClass; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLQuery('class', { - description: 'The class query can be used to retrieve an existing object class.', - args: { - name: schemaTypes.CLASS_NAME_ATT - }, - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS), - resolve: async (_source, args, context) => { - try { - const { - name - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - const schema = await config.database.loadSchema({ - clearCache: true - }); - const parseClass = await getClass(name, schema); - return { - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }, true, true); - parseGraphQLSchema.addGraphQLQuery('classes', { - description: 'The classes query can be used to retrieve the existing object classes.', - type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(schemaTypes.CLASS))), - resolve: async (_source, _args, context) => { - try { - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - const schema = await config.database.loadSchema({ - clearCache: true - }); - return (await schema.getAllClasses(true)).map(parseClass => ({ - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - })); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hUXVlcmllcy5qcyJdLCJuYW1lcyI6WyJnZXRDbGFzcyIsIm5hbWUiLCJzY2hlbWEiLCJnZXRPbmVTY2hlbWEiLCJlIiwidW5kZWZpbmVkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImFyZ3MiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJyZXNvbHZlIiwiX3NvdXJjZSIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJjbGFzc05hbWUiLCJzY2hlbWFGaWVsZHMiLCJmaWVsZHMiLCJoYW5kbGVFcnJvciIsIkdyYXBoUUxMaXN0IiwiX2FyZ3MiLCJnZXRBbGxDbGFzc2VzIiwibWFwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsUUFBUSxHQUFHLE9BQU9DLElBQVAsRUFBYUMsTUFBYixLQUF3QjtBQUN2QyxNQUFJO0FBQ0YsV0FBTyxNQUFNQSxNQUFNLENBQUNDLFlBQVAsQ0FBb0JGLElBQXBCLEVBQTBCLElBQTFCLENBQWI7QUFDRCxHQUZELENBRUUsT0FBT0csQ0FBUCxFQUFVO0FBQ1YsUUFBSUEsQ0FBQyxLQUFLQyxTQUFWLEVBQXFCO0FBQ25CLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUgsU0FBUVAsSUFBSyxrQkFGVixDQUFOO0FBSUQsS0FMRCxNQUtPO0FBQ0wsWUFBTSxJQUFJSyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUUscUJBRFIsRUFFSix5QkFGSSxDQUFOO0FBSUQ7QUFDRjtBQUNGLENBaEJEOzs7O0FBa0JBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakNBLEVBQUFBLGtCQUFrQixDQUFDQyxlQUFuQixDQUNFLE9BREYsRUFFRTtBQUNFQyxJQUFBQSxXQUFXLEVBQ1QsbUVBRko7QUFHRUMsSUFBQUEsSUFBSSxFQUFFO0FBQ0piLE1BQUFBLElBQUksRUFBRWMsV0FBVyxDQUFDQztBQURkLEtBSFI7QUFNRUMsSUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CSCxXQUFXLENBQUNJLEtBQS9CLENBTlI7QUFPRUMsSUFBQUEsT0FBTyxFQUFFLE9BQU9DLE9BQVAsRUFBZ0JQLElBQWhCLEVBQXNCUSxPQUF0QixLQUFrQztBQUN6QyxVQUFJO0FBQ0YsY0FBTTtBQUFFckIsVUFBQUE7QUFBRixZQUFXYSxJQUFqQjtBQUNBLGNBQU07QUFBRVMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7QUFFQSxjQUFNdEIsTUFBTSxHQUFHLE1BQU1xQixNQUFNLENBQUNFLFFBQVAsQ0FBZ0JDLFVBQWhCLENBQTJCO0FBQUVDLFVBQUFBLFVBQVUsRUFBRTtBQUFkLFNBQTNCLENBQXJCO0FBQ0EsY0FBTUMsVUFBVSxHQUFHLE1BQU01QixRQUFRLENBQUNDLElBQUQsRUFBT0MsTUFBUCxDQUFqQztBQUNBLGVBQU87QUFDTEQsVUFBQUEsSUFBSSxFQUFFMkIsVUFBVSxDQUFDQyxTQURaO0FBRUxDLFVBQUFBLFlBQVksRUFBRSxzQ0FBbUJGLFVBQVUsQ0FBQ0csTUFBOUI7QUFGVCxTQUFQO0FBSUQsT0FaRCxDQVlFLE9BQU8zQixDQUFQLEVBQVU7QUFDVk8sUUFBQUEsa0JBQWtCLENBQUNxQixXQUFuQixDQUErQjVCLENBQS9CO0FBQ0Q7QUFDRjtBQXZCSCxHQUZGLEVBMkJFLElBM0JGLEVBNEJFLElBNUJGO0FBK0JBTyxFQUFBQSxrQkFBa0IsQ0FBQ0MsZUFBbkIsQ0FDRSxTQURGLEVBRUU7QUFDRUMsSUFBQUEsV0FBVyxFQUNULHdFQUZKO0FBR0VJLElBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUNKLElBQUllLG9CQUFKLENBQWdCLElBQUlmLHVCQUFKLENBQW1CSCxXQUFXLENBQUNJLEtBQS9CLENBQWhCLENBREksQ0FIUjtBQU1FQyxJQUFBQSxPQUFPLEVBQUUsT0FBT0MsT0FBUCxFQUFnQmEsS0FBaEIsRUFBdUJaLE9BQXZCLEtBQW1DO0FBQzFDLFVBQUk7QUFDRixjQUFNO0FBQUVDLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUE7QUFBVixZQUFtQkYsT0FBekI7QUFFQSx1REFBdUJFLElBQXZCO0FBRUEsY0FBTXRCLE1BQU0sR0FBRyxNQUFNcUIsTUFBTSxDQUFDRSxRQUFQLENBQWdCQyxVQUFoQixDQUEyQjtBQUFFQyxVQUFBQSxVQUFVLEVBQUU7QUFBZCxTQUEzQixDQUFyQjtBQUNBLGVBQU8sQ0FBQyxNQUFNekIsTUFBTSxDQUFDaUMsYUFBUCxDQUFxQixJQUFyQixDQUFQLEVBQW1DQyxHQUFuQyxDQUF1Q1IsVUFBVSxLQUFLO0FBQzNEM0IsVUFBQUEsSUFBSSxFQUFFMkIsVUFBVSxDQUFDQyxTQUQwQztBQUUzREMsVUFBQUEsWUFBWSxFQUFFLHNDQUFtQkYsVUFBVSxDQUFDRyxNQUE5QjtBQUY2QyxTQUFMLENBQWpELENBQVA7QUFJRCxPQVZELENBVUUsT0FBTzNCLENBQVAsRUFBVTtBQUNWTyxRQUFBQSxrQkFBa0IsQ0FBQ3FCLFdBQW5CLENBQStCNUIsQ0FBL0I7QUFDRDtBQUNGO0FBcEJILEdBRkYsRUF3QkUsSUF4QkYsRUF5QkUsSUF6QkY7QUEyQkQsQ0EzREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCwgR3JhcGhRTExpc3QgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IHRyYW5zZm9ybVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMnO1xuaW1wb3J0ICogYXMgc2NoZW1hVHlwZXMgZnJvbSAnLi9zY2hlbWFUeXBlcyc7XG5pbXBvcnQgeyBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRDbGFzcyA9IGFzeW5jIChuYW1lLCBzY2hlbWEpID0+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgc2NoZW1hLmdldE9uZVNjaGVtYShuYW1lLCB0cnVlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICBgQ2xhc3MgJHtuYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgJ0RhdGFiYXNlIGFkYXB0ZXIgZXJyb3IuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdjbGFzcycsXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgY2xhc3MgcXVlcnkgY2FuIGJlIHVzZWQgdG8gcmV0cmlldmUgYW4gZXhpc3Rpbmcgb2JqZWN0IGNsYXNzLicsXG4gICAgICBhcmdzOiB7XG4gICAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgICAgfSxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUyksXG4gICAgICByZXNvbHZlOiBhc3luYyAoX3NvdXJjZSwgYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MoYXV0aCk7XG5cbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgICAgY29uc3QgcGFyc2VDbGFzcyA9IGF3YWl0IGdldENsYXNzKG5hbWUsIHNjaGVtYSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IHBhcnNlQ2xhc3MuY2xhc3NOYW1lLFxuICAgICAgICAgICAgc2NoZW1hRmllbGRzOiB0cmFuc2Zvcm1Ub0dyYXBoUUwocGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdjbGFzc2VzJyxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBjbGFzc2VzIHF1ZXJ5IGNhbiBiZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBleGlzdGluZyBvYmplY3QgY2xhc3Nlcy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSlcbiAgICAgICksXG4gICAgICByZXNvbHZlOiBhc3luYyAoX3NvdXJjZSwgX2FyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MoYXV0aCk7XG5cbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgICAgcmV0dXJuIChhd2FpdCBzY2hlbWEuZ2V0QWxsQ2xhc3Nlcyh0cnVlKSkubWFwKHBhcnNlQ2xhc3MgPT4gKHtcbiAgICAgICAgICAgIG5hbWU6IHBhcnNlQ2xhc3MuY2xhc3NOYW1lLFxuICAgICAgICAgICAgc2NoZW1hRmllbGRzOiB0cmFuc2Zvcm1Ub0dyYXBoUUwocGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0pKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xufTtcblxuZXhwb3J0IHsgZ2V0Q2xhc3MsIGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaTypes.js b/lib/GraphQL/loaders/schemaTypes.js deleted file mode 100644 index face4b3b4b..0000000000 --- a/lib/GraphQL/loaders/schemaTypes.js +++ /dev/null @@ -1,376 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.CLASS = exports.CLASS_NAME_ATT = exports.SCHEMA_FIELDS_INPUT = exports.SCHEMA_ACL_FIELD = exports.SCHEMA_RELATION_FIELD = exports.SCHEMA_RELATION_FIELD_INPUT = exports.SCHEMA_POINTER_FIELD = exports.SCHEMA_POINTER_FIELD_INPUT = exports.TARGET_CLASS_ATT = exports.SCHEMA_BYTES_FIELD = exports.SCHEMA_BYTES_FIELD_INPUT = exports.SCHEMA_POLYGON_FIELD = exports.SCHEMA_POLYGON_FIELD_INPUT = exports.SCHEMA_GEO_POINT_FIELD = exports.SCHEMA_GEO_POINT_FIELD_INPUT = exports.SCHEMA_FILE_FIELD = exports.SCHEMA_FILE_FIELD_INPUT = exports.SCHEMA_DATE_FIELD = exports.SCHEMA_DATE_FIELD_INPUT = exports.SCHEMA_OBJECT_FIELD = exports.SCHEMA_OBJECT_FIELD_INPUT = exports.SCHEMA_ARRAY_FIELD = exports.SCHEMA_ARRAY_FIELD_INPUT = exports.SCHEMA_BOOLEAN_FIELD = exports.SCHEMA_BOOLEAN_FIELD_INPUT = exports.SCHEMA_NUMBER_FIELD = exports.SCHEMA_NUMBER_FIELD_INPUT = exports.SCHEMA_STRING_FIELD = exports.SCHEMA_STRING_FIELD_INPUT = exports.SCHEMA_FIELD_INPUT = exports.SCHEMA_FIELD_NAME_ATT = void 0; - -var _graphql = require("graphql"); - -const SCHEMA_FIELD_NAME_ATT = { - description: 'This is the field name.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.SCHEMA_FIELD_NAME_ATT = SCHEMA_FIELD_NAME_ATT; -const SCHEMA_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaFieldInput', - description: 'The SchemaFieldInput is used to specify a field of an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_FIELD_INPUT = SCHEMA_FIELD_INPUT; -const SCHEMA_FIELD = new _graphql.GraphQLInterfaceType({ - name: 'SchemaField', - description: 'The SchemaField interface type is used as a base type for the different supported fields of an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - }, - resolveType: value => ({ - String: SCHEMA_STRING_FIELD, - Number: SCHEMA_NUMBER_FIELD, - Boolean: SCHEMA_BOOLEAN_FIELD, - Array: SCHEMA_ARRAY_FIELD, - Object: SCHEMA_OBJECT_FIELD, - Date: SCHEMA_DATE_FIELD, - File: SCHEMA_FILE_FIELD, - GeoPoint: SCHEMA_GEO_POINT_FIELD, - Polygon: SCHEMA_POLYGON_FIELD, - Bytes: SCHEMA_BYTES_FIELD, - Pointer: SCHEMA_POINTER_FIELD, - Relation: SCHEMA_RELATION_FIELD, - ACL: SCHEMA_ACL_FIELD - })[value.type] -}); -const SCHEMA_STRING_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaStringFieldInput', - description: 'The SchemaStringFieldInput is used to specify a field of type string for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_STRING_FIELD_INPUT = SCHEMA_STRING_FIELD_INPUT; -const SCHEMA_STRING_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaStringField', - description: 'The SchemaStringField is used to return information of a String field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_STRING_FIELD = SCHEMA_STRING_FIELD; -const SCHEMA_NUMBER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaNumberFieldInput', - description: 'The SchemaNumberFieldInput is used to specify a field of type number for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_NUMBER_FIELD_INPUT = SCHEMA_NUMBER_FIELD_INPUT; -const SCHEMA_NUMBER_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaNumberField', - description: 'The SchemaNumberField is used to return information of a Number field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_NUMBER_FIELD = SCHEMA_NUMBER_FIELD; -const SCHEMA_BOOLEAN_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaBooleanFieldInput', - description: 'The SchemaBooleanFieldInput is used to specify a field of type boolean for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BOOLEAN_FIELD_INPUT = SCHEMA_BOOLEAN_FIELD_INPUT; -const SCHEMA_BOOLEAN_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaBooleanField', - description: 'The SchemaBooleanField is used to return information of a Boolean field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BOOLEAN_FIELD = SCHEMA_BOOLEAN_FIELD; -const SCHEMA_ARRAY_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaArrayFieldInput', - description: 'The SchemaArrayFieldInput is used to specify a field of type array for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_ARRAY_FIELD_INPUT = SCHEMA_ARRAY_FIELD_INPUT; -const SCHEMA_ARRAY_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaArrayField', - description: 'The SchemaArrayField is used to return information of an Array field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_ARRAY_FIELD = SCHEMA_ARRAY_FIELD; -const SCHEMA_OBJECT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaObjectFieldInput', - description: 'The SchemaObjectFieldInput is used to specify a field of type object for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_OBJECT_FIELD_INPUT = SCHEMA_OBJECT_FIELD_INPUT; -const SCHEMA_OBJECT_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaObjectField', - description: 'The SchemaObjectField is used to return information of an Object field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_OBJECT_FIELD = SCHEMA_OBJECT_FIELD; -const SCHEMA_DATE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaDateFieldInput', - description: 'The SchemaDateFieldInput is used to specify a field of type date for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_DATE_FIELD_INPUT = SCHEMA_DATE_FIELD_INPUT; -const SCHEMA_DATE_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaDateField', - description: 'The SchemaDateField is used to return information of a Date field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_DATE_FIELD = SCHEMA_DATE_FIELD; -const SCHEMA_FILE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaFileFieldInput', - description: 'The SchemaFileFieldInput is used to specify a field of type file for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_FILE_FIELD_INPUT = SCHEMA_FILE_FIELD_INPUT; -const SCHEMA_FILE_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaFileField', - description: 'The SchemaFileField is used to return information of a File field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_FILE_FIELD = SCHEMA_FILE_FIELD; -const SCHEMA_GEO_POINT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaGeoPointFieldInput', - description: 'The SchemaGeoPointFieldInput is used to specify a field of type geo point for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_GEO_POINT_FIELD_INPUT = SCHEMA_GEO_POINT_FIELD_INPUT; -const SCHEMA_GEO_POINT_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaGeoPointField', - description: 'The SchemaGeoPointField is used to return information of a Geo Point field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_GEO_POINT_FIELD = SCHEMA_GEO_POINT_FIELD; -const SCHEMA_POLYGON_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaPolygonFieldInput', - description: 'The SchemaPolygonFieldInput is used to specify a field of type polygon for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_POLYGON_FIELD_INPUT = SCHEMA_POLYGON_FIELD_INPUT; -const SCHEMA_POLYGON_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaPolygonField', - description: 'The SchemaPolygonField is used to return information of a Polygon field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_POLYGON_FIELD = SCHEMA_POLYGON_FIELD; -const SCHEMA_BYTES_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaBytesFieldInput', - description: 'The SchemaBytesFieldInput is used to specify a field of type bytes for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BYTES_FIELD_INPUT = SCHEMA_BYTES_FIELD_INPUT; -const SCHEMA_BYTES_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaBytesField', - description: 'The SchemaBytesField is used to return information of a Bytes field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BYTES_FIELD = SCHEMA_BYTES_FIELD; -const TARGET_CLASS_ATT = { - description: 'This is the name of the target class for the field.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.TARGET_CLASS_ATT = TARGET_CLASS_ATT; -const SCHEMA_POINTER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'PointerFieldInput', - description: 'The PointerFieldInput is used to specify a field of type pointer for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_POINTER_FIELD_INPUT = SCHEMA_POINTER_FIELD_INPUT; -const SCHEMA_POINTER_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaPointerField', - description: 'The SchemaPointerField is used to return information of a Pointer field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_POINTER_FIELD = SCHEMA_POINTER_FIELD; -const SCHEMA_RELATION_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'RelationFieldInput', - description: 'The RelationFieldInput is used to specify a field of type relation for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_RELATION_FIELD_INPUT = SCHEMA_RELATION_FIELD_INPUT; -const SCHEMA_RELATION_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaRelationField', - description: 'The SchemaRelationField is used to return information of a Relation field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_RELATION_FIELD = SCHEMA_RELATION_FIELD; -const SCHEMA_ACL_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaACLField', - description: 'The SchemaACLField is used to return information of an ACL field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_ACL_FIELD = SCHEMA_ACL_FIELD; -const SCHEMA_FIELDS_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaFieldsInput', - description: `The CreateClassSchemaInput type is used to specify the schema for a new object class to be created.`, - fields: { - addStrings: { - description: 'These are the String fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_STRING_FIELD_INPUT)) - }, - addNumbers: { - description: 'These are the Number fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_NUMBER_FIELD_INPUT)) - }, - addBooleans: { - description: 'These are the Boolean fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BOOLEAN_FIELD_INPUT)) - }, - addArrays: { - description: 'These are the Array fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_ARRAY_FIELD_INPUT)) - }, - addObjects: { - description: 'These are the Object fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_OBJECT_FIELD_INPUT)) - }, - addDates: { - description: 'These are the Date fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_DATE_FIELD_INPUT)) - }, - addFiles: { - description: 'These are the File fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FILE_FIELD_INPUT)) - }, - addGeoPoint: { - description: 'This is the Geo Point field to be added to the class schema. Currently it is supported only one GeoPoint field per Class.', - type: SCHEMA_GEO_POINT_FIELD_INPUT - }, - addPolygons: { - description: 'These are the Polygon fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POLYGON_FIELD_INPUT)) - }, - addBytes: { - description: 'These are the Bytes fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BYTES_FIELD_INPUT)) - }, - addPointers: { - description: 'These are the Pointer fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POINTER_FIELD_INPUT)) - }, - addRelations: { - description: 'These are the Relation fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_RELATION_FIELD_INPUT)) - }, - remove: { - description: 'These are the fields to be removed from the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD_INPUT)) - } - } -}); -exports.SCHEMA_FIELDS_INPUT = SCHEMA_FIELDS_INPUT; -const CLASS_NAME_ATT = { - description: 'This is the name of the object class.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.CLASS_NAME_ATT = CLASS_NAME_ATT; -const CLASS = new _graphql.GraphQLObjectType({ - name: 'Class', - description: `The Class type is used to return the information about an object class.`, - fields: { - name: CLASS_NAME_ATT, - schemaFields: { - description: "These are the schema's fields of the object class.", - type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD))) - } - } -}); -exports.CLASS = CLASS; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLType(SCHEMA_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_ACL_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_FIELDS_INPUT, true); - parseGraphQLSchema.addGraphQLType(CLASS, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hVHlwZXMuanMiXSwibmFtZXMiOlsiU0NIRU1BX0ZJRUxEX05BTUVfQVRUIiwiZGVzY3JpcHRpb24iLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiU0NIRU1BX0ZJRUxEX0lOUFVUIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJmaWVsZHMiLCJTQ0hFTUFfRklFTEQiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsInJlc29sdmVUeXBlIiwidmFsdWUiLCJTdHJpbmciLCJTQ0hFTUFfU1RSSU5HX0ZJRUxEIiwiTnVtYmVyIiwiU0NIRU1BX05VTUJFUl9GSUVMRCIsIkJvb2xlYW4iLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRCIsIkFycmF5IiwiU0NIRU1BX0FSUkFZX0ZJRUxEIiwiT2JqZWN0IiwiU0NIRU1BX09CSkVDVF9GSUVMRCIsIkRhdGUiLCJTQ0hFTUFfREFURV9GSUVMRCIsIkZpbGUiLCJTQ0hFTUFfRklMRV9GSUVMRCIsIkdlb1BvaW50IiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRCIsIlBvbHlnb24iLCJTQ0hFTUFfUE9MWUdPTl9GSUVMRCIsIkJ5dGVzIiwiU0NIRU1BX0JZVEVTX0ZJRUxEIiwiUG9pbnRlciIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEIiwiUmVsYXRpb24iLCJTQ0hFTUFfUkVMQVRJT05fRklFTEQiLCJBQ0wiLCJTQ0hFTUFfQUNMX0ZJRUxEIiwiU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCIsIkdyYXBoUUxPYmplY3RUeXBlIiwiaW50ZXJmYWNlcyIsIlNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQiLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCIsIlNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQiLCJTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCIsIlNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVUIiwiVEFSR0VUX0NMQVNTX0FUVCIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUIiwidGFyZ2V0Q2xhc3NOYW1lIiwiU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0ZJRUxEU19JTlBVVCIsImFkZFN0cmluZ3MiLCJHcmFwaFFMTGlzdCIsImFkZE51bWJlcnMiLCJhZGRCb29sZWFucyIsImFkZEFycmF5cyIsImFkZE9iamVjdHMiLCJhZGREYXRlcyIsImFkZEZpbGVzIiwiYWRkR2VvUG9pbnQiLCJhZGRQb2x5Z29ucyIsImFkZEJ5dGVzIiwiYWRkUG9pbnRlcnMiLCJhZGRSZWxhdGlvbnMiLCJyZW1vdmUiLCJDTEFTU19OQU1FX0FUVCIsIkNMQVNTIiwic2NoZW1hRmllbGRzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImFkZEdyYXBoUUxUeXBlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBU0EsTUFBTUEscUJBQXFCLEdBQUc7QUFDNUJDLEVBQUFBLFdBQVcsRUFBRSx5QkFEZTtBQUU1QkMsRUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CQyxzQkFBbkI7QUFGc0IsQ0FBOUI7O0FBS0EsTUFBTUMsa0JBQWtCLEdBQUcsSUFBSUMsK0JBQUosQ0FBMkI7QUFDcERDLEVBQUFBLElBQUksRUFBRSxrQkFEOEM7QUFFcEROLEVBQUFBLFdBQVcsRUFDVCw0RUFIa0Q7QUFJcERPLEVBQUFBLE1BQU0sRUFBRTtBQUNORCxJQUFBQSxJQUFJLEVBQUVQO0FBREE7QUFKNEMsQ0FBM0IsQ0FBM0I7O0FBU0EsTUFBTVMsWUFBWSxHQUFHLElBQUlDLDZCQUFKLENBQXlCO0FBQzVDSCxFQUFBQSxJQUFJLEVBQUUsYUFEc0M7QUFFNUNOLEVBQUFBLFdBQVcsRUFDVCxxSEFIMEM7QUFJNUNPLEVBQUFBLE1BQU0s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QUFuQixDQUFrQzFCLDBCQUFsQyxFQUE4RCxJQUE5RDtBQUNBeUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDN0Msb0JBQWxDLEVBQXdELElBQXhEO0FBQ0E0QyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6Qix3QkFBbEMsRUFBNEQsSUFBNUQ7QUFDQXdCLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQzNDLGtCQUFsQyxFQUFzRCxJQUF0RDtBQUNBMEMsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkIsMEJBQWxDLEVBQThELElBQTlEO0FBQ0FzQixFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6QyxvQkFBbEMsRUFBd0QsSUFBeEQ7QUFDQXdDLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3JCLDJCQUFsQyxFQUErRCxJQUEvRDtBQUNBb0IsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkMscUJBQWxDLEVBQXlELElBQXpEO0FBQ0FzQyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0NyQyxnQkFBbEMsRUFBb0QsSUFBcEQ7QUFDQW9DLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3BCLG1CQUFsQyxFQUF1RCxJQUF2RDtBQUNBbUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDSixLQUFsQyxFQUF5QyxJQUF6QztBQUNELENBN0JEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxTdHJpbmcsXG4gIEdyYXBoUUxJbnB1dE9iamVjdFR5cGUsXG4gIEdyYXBoUUxMaXN0LFxuICBHcmFwaFFMT2JqZWN0VHlwZSxcbiAgR3JhcGhRTEludGVyZmFjZVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuXG5jb25zdCBTQ0hFTUFfRklFTERfTkFNRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZmllbGQgbmFtZS4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBTQ0hFTUFfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9GSUVMRCA9IG5ldyBHcmFwaFFMSW50ZXJmYWNlVHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRmllbGQgaW50ZXJmYWNlIHR5cGUgaXMgdXNlZCBhcyBhIGJhc2UgdHlwZSBmb3IgdGhlIGRpZmZlcmVudCBzdXBwb3J0ZWQgZmllbGRzIG9mIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxuICByZXNvbHZlVHlwZTogdmFsdWUgPT5cbiAgICAoe1xuICAgICAgU3RyaW5nOiBTQ0hFTUFfU1RSSU5HX0ZJRUxELFxuICAgICAgTnVtYmVyOiBTQ0hFTUFfTlVNQkVSX0ZJRUxELFxuICAgICAgQm9vbGVhbjogU0NIRU1BX0JPT0xFQU5fRklFTEQsXG4gICAgICBBcnJheTogU0NIRU1BX0FSUkFZX0ZJRUxELFxuICAgICAgT2JqZWN0OiBTQ0hFTUFfT0JKRUNUX0ZJRUxELFxuICAgICAgRGF0ZTogU0NIRU1BX0RBVEVfRklFTEQsXG4gICAgICBGaWxlOiBTQ0hFTUFfRklMRV9GSUVMRCxcbiAgICAgIEdlb1BvaW50OiBTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxELFxuICAgICAgUG9seWdvbjogU0NIRU1BX1BPTFlHT05fRklFTEQsXG4gICAgICBCeXRlczogU0NIRU1BX0JZVEVTX0ZJRUxELFxuICAgICAgUG9pbnRlcjogU0NIRU1BX1BPSU5URVJfRklFTEQsXG4gICAgICBSZWxhdGlvbjogU0NIRU1BX1JFTEFUSU9OX0ZJRUxELFxuICAgICAgQUNMOiBTQ0hFTUFfQUNMX0ZJRUxELFxuICAgIH1bdmFsdWUudHlwZV0pLFxufSk7XG5cbmNvbnN0IFNDSEVNQV9TVFJJTkdfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFTdHJpbmdGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFTdHJpbmdGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgc3RyaW5nIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfU1RSSU5HX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYVN0cmluZ0ZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFTdHJpbmdGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFN0cmluZyBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFOdW1iZXJGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFOdW1iZXJGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgbnVtYmVyIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfTlVNQkVSX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYU51bWJlckZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFOdW1iZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIE51bWJlciBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUJvb2xlYW5GaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgYm9vbGVhbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JPT0xFQU5fRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFCb29sZWFuRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBCb29sZWFuIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0FSUkFZX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQXJyYXlGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFBcnJheUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBhcnJheSBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0FSUkFZX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUFycmF5RmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUFycmF5RmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gQXJyYXkgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfT0JKRUNUX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hT2JqZWN0RmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hT2JqZWN0RmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIG9iamVjdCBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX09CSkVDVF9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFPYmplY3RGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hT2JqZWN0RmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gT2JqZWN0IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0RBVEVfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRGF0ZUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBkYXRlIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfREFURV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYURhdGVGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIERhdGUgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUZpbGVGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFGaWxlRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIGZpbGUgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9GSUxFX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUZpbGVGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRmlsZUZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgRmlsZSBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9HRU9fUE9JTlRfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFHZW9Qb2ludEZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUdlb1BvaW50RmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIGdlbyBwb2ludCBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0dFT19QT0lOVF9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFHZW9Qb2ludEZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFHZW9Qb2ludEZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgR2VvIFBvaW50IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hUG9seWdvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBwb2x5Z29uIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfUE9MWUdPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYVBvbHlnb25GaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFBvbHlnb24gZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfQllURVNfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFCeXRlc0ZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUJ5dGVzRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIGJ5dGVzIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfQllURVNfRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQnl0ZXNGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hQnl0ZXNGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIEJ5dGVzIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgVEFSR0VUX0NMQVNTX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgY2xhc3MgZm9yIHRoZSBmaWVsZC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBTQ0hFTUFfUE9JTlRFUl9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1BvaW50ZXJGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBQb2ludGVyRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIHBvaW50ZXIgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICAgIHRhcmdldENsYXNzTmFtZTogVEFSR0VUX0NMQVNTX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfUE9JTlRFUl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2ludGVyRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYVBvaW50ZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFBvaW50ZXIgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgICB0YXJnZXRDbGFzc05hbWU6IFRBUkdFVF9DTEFTU19BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUmVsYXRpb25GaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBSZWxhdGlvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSByZWxhdGlvbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9SRUxBVElPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFSZWxhdGlvbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFSZWxhdGlvbkZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgUmVsYXRpb24gZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgICB0YXJnZXRDbGFzc05hbWU6IFRBUkdFVF9DTEFTU19BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0FDTF9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFBQ0xGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hQUNMRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gQUNMIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0ZJRUxEU19JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUZpZWxkc0lucHV0JyxcbiAgZGVzY3JpcHRpb246IGBUaGUgQ3JlYXRlQ2xhc3NTY2hlbWFJbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgc2NoZW1hIGZvciBhIG5ldyBvYmplY3QgY2xhc3MgdG8gYmUgY3JlYXRlZC5gLFxuICBmaWVsZHM6IHtcbiAgICBhZGRTdHJpbmdzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgU3RyaW5nIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9TVFJJTkdfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZE51bWJlcnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBOdW1iZXIgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkQm9vbGVhbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBCb29sZWFuIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRBcnJheXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBBcnJheSBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfQVJSQVlfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZE9iamVjdHM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBPYmplY3QgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX09CSkVDVF9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkRGF0ZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBEYXRlIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9EQVRFX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRGaWxlczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEZpbGUgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0ZJTEVfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZEdlb1BvaW50OiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIEdlbyBQb2ludCBmaWVsZCB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLiBDdXJyZW50bHkgaXQgaXMgc3VwcG9ydGVkIG9ubHkgb25lIEdlb1BvaW50IGZpZWxkIHBlciBDbGFzcy4nLFxuICAgICAgdHlwZTogU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCxcbiAgICB9LFxuICAgIGFkZFBvbHlnb25zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgUG9seWdvbiBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfUE9MWUdPTl9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkQnl0ZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlc2UgYXJlIHRoZSBCeXRlcyBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfQllURVNfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZFBvaW50ZXJzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgUG9pbnRlciBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfUE9JTlRFUl9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkUmVsYXRpb25zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZXNlIGFyZSB0aGUgUmVsYXRpb24gZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICByZW1vdmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBDTEFTU19OQU1FX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBvYmplY3QgY2xhc3MuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxTdHJpbmcpLFxufTtcblxuY29uc3QgQ0xBU1MgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnQ2xhc3MnLFxuICBkZXNjcmlwdGlvbjogYFRoZSBDbGFzcyB0eXBlIGlzIHVzZWQgdG8gcmV0dXJuIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhbiBvYmplY3QgY2xhc3MuYCxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogQ0xBU1NfTkFNRV9BVFQsXG4gICAgc2NoZW1hRmllbGRzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJUaGVzZSBhcmUgdGhlIHNjaGVtYSdzIGZpZWxkcyBvZiB0aGUgb2JqZWN0IGNsYXNzLlwiLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9GSUVMRCkpXG4gICAgICApLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfU1RSSU5HX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX05VTUJFUl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQk9PTEVBTl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQVJSQVlfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0FSUkFZX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX09CSkVDVF9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfREFURV9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklMRV9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9HRU9fUE9JTlRfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1BPTFlHT05fRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9CWVRFU19GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9JTlRFUl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9JTlRFUl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUkVMQVRJT05fRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX1JFTEFUSU9OX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9BQ0xfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0ZJRUxEU19JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShDTEFTUywgdHJ1ZSk7XG59O1xuXG5leHBvcnQge1xuICBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIFNDSEVNQV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX1NUUklOR19GSUVMRCxcbiAgU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX05VTUJFUl9GSUVMRCxcbiAgU0NIRU1BX0JPT0xFQU5fRklFTERfSU5QVVQsXG4gIFNDSEVNQV9CT09MRUFOX0ZJRUxELFxuICBTQ0hFTUFfQVJSQVlfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9BUlJBWV9GSUVMRCxcbiAgU0NIRU1BX09CSkVDVF9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX09CSkVDVF9GSUVMRCxcbiAgU0NIRU1BX0RBVEVfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9EQVRFX0ZJRUxELFxuICBTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0ZJTEVfRklFTEQsXG4gIFNDSEVNQV9HRU9fUE9JTlRfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9HRU9fUE9JTlRfRklFTEQsXG4gIFNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfUE9MWUdPTl9GSUVMRCxcbiAgU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfQllURVNfRklFTEQsXG4gIFRBUkdFVF9DTEFTU19BVFQsXG4gIFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfUE9JTlRFUl9GSUVMRCxcbiAgU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfUkVMQVRJT05fRklFTEQsXG4gIFNDSEVNQV9BQ0xfRklFTEQsXG4gIFNDSEVNQV9GSUVMRFNfSU5QVVQsXG4gIENMQVNTX05BTUVfQVRULFxuICBDTEFTUyxcbiAgbG9hZCxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersMutations.js b/lib/GraphQL/loaders/usersMutations.js deleted file mode 100644 index b20234d4a5..0000000000 --- a/lib/GraphQL/loaders/usersMutations.js +++ /dev/null @@ -1,333 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _UsersRouter = _interopRequireDefault(require("../../Routers/UsersRouter")); - -var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); - -var _defaultGraphQLTypes = require("./defaultGraphQLTypes"); - -var _usersQueries = require("./usersQueries"); - -var _mutation = require("../transformers/mutation"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const usersRouter = new _UsersRouter.default(); - -const load = parseGraphQLSchema => { - if (parseGraphQLSchema.isUsersClassDisabled) { - return; - } - - const signUpMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'SignUp', - description: 'The signUp mutation can be used to create and sign up a new user.', - inputFields: { - fields: { - descriptions: 'These are the fields of the new user to be created and signed up.', - type: parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType - } - }, - outputFields: { - viewer: { - description: 'This is the new user that was created, signed up and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - const { - fields - } = args; - const { - config, - auth, - info - } = context; - const parseFields = await (0, _mutation.transformTypes)('create', fields, { - className: '_User', - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const { - sessionToken, - objectId - } = await objectsMutations.createObject('_User', parseFields, config, auth, info); - context.info.sessionToken = sessionToken; - return { - viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(signUpMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true); - const logInWithMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'LogInWith', - description: 'The logInWith mutation can be used to signup, login user with 3rd party authentication system. This mutation create a user if the authData do not correspond to an existing one.', - inputFields: { - authData: { - descriptions: 'This is the auth data of your custom auth provider', - type: new _graphql.GraphQLNonNull(_defaultGraphQLTypes.OBJECT) - }, - fields: { - descriptions: 'These are the fields of the user to be created/updated and logged in.', - type: new _graphql.GraphQLInputObjectType({ - name: 'UserLoginWithInput', - fields: () => { - const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType.getFields(); - return Object.keys(classGraphQLCreateFields).reduce((fields, fieldName) => { - if (fieldName !== 'password' && fieldName !== 'username' && fieldName !== 'authData') { - fields[fieldName] = classGraphQLCreateFields[fieldName]; - } - - return fields; - }, {}); - } - }) - } - }, - outputFields: { - viewer: { - description: 'This is the new user that was created, signed up and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - const { - fields, - authData - } = args; - const { - config, - auth, - info - } = context; - const parseFields = await (0, _mutation.transformTypes)('create', fields, { - className: '_User', - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const { - sessionToken, - objectId - } = await objectsMutations.createObject('_User', _objectSpread(_objectSpread({}, parseFields), {}, { - authData - }), config, auth, info); - context.info.sessionToken = sessionToken; - return { - viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(logInWithMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(logInWithMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('logInWith', logInWithMutation, true, true); - const logInMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'LogIn', - description: 'The logIn mutation can be used to log in an existing user.', - inputFields: { - username: { - description: 'This is the username used to log in the user.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - password: { - description: 'This is the password used to log in the user.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - }, - outputFields: { - viewer: { - description: 'This is the existing user that was logged in and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - const { - username, - password - } = args; - const { - config, - auth, - info - } = context; - const { - sessionToken, - objectId - } = (await usersRouter.handleLogIn({ - body: { - username, - password - }, - query: {}, - config, - auth, - info - })).response; - context.info.sessionToken = sessionToken; - return { - viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(logInMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(logInMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('logIn', logInMutation, true, true); - const logOutMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'LogOut', - description: 'The logOut mutation can be used to log out an existing user.', - outputFields: { - viewer: { - description: 'This is the existing user that was logged out and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (_args, context, mutationInfo) => { - try { - const { - config, - auth, - info - } = context; - const viewer = await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', auth.user.id); - await usersRouter.handleLogOut({ - config, - auth, - info - }); - return { - viewer - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(logOutMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(logOutMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('logOut', logOutMutation, true, true); - const resetPasswordMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'ResetPassword', - description: 'The resetPassword mutation can be used to reset the password of an existing user.', - inputFields: { - email: { - descriptions: 'Email of the user that should receive the reset email', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - }, - outputFields: { - ok: { - description: "It's always true.", - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - }, - mutateAndGetPayload: async ({ - email - }, context) => { - const { - config, - auth, - info - } = context; - await usersRouter.handleResetRequest({ - body: { - email - }, - config, - auth, - info - }); - return { - ok: true - }; - } - }); - parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); - const sendVerificationEmailMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'SendVerificationEmail', - description: 'The sendVerificationEmail mutation can be used to send the verification email again.', - inputFields: { - email: { - descriptions: 'Email of the user that should receive the verification email', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - }, - outputFields: { - ok: { - description: "It's always true.", - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - }, - mutateAndGetPayload: async ({ - email - }, context) => { - try { - const { - config, - auth, - info - } = context; - await usersRouter.handleVerificationEmailRequest({ - body: { - email - }, - config, - auth, - info - }); - return { - ok: true - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('sendVerificationEmail', sendVerificationEmailMutation, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsidXNlcnNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNpZ25VcE11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJmaWVsZHMiLCJkZXNjcmlwdGlvbnMiLCJ0eXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsIm91dHB1dEZpZWxkcyIsInZpZXdlciIsIkdyYXBoUUxOb25OdWxsIiwidmlld2VyVHlwZSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJjbGFzc05hbWUiLCJyZXEiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3RJZCIsIm9iamVjdHNNdXRhdGlvbnMiLCJjcmVhdGVPYmplY3QiLCJlIiwiaGFuZGxlRXJyb3IiLCJhZGRHcmFwaFFMVHlwZSIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIiwibG9nSW5XaXRoTXV0YXRpb24iLCJhdXRoRGF0YSIsIk9CSkVDVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJjbGFzc0dyYXBoUUxDcmVhdGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiZmllbGROYW1lIiwibG9nSW5NdXRhdGlvbiIsInVzZXJuYW1lIiwiR3JhcGhRTFN0cmluZyIsInBhc3N3b3JkIiwiaGFuZGxlTG9nSW4iLCJib2R5IiwicXVlcnkiLCJyZXNwb25zZSIsImxvZ091dE11dGF0aW9uIiwiX2FyZ3MiLCJ1c2VyIiwiaWQiLCJoYW5kbGVMb2dPdXQiLCJyZXNldFBhc3N3b3JkTXV0YXRpb24iLCJlbWFpbCIsIm9rIiwiR3JhcGhRTEJvb2xlYW4iLCJoYW5kbGVSZXNldFJlcXVlc3QiLCJzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbiIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQU1BOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLFdBQVcsR0FBRyxJQUFJQyxvQkFBSixFQUFwQjs7QUFFQSxNQUFNQyxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLE1BQUlBLGtCQUFrQixDQUFDQyxvQkFBdkIsRUFBNkM7QUFDM0M7QUFDRDs7QUFFRCxRQUFNQyxjQUFjLEdBQUcsZ0RBQTZCO0FBQ2xEQyxJQUFBQSxJQUFJLEVBQUUsUUFENEM7QUFFbERDLElBQUFBLFdBQVcsRUFDVCxtRUFIZ0Q7QUFJbERDLElBQUFBLFdBQVcsRUFBRTtBQUNYQyxNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUNWLG1FQUZJO0FBR05DLFFBQUFBLElBQUksRUFDRlIsa0JBQWtCLENBQUNTLGVBQW5CLENBQW1DLE9BQW5DLEVBQTRDQztBQUp4QztBQURHLEtBSnFDO0FBWWxEQyxJQUFBQSxZQUFZLEVBQUU7QUFDWkMsTUFBQUEsTUFBTSxFQUFFO0FBQ05SLFFBQUFBLFdBQVcsRUFDVCw0RUFGSTtBQUdOSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJiLGtCQUFrQixDQUFDYyxVQUF0QztBQUhBO0FBREksS0Fab0M7QUFtQmxEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsRUFBc0JDLFlBQXRCLEtBQXVDO0FBQzFELFVBQUk7QUFDRixjQUFNO0FBQUVaLFVBQUFBO0FBQUYsWUFBYVUsSUFBbkI7QUFDQSxjQUFNO0FBQUVHLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUEsSUFBVjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBeUJKLE9BQS9CO0FBRUEsY0FBTUssV0FBVyxHQUFHLE1BQU0sOEJBQWUsUUFBZixFQUF5QmhCLE1BQXpCLEVBQWlDO0FBQ3pEaUIsVUFBQUEsU0FBUyxFQUFFLE9BRDhDO0FBRXpEdkIsVUFBQUEsa0JBRnlEO0FBR3pEd0IsVUFBQUEsR0FBRyxFQUFFO0FBQUVMLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEI7QUFIb0QsU0FBakMsQ0FBMUI7QUFNQSxjQUFNO0FBQUVJLFVBQUFBLFlBQUY7QUFBZ0JDLFVBQUFBO0FBQWhCLFlBQTZCLE1BQU1DLGdCQUFnQixDQUFDQyxZQUFqQixDQUN2QyxPQUR1QyxFQUV2Q04sV0FGdUMsRUFHdkNILE1BSHVDLEVBSXZDQyxJQUp1QyxFQUt2Q0MsSUFMdUMsQ0FBekM7QUFRQUosUUFBQUEsT0FBTyxDQUFDSSxJQUFSLENBQWFJLFlBQWIsR0FBNEJBLFlBQTVCO0FBRUEsZUFBTztBQUNMYixVQUFBQSxNQUFNLEVBQUUsTUFBTSwyQ0FDWkssT0FEWSxFQUVaQyxZQUZZLEVBR1osY0FIWSxFQUlaUSxRQUpZO0FBRFQsU0FBUDtBQVFELE9BNUJELENBNEJFLE9BQU9HLENBQVAsRUFBVTtBQUNWN0IsUUFBQUEsa0JBQWtCLENBQUM4QixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBbkRpRCxHQUE3QixDQUF2QjtBQXNEQTdCLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FDRTdCLGNBQWMsQ0FBQ2MsSUFBZixDQUFvQmdCLEtBQXBCLENBQTBCeEIsSUFBMUIsQ0FBK0J5QixNQURqQyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDN0IsY0FBYyxDQUFDTSxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxRQUF0QyxFQUFnRGhDLGNBQWhELEVBQWdFLElBQWhFLEVBQXNFLElBQXRFO0FBQ0EsUUFBTWlDLGlCQUFpQixHQUFHLGdEQUE2QjtBQUNyRGhDLElBQUFBLElBQUksRUFBRSxXQUQrQztBQUVyREMsSUFBQUEsV0FBVyxFQUNULGtMQUhtRDtBQUlyREMsSUFBQUEsV0FBVyxFQUFFO0FBQ1grQixNQUFBQSxRQUFRLEVBQUU7QUFDUjdCLFFBQUFBLFlBQVksRUFBRSxvREFETjtBQUVSQyxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJ3QiwyQkFBbkI7QUFGRSxPQURDO0FBS1gvQixNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUNWLHVFQUZJO0FBR05DLFFBQUFBLElBQUksRUFBRSxJQUFJOEIsK0JBQUosQ0FBMkI7QUFDL0JuQyxVQUFBQSxJQUFJLEVBQUUsb0JBRHlCO0FBRS9CRyxVQUFBQSxNQUFNLEVBQUUsTUFBTTtBQUNaLGtCQUFNaUMsd0JBQXdCLEdBQUd2QyxrQkFBa0IsQ0FBQ1MsZUFBbkIsQ0FDL0IsT0FEK0IsRUFFL0JDLHNCQUYrQixDQUVSOEIsU0FGUSxFQUFqQztBQUdBLG1CQUFPQyxNQUFNLENBQUNDLElBQVAsQ0FBWUgsd0JBQVosRUFBc0NJLE1BQXRDLENBQ0wsQ0FBQ3JDLE1BQUQsRUFBU3NDLFNBQVQsS0FBdUI7QUFDckIsa0JBQ0VBLFNBQVMsS0FBSyxVQUFkLElBQ0FBLFNBQVMsS0FBSyxVQURkLElBRUFBLFNBQVMsS0FBSyxVQUhoQixFQUlFO0FBQ0F0QyxnQkFBQUEsTUFBTSxDQUFDc0MsU0FBRCxDQUFOLEdBQW9CTCx3QkFBd0IsQ0FBQ0ssU0FBRCxDQUE1QztBQUNEOztBQUNELHFCQUFPdEMsTUFBUDtBQUNELGFBVkksRUFXTCxFQVhLLENBQVA7QUFhRDtBQW5COEIsU0FBM0I7QUFIQTtBQUxHLEtBSndDO0FBbUNyREssSUFBQUEsWUFBWSxFQUFFO0FBQ1pDLE1BQUFBLE1BQU0sRUFBRTtBQUNOUixRQUFBQSxXQUFXLEVBQ1QsNEVBRkk7QUFHTkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1CYixrQkFBa0IsQ0FBQ2MsVUFBdEM7QUFIQTtBQURJLEtBbkN1QztBQTBDckRDLElBQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsVUFBSTtBQUNGLGNBQU07QUFBRVosVUFBQUEsTUFBRjtBQUFVOEIsVUFBQUE7QUFBVixZQUF1QnBCLElBQTdCO0FBQ0EsY0FBTTtBQUFFRyxVQUFBQSxNQUFGO0FBQVVDLFVBQUFBLElBQVY7QUFBZ0JDLFVBQUFBO0FBQWhCLFlBQXlCSixPQUEvQjtBQUVBLGNBQU1LLFdBQVcsR0FBRyxNQUFNLDhCQUFlLFFBQWYsRUFBeUJoQixNQUF6QixFQUFpQztBQUN6RGlCLFVBQUFBLFNBQVMsRUFBRSxPQUQ4QztBQUV6RHZCLFVBQUFBLGtCQUZ5RDtBQUd6RHdCLFVBQUFBLEdBQUcsRUFBRTtBQUFFTCxZQUFBQSxNQUFGO0FBQVVDLFlBQUFBLElBQVY7QUFBZ0JDLFlBQUFBO0FBQWhCO0FBSG9ELFNBQWpDLENBQTFCO0FBTUEsY0FBTTtBQUFFSSxVQUFBQSxZQUFGO0FBQWdCQyxVQUFBQTtBQUFoQixZQUE2QixNQUFNQyxnQkFBZ0IsQ0FBQ0MsWUFBakIsQ0FDdkMsT0FEdUMsa0NBRWxDTixXQUZrQztBQUVyQmMsVUFBQUE7QUFGcUIsWUFHdkNqQixNQUh1QyxFQUl2Q0MsSUFKdUMsRUFLdkNDLElBTHVDLENBQXpDO0FBUUFKLFFBQUFBLE9BQU8sQ0FBQ0ksSUFBUixDQUFhSSxZQUFiLEdBQTRCQSxZQUE1QjtBQUVBLGVBQU87QUFDTGIsVUFBQUEsTUFBTSxFQUFFLE1BQU0sMkNBQ1pLLE9BRFksRUFFWkMsWUFGWSxFQUdaLGNBSFksRUFJWlEsUUFKWTtBQURULFNBQVA7QUFRRCxPQTVCRCxDQTRCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQTFFb0QsR0FBN0IsQ0FBMUI7QUE2RUE3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VJLGlCQUFpQixDQUFDbkIsSUFBbEIsQ0FBdUJnQixLQUF2QixDQUE2QnhCLElBQTdCLENBQWtDeUIsTUFEcEMsRUFFRSxJQUZGLEVBR0UsSUFIRjtBQUtBakMsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQ0ksaUJBQWlCLENBQUMzQixJQUFwRCxFQUEwRCxJQUExRCxFQUFnRSxJQUFoRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUNFLFdBREYsRUFFRUMsaUJBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU9BLFFBQU1VLGFBQWEsR0FBRyxnREFBNkI7QUFDakQxQyxJQUFBQSxJQUFJLEVBQUUsT0FEMkM7QUFFakRDLElBQUFBLFdBQVcsRUFBRSw0REFGb0M7QUFHakRDLElBQUFBLFdBQVcsRUFBRTtBQUNYeUMsTUFBQUEsUUFBUSxFQUFFO0FBQ1IxQyxRQUFBQSxXQUFXLEVBQUUsK0NBREw7QUFFUkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1Ca0Msc0JBQW5CO0FBRkUsT0FEQztBQUtYQyxNQUFBQSxRQUFRLEVBQUU7QUFDUjVDLFFBQUFBLFdBQVcsRUFBRSwrQ0FETDtBQUVSSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJrQyxzQkFBbkI7QUFGRTtBQUxDLEtBSG9DO0FBYWpEcEMsSUFBQUEsWUFBWSxFQUFFO0FBQ1pDLE1BQUFBLE1BQU0sRUFBRTtBQUNOUixRQUFBQSxXQUFXLEVBQ1Qsd0VBRkk7QUFHTkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1CYixrQkFBa0IsQ0FBQ2MsVUFBdEM7QUFIQTtBQURJLEtBYm1DO0FBb0JqREMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBT0MsSUFBUCxFQUFhQyxPQUFiLEVBQXNCQyxZQUF0QixLQUF1QztBQUMxRCxVQUFJO0FBQ0YsY0FBTTtBQUFFNEIsVUFBQUEsUUFBRjtBQUFZRSxVQUFBQTtBQUFaLFlBQXlCaEMsSUFBL0I7QUFDQSxjQUFNO0FBQUVHLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUEsSUFBVjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBeUJKLE9BQS9CO0FBRUEsY0FBTTtBQUFFUSxVQUFBQSxZQUFGO0FBQWdCQyxVQUFBQTtBQUFoQixZQUE2QixDQUNqQyxNQUFNN0IsV0FBVyxDQUFDb0QsV0FBWixDQUF3QjtBQUM1QkMsVUFBQUEsSUFBSSxFQUFFO0FBQ0pKLFlBQUFBLFFBREk7QUFFSkUsWUFBQUE7QUFGSSxXQURzQjtBQUs1QkcsVUFBQUEsS0FBSyxFQUFFLEVBTHFCO0FBTTVCaEMsVUFBQUEsTUFONEI7QUFPNUJDLFVBQUFBLElBUDRCO0FBUTVCQyxVQUFBQTtBQVI0QixTQUF4QixDQUQyQixFQVdqQytCLFFBWEY7QUFhQW5DLFFBQUFBLE9BQU8sQ0FBQ0ksSUFBUixDQUFhSSxZQUFiLEdBQTRCQSxZQUE1QjtBQUVBLGVBQU87QUFDTGIsVUFBQUEsTUFBTSxFQUFFLE1BQU0sMkNBQ1pLLE9BRFksRUFFWkMsWUFGWSxFQUdaLGNBSFksRUFJWlEsUUFKWTtBQURULFNBQVA7QUFRRCxPQTNCRCxDQTJCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQW5EZ0QsR0FBN0IsQ0FBdEI7QUFzREE3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VjLGFBQWEsQ0FBQzdCLElBQWQsQ0FBbUJnQixLQUFuQixDQUF5QnhCLElBQXpCLENBQThCeUIsTUFEaEMsRUFFRSxJQUZGLEVBR0UsSUFIRjtBQUtBakMsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQ2MsYUFBYSxDQUFDckMsSUFBaEQsRUFBc0QsSUFBdEQsRUFBNEQsSUFBNUQ7QUFDQVIsRUFBQUEsa0JBQWtCLENBQUNrQyxrQkFBbkIsQ0FBc0MsT0FBdEMsRUFBK0NXLGFBQS9DLEVBQThELElBQTlELEVBQW9FLElBQXBFO0FBRUEsUUFBTVEsY0FBYyxHQUFHLGdEQUE2QjtBQUNsRGxELElBQUFBLElBQUksRUFBRSxRQUQ0QztBQUVsREMsSUFBQUEsV0FBVyxFQUFFLDhEQUZxQztBQUdsRE8sSUFBQUEsWUFBWSxFQUFFO0FBQ1pDLE1BQUFBLE1BQU0sRUFBRTtBQUNOUixRQUFBQSxXQUFXLEVBQ1QseUVBRkk7QUFHTkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1CYixrQkFBa0IsQ0FBQ2MsVUFBdEM7QUFIQTtBQURJLEtBSG9DO0FBVWxEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPdUMsS0FBUCxFQUFjckMsT0FBZCxFQUF1QkMsWUFBdkIsS0FBd0M7QUFDM0QsVUFBSTtBQUNGLGNBQU07QUFBRUMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNTCxNQUFNLEdBQUcsTUFBTSwyQ0FDbkJLLE9BRG1CLEVBRW5CQyxZQUZtQixFQUduQixjQUhtQixFQUluQkUsSUFBSSxDQUFDbUMsSUFBTCxDQUFVQyxFQUpTLENBQXJCO0FBT0EsY0FBTTNELFdBQVcsQ0FBQzRELFlBQVosQ0FBeUI7QUFDN0J0QyxVQUFBQSxNQUQ2QjtBQUU3QkMsVUFBQUEsSUFGNkI7QUFHN0JDLFVBQUFBO0FBSDZCLFNBQXpCLENBQU47QUFNQSxlQUFPO0FBQUVULFVBQUFBO0FBQUYsU0FBUDtBQUNELE9BakJELENBaUJFLE9BQU9pQixDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQS9CaUQsR0FBN0IsQ0FBdkI7QUFrQ0E3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VzQixjQUFjLENBQUNyQyxJQUFmLENBQW9CZ0IsS0FBcEIsQ0FBMEJ4QixJQUExQixDQUErQnlCLE1BRGpDLEVBRUUsSUFGRixFQUdFLElBSEY7QUFLQWpDLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FBa0NzQixjQUFjLENBQUM3QyxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxRQUF0QyxFQUFnRG1CLGNBQWhELEVBQWdFLElBQWhFLEVBQXNFLElBQXRFO0FBRUEsUUFBTUsscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pEdkQsSUFBQUEsSUFBSSxFQUFFLGVBRG1EO0FBRXpEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHVEO0FBSXpEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWHNELE1BQUFBLEtBQUssRUFBRTtBQUNMcEQsUUFBQUEsWUFBWSxFQUFFLHVEQURUO0FBRUxDLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmtDLHNCQUFuQjtBQUZEO0FBREksS0FKNEM7QUFVekRwQyxJQUFBQSxZQUFZLEVBQUU7QUFDWmlELE1BQUFBLEVBQUUsRUFBRTtBQUNGeEQsUUFBQUEsV0FBVyxFQUFFLG1CQURYO0FBRUZJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmdELHVCQUFuQjtBQUZKO0FBRFEsS0FWMkM7QUFnQnpEOUMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBTztBQUFFNEMsTUFBQUE7QUFBRixLQUFQLEVBQWtCMUMsT0FBbEIsS0FBOEI7QUFDakQsWUFBTTtBQUFFRSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCSixPQUEvQjtBQUVBLFlBQU1wQixXQUFXLENBQUNpRSxrQkFBWixDQUErQjtBQUNuQ1osUUFBQUEsSUFBSSxFQUFFO0FBQ0pTLFVBQUFBO0FBREksU0FENkI7QUFJbkN4QyxRQUFBQSxNQUptQztBQUtuQ0MsUUFBQUEsSUFMbUM7QUFNbkNDLFFBQUFBO0FBTm1DLE9BQS9CLENBQU47QUFTQSxhQUFPO0FBQUV1QyxRQUFBQSxFQUFFLEVBQUU7QUFBTixPQUFQO0FBQ0Q7QUE3QndELEdBQTdCLENBQTlCO0FBZ0NBNUQsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUNFMkIscUJBQXFCLENBQUMxQyxJQUF0QixDQUEyQmdCLEtBQTNCLENBQWlDeEIsSUFBakMsQ0FBc0N5QixNQUR4QyxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDMkIscUJBQXFCLENBQUNsRCxJQUF4RCxFQUE4RCxJQUE5RCxFQUFvRSxJQUFwRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUNFLGVBREYsRUFFRXdCLHFCQUZGLEVBR0UsSUFIRixFQUlFLElBSkY7QUFPQSxRQUFNSyw2QkFBNkIsR0FBRyxnREFBNkI7QUFDakU1RCxJQUFBQSxJQUFJLEVBQUUsdUJBRDJEO0FBRWpFQyxJQUFBQSxXQUFXLEVBQ1Qsc0ZBSCtEO0FBSWpFQyxJQUFBQSxXQUFXLEVBQUU7QUFDWHNELE1BQUFBLEtBQUssRUFBRTtBQUNMcEQsUUFBQUEsWUFBWSxFQUNWLDhEQUZHO0FBR0xDLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmtDLHNCQUFuQjtBQUhEO0FBREksS0FKb0Q7QUFXakVwQyxJQUFBQSxZQUFZLEVBQUU7QUFDWmlELE1BQUFBLEVBQUUsRUFBRTtBQUNGeEQsUUFBQUEsV0FBVyxFQUFFLG1CQURYO0FBRUZJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmdELHVCQUFuQjtBQUZKO0FBRFEsS0FYbUQ7QUFpQmpFOUMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBTztBQUFFNEMsTUFBQUE7QUFBRixLQUFQLEVBQWtCMUMsT0FBbEIsS0FBOEI7QUFDakQsVUFBSTtBQUNGLGNBQU07QUFBRUUsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNcEIsV0FBVyxDQUFDbUUsOEJBQVosQ0FBMkM7QUFDL0NkLFVBQUFBLElBQUksRUFBRTtBQUNKUyxZQUFBQTtBQURJLFdBRHlDO0FBSS9DeEMsVUFBQUEsTUFKK0M7QUFLL0NDLFVBQUFBLElBTCtDO0FBTS9DQyxVQUFBQTtBQU4rQyxTQUEzQyxDQUFOO0FBU0EsZUFBTztBQUFFdUMsVUFBQUEsRUFBRSxFQUFFO0FBQU4sU0FBUDtBQUNELE9BYkQsQ0FhRSxPQUFPL0IsQ0FBUCxFQUFVO0FBQ1Y3QixRQUFBQSxrQkFBa0IsQ0FBQzhCLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUFsQ2dFLEdBQTdCLENBQXRDO0FBcUNBN0IsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUNFZ0MsNkJBQTZCLENBQUMvQyxJQUE5QixDQUFtQ2dCLEtBQW5DLENBQXlDeEIsSUFBekMsQ0FBOEN5QixNQURoRCxFQUVFLElBRkYsRUFHRSxJQUhGO0FBS0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQ0VnQyw2QkFBNkIsQ0FBQ3ZELElBRGhDLEVBRUUsSUFGRixFQUdFLElBSEY7QUFLQVIsRUFBQUEsa0JBQWtCLENBQUNrQyxrQkFBbkIsQ0FDRSx1QkFERixFQUVFNkIsNkJBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU1ELENBdFdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxTdHJpbmcsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMSW5wdXRPYmplY3RUeXBlLFxufSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCBVc2Vyc1JvdXRlciBmcm9tICcuLi8uLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcbmltcG9ydCAqIGFzIG9iamVjdHNNdXRhdGlvbnMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzTXV0YXRpb25zJztcbmltcG9ydCB7IE9CSkVDVCB9IGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgeyBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbiB9IGZyb20gJy4vdXNlcnNRdWVyaWVzJztcbmltcG9ydCB7IHRyYW5zZm9ybVR5cGVzIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL211dGF0aW9uJztcblxuY29uc3QgdXNlcnNSb3V0ZXIgPSBuZXcgVXNlcnNSb3V0ZXIoKTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGlmIChwYXJzZUdyYXBoUUxTY2hlbWEuaXNVc2Vyc0NsYXNzRGlzYWJsZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBzaWduVXBNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdTaWduVXAnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBzaWduVXAgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGFuZCBzaWduIHVwIGEgbmV3IHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczpcbiAgICAgICAgICAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgb2YgdGhlIG5ldyB1c2VyIHRvIGJlIGNyZWF0ZWQgYW5kIHNpZ25lZCB1cC4nLFxuICAgICAgICB0eXBlOlxuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbJ19Vc2VyJ10uY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhpcyBpcyB0aGUgbmV3IHVzZXIgdGhhdCB3YXMgY3JlYXRlZCwgc2lnbmVkIHVwIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgeyBzZXNzaW9uVG9rZW4sIG9iamVjdElkIH0gPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm9cbiAgICAgICAgKTtcblxuICAgICAgICBjb250ZXh0LmluZm8uc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmlld2VyOiBhd2FpdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbihcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBtdXRhdGlvbkluZm8sXG4gICAgICAgICAgICAndmlld2VyLnVzZXIuJyxcbiAgICAgICAgICAgIG9iamVjdElkXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBzaWduVXBNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoc2lnblVwTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ3NpZ25VcCcsIHNpZ25VcE11dGF0aW9uLCB0cnVlLCB0cnVlKTtcbiAgY29uc3QgbG9nSW5XaXRoTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnTG9nSW5XaXRoJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgbG9nSW5XaXRoIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIHNpZ251cCwgbG9naW4gdXNlciB3aXRoIDNyZCBwYXJ0eSBhdXRoZW50aWNhdGlvbiBzeXN0ZW0uIFRoaXMgbXV0YXRpb24gY3JlYXRlIGEgdXNlciBpZiB0aGUgYXV0aERhdGEgZG8gbm90IGNvcnJlc3BvbmQgdG8gYW4gZXhpc3Rpbmcgb25lLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIGF1dGhEYXRhOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczogJ1RoaXMgaXMgdGhlIGF1dGggZGF0YSBvZiB5b3VyIGN1c3RvbSBhdXRoIHByb3ZpZGVyJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKE9CSkVDVCksXG4gICAgICB9LFxuICAgICAgZmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczpcbiAgICAgICAgICAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgb2YgdGhlIHVzZXIgdG8gYmUgY3JlYXRlZC91cGRhdGVkIGFuZCBsb2dnZWQgaW4uJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgICAgICAgIG5hbWU6ICdVc2VyTG9naW5XaXRoSW5wdXQnLFxuICAgICAgICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlRmllbGRzID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tcbiAgICAgICAgICAgICAgJ19Vc2VyJ1xuICAgICAgICAgICAgXS5jbGFzc0dyYXBoUUxDcmVhdGVUeXBlLmdldEZpZWxkcygpO1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNsYXNzR3JhcGhRTENyZWF0ZUZpZWxkcykucmVkdWNlKFxuICAgICAgICAgICAgICAoZmllbGRzLCBmaWVsZE5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICBmaWVsZE5hbWUgIT09ICdwYXNzd29yZCcgJiZcbiAgICAgICAgICAgICAgICAgIGZpZWxkTmFtZSAhPT0gJ3VzZXJuYW1lJyAmJlxuICAgICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAnYXV0aERhdGEnXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZHNbZmllbGROYW1lXSA9IGNsYXNzR3JhcGhRTENyZWF0ZUZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7fVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhpcyBpcyB0aGUgbmV3IHVzZXIgdGhhdCB3YXMgY3JlYXRlZCwgc2lnbmVkIHVwIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRzLCBhdXRoRGF0YSB9ID0gYXJncztcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgY29uc3QgcGFyc2VGaWVsZHMgPSBhd2FpdCB0cmFuc2Zvcm1UeXBlcygnY3JlYXRlJywgZmllbGRzLCB7XG4gICAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHsgc2Vzc2lvblRva2VuLCBvYmplY3RJZCB9ID0gYXdhaXQgb2JqZWN0c011dGF0aW9ucy5jcmVhdGVPYmplY3QoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7IC4uLnBhcnNlRmllbGRzLCBhdXRoRGF0YSB9LFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm9cbiAgICAgICAgKTtcblxuICAgICAgICBjb250ZXh0LmluZm8uc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmlld2VyOiBhd2FpdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbihcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBtdXRhdGlvbkluZm8sXG4gICAgICAgICAgICAndmlld2VyLnVzZXIuJyxcbiAgICAgICAgICAgIG9iamVjdElkXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBsb2dJbldpdGhNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nSW5XaXRoTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oXG4gICAgJ2xvZ0luV2l0aCcsXG4gICAgbG9nSW5XaXRoTXV0YXRpb24sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG5cbiAgY29uc3QgbG9nSW5NdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdMb2dJbicsXG4gICAgZGVzY3JpcHRpb246ICdUaGUgbG9nSW4gbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gbG9nIGluIGFuIGV4aXN0aW5nIHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgdXNlcm5hbWU6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1c2VybmFtZSB1c2VkIHRvIGxvZyBpbiB0aGUgdXNlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgICAgcGFzc3dvcmQ6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBwYXNzd29yZCB1c2VkIHRvIGxvZyBpbiB0aGUgdXNlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICB2aWV3ZXI6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoaXMgaXMgdGhlIGV4aXN0aW5nIHVzZXIgdGhhdCB3YXMgbG9nZ2VkIGluIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCB7IHNlc3Npb25Ub2tlbiwgb2JqZWN0SWQgfSA9IChcbiAgICAgICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVMb2dJbih7XG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBxdWVyeToge30sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICB9KVxuICAgICAgICApLnJlc3BvbnNlO1xuXG4gICAgICAgIGNvbnRleHQuaW5mby5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uVG9rZW47XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2aWV3ZXI6IGF3YWl0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuKFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIG11dGF0aW9uSW5mbyxcbiAgICAgICAgICAgICd2aWV3ZXIudXNlci4nLFxuICAgICAgICAgICAgb2JqZWN0SWRcbiAgICAgICAgICApLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIGxvZ0luTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGxvZ0luTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2xvZ0luJywgbG9nSW5NdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgY29uc3QgbG9nT3V0TXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnTG9nT3V0JyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBsb2dPdXQgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gbG9nIG91dCBhbiBleGlzdGluZyB1c2VyLicsXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICB2aWV3ZXI6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoaXMgaXMgdGhlIGV4aXN0aW5nIHVzZXIgdGhhdCB3YXMgbG9nZ2VkIG91dCBhbmQgcmV0dXJuZWQgYXMgYSB2aWV3ZXIuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHBhcnNlR3JhcGhRTFNjaGVtYS52aWV3ZXJUeXBlKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoX2FyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgY29uc3Qgdmlld2VyID0gYXdhaXQgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4oXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBtdXRhdGlvbkluZm8sXG4gICAgICAgICAgJ3ZpZXdlci51c2VyLicsXG4gICAgICAgICAgYXV0aC51c2VyLmlkXG4gICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgdXNlcnNSb3V0ZXIuaGFuZGxlTG9nT3V0KHtcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyB2aWV3ZXIgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBsb2dPdXRNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nT3V0TXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2xvZ091dCcsIGxvZ091dE11dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCByZXNldFBhc3N3b3JkTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnUmVzZXRQYXNzd29yZCcsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhlIHJlc2V0UGFzc3dvcmQgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gcmVzZXQgdGhlIHBhc3N3b3JkIG9mIGFuIGV4aXN0aW5nIHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZW1haWw6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOiAnRW1haWwgb2YgdGhlIHVzZXIgdGhhdCBzaG91bGQgcmVjZWl2ZSB0aGUgcmVzZXQgZW1haWwnLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBvazoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJdCdzIGFsd2F5cyB0cnVlLlwiLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jICh7IGVtYWlsIH0sIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVSZXNldFJlcXVlc3Qoe1xuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgZW1haWwsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgaW5mbyxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICByZXNldFBhc3N3b3JkTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHJlc2V0UGFzc3dvcmRNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAncmVzZXRQYXNzd29yZCcsXG4gICAgcmVzZXRQYXNzd29yZE11dGF0aW9uLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIGNvbnN0IHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ1NlbmRWZXJpZmljYXRpb25FbWFpbCcsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhlIHNlbmRWZXJpZmljYXRpb25FbWFpbCBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBzZW5kIHRoZSB2ZXJpZmljYXRpb24gZW1haWwgYWdhaW4uJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZW1haWw6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOlxuICAgICAgICAgICdFbWFpbCBvZiB0aGUgdXNlciB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSB2ZXJpZmljYXRpb24gZW1haWwnLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBvazoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJdCdzIGFsd2F5cyB0cnVlLlwiLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jICh7IGVtYWlsIH0sIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGF3YWl0IHVzZXJzUm91dGVyLmhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCh7XG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShcbiAgICBzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbi50eXBlLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKFxuICAgICdzZW5kVmVyaWZpY2F0aW9uRW1haWwnLFxuICAgIHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uLFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersQueries.js b/lib/GraphQL/loaders/usersQueries.js deleted file mode 100644 index f12a5633f4..0000000000 --- a/lib/GraphQL/loaders/usersQueries.js +++ /dev/null @@ -1,111 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getUserFromSessionToken = exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _rest = _interopRequireDefault(require("../../rest")); - -var _parseClassTypes = require("./parseClassTypes"); - -var _Auth = require("../../Auth"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const getUserFromSessionToken = async (context, queryInfo, keysPrefix, userId) => { - const { - info, - config - } = context; - - if (!info || !info.sessionToken) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - const sessionToken = info.sessionToken; - const selectedFields = (0, _graphqlListFields.default)(queryInfo).filter(field => field.startsWith(keysPrefix)).map(field => field.replace(keysPrefix, '')); - const keysAndInclude = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); - const { - keys - } = keysAndInclude; - let { - include - } = keysAndInclude; - - if (userId && !keys && !include) { - return { - sessionToken - }; - } else if (keys && !include) { - include = 'user'; - } - - if (userId) { - // We need to re create the auth context - // to avoid security breach if userId is provided - context.auth = new _Auth.Auth({ - config, - isMaster: context.auth.isMaster, - user: { - id: userId - } - }); - } - - const options = {}; - - if (keys) { - options.keys = keys.split(',').map(key => `${key}`).join(','); - } - - if (include) { - options.include = include.split(',').map(included => `${included}`).join(','); - } - - const response = await _rest.default.find(config, context.auth, '_User', // Get the user it self from auth object - { - objectId: context.auth.user.id - }, options, info.clientVersion, info.context); - - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } else { - const user = response.results[0]; - return { - sessionToken, - user - }; - } -}; - -exports.getUserFromSessionToken = getUserFromSessionToken; - -const load = parseGraphQLSchema => { - if (parseGraphQLSchema.isUsersClassDisabled) { - return; - } - - parseGraphQLSchema.addGraphQLQuery('viewer', { - description: 'The viewer query can be used to return the current user data.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType), - - async resolve(_source, _args, context, queryInfo) { - try { - return await getUserFromSessionToken(context, queryInfo, 'user.', false); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - }, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImdldFVzZXJGcm9tU2Vzc2lvblRva2VuIiwiY29udGV4dCIsInF1ZXJ5SW5mbyIsImtleXNQcmVmaXgiLCJ1c2VySWQiLCJpbmZvIiwiY29uZmlnIiwic2Vzc2lvblRva2VuIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsInNlbGVjdGVkRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsImtleXNBbmRJbmNsdWRlIiwia2V5cyIsImluY2x1ZGUiLCJhdXRoIiwiQXV0aCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwib3B0aW9ucyIsInNwbGl0Iiwia2V5Iiwiam9pbiIsImluY2x1ZGVkIiwicmVzcG9uc2UiLCJyZXN0IiwiZmluZCIsIm9iamVjdElkIiwiY2xpZW50VmVyc2lvbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2FkIiwicGFyc2VHcmFwaFFMU2NoZW1hIiwiaXNVc2Vyc0NsYXNzRGlzYWJsZWQiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsInZpZXdlclR5cGUiLCJyZXNvbHZlIiwiX3NvdXJjZSIsIl9hcmdzIiwiZSIsImhhbmRsZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSx1QkFBdUIsR0FBRyxPQUM5QkMsT0FEOEIsRUFFOUJDLFNBRjhCLEVBRzlCQyxVQUg4QixFQUk5QkMsTUFKOEIsS0FLM0I7QUFDSCxRQUFNO0FBQUVDLElBQUFBLElBQUY7QUFBUUMsSUFBQUE7QUFBUixNQUFtQkwsT0FBekI7O0FBQ0EsTUFBSSxDQUFDSSxJQUFELElBQVMsQ0FBQ0EsSUFBSSxDQUFDRSxZQUFuQixFQUFpQztBQUMvQixVQUFNLElB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QUFuQixDQUNFLFFBREYsRUFFRTtBQUNFQyxJQUFBQSxXQUFXLEVBQ1QsK0RBRko7QUFHRUMsSUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CTCxrQkFBa0IsQ0FBQ00sVUFBdEMsQ0FIUjs7QUFJRSxVQUFNQyxPQUFOLENBQWNDLE9BQWQsRUFBdUJDLEtBQXZCLEVBQThCOUMsT0FBOUIsRUFBdUNDLFNBQXZDLEVBQWtEO0FBQ2hELFVBQUk7QUFDRixlQUFPLE1BQU1GLHVCQUF1QixDQUNsQ0MsT0FEa0MsRUFFbENDLFNBRmtDLEVBR2xDLE9BSGtDLEVBSWxDLEtBSmtDLENBQXBDO0FBTUQsT0FQRCxDQU9FLE9BQU84QyxDQUFQLEVBQVU7QUFDVlYsUUFBQUEsa0JBQWtCLENBQUNXLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7O0FBZkgsR0FGRixFQW1CRSxJQW5CRixFQW9CRSxJQXBCRjtBQXNCRCxDQTNCRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEdyYXBoUUxOb25OdWxsIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuaW1wb3J0IHsgZXh0cmFjdEtleXNBbmRJbmNsdWRlIH0gZnJvbSAnLi9wYXJzZUNsYXNzVHlwZXMnO1xuaW1wb3J0IHsgQXV0aCB9IGZyb20gJy4uLy4uL0F1dGgnO1xuXG5jb25zdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbiA9IGFzeW5jIChcbiAgY29udGV4dCxcbiAgcXVlcnlJbmZvLFxuICBrZXlzUHJlZml4LFxuICB1c2VySWRcbikgPT4ge1xuICBjb25zdCB7IGluZm8sIGNvbmZpZyB9ID0gY29udGV4dDtcbiAgaWYgKCFpbmZvIHx8ICFpbmZvLnNlc3Npb25Ub2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTixcbiAgICAgICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nXG4gICAgKTtcbiAgfVxuICBjb25zdCBzZXNzaW9uVG9rZW4gPSBpbmZvLnNlc3Npb25Ub2tlbjtcbiAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbylcbiAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoa2V5c1ByZWZpeCkpXG4gICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKGtleXNQcmVmaXgsICcnKSk7XG5cbiAgY29uc3Qga2V5c0FuZEluY2x1ZGUgPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuICBjb25zdCB7IGtleXMgfSA9IGtleXNBbmRJbmNsdWRlO1xuICBsZXQgeyBpbmNsdWRlIH0gPSBrZXlzQW5kSW5jbHVkZTtcblxuICBpZiAodXNlcklkICYmICFrZXlzICYmICFpbmNsdWRlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlc3Npb25Ub2tlbixcbiAgICB9O1xuICB9IGVsc2UgaWYgKGtleXMgJiYgIWluY2x1ZGUpIHtcbiAgICBpbmNsdWRlID0gJ3VzZXInO1xuICB9XG5cbiAgaWYgKHVzZXJJZCkge1xuICAgIC8vIFdlIG5lZWQgdG8gcmUgY3JlYXRlIHRoZSBhdXRoIGNvbnRleHRcbiAgICAvLyB0byBhdm9pZCBzZWN1cml0eSBicmVhY2ggaWYgdXNlcklkIGlzIHByb3ZpZGVkXG4gICAgY29udGV4dC5hdXRoID0gbmV3IEF1dGgoe1xuICAgICAgY29uZmlnLFxuICAgICAgaXNNYXN0ZXI6IGNvbnRleHQuYXV0aC5pc01hc3RlcixcbiAgICAgIHVzZXI6IHsgaWQ6IHVzZXJJZCB9LFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICBpZiAoa2V5cykge1xuICAgIG9wdGlvbnMua2V5cyA9IGtleXNcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAubWFwKGtleSA9PiBgJHtrZXl9YClcbiAgICAgIC5qb2luKCcsJyk7XG4gIH1cbiAgaWYgKGluY2x1ZGUpIHtcbiAgICBvcHRpb25zLmluY2x1ZGUgPSBpbmNsdWRlXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcChpbmNsdWRlZCA9PiBgJHtpbmNsdWRlZH1gKVxuICAgICAgLmpvaW4oJywnKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVzdC5maW5kKFxuICAgIGNvbmZpZyxcbiAgICBjb250ZXh0LmF1dGgsXG4gICAgJ19Vc2VyJyxcbiAgICAvLyBHZXQgdGhlIHVzZXIgaXQgc2VsZiBmcm9tIGF1dGggb2JqZWN0XG4gICAgeyBvYmplY3RJZDogY29udGV4dC5hdXRoLnVzZXIuaWQgfSxcbiAgICBvcHRpb25zLFxuICAgIGluZm8uY2xpZW50VmVyc2lvbixcbiAgICBpbmZvLmNvbnRleHRcbiAgKTtcbiAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sXG4gICAgICAnSW52YWxpZCBzZXNzaW9uIHRva2VuJ1xuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlc3Npb25Ub2tlbixcbiAgICAgIHVzZXIsXG4gICAgfTtcbiAgfVxufTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGlmIChwYXJzZUdyYXBoUUxTY2hlbWEuaXNVc2Vyc0NsYXNzRGlzYWJsZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICd2aWV3ZXInLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIHZpZXdlciBxdWVyeSBjYW4gYmUgdXNlZCB0byByZXR1cm4gdGhlIGN1cnJlbnQgdXNlciBkYXRhLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgYXN5bmMgcmVzb2x2ZShfc291cmNlLCBfYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuKFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICAgICd1c2VyLicsXG4gICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCB7IGxvYWQsIGdldFVzZXJGcm9tU2Vzc2lvblRva2VuIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/parseGraphQLUtils.js b/lib/GraphQL/parseGraphQLUtils.js deleted file mode 100644 index 3677a6ca26..0000000000 --- a/lib/GraphQL/parseGraphQLUtils.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.enforceMasterKeyAccess = enforceMasterKeyAccess; -exports.toGraphQLError = toGraphQLError; -exports.getParseClassMutationConfig = exports.extractKeysAndInclude = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _apolloServerCore = require("apollo-server-core"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function enforceMasterKeyAccess(auth) { - if (!auth.isMaster) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, 'unauthorized: master key is required'); - } -} - -function toGraphQLError(error) { - let code, message; - - if (error instanceof _node.default.Error) { - code = error.code; - message = error.message; - } else { - code = _node.default.Error.INTERNAL_SERVER_ERROR; - message = 'Internal server error'; - } - - return new _apolloServerCore.ApolloError(message, code); -} - -const extractKeysAndInclude = selectedFields => { - selectedFields = selectedFields.filter(field => !field.includes('__typename')); // Handles "id" field for both current and included objects - - selectedFields = selectedFields.map(field => { - if (field === 'id') return 'objectId'; - return field.endsWith('.id') ? `${field.substring(0, field.lastIndexOf('.id'))}.objectId` : field; - }); - let keys = undefined; - let include = undefined; - - if (selectedFields.length > 0) { - keys = [...new Set(selectedFields)].join(','); // We can use this shortcut since optimization is handled - // later on RestQuery, avoid overhead here. - - include = keys; - } - - return { - // If authData is detected keys will not work properly - // since authData has a special storage behavior - // so we need to skip keys currently - keys: keys && keys.indexOf('authData') === -1 ? keys : undefined, - include - }; -}; - -exports.extractKeysAndInclude = extractKeysAndInclude; - -const getParseClassMutationConfig = function (parseClassConfig) { - return parseClassConfig && parseClassConfig.mutation || {}; -}; - -exports.getParseClassMutationConfig = getParseClassMutationConfig; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML3BhcnNlR3JhcGhRTFV0aWxzLmpzIl0sIm5hbWVzIjpbImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJhdXRoIiwiaXNNYXN0ZXIiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInRvR3JhcGhRTEVycm9yIiwiZXJyb3IiLCJjb2RlIiwibWVzc2FnZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIkFwb2xsb0Vycm9yIiwiZXh0cmFjdEtleXNBbmRJbmNsdWRlIiwic2VsZWN0ZWRGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwibWFwIiwiZW5kc1dpdGgiLCJzdWJzdHJpbmciLCJsYXN0SW5kZXhPZiIsImtleXMiLCJ1bmRlZmluZWQiLCJpbmNsdWRlIiwibGVuZ3RoIiwiU2V0Iiwiam9pbiIsImluZGV4T2YiLCJnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWciLCJwYXJzZUNsYXNzQ29uZmlnIiwibXV0YXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sU0FBU0Esc0JBQVQsQ0FBZ0NDLElBQWhDLEVBQXNDO0FBQzNDLE1BQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFWLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxtQkFBNUIsRUFBaUQsc0NBQWpELENBQU47QUFDRDtBQUNGOztBQUVNLFNBQVNDLGNBQVQsQ0FBd0JDLEtBQXhCLEVBQStCO0FBQ3BDLE1BQUlDLElBQUosRUFBVUMsT0FBVjs7QUFDQSxNQUFJRixLQUFLLFlBQVlKLGNBQU1DLEtBQTNCLEVBQWtDO0FBQ2hDSSxJQUFBQSxJQUFJLEdBQUdELEtBQUssQ0FBQ0MsSUFBYjtBQUNBQyxJQUFBQSxPQUFPLEdBQUdGLEtBQUssQ0FBQ0UsT0FBaEI7QUFDRCxHQUhELE1BR087QUFDTEQsSUFBQUEsSUFBSSxHQUFHTCxjQUFNQyxLQUFOLENBQVlNLHFCQUFuQjtBQUNBRCxJQUFBQSxPQUFPLEdBQUcsdUJBQVY7QUFDRDs7QUFDRCxTQUFPLElBQUlFLDZCQUFKLENBQWdCRixPQUFoQixFQUF5QkQsSUFBekIsQ0FBUDtBQUNEOztBQUVNLE1BQU1JLHFCQUFxQixHQUFHQyxjQUFjLElBQUk7QUFDckRBLEVBQUFBLGNBQWMsR0FBR0EsY0FBYyxDQUFDQyxNQUFmLENBQXNCQyxLQUFLLElBQUksQ0FBQ0EsS0FBSyxDQUFDQyxRQUFOLENBQWUsWUFBZixDQUFoQyxDQUFqQixDQURxRCxDQUVyRDs7QUFDQUgsRUFBQUEsY0FBYyxHQUFHQSxjQUFjLENBQUNJLEdBQWYsQ0FBbUJGLEtBQUssSUFBSTtBQUMzQyxRQUFJQSxLQUFLLEtBQUssSUFBZCxFQUFvQixPQUFPLFVBQVA7QUFDcEIsV0FBT0EsS0FBSyxDQUFDRyxRQUFOLENBQWUsS0FBZixJQUNGLEdBQUVILEtBQUssQ0FBQ0ksU0FBTixDQUFnQixDQUFoQixFQUFtQkosS0FBSyxDQUFDSyxXQUFOLENBQWtCLEtBQWxCLENBQW5CLENBQTZDLFdBRDdDLEdBRUhMLEtBRko7QUFHRCxHQUxnQixDQUFqQjtBQU1BLE1BQUlNLElBQUksR0FBR0MsU0FBWDtBQUNBLE1BQUlDLE9BQU8sR0FBR0QsU0FBZDs7QUFFQSxNQUFJVCxjQUFjLENBQUNXLE1BQWYsR0FBd0IsQ0FBNUIsRUFBK0I7QUFDN0JILElBQUFBLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSUksR0FBSixDQUFRWixjQUFSLENBQUosRUFBNkJhLElBQTdCLENBQWtDLEdBQWxDLENBQVAsQ0FENkIsQ0FFN0I7QUFDQTs7QUFDQUgsSUFBQUEsT0FBTyxHQUFHRixJQUFWO0FBQ0Q7O0FBRUQsU0FBTztBQUNMO0FBQ0E7QUFDQTtBQUNBQSxJQUFBQSxJQUFJLEVBQUVBLElBQUksSUFBSUEsSUFBSSxDQUFDTSxPQUFMLENBQWEsVUFBYixNQUE2QixDQUFDLENBQXRDLEdBQTBDTixJQUExQyxHQUFpREMsU0FKbEQ7QUFLTEMsSUFBQUE7QUFMSyxHQUFQO0FBT0QsQ0ExQk07Ozs7QUE0QkEsTUFBTUssMkJBQTJCLEdBQUcsVUFBVUMsZ0JBQVYsRUFBNEI7QUFDckUsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxRQUF0QyxJQUFtRCxFQUExRDtBQUNELENBRk0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBBcG9sbG9FcnJvciB9IGZyb20gJ2Fwb2xsby1zZXJ2ZXItY29yZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpIHtcbiAgaWYgKCFhdXRoLmlzTWFzdGVyKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9HcmFwaFFMRXJyb3IoZXJyb3IpIHtcbiAgbGV0IGNvZGUsIG1lc3NhZ2U7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgY29kZSA9IGVycm9yLmNvZGU7XG4gICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gIH0gZWxzZSB7XG4gICAgY29kZSA9IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjtcbiAgICBtZXNzYWdlID0gJ0ludGVybmFsIHNlcnZlciBlcnJvcic7XG4gIH1cbiAgcmV0dXJuIG5ldyBBcG9sbG9FcnJvcihtZXNzYWdlLCBjb2RlKTtcbn1cblxuZXhwb3J0IGNvbnN0IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSA9IHNlbGVjdGVkRmllbGRzID0+IHtcbiAgc2VsZWN0ZWRGaWVsZHMgPSBzZWxlY3RlZEZpZWxkcy5maWx0ZXIoZmllbGQgPT4gIWZpZWxkLmluY2x1ZGVzKCdfX3R5cGVuYW1lJykpO1xuICAvLyBIYW5kbGVzIFwiaWRcIiBmaWVsZCBmb3IgYm90aCBjdXJyZW50IGFuZCBpbmNsdWRlZCBvYmplY3RzXG4gIHNlbGVjdGVkRmllbGRzID0gc2VsZWN0ZWRGaWVsZHMubWFwKGZpZWxkID0+IHtcbiAgICBpZiAoZmllbGQgPT09ICdpZCcpIHJldHVybiAnb2JqZWN0SWQnO1xuICAgIHJldHVybiBmaWVsZC5lbmRzV2l0aCgnLmlkJylcbiAgICAgID8gYCR7ZmllbGQuc3Vic3RyaW5nKDAsIGZpZWxkLmxhc3RJbmRleE9mKCcuaWQnKSl9Lm9iamVjdElkYFxuICAgICAgOiBmaWVsZDtcbiAgfSk7XG4gIGxldCBrZXlzID0gdW5kZWZpbmVkO1xuICBsZXQgaW5jbHVkZSA9IHVuZGVmaW5lZDtcblxuICBpZiAoc2VsZWN0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgIGtleXMgPSBbLi4ubmV3IFNldChzZWxlY3RlZEZpZWxkcyldLmpvaW4oJywnKTtcbiAgICAvLyBXZSBjYW4gdXNlIHRoaXMgc2hvcnRjdXQgc2luY2Ugb3B0aW1pemF0aW9uIGlzIGhhbmRsZWRcbiAgICAvLyBsYXRlciBvbiBSZXN0UXVlcnksIGF2b2lkIG92ZXJoZWFkIGhlcmUuXG4gICAgaW5jbHVkZSA9IGtleXM7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC8vIElmIGF1dGhEYXRhIGlzIGRldGVjdGVkIGtleXMgd2lsbCBub3Qgd29yayBwcm9wZXJseVxuICAgIC8vIHNpbmNlIGF1dGhEYXRhIGhhcyBhIHNwZWNpYWwgc3RvcmFnZSBiZWhhdmlvclxuICAgIC8vIHNvIHdlIG5lZWQgdG8gc2tpcCBrZXlzIGN1cnJlbnRseVxuICAgIGtleXM6IGtleXMgJiYga2V5cy5pbmRleE9mKCdhdXRoRGF0YScpID09PSAtMSA/IGtleXMgOiB1bmRlZmluZWQsXG4gICAgaW5jbHVkZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcgPSBmdW5jdGlvbiAocGFyc2VDbGFzc0NvbmZpZykge1xuICByZXR1cm4gKHBhcnNlQ2xhc3NDb25maWcgJiYgcGFyc2VDbGFzc0NvbmZpZy5tdXRhdGlvbikgfHwge307XG59O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/className.js b/lib/GraphQL/transformers/className.js deleted file mode 100644 index a3b221d3fe..0000000000 --- a/lib/GraphQL/transformers/className.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformClassNameToGraphQL = void 0; - -const transformClassNameToGraphQL = className => { - if (className[0] === '_') { - className = className.slice(1); - } - - return className[0].toUpperCase() + className.slice(1); -}; - -exports.transformClassNameToGraphQL = transformClassNameToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jbGFzc05hbWUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMIiwiY2xhc3NOYW1lIiwic2xpY2UiLCJ0b1VwcGVyQ2FzZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLDJCQUEyQixHQUFHQyxTQUFTLElBQUk7QUFDL0MsTUFBSUEsU0FBUyxDQUFDLENBQUQsQ0FBVCxLQUFpQixHQUFyQixFQUEwQjtBQUN4QkEsSUFBQUEsU0FBUyxHQUFHQSxTQUFTLENBQUNDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBWjtBQUNEOztBQUNELFNBQU9ELFNBQVMsQ0FBQyxDQUFELENBQVQsQ0FBYUUsV0FBYixLQUE2QkYsU0FBUyxDQUFDQyxLQUFWLENBQWdCLENBQWhCLENBQXBDO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCA9IGNsYXNzTmFtZSA9PiB7XG4gIGlmIChjbGFzc05hbWVbMF0gPT09ICdfJykge1xuICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBjbGFzc05hbWUuc2xpY2UoMSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/constraintType.js b/lib/GraphQL/transformers/constraintType.js deleted file mode 100644 index 8303be5643..0000000000 --- a/lib/GraphQL/transformers/constraintType.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformConstraintTypeToGraphQL = void 0; - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const transformConstraintTypeToGraphQL = (parseType, targetClass, parseClassTypes, fieldName) => { - if (fieldName === 'id' || fieldName === 'objectId') { - return defaultGraphQLTypes.ID_WHERE_INPUT; - } - - switch (parseType) { - case 'String': - return defaultGraphQLTypes.STRING_WHERE_INPUT; - - case 'Number': - return defaultGraphQLTypes.NUMBER_WHERE_INPUT; - - case 'Boolean': - return defaultGraphQLTypes.BOOLEAN_WHERE_INPUT; - - case 'Array': - return defaultGraphQLTypes.ARRAY_WHERE_INPUT; - - case 'Object': - return defaultGraphQLTypes.OBJECT_WHERE_INPUT; - - case 'Date': - return defaultGraphQLTypes.DATE_WHERE_INPUT; - - case 'Pointer': - if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { - return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'File': - return defaultGraphQLTypes.FILE_WHERE_INPUT; - - case 'GeoPoint': - return defaultGraphQLTypes.GEO_POINT_WHERE_INPUT; - - case 'Polygon': - return defaultGraphQLTypes.POLYGON_WHERE_INPUT; - - case 'Bytes': - return defaultGraphQLTypes.BYTES_WHERE_INPUT; - - case 'ACL': - return defaultGraphQLTypes.OBJECT_WHERE_INPUT; - - case 'Relation': - if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { - return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - default: - return undefined; - } -}; - -exports.transformConstraintTypeToGraphQL = transformConstraintTypeToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jb25zdHJhaW50VHlwZS5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1Db25zdHJhaW50VHlwZVRvR3JhcGhRTCIsInBhcnNlVHlwZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwiZmllbGROYW1lIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIklEX1dIRVJFX0lOUFVUIiwiU1RSSU5HX1dIRVJFX0lOUFVUIiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiT0JKRUNUX1dIRVJFX0lOUFVUIiwiREFURV9XSEVSRV9JTlBVVCIsImNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlIiwiT0JKRUNUIiwiRklMRV9XSEVSRV9JTlBVVCIsIkdFT19QT0lOVF9XSEVSRV9JTlBVVCIsIlBPTFlHT05fV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7QUFFQSxNQUFNQSxnQ0FBZ0MsR0FBRyxDQUN2Q0MsU0FEdUMsRUFFdkNDLFdBRnVDLEVBR3ZDQyxlQUh1QyxFQUl2Q0MsU0FKdUMsS0FLcEM7QUFDSCxNQUFJQSxTQUFTLEtBQUssSUFBZCxJQUFzQkEsU0FBUyxLQUFLLFVBQXhDLEVBQW9EO0FBQ2xELFdBQU9DLG1CQUFtQixDQUFDQyxjQUEzQjtBQUNEOztBQUVELFVBQVFMLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPSSxtQkFBbUIsQ0FBQ0Usa0JBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9GLG1CQUFtQixDQUFDRyxrQkFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsYUFBT0gsbUJBQW1CLENBQUNJLG1CQUEzQjs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPSixtQkFBbUIsQ0FBQ0ssaUJBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9MLG1CQUFtQixDQUFDTSxrQkFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT04sbUJBQW1CLENBQUNPLGdCQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxVQUNFVCxlQUFlLENBQUNELFdBQUQsQ0FBZixJQUNBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBRi9CLEVBR0U7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBQXBDO0FBQ0QsT0FMRCxNQUtPO0FBQ0wsZUFBT1IsbUJBQW1CLENBQUNTLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT1QsbUJBQW1CLENBQUNVLGdCQUEzQjs7QUFDRixTQUFLLFVBQUw7QUFDRSxhQUFPVixtQkFBbUIsQ0FBQ1cscUJBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9YLG1CQUFtQixDQUFDWSxtQkFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1osbUJBQW1CLENBQUNhLGlCQUEzQjs7QUFDRixTQUFLLEtBQUw7QUFDRSxhQUFPYixtQkFBbUIsQ0FBQ00sa0JBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLFVBQ0VSLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLElBQ0FDLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FGL0IsRUFHRTtBQUNBLGVBQU9WLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FBcEM7QUFDRCxPQUxELE1BS087QUFDTCxlQUFPUixtQkFBbUIsQ0FBQ1MsTUFBM0I7QUFDRDs7QUFDSDtBQUNFLGFBQU9LLFNBQVA7QUExQ0o7QUE0Q0QsQ0F0REQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5cbmNvbnN0IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMID0gKFxuICBwYXJzZVR5cGUsXG4gIHRhcmdldENsYXNzLFxuICBwYXJzZUNsYXNzVHlwZXMsXG4gIGZpZWxkTmFtZVxuKSA9PiB7XG4gIGlmIChmaWVsZE5hbWUgPT09ICdpZCcgfHwgZmllbGROYW1lID09PSAnb2JqZWN0SWQnKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuSURfV0hFUkVfSU5QVVQ7XG4gIH1cblxuICBzd2l0Y2ggKHBhcnNlVHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5TVFJJTkdfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk5VTUJFUl9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJPT0xFQU5fV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQVJSQVlfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVF9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkRBVEVfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlRfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuZXhwb3J0IHsgdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/inputType.js b/lib/GraphQL/transformers/inputType.js deleted file mode 100644 index 8606eaa889..0000000000 --- a/lib/GraphQL/transformers/inputType.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformInputTypeToGraphQL = void 0; - -var _graphql = require("graphql"); - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const transformInputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { - switch (parseType) { - case 'String': - return _graphql.GraphQLString; - - case 'Number': - return _graphql.GraphQLFloat; - - case 'Boolean': - return _graphql.GraphQLBoolean; - - case 'Array': - return new _graphql.GraphQLList(defaultGraphQLTypes.ANY); - - case 'Object': - return defaultGraphQLTypes.OBJECT; - - case 'Date': - return defaultGraphQLTypes.DATE; - - case 'Pointer': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLPointerType) { - return parseClassTypes[targetClass].classGraphQLPointerType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'Relation': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationType) { - return parseClassTypes[targetClass].classGraphQLRelationType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'File': - return defaultGraphQLTypes.FILE_INPUT; - - case 'GeoPoint': - return defaultGraphQLTypes.GEO_POINT_INPUT; - - case 'Polygon': - return defaultGraphQLTypes.POLYGON_INPUT; - - case 'Bytes': - return defaultGraphQLTypes.BYTES; - - case 'ACL': - return defaultGraphQLTypes.ACL_INPUT; - - default: - return undefined; - } -}; - -exports.transformInputTypeToGraphQL = transformInputTypeToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9pbnB1dFR5cGUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMIiwicGFyc2VUeXBlIiwidGFyZ2V0Q2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJHcmFwaFFMU3RyaW5nIiwiR3JhcGhRTEZsb2F0IiwiR3JhcGhRTEJvb2xlYW4iLCJHcmFwaFFMTGlzdCIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJBTlkiLCJPQkpFQ1QiLCJEQVRFIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUiLCJGSUxFX0lOUFVUIiwiR0VPX1BPSU5UX0lOUFVUIiwiUE9MWUdPTl9JTlBVVCIsIkJZVEVTIiwiQUNMX0lOUFVUIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBTUE7Ozs7OztBQUVBLE1BQU1BLDJCQUEyQixHQUFHLENBQ2xDQyxTQURrQyxFQUVsQ0MsV0FGa0MsRUFHbENDLGVBSGtDLEtBSS9CO0FBQ0gsVUFBUUYsU0FBUjtBQUNFLFNBQUssUUFBTDtBQUNFLGFBQU9HLHNCQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9DLHFCQUFQOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9DLHVCQUFQOztBQUNGLFNBQUssT0FBTDtBQUNFLGFBQU8sSUFBSUMsb0JBQUosQ0FBZ0JDLG1CQUFtQixDQUFDQyxHQUFwQyxDQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9ELG1CQUFtQixDQUFDRSxNQUEzQjs7QUFDRixTQUFLLE1BQUw7QUFDRSxhQUFPRixtQkFBbUIsQ0FBQ0csSUFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsVUFDRVIsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBSC9CLEVBSUU7QUFDQSxlQUFPVCxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0osbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxVQUFMO0FBQ0UsVUFDRVAsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBSC9CLEVBSUU7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0wsbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNNLFVBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU9OLG1CQUFtQixDQUFDTyxlQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPUCxtQkFBbUIsQ0FBQ1EsYUFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1IsbUJBQW1CLENBQUNTLEtBQTNCOztBQUNGLFNBQUssS0FBTDtBQUNFLGFBQU9ULG1CQUFtQixDQUFDVSxTQUEzQjs7QUFDRjtBQUNFLGFBQU9DLFNBQVA7QUE1Q0o7QUE4Q0QsQ0FuREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMRmxvYXQsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMTGlzdCxcbn0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5cbmNvbnN0IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCA9IChcbiAgcGFyc2VUeXBlLFxuICB0YXJnZXRDbGFzcyxcbiAgcGFyc2VDbGFzc1R5cGVzXG4pID0+IHtcbiAgc3dpdGNoIChwYXJzZVR5cGUpIHtcbiAgICBjYXNlICdTdHJpbmcnOlxuICAgICAgcmV0dXJuIEdyYXBoUUxTdHJpbmc7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiBHcmFwaFFMRmxvYXQ7XG4gICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICByZXR1cm4gR3JhcGhRTEJvb2xlYW47XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIG5ldyBHcmFwaFFMTGlzdChkZWZhdWx0R3JhcGhRTFR5cGVzLkFOWSk7XG4gICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkRBVEU7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlcyAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUG9pbnRlclR5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxQb2ludGVyVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBjYXNlICdSZWxhdGlvbic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlcyAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9JTlBVVDtcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlRfSU5QVVQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX0lOUFVUO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5BQ0xfSU5QVVQ7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/mutation.js b/lib/GraphQL/transformers/mutation.js deleted file mode 100644 index 76c3e3144e..0000000000 --- a/lib/GraphQL/transformers/mutation.js +++ /dev/null @@ -1,275 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformTypes = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphqlRelay = require("graphql-relay"); - -var _filesMutations = require("../loaders/filesMutations"); - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const transformTypes = async (inputType, fields, { - className, - parseGraphQLSchema, - req -}) => { - const { - classGraphQLCreateType, - classGraphQLUpdateType, - config: { - isCreateEnabled, - isUpdateEnabled - } - } = parseGraphQLSchema.parseClassTypes[className]; - const parseClass = parseGraphQLSchema.parseClasses.find(clazz => clazz.className === className); - - if (fields) { - const classGraphQLCreateTypeFields = isCreateEnabled && classGraphQLCreateType ? classGraphQLCreateType.getFields() : null; - const classGraphQLUpdateTypeFields = isUpdateEnabled && classGraphQLUpdateType ? classGraphQLUpdateType.getFields() : null; - const promises = Object.keys(fields).map(async field => { - let inputTypeField; - - if (inputType === 'create' && classGraphQLCreateTypeFields) { - inputTypeField = classGraphQLCreateTypeFields[field]; - } else if (classGraphQLUpdateTypeFields) { - inputTypeField = classGraphQLUpdateTypeFields[field]; - } - - if (inputTypeField) { - switch (true) { - case inputTypeField.type === defaultGraphQLTypes.GEO_POINT_INPUT: - fields[field] = transformers.geoPoint(fields[field]); - break; - - case inputTypeField.type === defaultGraphQLTypes.POLYGON_INPUT: - fields[field] = transformers.polygon(fields[field]); - break; - - case inputTypeField.type === defaultGraphQLTypes.FILE_INPUT: - fields[field] = await transformers.file(fields[field], req); - break; - - case parseClass.fields[field].type === 'Relation': - fields[field] = await transformers.relation(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); - break; - - case parseClass.fields[field].type === 'Pointer': - fields[field] = await transformers.pointer(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); - break; - } - } - }); - await Promise.all(promises); - if (fields.ACL) fields.ACL = transformers.ACL(fields.ACL); - } - - return fields; -}; - -exports.transformTypes = transformTypes; -const transformers = { - file: async ({ - file, - upload - }, { - config - }) => { - if (file === null && !upload) { - return null; - } - - if (upload) { - const { - fileInfo - } = await (0, _filesMutations.handleUpload)(upload, config); - return _objectSpread(_objectSpread({}, fileInfo), {}, { - __type: 'File' - }); - } else if (file && file.name) { - return { - name: file.name, - __type: 'File', - url: file.url - }; - } - - throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); - }, - polygon: value => ({ - __type: 'Polygon', - coordinates: value.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]) - }), - geoPoint: value => _objectSpread(_objectSpread({}, value), {}, { - __type: 'GeoPoint' - }), - ACL: value => { - const parseACL = {}; - - if (value.public) { - parseACL['*'] = { - read: value.public.read, - write: value.public.write - }; - } - - if (value.users) { - value.users.forEach(rule => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(rule.userId); - - if (globalIdObject.type === '_User') { - rule.userId = globalIdObject.id; - } - - parseACL[rule.userId] = { - read: rule.read, - write: rule.write - }; - }); - } - - if (value.roles) { - value.roles.forEach(rule => { - parseACL[`role:${rule.roleName}`] = { - read: rule.read, - write: rule.write - }; - }); - } - - return parseACL; - }, - relation: async (targetClass, field, value, parseGraphQLSchema, { - config, - auth, - info - }) => { - if (Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide at least one operation on the relation mutation of field ${field}`); - const op = { - __op: 'Batch', - ops: [] - }; - let nestedObjectsToAdd = []; - - if (value.createAndAdd) { - nestedObjectsToAdd = (await Promise.all(value.createAndAdd.map(async input => { - const parseFields = await transformTypes('create', input, { - className: targetClass, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - return objectsMutations.createObject(targetClass, parseFields, config, auth, info); - }))).map(object => ({ - __type: 'Pointer', - className: targetClass, - objectId: object.objectId - })); - } - - if (value.add || nestedObjectsToAdd.length > 0) { - if (!value.add) value.add = []; - value.add = value.add.map(input => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); - - if (globalIdObject.type === targetClass) { - input = globalIdObject.id; - } - - return { - __type: 'Pointer', - className: targetClass, - objectId: input - }; - }); - op.ops.push({ - __op: 'AddRelation', - objects: [...value.add, ...nestedObjectsToAdd] - }); - } - - if (value.remove) { - op.ops.push({ - __op: 'RemoveRelation', - objects: value.remove.map(input => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); - - if (globalIdObject.type === targetClass) { - input = globalIdObject.id; - } - - return { - __type: 'Pointer', - className: targetClass, - objectId: input - }; - }) - }); - } - - return op; - }, - pointer: async (targetClass, field, value, parseGraphQLSchema, { - config, - auth, - info - }) => { - if (Object.keys(value).length > 1 || Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide link OR createLink on the pointer mutation of field ${field}`); - let nestedObjectToAdd; - - if (value.createAndLink) { - const parseFields = await transformTypes('create', value.createAndLink, { - className: targetClass, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - nestedObjectToAdd = await objectsMutations.createObject(targetClass, parseFields, config, auth, info); - return { - __type: 'Pointer', - className: targetClass, - objectId: nestedObjectToAdd.objectId - }; - } - - if (value.link) { - let objectId = value.link; - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(objectId); - - if (globalIdObject.type === targetClass) { - objectId = globalIdObject.id; - } - - return { - __type: 'Pointer', - className: targetClass, - objectId - }; - } - } -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9tdXRhdGlvbi5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1UeXBlcyIsImlucHV0VHlwZSIsImZpZWxkcyIsImNsYXNzTmFtZSIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInJlcSIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY29uZmlnIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwicGFyc2VDbGFzc1R5cGVzIiwicGFyc2VDbGFzcyIsInBhcnNlQ2xhc3NlcyIsImZpbmQiLCJjbGF6eiIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzIiwicHJvbWlzZXMiLCJPYmplY3QiLCJrZXlzIiwibWFwIiwiZmllbGQiLCJpbnB1dFR5cGVGaWVsZCIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiR0VPX1BPSU5UX0lOUFVUIiwidHJhbnNmb3JtZXJzIiwiZ2VvUG9pbnQiLCJQT0xZR09OX0lOUFVUIiwicG9seWdvbiIsIkZJTEVfSU5QVVQiLCJmaWxlIiwicmVsYXRpb24iLCJ0YXJnZXRDbGFzcyIsInBvaW50ZXIiLCJQcm9taXNlIiwiYWxsIiwiQUNMIiwidXBsb2FkIiwiZmlsZUluZm8iLCJfX3R5cGUiLCJuYW1lIiwidXJsIiwiUGFyc2UiLCJFcnJvciIsIkZJTEVfU0FWRV9FUlJPUiIsInZhbHVlIiwiY29vcmRpbmF0ZXMiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsInBhcnNlQUNMIiwicHVibGljIiwicmVhZCIsIndyaXRlIiwidXNlcnMiLCJmb3JFYWNoIiwicnVsZSIsImdsb2JhbElkT2JqZWN0IiwidXNlcklkIiwiaWQiLCJyb2xlcyIsInJvbGVOYW1lIiwiYXV0aCIsImluZm8iLCJsZW5ndGgiLCJJTlZBTElEX1BPSU5URVIiLCJvcCIsIl9fb3AiLCJvcHMiLCJuZXN0ZWRPYmplY3RzVG9BZGQiLCJjcmVhdGVBbmRBZGQiLCJpbnB1dCIsInBhcnNlRmllbGRzIiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsIm9iamVjdCIsIm9iamVjdElkIiwiYWRkIiwicHVzaCIsIm9iamVjdHMiLCJyZW1vdmUiLCJuZXN0ZWRPYmplY3RUb0FkZCIsImNyZWF0ZUFuZExpbmsiLCJsaW5rIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsY0FBYyxHQUFHLE9BQ3JCQyxTQURxQixFQUVyQkMsTUFGcUIsRUFHckI7QUFBRUMsRUFBQUEsU0FBRjtBQUFhQyxFQUFBQSxrQkFBYjtBQUFpQ0MsRUFBQUE7QUFBakMsQ0FIcUIsS0FJbEI7QUFDSCxRQUFNO0FBQ0pDLElBQUFBLHNCQURJO0FBRUpDLElBQUFBLHNCQUZJO0FBR0pDLElBQUFBLE1BQU0sRUFBRTtBQUFFQyxNQUFBQSxlQUFGO0FBQW1CQyxNQUFBQTtBQUFuQjtBQUhKLE1BSUZOLGtCQUFrQixDQUFDTyxlQUFuQixDQUFtQ1IsU0FBbkMsQ0FKSjtBQUtBLFFBQU1TLFVBQVUsR0FBR1Isa0JBQWtCLENBQUNTLFlBQW5CLENBQWdDQyxJQUFoQyxDQUNoQkMsS0FBRCxJQUFXQSxLQUFLLENBQUNaLFNBQU4sS0FBb0JBLFNBRGQsQ0FBbkI7O0FBR0EsTUFBSUQsTUFBSixFQUFZO0FBQ1YsVUFBTWMsNEJBQTRCLEdBQ2hDUCxlQUFlLElBQUlILHNCQUFuQixHQUNJQSxzQkFBc0IsQ0FBQ1csU0FBdkIsRUFESixHQUVJLElBSE47QUFJQSxVQUFNQyw0QkFBNEIsR0FDaENSLGVBQWUsSUFBSUgsc0JBQW5CLEdBQ0lBLHNCQUFzQixDQUFDVSxTQUF2QixFQURKLEdBRUksSUFITjtBQUlBLFVBQU1FLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVluQixNQUFaLEVBQW9Cb0IsR0FBcEIsQ0FBd0IsTUFB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T0FBUDtBQUtEOztBQUNELFFBQUk5QixLQUFLLENBQUNxQyxJQUFWLEVBQWdCO0FBQ2QsVUFBSVAsUUFBUSxHQUFHOUIsS0FBSyxDQUFDcUMsSUFBckI7QUFDQSxZQUFNMUIsY0FBYyxHQUFHLGdDQUFhbUIsUUFBYixDQUF2Qjs7QUFDQSxVQUFJbkIsY0FBYyxDQUFDbEMsSUFBZixLQUF3QlUsV0FBNUIsRUFBeUM7QUFDdkMyQyxRQUFBQSxRQUFRLEdBQUduQixjQUFjLENBQUNFLEVBQTFCO0FBQ0Q7O0FBQ0QsYUFBTztBQUNMbkIsUUFBQUEsTUFBTSxFQUFFLFNBREg7QUFFTHZDLFFBQUFBLFNBQVMsRUFBRWdDLFdBRk47QUFHTDJDLFFBQUFBO0FBSEssT0FBUDtBQUtEO0FBQ0Y7QUFwTGtCLENBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgeyBoYW5kbGVVcGxvYWQgfSBmcm9tICcuLi9sb2FkZXJzL2ZpbGVzTXV0YXRpb25zJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi4vbG9hZGVycy9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCAqIGFzIG9iamVjdHNNdXRhdGlvbnMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzTXV0YXRpb25zJztcblxuY29uc3QgdHJhbnNmb3JtVHlwZXMgPSBhc3luYyAoXG4gIGlucHV0VHlwZTogJ2NyZWF0ZScgfCAndXBkYXRlJyxcbiAgZmllbGRzLFxuICB7IGNsYXNzTmFtZSwgcGFyc2VHcmFwaFFMU2NoZW1hLCByZXEgfVxuKSA9PiB7XG4gIGNvbnN0IHtcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUsXG4gICAgY29uZmlnOiB7IGlzQ3JlYXRlRW5hYmxlZCwgaXNVcGRhdGVFbmFibGVkIH0sXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG4gIGNvbnN0IHBhcnNlQ2xhc3MgPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzLmZpbmQoXG4gICAgKGNsYXp6KSA9PiBjbGF6ei5jbGFzc05hbWUgPT09IGNsYXNzTmFtZVxuICApO1xuICBpZiAoZmllbGRzKSB7XG4gICAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZUZpZWxkcyA9XG4gICAgICBpc0NyZWF0ZUVuYWJsZWQgJiYgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZVxuICAgICAgICA/IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUuZ2V0RmllbGRzKClcbiAgICAgICAgOiBudWxsO1xuICAgIGNvbnN0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVGaWVsZHMgPVxuICAgICAgaXNVcGRhdGVFbmFibGVkICYmIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVcbiAgICAgICAgPyBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLmdldEZpZWxkcygpXG4gICAgICAgIDogbnVsbDtcbiAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKGZpZWxkcykubWFwKGFzeW5jIChmaWVsZCkgPT4ge1xuICAgICAgbGV0IGlucHV0VHlwZUZpZWxkO1xuICAgICAgaWYgKGlucHV0VHlwZSA9PT0gJ2NyZWF0ZScgJiYgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZUZpZWxkcykge1xuICAgICAgICBpbnB1dFR5cGVGaWVsZCA9IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHNbZmllbGRdO1xuICAgICAgfSBlbHNlIGlmIChjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzKSB7XG4gICAgICAgIGlucHV0VHlwZUZpZWxkID0gY2xhc3NHcmFwaFFMVXBkYXRlVHlwZUZpZWxkc1tmaWVsZF07XG4gICAgICB9XG4gICAgICBpZiAoaW5wdXRUeXBlRmllbGQpIHtcbiAgICAgICAgc3dpdGNoICh0cnVlKSB7XG4gICAgICAgICAgY2FzZSBpbnB1dFR5cGVGaWVsZC50eXBlID09PSBkZWZhdWx0R3JhcGhRTFR5cGVzLkdFT19QT0lOVF9JTlBVVDpcbiAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSB0cmFuc2Zvcm1lcnMuZ2VvUG9pbnQoZmllbGRzW2ZpZWxkXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGlucHV0VHlwZUZpZWxkLnR5cGUgPT09IGRlZmF1bHRHcmFwaFFMVHlwZXMuUE9MWUdPTl9JTlBVVDpcbiAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSB0cmFuc2Zvcm1lcnMucG9seWdvbihmaWVsZHNbZmllbGRdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgaW5wdXRUeXBlRmllbGQudHlwZSA9PT0gZGVmYXVsdEdyYXBoUUxUeXBlcy5GSUxFX0lOUFVUOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IGF3YWl0IHRyYW5zZm9ybWVycy5maWxlKGZpZWxkc1tmaWVsZF0sIHJlcSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IGF3YWl0IHRyYW5zZm9ybWVycy5yZWxhdGlvbihcbiAgICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgICByZXFcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcic6XG4gICAgICAgICAgICBmaWVsZHNbZmllbGRdID0gYXdhaXQgdHJhbnNmb3JtZXJzLnBvaW50ZXIoXG4gICAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICAgICAgZmllbGQsXG4gICAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0sXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgICAgcmVxXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgaWYgKGZpZWxkcy5BQ0wpIGZpZWxkcy5BQ0wgPSB0cmFuc2Zvcm1lcnMuQUNMKGZpZWxkcy5BQ0wpO1xuICB9XG4gIHJldHVybiBmaWVsZHM7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1lcnMgPSB7XG4gIGZpbGU6IGFzeW5jICh7IGZpbGUsIHVwbG9hZCB9LCB7IGNvbmZpZyB9KSA9PiB7XG4gICAgaWYgKGZpbGUgPT09IG51bGwgJiYgIXVwbG9hZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh1cGxvYWQpIHtcbiAgICAgIGNvbnN0IHsgZmlsZUluZm8gfSA9IGF3YWl0IGhhbmRsZVVwbG9hZCh1cGxvYWQsIGNvbmZpZyk7XG4gICAgICByZXR1cm4geyAuLi5maWxlSW5mbywgX190eXBlOiAnRmlsZScgfTtcbiAgICB9IGVsc2UgaWYgKGZpbGUgJiYgZmlsZS5uYW1lKSB7XG4gICAgICByZXR1cm4geyBuYW1lOiBmaWxlLm5hbWUsIF9fdHlwZTogJ0ZpbGUnLCB1cmw6IGZpbGUudXJsIH07XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsICdJbnZhbGlkIGZpbGUgdXBsb2FkLicpO1xuICB9LFxuICBwb2x5Z29uOiAodmFsdWUpID0+ICh7XG4gICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgY29vcmRpbmF0ZXM6IHZhbHVlLm1hcCgoZ2VvUG9pbnQpID0+IFtcbiAgICAgIGdlb1BvaW50LmxhdGl0dWRlLFxuICAgICAgZ2VvUG9pbnQubG9uZ2l0dWRlLFxuICAgIF0pLFxuICB9KSxcbiAgZ2VvUG9pbnQ6ICh2YWx1ZSkgPT4gKHtcbiAgICAuLi52YWx1ZSxcbiAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gIH0pLFxuICBBQ0w6ICh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IHBhcnNlQUNMID0ge307XG4gICAgaWYgKHZhbHVlLnB1YmxpYykge1xuICAgICAgcGFyc2VBQ0xbJyonXSA9IHtcbiAgICAgICAgcmVhZDogdmFsdWUucHVibGljLnJlYWQsXG4gICAgICAgIHdyaXRlOiB2YWx1ZS5wdWJsaWMud3JpdGUsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodmFsdWUudXNlcnMpIHtcbiAgICAgIHZhbHVlLnVzZXJzLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQocnVsZS51c2VySWQpO1xuICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgIHJ1bGUudXNlcklkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGFyc2VBQ0xbcnVsZS51c2VySWRdID0ge1xuICAgICAgICAgIHJlYWQ6IHJ1bGUucmVhZCxcbiAgICAgICAgICB3cml0ZTogcnVsZS53cml0ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodmFsdWUucm9sZXMpIHtcbiAgICAgIHZhbHVlLnJvbGVzLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgcGFyc2VBQ0xbYHJvbGU6JHtydWxlLnJvbGVOYW1lfWBdID0ge1xuICAgICAgICAgIHJlYWQ6IHJ1bGUucmVhZCxcbiAgICAgICAgICB3cml0ZTogcnVsZS53cml0ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VBQ0w7XG4gIH0sXG4gIHJlbGF0aW9uOiBhc3luYyAoXG4gICAgdGFyZ2V0Q2xhc3MsXG4gICAgZmllbGQsXG4gICAgdmFsdWUsXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgIHsgY29uZmlnLCBhdXRoLCBpbmZvIH1cbiAgKSA9PiB7XG4gICAgaWYgKE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGggPT09IDApXG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUE9JTlRFUixcbiAgICAgICAgYFlvdSBuZWVkIHRvIHByb3ZpZGUgYXQgbGVhc3Qgb25lIG9wZXJhdGlvbiBvbiB0aGUgcmVsYXRpb24gbXV0YXRpb24gb2YgZmllbGQgJHtmaWVsZH1gXG4gICAgICApO1xuXG4gICAgY29uc3Qgb3AgPSB7XG4gICAgICBfX29wOiAnQmF0Y2gnLFxuICAgICAgb3BzOiBbXSxcbiAgICB9O1xuICAgIGxldCBuZXN0ZWRPYmplY3RzVG9BZGQgPSBbXTtcblxuICAgIGlmICh2YWx1ZS5jcmVhdGVBbmRBZGQpIHtcbiAgICAgIG5lc3RlZE9iamVjdHNUb0FkZCA9IChcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgdmFsdWUuY3JlYXRlQW5kQWRkLm1hcChhc3luYyAoaW5wdXQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIGlucHV0LCB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0c011dGF0aW9ucy5jcmVhdGVPYmplY3QoXG4gICAgICAgICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICAgICAgICBwYXJzZUZpZWxkcyxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICkubWFwKChvYmplY3QpID0+ICh7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICBvYmplY3RJZDogb2JqZWN0Lm9iamVjdElkLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5hZGQgfHwgbmVzdGVkT2JqZWN0c1RvQWRkLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghdmFsdWUuYWRkKSB2YWx1ZS5hZGQgPSBbXTtcbiAgICAgIHZhbHVlLmFkZCA9IHZhbHVlLmFkZC5tYXAoKGlucHV0KSA9PiB7XG4gICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGlucHV0KTtcbiAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IHRhcmdldENsYXNzKSB7XG4gICAgICAgICAgaW5wdXQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgb2JqZWN0SWQ6IGlucHV0LFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBvcC5vcHMucHVzaCh7XG4gICAgICAgIF9fb3A6ICdBZGRSZWxhdGlvbicsXG4gICAgICAgIG9iamVjdHM6IFsuLi52YWx1ZS5hZGQsIC4uLm5lc3RlZE9iamVjdHNUb0FkZF0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUucmVtb3ZlKSB7XG4gICAgICBvcC5vcHMucHVzaCh7XG4gICAgICAgIF9fb3A6ICdSZW1vdmVSZWxhdGlvbicsXG4gICAgICAgIG9iamVjdHM6IHZhbHVlLnJlbW92ZS5tYXAoKGlucHV0KSA9PiB7XG4gICAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaW5wdXQpO1xuICAgICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSB0YXJnZXRDbGFzcykge1xuICAgICAgICAgICAgaW5wdXQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgICAgIG9iamVjdElkOiBpbnB1dCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gb3A7XG4gIH0sXG4gIHBvaW50ZXI6IGFzeW5jIChcbiAgICB0YXJnZXRDbGFzcyxcbiAgICBmaWVsZCxcbiAgICB2YWx1ZSxcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgeyBjb25maWcsIGF1dGgsIGluZm8gfVxuICApID0+IHtcbiAgICBpZiAoT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA+IDEgfHwgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMClcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9QT0lOVEVSLFxuICAgICAgICBgWW91IG5lZWQgdG8gcHJvdmlkZSBsaW5rIE9SIGNyZWF0ZUxpbmsgb24gdGhlIHBvaW50ZXIgbXV0YXRpb24gb2YgZmllbGQgJHtmaWVsZH1gXG4gICAgICApO1xuXG4gICAgbGV0IG5lc3RlZE9iamVjdFRvQWRkO1xuICAgIGlmICh2YWx1ZS5jcmVhdGVBbmRMaW5rKSB7XG4gICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCB2YWx1ZS5jcmVhdGVBbmRMaW5rLCB7XG4gICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgfSk7XG4gICAgICBuZXN0ZWRPYmplY3RUb0FkZCA9IGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuY3JlYXRlT2JqZWN0KFxuICAgICAgICB0YXJnZXRDbGFzcyxcbiAgICAgICAgcGFyc2VGaWVsZHMsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgaW5mb1xuICAgICAgKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICBvYmplY3RJZDogbmVzdGVkT2JqZWN0VG9BZGQub2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodmFsdWUubGluaykge1xuICAgICAgbGV0IG9iamVjdElkID0gdmFsdWUubGluaztcbiAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKG9iamVjdElkKTtcbiAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSB0YXJnZXRDbGFzcykge1xuICAgICAgICBvYmplY3RJZCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgIG9iamVjdElkLFxuICAgICAgfTtcbiAgICB9XG4gIH0sXG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1UeXBlcyB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/outputType.js b/lib/GraphQL/transformers/outputType.js deleted file mode 100644 index e01c729f6f..0000000000 --- a/lib/GraphQL/transformers/outputType.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformOutputTypeToGraphQL = void 0; - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -var _graphql = require("graphql"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const transformOutputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { - switch (parseType) { - case 'String': - return _graphql.GraphQLString; - - case 'Number': - return _graphql.GraphQLFloat; - - case 'Boolean': - return _graphql.GraphQLBoolean; - - case 'Array': - return new _graphql.GraphQLList(defaultGraphQLTypes.ARRAY_RESULT); - - case 'Object': - return defaultGraphQLTypes.OBJECT; - - case 'Date': - return defaultGraphQLTypes.DATE; - - case 'Pointer': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLOutputType) { - return parseClassTypes[targetClass].classGraphQLOutputType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'Relation': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLFindResultType) { - return new _graphql.GraphQLNonNull(parseClassTypes[targetClass].classGraphQLFindResultType); - } else { - return new _graphql.GraphQLNonNull(defaultGraphQLTypes.OBJECT); - } - - case 'File': - return defaultGraphQLTypes.FILE_INFO; - - case 'GeoPoint': - return defaultGraphQLTypes.GEO_POINT; - - case 'Polygon': - return defaultGraphQLTypes.POLYGON; - - case 'Bytes': - return defaultGraphQLTypes.BYTES; - - case 'ACL': - return new _graphql.GraphQLNonNull(defaultGraphQLTypes.ACL); - - default: - return undefined; - } -}; - -exports.transformOutputTypeToGraphQL = transformOutputTypeToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlLmpzIl0sIm5hbWVzIjpbInRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwiLCJwYXJzZVR5cGUiLCJ0YXJnZXRDbGFzcyIsInBhcnNlQ2xhc3NUeXBlcyIsIkdyYXBoUUxTdHJpbmciLCJHcmFwaFFMRmxvYXQiLCJHcmFwaFFMQm9vbGVhbiIsIkdyYXBoUUxMaXN0IiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkFSUkFZX1JFU1VMVCIsIk9CSkVDVCIsIkRBVEUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkZJTEVfSU5GTyIsIkdFT19QT0lOVCIsIlBPTFlHT04iLCJCWVRFUyIsIkFDTCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7QUFRQSxNQUFNQSw0QkFBNEIsR0FBRyxDQUNuQ0MsU0FEbUMsRUFFbkNDLFdBRm1DLEVBR25DQyxlQUhtQyxLQUloQztBQUNILFVBQVFGLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPRyxzQkFBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPQyxxQkFBUDs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPQyx1QkFBUDs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPLElBQUlDLG9CQUFKLENBQWdCQyxtQkFBbUIsQ0FBQ0MsWUFBcEMsQ0FBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPRCxtQkFBbUIsQ0FBQ0UsTUFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNHLElBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLFVBQ0VSLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUgvQixFQUlFO0FBQ0EsZUFBT1QsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUFwQztBQUNELE9BTkQsTUFNTztBQUNMLGVBQU9KLG1CQUFtQixDQUFDRSxNQUEzQjtBQUNEOztBQUNILFNBQUssVUFBTDtBQUNFLFVBQ0VQLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJXLDBCQUgvQixFQUlFO0FBQ0EsZUFBTyxJQUFJQyx1QkFBSixDQUNMWCxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsMEJBRHhCLENBQVA7QUFHRCxPQVJELE1BUU87QUFDTCxlQUFPLElBQUlDLHVCQUFKLENBQW1CTixtQkFBbUIsQ0FBQ0UsTUFBdkMsQ0FBUDtBQUNEOztBQUNILFNBQUssTUFBTDtBQUNFLGFBQU9GLG1CQUFtQixDQUFDTyxTQUEzQjs7QUFDRixTQUFLLFVBQUw7QUFDRSxhQUFPUCxtQkFBbUIsQ0FBQ1EsU0FBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsYUFBT1IsbUJBQW1CLENBQUNTLE9BQTNCOztBQUNGLFNBQUssT0FBTDtBQUNFLGFBQU9ULG1CQUFtQixDQUFDVSxLQUEzQjs7QUFDRixTQUFLLEtBQUw7QUFDRSxhQUFPLElBQUlKLHVCQUFKLENBQW1CTixtQkFBbUIsQ0FBQ1csR0FBdkMsQ0FBUDs7QUFDRjtBQUNFLGFBQU9DLFNBQVA7QUE5Q0o7QUFnREQsQ0FyREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQge1xuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMRmxvYXQsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTE5vbk51bGwsXG59IGZyb20gJ2dyYXBocWwnO1xuXG5jb25zdCB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMID0gKFxuICBwYXJzZVR5cGUsXG4gIHRhcmdldENsYXNzLFxuICBwYXJzZUNsYXNzVHlwZXNcbikgPT4ge1xuICBzd2l0Y2ggKHBhcnNlVHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gR3JhcGhRTFN0cmluZztcbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAgcmV0dXJuIEdyYXBoUUxGbG9hdDtcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiBHcmFwaFFMQm9vbGVhbjtcbiAgICBjYXNlICdBcnJheSc6XG4gICAgICByZXR1cm4gbmV3IEdyYXBoUUxMaXN0KGRlZmF1bHRHcmFwaFFMVHlwZXMuQVJSQVlfUkVTVUxUKTtcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuREFURTtcbiAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgIGlmIChcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMT3V0cHV0VHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBjYXNlICdSZWxhdGlvbic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlcyAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbmV3IEdyYXBoUUxOb25OdWxsKFxuICAgICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGVcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgR3JhcGhRTE5vbk51bGwoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1QpO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9JTkZPO1xuICAgIGNhc2UgJ0dlb1BvaW50JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkdFT19QT0lOVDtcbiAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLlBPTFlHT047XG4gICAgY2FzZSAnQnl0ZXMnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQllURVM7XG4gICAgY2FzZSAnQUNMJzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhRTE5vbk51bGwoZGVmYXVsdEdyYXBoUUxUeXBlcy5BQ0wpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/transformers/query.js b/lib/GraphQL/transformers/query.js deleted file mode 100644 index 00f6aa5854..0000000000 --- a/lib/GraphQL/transformers/query.js +++ /dev/null @@ -1,273 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformQueryInputToParse = exports.transformQueryConstraintInputToParse = void 0; - -var _graphqlRelay = require("graphql-relay"); - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const parseQueryMap = { - OR: '$or', - AND: '$and', - NOR: '$nor' -}; -const parseConstraintMap = { - equalTo: '$eq', - notEqualTo: '$ne', - lessThan: '$lt', - lessThanOrEqualTo: '$lte', - greaterThan: '$gt', - greaterThanOrEqualTo: '$gte', - in: '$in', - notIn: '$nin', - exists: '$exists', - inQueryKey: '$select', - notInQueryKey: '$dontSelect', - inQuery: '$inQuery', - notInQuery: '$notInQuery', - containedBy: '$containedBy', - contains: '$all', - matchesRegex: '$regex', - options: '$options', - text: '$text', - search: '$search', - term: '$term', - language: '$language', - caseSensitive: '$caseSensitive', - diacriticSensitive: '$diacriticSensitive', - nearSphere: '$nearSphere', - maxDistance: '$maxDistance', - maxDistanceInRadians: '$maxDistanceInRadians', - maxDistanceInMiles: '$maxDistanceInMiles', - maxDistanceInKilometers: '$maxDistanceInKilometers', - within: '$within', - box: '$box', - geoWithin: '$geoWithin', - polygon: '$polygon', - centerSphere: '$centerSphere', - geoIntersects: '$geoIntersects', - point: '$point' -}; - -const transformQueryConstraintInputToParse = (constraints, parentFieldName, className, parentConstraints, parseClasses) => { - const fields = parseClasses.find(parseClass => parseClass.className === className).fields; - - if (parentFieldName === 'id' && className) { - Object.keys(constraints).forEach(constraintName => { - const constraintValue = constraints[constraintName]; - - if (typeof constraintValue === 'string') { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(constraintValue); - - if (globalIdObject.type === className) { - constraints[constraintName] = globalIdObject.id; - } - } else if (Array.isArray(constraintValue)) { - constraints[constraintName] = constraintValue.map(value => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(value); - - if (globalIdObject.type === className) { - return globalIdObject.id; - } - - return value; - }); - } - }); - parentConstraints.objectId = constraints; - delete parentConstraints.id; - } - - Object.keys(constraints).forEach(fieldName => { - let fieldValue = constraints[fieldName]; - - if (parseConstraintMap[fieldName]) { - constraints[parseConstraintMap[fieldName]] = constraints[fieldName]; - delete constraints[fieldName]; - } - /** - * If we have a key-value pair, we need to change the way the constraint is structured. - * - * Example: - * From: - * { - * "someField": { - * "lessThan": { - * "key":"foo.bar", - * "value": 100 - * }, - * "greaterThan": { - * "key":"foo.bar", - * "value": 10 - * } - * } - * } - * - * To: - * { - * "someField.foo.bar": { - * "$lt": 100, - * "$gt": 10 - * } - * } - */ - - - if (fieldValue.key && fieldValue.value && parentConstraints && parentFieldName) { - delete parentConstraints[parentFieldName]; - parentConstraints[`${parentFieldName}.${fieldValue.key}`] = _objectSpread(_objectSpread({}, parentConstraints[`${parentFieldName}.${fieldValue.key}`]), {}, { - [parseConstraintMap[fieldName]]: fieldValue.value - }); - } else if (fields[parentFieldName] && (fields[parentFieldName].type === 'Pointer' || fields[parentFieldName].type === 'Relation')) { - const { - targetClass - } = fields[parentFieldName]; - - if (fieldName === 'exists') { - if (fields[parentFieldName].type === 'Relation') { - const whereTarget = fieldValue ? 'where' : 'notWhere'; - - if (constraints[whereTarget]) { - if (constraints[whereTarget].objectId) { - constraints[whereTarget].objectId = _objectSpread(_objectSpread({}, constraints[whereTarget].objectId), {}, { - $exists: fieldValue - }); - } else { - constraints[whereTarget].objectId = { - $exists: fieldValue - }; - } - } else { - const parseWhereTarget = fieldValue ? '$inQuery' : '$notInQuery'; - parentConstraints[parentFieldName][parseWhereTarget] = { - where: { - objectId: { - $exists: true - } - }, - className: targetClass - }; - } - - delete constraints.$exists; - } else { - parentConstraints[parentFieldName].$exists = fieldValue; - } - - return; - } - - switch (fieldName) { - case 'have': - parentConstraints[parentFieldName].$inQuery = { - where: fieldValue, - className: targetClass - }; - transformQueryInputToParse(parentConstraints[parentFieldName].$inQuery.where, targetClass, parseClasses); - break; - - case 'haveNot': - parentConstraints[parentFieldName].$notInQuery = { - where: fieldValue, - className: targetClass - }; - transformQueryInputToParse(parentConstraints[parentFieldName].$notInQuery.where, targetClass, parseClasses); - break; - } - - delete constraints[fieldName]; - return; - } - - switch (fieldName) { - case 'point': - if (typeof fieldValue === 'object' && !fieldValue.__type) { - fieldValue.__type = 'GeoPoint'; - } - - break; - - case 'nearSphere': - if (typeof fieldValue === 'object' && !fieldValue.__type) { - fieldValue.__type = 'GeoPoint'; - } - - break; - - case 'box': - if (typeof fieldValue === 'object' && fieldValue.bottomLeft && fieldValue.upperRight) { - fieldValue = [_objectSpread({ - __type: 'GeoPoint' - }, fieldValue.bottomLeft), _objectSpread({ - __type: 'GeoPoint' - }, fieldValue.upperRight)]; - constraints[parseConstraintMap[fieldName]] = fieldValue; - } - - break; - - case 'polygon': - if (fieldValue instanceof Array) { - fieldValue.forEach(geoPoint => { - if (typeof geoPoint === 'object' && !geoPoint.__type) { - geoPoint.__type = 'GeoPoint'; - } - }); - } - - break; - - case 'centerSphere': - if (typeof fieldValue === 'object' && fieldValue.center && fieldValue.distance) { - fieldValue = [_objectSpread({ - __type: 'GeoPoint' - }, fieldValue.center), fieldValue.distance]; - constraints[parseConstraintMap[fieldName]] = fieldValue; - } - - break; - } - - if (typeof fieldValue === 'object') { - if (fieldName === 'where') { - transformQueryInputToParse(fieldValue, className, parseClasses); - } else { - transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); - } - } - }); -}; - -exports.transformQueryConstraintInputToParse = transformQueryConstraintInputToParse; - -const transformQueryInputToParse = (constraints, className, parseClasses) => { - if (!constraints || typeof constraints !== 'object') { - return; - } - - Object.keys(constraints).forEach(fieldName => { - const fieldValue = constraints[fieldName]; - - if (parseQueryMap[fieldName]) { - delete constraints[fieldName]; - fieldName = parseQueryMap[fieldName]; - constraints[fieldName] = fieldValue; - fieldValue.forEach(fieldValueItem => { - transformQueryInputToParse(fieldValueItem, className, parseClasses); - }); - return; - } else { - transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); - } - }); -}; - -exports.transformQueryInputToParse = transformQueryInputToParse; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9xdWVyeS5qcyJdLCJuYW1lcyI6WyJwYXJzZVF1ZXJ5TWFwIiwiT1IiLCJBTkQiLCJOT1IiLCJwYXJzZUNvbnN0cmFpbnRNYXAiLCJlcXVhbFRvIiwibm90RXF1YWxUbyIsImxlc3NUaGFuIiwibGVzc1RoYW5PckVxdWFsVG8iLCJncmVhdGVyVGhhbiIsImdyZWF0ZXJUaGFuT3JFcXVhbFRvIiwiaW4iLCJub3RJbiIsImV4aXN0cyIsImluUXVlcnlLZXkiLCJub3RJblF1ZXJ5S2V5IiwiaW5RdWVyeSIsIm5vdEluUXVlcnkiLCJjb250YWluZWRCeSIsImNvbnRhaW5zIiwibWF0Y2hlc1JlZ2V4Iiwib3B0aW9ucyIsInRleHQiLCJzZWFyY2giLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwibmVhclNwaGVyZSIsIm1heERpc3RhbmNlIiwibWF4RGlzdGFuY2VJblJhZGlhbnMiLCJtYXhEaXN0YW5jZUluTWlsZXMiLCJtYXhEaXN0YW5jZUluS2lsb21ldGVycyIsIndpdGhpbiIsImJveCIsImdlb1dpdGhpbiIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJnZW9JbnRlcnNlY3RzIiwicG9pbnQiLCJ0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UiLCJjb25zdHJhaW50cyIsInBhcmVudEZpZWxkTmFtZSIsImNsYXNzTmFtZSIsInBhcmVudENvbnN0cmFpbnRzIiwicGFyc2VDbGFzc2VzIiwiZmllbGRzIiwiZmluZCIsInBhcnNlQ2xhc3MiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImNvbnN0cmFpbnROYW1lIiwiY29uc3RyYWludFZhbHVlIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiaWQiLCJBcnJheSIsImlzQXJyYXkiLCJtYXAiLCJ2YWx1ZSIsIm9iamVjdElkIiwiZmllbGROYW1lIiwiZmllbGRWYWx1ZSIsImtleSIsInRhcmdldENsYXNzIiwid2hlcmVUYXJnZXQiLCIkZXhpc3RzIiwicGFyc2VXaGVyZVRhcmdldCIsIndoZXJlIiwiJGluUXVlcnkiLCJ0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSIsIiRub3RJblF1ZXJ5IiwiX190eXBlIiwiYm90dG9tTGVmdCIsInVwcGVyUmlnaHQiLCJnZW9Qb2ludCIsImNlbnRlciIsImRpc3RhbmNlIiwiZmllbGRWYWx1ZUl0ZW0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7Ozs7Ozs7QUFFQSxNQUFNQSxhQUFhLEdBQUc7QUFDcEJDLEVBQUFBLEVBQUUsRUFBRSxLQURnQjtBQUVwQkMsRUFBQUEsR0FBRyxFQUFFLE1BRmU7QUFHcEJDLEVBQUFBLEdBQUcsRUFBRTtBQUhlLENBQXRCO0FBTUEsTUFBTUMsa0JBQWtCLEdBQUc7QUFDekJDLEVBQUFBLE9BQU8sRUFBRSxLQURnQjtBQUV6QkMsRUFBQUEsVUFBVSxFQUFFLEtBRmE7QUFHekJDLEVBQUFBLFFBQVEsRUFBRSxLQUhlO0FBSXpCQyxFQUFBQSxpQkFBaUIsRUFBRSxNQUpNO0FBS3pCQyxFQUFBQSxXQUFXLEVBQUUsS0FMWTtBQU16QkMsRUFBQUEsb0JBQW9CLEVBQUUsTUFORztBQU96QkMsRUFBQUEsRUFBRSxFQUFFLEtBUHFCO0FBUXpCQyxFQUFBQSxLQUFLLEVBQUUsTUFSa0I7QUFTekJDLEVBQUFBLE1BQU0sRUFBRSxTQVRpQjtBQVV6QkMsRUFBQUEsVUFBVSxFQUFFLFNBVmE7QUFXekJDLEVBQUFBLGFBQWEsRUFBRSxhQVhVO0FBWXpCQyxFQUFBQSxPQUFPLEVBQUUsVUFaZ0I7QUFhekJDLEVBQUFBLFVBQVUsRUFBRSxhQWJhO0FBY3pCQyxFQUFBQSxXQUFXLEVBQUUsY0FkWTtBQWV6QkMsRUFBQUEsUUFBUSxFQUFFLE1BZmU7QUFnQnpCQyxFQUFBQSxZQUFZLEVBQUUsUUFoQlc7QUFpQnpCQyxFQUFBQSxPQUFPLEVBQUUsVUFqQmdCO0FBa0J6QkMsRUFBQUEsSUFBSSxFQUFFLE9BbEJtQjtBQW1CekJD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LGFBQWEsQ0FBQzhELFNBQUQsQ0FBakIsRUFBOEI7QUFDNUIsYUFBT3JCLFdBQVcsQ0FBQ3FCLFNBQUQsQ0FBbEI7QUFDQUEsTUFBQUEsU0FBUyxHQUFHOUQsYUFBYSxDQUFDOEQsU0FBRCxDQUF6QjtBQUNBckIsTUFBQUEsV0FBVyxDQUFDcUIsU0FBRCxDQUFYLEdBQXlCQyxVQUF6QjtBQUNBQSxNQUFBQSxVQUFVLENBQUNaLE9BQVgsQ0FBbUI0QixjQUFjLElBQUk7QUFDbkNSLFFBQUFBLDBCQUEwQixDQUFDUSxjQUFELEVBQWlCcEMsU0FBakIsRUFBNEJFLFlBQTVCLENBQTFCO0FBQ0QsT0FGRDtBQUdBO0FBQ0QsS0FSRCxNQVFPO0FBQ0xMLE1BQUFBLG9DQUFvQyxDQUNsQ3VCLFVBRGtDLEVBRWxDRCxTQUZrQyxFQUdsQ25CLFNBSGtDLEVBSWxDRixXQUprQyxFQUtsQ0ksWUFMa0MsQ0FBcEM7QUFPRDtBQUNGLEdBcEJEO0FBcUJELENBMUJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5cbmNvbnN0IHBhcnNlUXVlcnlNYXAgPSB7XG4gIE9SOiAnJG9yJyxcbiAgQU5EOiAnJGFuZCcsXG4gIE5PUjogJyRub3InLFxufTtcblxuY29uc3QgcGFyc2VDb25zdHJhaW50TWFwID0ge1xuICBlcXVhbFRvOiAnJGVxJyxcbiAgbm90RXF1YWxUbzogJyRuZScsXG4gIGxlc3NUaGFuOiAnJGx0JyxcbiAgbGVzc1RoYW5PckVxdWFsVG86ICckbHRlJyxcbiAgZ3JlYXRlclRoYW46ICckZ3QnLFxuICBncmVhdGVyVGhhbk9yRXF1YWxUbzogJyRndGUnLFxuICBpbjogJyRpbicsXG4gIG5vdEluOiAnJG5pbicsXG4gIGV4aXN0czogJyRleGlzdHMnLFxuICBpblF1ZXJ5S2V5OiAnJHNlbGVjdCcsXG4gIG5vdEluUXVlcnlLZXk6ICckZG9udFNlbGVjdCcsXG4gIGluUXVlcnk6ICckaW5RdWVyeScsXG4gIG5vdEluUXVlcnk6ICckbm90SW5RdWVyeScsXG4gIGNvbnRhaW5lZEJ5OiAnJGNvbnRhaW5lZEJ5JyxcbiAgY29udGFpbnM6ICckYWxsJyxcbiAgbWF0Y2hlc1JlZ2V4OiAnJHJlZ2V4JyxcbiAgb3B0aW9uczogJyRvcHRpb25zJyxcbiAgdGV4dDogJyR0ZXh0JyxcbiAgc2VhcmNoOiAnJHNlYXJjaCcsXG4gIHRlcm06ICckdGVybScsXG4gIGxhbmd1YWdlOiAnJGxhbmd1YWdlJyxcbiAgY2FzZVNlbnNpdGl2ZTogJyRjYXNlU2Vuc2l0aXZlJyxcbiAgZGlhY3JpdGljU2Vuc2l0aXZlOiAnJGRpYWNyaXRpY1NlbnNpdGl2ZScsXG4gIG5lYXJTcGhlcmU6ICckbmVhclNwaGVyZScsXG4gIG1heERpc3RhbmNlOiAnJG1heERpc3RhbmNlJyxcbiAgbWF4RGlzdGFuY2VJblJhZGlhbnM6ICckbWF4RGlzdGFuY2VJblJhZGlhbnMnLFxuICBtYXhEaXN0YW5jZUluTWlsZXM6ICckbWF4RGlzdGFuY2VJbk1pbGVzJyxcbiAgbWF4RGlzdGFuY2VJbktpbG9tZXRlcnM6ICckbWF4RGlzdGFuY2VJbktpbG9tZXRlcnMnLFxuICB3aXRoaW46ICckd2l0aGluJyxcbiAgYm94OiAnJGJveCcsXG4gIGdlb1dpdGhpbjogJyRnZW9XaXRoaW4nLFxuICBwb2x5Z29uOiAnJHBvbHlnb24nLFxuICBjZW50ZXJTcGhlcmU6ICckY2VudGVyU3BoZXJlJyxcbiAgZ2VvSW50ZXJzZWN0czogJyRnZW9JbnRlcnNlY3RzJyxcbiAgcG9pbnQ6ICckcG9pbnQnLFxufTtcblxuY29uc3QgdHJhbnNmb3JtUXVlcnlDb25zdHJhaW50SW5wdXRUb1BhcnNlID0gKFxuICBjb25zdHJhaW50cyxcbiAgcGFyZW50RmllbGROYW1lLFxuICBjbGFzc05hbWUsXG4gIHBhcmVudENvbnN0cmFpbnRzLFxuICBwYXJzZUNsYXNzZXNcbikgPT4ge1xuICBjb25zdCBmaWVsZHMgPSBwYXJzZUNsYXNzZXMuZmluZChcbiAgICBwYXJzZUNsYXNzID0+IHBhcnNlQ2xhc3MuY2xhc3NOYW1lID09PSBjbGFzc05hbWVcbiAgKS5maWVsZHM7XG4gIGlmIChwYXJlbnRGaWVsZE5hbWUgPT09ICdpZCcgJiYgY2xhc3NOYW1lKSB7XG4gICAgT2JqZWN0LmtleXMoY29uc3RyYWludHMpLmZvckVhY2goY29uc3RyYWludE5hbWUgPT4ge1xuICAgICAgY29uc3QgY29uc3RyYWludFZhbHVlID0gY29uc3RyYWludHNbY29uc3RyYWludE5hbWVdO1xuICAgICAgaWYgKHR5cGVvZiBjb25zdHJhaW50VmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGNvbnN0cmFpbnRWYWx1ZSk7XG5cbiAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IGNsYXNzTmFtZSkge1xuICAgICAgICAgIGNvbnN0cmFpbnRzW2NvbnN0cmFpbnROYW1lXSA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY29uc3RyYWludFZhbHVlKSkge1xuICAgICAgICBjb25zdHJhaW50c1tjb25zdHJhaW50TmFtZV0gPSBjb25zdHJhaW50VmFsdWUubWFwKHZhbHVlID0+IHtcbiAgICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZCh2YWx1ZSk7XG5cbiAgICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBwYXJlbnRDb25zdHJhaW50cy5vYmplY3RJZCA9IGNvbnN0cmFpbnRzO1xuICAgIGRlbGV0ZSBwYXJlbnRDb25zdHJhaW50cy5pZDtcbiAgfVxuICBPYmplY3Qua2V5cyhjb25zdHJhaW50cykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgIGxldCBmaWVsZFZhbHVlID0gY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICBpZiAocGFyc2VDb25zdHJhaW50TWFwW2ZpZWxkTmFtZV0pIHtcbiAgICAgIGNvbnN0cmFpbnRzW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXSA9IGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG4gICAgICBkZWxldGUgY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgd2UgaGF2ZSBhIGtleS12YWx1ZSBwYWlyLCB3ZSBuZWVkIHRvIGNoYW5nZSB0aGUgd2F5IHRoZSBjb25zdHJhaW50IGlzIHN0cnVjdHVyZWQuXG4gICAgICpcbiAgICAgKiBFeGFtcGxlOlxuICAgICAqICAgRnJvbTpcbiAgICAgKiAgIHtcbiAgICAgKiAgICAgXCJzb21lRmllbGRcIjoge1xuICAgICAqICAgICAgIFwibGVzc1RoYW5cIjoge1xuICAgICAqICAgICAgICAgXCJrZXlcIjpcImZvby5iYXJcIixcbiAgICAgKiAgICAgICAgIFwidmFsdWVcIjogMTAwXG4gICAgICogICAgICAgfSxcbiAgICAgKiAgICAgICBcImdyZWF0ZXJUaGFuXCI6IHtcbiAgICAgKiAgICAgICAgIFwia2V5XCI6XCJmb28uYmFyXCIsXG4gICAgICogICAgICAgICBcInZhbHVlXCI6IDEwXG4gICAgICogICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogICB9XG4gICAgICpcbiAgICAgKiAgIFRvOlxuICAgICAqICAge1xuICAgICAqICAgICBcInNvbWVGaWVsZC5mb28uYmFyXCI6IHtcbiAgICAgKiAgICAgICBcIiRsdFwiOiAxMDAsXG4gICAgICogICAgICAgXCIkZ3RcIjogMTBcbiAgICAgKiAgICAgIH1cbiAgICAgKiAgIH1cbiAgICAgKi9cbiAgICBpZiAoXG4gICAgICBmaWVsZFZhbHVlLmtleSAmJlxuICAgICAgZmllbGRWYWx1ZS52YWx1ZSAmJlxuICAgICAgcGFyZW50Q29uc3RyYWludHMgJiZcbiAgICAgIHBhcmVudEZpZWxkTmFtZVxuICAgICkge1xuICAgICAgZGVsZXRlIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV07XG4gICAgICBwYXJlbnRDb25zdHJhaW50c1tgJHtwYXJlbnRGaWVsZE5hbWV9LiR7ZmllbGRWYWx1ZS5rZXl9YF0gPSB7XG4gICAgICAgIC4uLnBhcmVudENvbnN0cmFpbnRzW2Ake3BhcmVudEZpZWxkTmFtZX0uJHtmaWVsZFZhbHVlLmtleX1gXSxcbiAgICAgICAgW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXTogZmllbGRWYWx1ZS52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdICYmXG4gICAgICAoZmllbGRzW3BhcmVudEZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInIHx8XG4gICAgICAgIGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbicpXG4gICAgKSB7XG4gICAgICBjb25zdCB7IHRhcmdldENsYXNzIH0gPSBmaWVsZHNbcGFyZW50RmllbGROYW1lXTtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdleGlzdHMnKSB7XG4gICAgICAgIGlmIChmaWVsZHNbcGFyZW50RmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgY29uc3Qgd2hlcmVUYXJnZXQgPSBmaWVsZFZhbHVlID8gJ3doZXJlJyA6ICdub3RXaGVyZSc7XG4gICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XSkge1xuICAgICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XS5vYmplY3RJZCkge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgLi4uY29uc3RyYWludHNbd2hlcmVUYXJnZXRdLm9iamVjdElkLFxuICAgICAgICAgICAgICAgICRleGlzdHM6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgJGV4aXN0czogZmllbGRWYWx1ZSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VXaGVyZVRhcmdldCA9IGZpZWxkVmFsdWUgPyAnJGluUXVlcnknIDogJyRub3RJblF1ZXJ5JztcbiAgICAgICAgICAgIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV1bcGFyc2VXaGVyZVRhcmdldF0gPSB7XG4gICAgICAgICAgICAgIHdoZXJlOiB7IG9iamVjdElkOiB7ICRleGlzdHM6IHRydWUgfSB9LFxuICAgICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzLiRleGlzdHM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyZW50Q29uc3RyYWludHNbcGFyZW50RmllbGROYW1lXS4kZXhpc3RzID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgICAgICBjYXNlICdoYXZlJzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdoYXZlTm90JzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN3aXRjaCAoZmllbGROYW1lKSB7XG4gICAgICBjYXNlICdwb2ludCc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbmVhclNwaGVyZSc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYm94JzpcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgIGZpZWxkVmFsdWUuYm90dG9tTGVmdCAmJlxuICAgICAgICAgIGZpZWxkVmFsdWUudXBwZXJSaWdodFxuICAgICAgICApIHtcbiAgICAgICAgICBmaWVsZFZhbHVlID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgICAgIC4uLmZpZWxkVmFsdWUuYm90dG9tTGVmdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ0dlb1BvaW50JyxcbiAgICAgICAgICAgICAgLi4uZmllbGRWYWx1ZS51cHBlclJpZ2h0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0cmFpbnRzW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXSA9IGZpZWxkVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwb2x5Z29uJzpcbiAgICAgICAgaWYgKGZpZWxkVmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGZpZWxkVmFsdWUuZm9yRWFjaChnZW9Qb2ludCA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGdlb1BvaW50ID09PSAnb2JqZWN0JyAmJiAhZ2VvUG9pbnQuX190eXBlKSB7XG4gICAgICAgICAgICAgIGdlb1BvaW50Ll9fdHlwZSA9ICdHZW9Qb2ludCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjZW50ZXJTcGhlcmUnOlxuICAgICAgICBpZiAoXG4gICAgICAgICAgdHlwZW9mIGZpZWxkVmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgZmllbGRWYWx1ZS5jZW50ZXIgJiZcbiAgICAgICAgICBmaWVsZFZhbHVlLmRpc3RhbmNlXG4gICAgICAgICkge1xuICAgICAgICAgIGZpZWxkVmFsdWUgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ0dlb1BvaW50JyxcbiAgICAgICAgICAgICAgLi4uZmllbGRWYWx1ZS5jZW50ZXIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZmllbGRWYWx1ZS5kaXN0YW5jZSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0cmFpbnRzW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXSA9IGZpZWxkVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICd3aGVyZScpIHtcbiAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoZmllbGRWYWx1ZSwgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJhbnNmb3JtUXVlcnlDb25zdHJhaW50SW5wdXRUb1BhcnNlKFxuICAgICAgICAgIGZpZWxkVmFsdWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICBjb25zdHJhaW50cyxcbiAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufTtcblxuY29uc3QgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UgPSAoY29uc3RyYWludHMsIGNsYXNzTmFtZSwgcGFyc2VDbGFzc2VzKSA9PiB7XG4gIGlmICghY29uc3RyYWludHMgfHwgdHlwZW9mIGNvbnN0cmFpbnRzICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIE9iamVjdC5rZXlzKGNvbnN0cmFpbnRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgY29uc3QgZmllbGRWYWx1ZSA9IGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG5cbiAgICBpZiAocGFyc2VRdWVyeU1hcFtmaWVsZE5hbWVdKSB7XG4gICAgICBkZWxldGUgY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICAgIGZpZWxkTmFtZSA9IHBhcnNlUXVlcnlNYXBbZmllbGROYW1lXTtcbiAgICAgIGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV0gPSBmaWVsZFZhbHVlO1xuICAgICAgZmllbGRWYWx1ZS5mb3JFYWNoKGZpZWxkVmFsdWVJdGVtID0+IHtcbiAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoZmllbGRWYWx1ZUl0ZW0sIGNsYXNzTmFtZSwgcGFyc2VDbGFzc2VzKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UoXG4gICAgICAgIGZpZWxkVmFsdWUsXG4gICAgICAgIGZpZWxkTmFtZSxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBjb25zdHJhaW50cyxcbiAgICAgICAgcGFyc2VDbGFzc2VzXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UsIHRyYW5zZm9ybVF1ZXJ5SW5wdXRUb1BhcnNlIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/transformers/schemaFields.js b/lib/GraphQL/transformers/schemaFields.js deleted file mode 100644 index 471edae4eb..0000000000 --- a/lib/GraphQL/transformers/schemaFields.js +++ /dev/null @@ -1,128 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformToGraphQL = exports.transformToParse = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const transformToParse = (graphQLSchemaFields, existingFields) => { - if (!graphQLSchemaFields) { - return {}; - } - - let parseSchemaFields = {}; - - const reducerGenerator = type => (parseSchemaFields, field) => { - if (type === 'Remove') { - if (existingFields[field.name]) { - return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { - [field.name]: { - __op: 'Delete' - } - }); - } else { - return parseSchemaFields; - } - } - - if (graphQLSchemaFields.remove && graphQLSchemaFields.remove.find(removeField => removeField.name === field.name)) { - return parseSchemaFields; - } - - if (parseSchemaFields[field.name] || existingFields && existingFields[field.name]) { - throw new _node.default.Error(_node.default.Error.INVALID_KEY_NAME, `Duplicated field name: ${field.name}`); - } - - if (type === 'Relation' || type === 'Pointer') { - return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { - [field.name]: { - type, - targetClass: field.targetClassName - } - }); - } - - return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { - [field.name]: { - type - } - }); - }; - - if (graphQLSchemaFields.addStrings) { - parseSchemaFields = graphQLSchemaFields.addStrings.reduce(reducerGenerator('String'), parseSchemaFields); - } - - if (graphQLSchemaFields.addNumbers) { - parseSchemaFields = graphQLSchemaFields.addNumbers.reduce(reducerGenerator('Number'), parseSchemaFields); - } - - if (graphQLSchemaFields.addBooleans) { - parseSchemaFields = graphQLSchemaFields.addBooleans.reduce(reducerGenerator('Boolean'), parseSchemaFields); - } - - if (graphQLSchemaFields.addArrays) { - parseSchemaFields = graphQLSchemaFields.addArrays.reduce(reducerGenerator('Array'), parseSchemaFields); - } - - if (graphQLSchemaFields.addObjects) { - parseSchemaFields = graphQLSchemaFields.addObjects.reduce(reducerGenerator('Object'), parseSchemaFields); - } - - if (graphQLSchemaFields.addDates) { - parseSchemaFields = graphQLSchemaFields.addDates.reduce(reducerGenerator('Date'), parseSchemaFields); - } - - if (graphQLSchemaFields.addFiles) { - parseSchemaFields = graphQLSchemaFields.addFiles.reduce(reducerGenerator('File'), parseSchemaFields); - } - - if (graphQLSchemaFields.addGeoPoint) { - parseSchemaFields = [graphQLSchemaFields.addGeoPoint].reduce(reducerGenerator('GeoPoint'), parseSchemaFields); - } - - if (graphQLSchemaFields.addPolygons) { - parseSchemaFields = graphQLSchemaFields.addPolygons.reduce(reducerGenerator('Polygon'), parseSchemaFields); - } - - if (graphQLSchemaFields.addBytes) { - parseSchemaFields = graphQLSchemaFields.addBytes.reduce(reducerGenerator('Bytes'), parseSchemaFields); - } - - if (graphQLSchemaFields.addPointers) { - parseSchemaFields = graphQLSchemaFields.addPointers.reduce(reducerGenerator('Pointer'), parseSchemaFields); - } - - if (graphQLSchemaFields.addRelations) { - parseSchemaFields = graphQLSchemaFields.addRelations.reduce(reducerGenerator('Relation'), parseSchemaFields); - } - - if (existingFields && graphQLSchemaFields.remove) { - parseSchemaFields = graphQLSchemaFields.remove.reduce(reducerGenerator('Remove'), parseSchemaFields); - } - - return parseSchemaFields; -}; - -exports.transformToParse = transformToParse; - -const transformToGraphQL = parseSchemaFields => { - return Object.keys(parseSchemaFields).map(name => ({ - name, - type: parseSchemaFields[name].type, - targetClassName: parseSchemaFields[name].targetClass - })); -}; - -exports.transformToGraphQL = transformToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtVG9QYXJzZSIsImdyYXBoUUxTY2hlbWFGaWVsZHMiLCJleGlzdGluZ0ZpZWxkcyIsInBhcnNlU2NoZW1hRmllbGRzIiwicmVkdWNlckdlbmVyYXRvciIsInR5cGUiLCJmaWVsZCIsIm5hbWUiLCJfX29wIiwicmVtb3ZlIiwiZmluZCIsInJlbW92ZUZpZWxkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfS0VZX05BTUUiLCJ0YXJnZXRDbGFzcyIsInRhcmdldENsYXNzTmFtZSIsImFkZFN0cmluZ3MiLCJyZWR1Y2UiLCJhZGROdW1iZXJzIiwiYWRkQm9vbGVhbnMiLCJhZGRBcnJheXMiLCJhZGRPYmplY3RzIiwiYWRkRGF0ZXMiLCJhZGRGaWxlcyIsImFkZEdlb1BvaW50IiwiYWRkUG9seWdvbnMiLCJhZGRCeXRlcyIsImFkZFBvaW50ZXJzIiwiYWRkUmVsYXRpb25zIiwidHJhbnNmb3JtVG9HcmFwaFFMIiwiT2JqZWN0Iiwia2V5cyIsIm1hcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7Ozs7O0FBRUEsTUFBTUEsZ0JBQWdCLEdBQUcsQ0FBQ0MsbUJBQUQsRUFBc0JDLGNBQXRCLEtBQXlDO0FBQ2hFLE1BQUksQ0FBQ0QsbUJBQUwsRUFBMEI7QUFDeEIsV0FBTyxFQUFQO0FBQ0Q7O0FBRUQsTUFBSUUsaUJBQWlCLEdBQUcsRUFBeEI7O0FBRUEsUUFBTUMsZ0JBQWdCLEdBQUdDLElBQUksSUFBSSxDQUFDRixpQkFBRCxFQUFvQkcsS0FBcEIsS0FBOEI7QUFDN0QsUUFBSUQsSUFBSSxLQUFLLFFBQWIsRUFBdUI7QUFDckIsVUFBSUgsY0FBYyxDQUFDSSxLQUFLLENBQUNDLElBQVAsQ0FBbEIsRUFBZ0M7QUFDOUIsK0NBQ0tKLGlCQURMO0FBRUUsV0FBQ0csS0FBSyxDQUFDQyxJQUFQLEdBQWM7QUFDWkMsWUFBQUEsSUFB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O0FBd0lBLE1BQU0yQixrQkFBa0IsR0FBRzNCLGlCQUFpQixJQUFJO0FBQzlDLFNBQU80QixNQUFNLENBQUNDLElBQVAsQ0FBWTdCLGlCQUFaLEVBQStCOEIsR0FBL0IsQ0FBbUMxQixJQUFJLEtBQUs7QUFDakRBLElBQUFBLElBRGlEO0FBRWpERixJQUFBQSxJQUFJLEVBQUVGLGlCQUFpQixDQUFDSSxJQUFELENBQWpCLENBQXdCRixJQUZtQjtBQUdqRFcsSUFBQUEsZUFBZSxFQUFFYixpQkFBaUIsQ0FBQ0ksSUFBRCxDQUFqQixDQUF3QlE7QUFIUSxHQUFMLENBQXZDLENBQVA7QUFLRCxDQU5EIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5jb25zdCB0cmFuc2Zvcm1Ub1BhcnNlID0gKGdyYXBoUUxTY2hlbWFGaWVsZHMsIGV4aXN0aW5nRmllbGRzKSA9PiB7XG4gIGlmICghZ3JhcGhRTFNjaGVtYUZpZWxkcykge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGxldCBwYXJzZVNjaGVtYUZpZWxkcyA9IHt9O1xuXG4gIGNvbnN0IHJlZHVjZXJHZW5lcmF0b3IgPSB0eXBlID0+IChwYXJzZVNjaGVtYUZpZWxkcywgZmllbGQpID0+IHtcbiAgICBpZiAodHlwZSA9PT0gJ1JlbW92ZScpIHtcbiAgICAgIGlmIChleGlzdGluZ0ZpZWxkc1tmaWVsZC5uYW1lXSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnBhcnNlU2NoZW1hRmllbGRzLFxuICAgICAgICAgIFtmaWVsZC5uYW1lXToge1xuICAgICAgICAgICAgX19vcDogJ0RlbGV0ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwYXJzZVNjaGVtYUZpZWxkcztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKFxuICAgICAgZ3JhcGhRTFNjaGVtYUZpZWxkcy5yZW1vdmUgJiZcbiAgICAgIGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlLmZpbmQoXG4gICAgICAgIHJlbW92ZUZpZWxkID0+IHJlbW92ZUZpZWxkLm5hbWUgPT09IGZpZWxkLm5hbWVcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybiBwYXJzZVNjaGVtYUZpZWxkcztcbiAgICB9XG4gICAgaWYgKFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNbZmllbGQubmFtZV0gfHxcbiAgICAgIChleGlzdGluZ0ZpZWxkcyAmJiBleGlzdGluZ0ZpZWxkc1tmaWVsZC5uYW1lXSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgYER1cGxpY2F0ZWQgZmllbGQgbmFtZTogJHtmaWVsZC5uYW1lfWBcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnUmVsYXRpb24nIHx8IHR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucGFyc2VTY2hlbWFGaWVsZHMsXG4gICAgICAgIFtmaWVsZC5uYW1lXToge1xuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgdGFyZ2V0Q2xhc3M6IGZpZWxkLnRhcmdldENsYXNzTmFtZSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAuLi5wYXJzZVNjaGVtYUZpZWxkcyxcbiAgICAgIFtmaWVsZC5uYW1lXToge1xuICAgICAgICB0eXBlLFxuICAgICAgfSxcbiAgICB9O1xuICB9O1xuXG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFN0cmluZ3MpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkU3RyaW5ncy5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdTdHJpbmcnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGROdW1iZXJzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZE51bWJlcnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignTnVtYmVyJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkQm9vbGVhbnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkQm9vbGVhbnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignQm9vbGVhbicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEFycmF5cykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRBcnJheXMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignQXJyYXknKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRPYmplY3RzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZE9iamVjdHMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignT2JqZWN0JyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkRGF0ZXMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkRGF0ZXMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignRGF0ZScpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEZpbGVzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZEZpbGVzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0ZpbGUnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRHZW9Qb2ludCkge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gW2dyYXBoUUxTY2hlbWFGaWVsZHMuYWRkR2VvUG9pbnRdLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0dlb1BvaW50JyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9seWdvbnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9seWdvbnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignUG9seWdvbicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJ5dGVzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJ5dGVzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0J5dGVzJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9pbnRlcnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUG9pbnRlcnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignUG9pbnRlcicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFJlbGF0aW9ucykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRSZWxhdGlvbnMucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignUmVsYXRpb24nKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZXhpc3RpbmdGaWVsZHMgJiYgZ3JhcGhRTFNjaGVtYUZpZWxkcy5yZW1vdmUpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1JlbW92ZScpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlU2NoZW1hRmllbGRzO1xufTtcblxuY29uc3QgdHJhbnNmb3JtVG9HcmFwaFFMID0gcGFyc2VTY2hlbWFGaWVsZHMgPT4ge1xuICByZXR1cm4gT2JqZWN0LmtleXMocGFyc2VTY2hlbWFGaWVsZHMpLm1hcChuYW1lID0+ICh7XG4gICAgbmFtZSxcbiAgICB0eXBlOiBwYXJzZVNjaGVtYUZpZWxkc1tuYW1lXS50eXBlLFxuICAgIHRhcmdldENsYXNzTmFtZTogcGFyc2VTY2hlbWFGaWVsZHNbbmFtZV0udGFyZ2V0Q2xhc3MsXG4gIH0pKTtcbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybVRvUGFyc2UsIHRyYW5zZm9ybVRvR3JhcGhRTCB9O1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/Client.js b/lib/LiveQuery/Client.js deleted file mode 100644 index 205e284d05..0000000000 --- a/lib/LiveQuery/Client.js +++ /dev/null @@ -1,114 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Client = void 0; - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const dafaultFields = ['className', 'objectId', 'updatedAt', 'createdAt', 'ACL']; - -class Client { - constructor(id, parseWebSocket, hasMasterKey = false, sessionToken, installationId) { - this.id = id; - this.parseWebSocket = parseWebSocket; - this.hasMasterKey = hasMasterKey; - this.sessionToken = sessionToken; - this.installationId = installationId; - this.roles = []; - this.subscriptionInfos = new Map(); - this.pushConnect = this._pushEvent('connected'); - this.pushSubscribe = this._pushEvent('subscribed'); - this.pushUnsubscribe = this._pushEvent('unsubscribed'); - this.pushCreate = this._pushEvent('create'); - this.pushEnter = this._pushEvent('enter'); - this.pushUpdate = this._pushEvent('update'); - this.pushDelete = this._pushEvent('delete'); - this.pushLeave = this._pushEvent('leave'); - } - - static pushResponse(parseWebSocket, message) { - _logger.default.verbose('Push Response : %j', message); - - parseWebSocket.send(message); - } - - static pushError(parseWebSocket, code, error, reconnect = true, requestId = null) { - Client.pushResponse(parseWebSocket, JSON.stringify({ - op: 'error', - error, - code, - reconnect, - requestId - })); - } - - addSubscriptionInfo(requestId, subscriptionInfo) { - this.subscriptionInfos.set(requestId, subscriptionInfo); - } - - getSubscriptionInfo(requestId) { - return this.subscriptionInfos.get(requestId); - } - - deleteSubscriptionInfo(requestId) { - return this.subscriptionInfos.delete(requestId); - } - - _pushEvent(type) { - return function (subscriptionId, parseObjectJSON, parseOriginalObjectJSON) { - const response = { - op: type, - clientId: this.id, - installationId: this.installationId - }; - - if (typeof subscriptionId !== 'undefined') { - response['requestId'] = subscriptionId; - } - - if (typeof parseObjectJSON !== 'undefined') { - let fields; - - if (this.subscriptionInfos.has(subscriptionId)) { - fields = this.subscriptionInfos.get(subscriptionId).fields; - } - - response['object'] = this._toJSONWithFields(parseObjectJSON, fields); - - if (parseOriginalObjectJSON) { - response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, fields); - } - } - - Client.pushResponse(this.parseWebSocket, JSON.stringify(response)); - }; - } - - _toJSONWithFields(parseObjectJSON, fields) { - if (!fields) { - return parseObjectJSON; - } - - const limitedParseObject = {}; - - for (const field of dafaultFields) { - limitedParseObject[field] = parseObjectJSON[field]; - } - - for (const field of fields) { - if (field in parseObjectJSON) { - limitedParseObject[field] = parseObjectJSON[field]; - } - } - - return limitedParseObject; - } - -} - -exports.Client = Client; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvQ2xpZW50LmpzIl0sIm5hbWVzIjpbImRhZmF1bHRGaWVsZHMiLCJDbGllbnQiLCJjb25zdHJ1Y3RvciIsImlkIiwicGFyc2VXZWJTb2NrZXQiLCJoYXNNYXN0ZXJLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInJvbGVzIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJNYXAiLCJwdXNoQ29ubmVjdCIsIl9wdXNoRXZlbnQiLCJwdXNoU3Vic2NyaWJlIiwicHVzaFVuc3Vic2NyaWJlIiwicHVzaENyZWF0ZSIsInB1c2hFbnRlciIsInB1c2hVcGRhdGUiLCJwdXNoRGVsZXRlIiwicHVzaExlYXZlIiwicHVzaFJlc3BvbnNlIiwibWVzc2FnZSIsImxvZ2dlciIsInZlcmJvc2UiLCJzZW5kIiwicHVzaEVycm9yIiwiY29kZSIsImVycm9yIiwicmVjb25uZWN0IiwicmVxdWVzdElkIiwiSlNPTiIsInN0cmluZ2lmeSIsIm9wIiwiYWRkU3Vic2NyaXB0aW9uSW5mbyIsInN1YnNjcmlwdGlvbkluZm8iLCJzZXQiLCJnZXRTdWJzY3JpcHRpb25JbmZvIiwiZ2V0IiwiZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyIsImRlbGV0ZSIsInR5cGUiLCJzdWJzY3JpcHRpb25JZCIsInBhcnNlT2JqZWN0SlNPTiIsInBhcnNlT3JpZ2luYWxPYmplY3RKU09OIiwicmVzcG9uc2UiLCJjbGllbnRJZCIsImZpZWxkcyIsImhhcyIsIl90b0pTT05XaXRoRmllbGRzIiwibGltaXRlZFBhcnNlT2JqZWN0IiwiZmllbGQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUtBLE1BQU1BLGFBQWEsR0FBRyxDQUFDLFdBQUQsRUFBYyxVQUFkLEVBQTBCLFdBQTFCLEVBQXVDLFdBQXZDLEVBQW9ELEtBQXBELENBQXRCOztBQUVBLE1BQU1DLE1BQU4sQ0FBYTtBQWtCWEMsRUFBQUEsV0FBVyxDQUNUQyxFQURTLEVBRVRDLGNBRlMsRUFHVEMs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cnQgdHlwZSB7IEZsYXR0ZW5lZE9iamVjdERhdGEgfSBmcm9tICcuL1N1YnNjcmlwdGlvbic7XG5leHBvcnQgdHlwZSBNZXNzYWdlID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNvbnN0IGRhZmF1bHRGaWVsZHMgPSBbJ2NsYXNzTmFtZScsICdvYmplY3RJZCcsICd1cGRhdGVkQXQnLCAnY3JlYXRlZEF0JywgJ0FDTCddO1xuXG5jbGFzcyBDbGllbnQge1xuICBpZDogbnVtYmVyO1xuICBwYXJzZVdlYlNvY2tldDogYW55O1xuICBoYXNNYXN0ZXJLZXk6IGJvb2xlYW47XG4gIHNlc3Npb25Ub2tlbjogc3RyaW5nO1xuICBpbnN0YWxsYXRpb25JZDogc3RyaW5nO1xuICB1c2VySWQ6IHN0cmluZztcbiAgcm9sZXM6IEFycmF5PHN0cmluZz47XG4gIHN1YnNjcmlwdGlvbkluZm9zOiBPYmplY3Q7XG4gIHB1c2hDb25uZWN0OiBGdW5jdGlvbjtcbiAgcHVzaFN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hVbnN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hDcmVhdGU6IEZ1bmN0aW9uO1xuICBwdXNoRW50ZXI6IEZ1bmN0aW9uO1xuICBwdXNoVXBkYXRlOiBGdW5jdGlvbjtcbiAgcHVzaERlbGV0ZTogRnVuY3Rpb247XG4gIHB1c2hMZWF2ZTogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaWQ6IG51bWJlcixcbiAgICBwYXJzZVdlYlNvY2tldDogYW55LFxuICAgIGhhc01hc3RlcktleTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIHNlc3Npb25Ub2tlbjogc3RyaW5nLFxuICAgIGluc3RhbGxhdGlvbklkOiBzdHJpbmdcbiAgKSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyc2VXZWJTb2NrZXQgPSBwYXJzZVdlYlNvY2tldDtcbiAgICB0aGlzLmhhc01hc3RlcktleSA9IGhhc01hc3RlcktleTtcbiAgICB0aGlzLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gICAgdGhpcy5yb2xlcyA9IFtdO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5wdXNoQ29ubmVjdCA9IHRoaXMuX3B1c2hFdmVudCgnY29ubmVjdGVkJyk7XG4gICAgdGhpcy5wdXNoU3Vic2NyaWJlID0gdGhpcy5fcHVzaEV2ZW50KCdzdWJzY3JpYmVkJyk7XG4gICAgdGhpcy5wdXNoVW5zdWJzY3JpYmUgPSB0aGlzLl9wdXNoRXZlbnQoJ3Vuc3Vic2NyaWJlZCcpO1xuICAgIHRoaXMucHVzaENyZWF0ZSA9IHRoaXMuX3B1c2hFdmVudCgnY3JlYXRlJyk7XG4gICAgdGhpcy5wdXNoRW50ZXIgPSB0aGlzLl9wdXNoRXZlbnQoJ2VudGVyJyk7XG4gICAgdGhpcy5wdXNoVXBkYXRlID0gdGhpcy5fcHVzaEV2ZW50KCd1cGRhdGUnKTtcbiAgICB0aGlzLnB1c2hEZWxldGUgPSB0aGlzLl9wdXNoRXZlbnQoJ2RlbGV0ZScpO1xuICAgIHRoaXMucHVzaExlYXZlID0gdGhpcy5fcHVzaEV2ZW50KCdsZWF2ZScpO1xuICB9XG5cbiAgc3RhdGljIHB1c2hSZXNwb25zZShwYXJzZVdlYlNvY2tldDogYW55LCBtZXNzYWdlOiBNZXNzYWdlKTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ1B1c2ggUmVzcG9uc2UgOiAlaicsIG1lc3NhZ2UpO1xuICAgIHBhcnNlV2ViU29ja2V0LnNlbmQobWVzc2FnZSk7XG4gIH1cblxuICBzdGF0aWMgcHVzaEVycm9yKFxuICAgIHBhcnNlV2ViU29ja2V0OiBhbnksXG4gICAgY29kZTogbnVtYmVyLFxuICAgIGVycm9yOiBzdHJpbmcsXG4gICAgcmVjb25uZWN0OiBib29sZWFuID0gdHJ1ZSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlciB8IHZvaWQgPSBudWxsXG4gICk6IHZvaWQge1xuICAgIENsaWVudC5wdXNoUmVzcG9uc2UoXG4gICAgICBwYXJzZVdlYlNvY2tldCxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgb3A6ICdlcnJvcicsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBjb2RlLFxuICAgICAgICByZWNvbm5lY3QsXG4gICAgICAgIHJlcXVlc3RJZCxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIsIHN1YnNjcmlwdGlvbkluZm86IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3Muc2V0KHJlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mbyk7XG4gIH1cblxuICBnZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZDogbnVtYmVyKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZVN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5kZWxldGUocmVxdWVzdElkKTtcbiAgfVxuXG4gIF9wdXNoRXZlbnQodHlwZTogc3RyaW5nKTogRnVuY3Rpb24ge1xuICAgIHJldHVybiBmdW5jdGlvbiAoXG4gICAgICBzdWJzY3JpcHRpb25JZDogbnVtYmVyLFxuICAgICAgcGFyc2VPYmplY3RKU09OOiBhbnksXG4gICAgICBwYXJzZU9yaWdpbmFsT2JqZWN0SlNPTjogYW55XG4gICAgKTogdm9pZCB7XG4gICAgICBjb25zdCByZXNwb25zZTogTWVzc2FnZSA9IHtcbiAgICAgICAgb3A6IHR5cGUsXG4gICAgICAgIGNsaWVudElkOiB0aGlzLmlkLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogdGhpcy5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXNwb25zZVsncmVxdWVzdElkJ10gPSBzdWJzY3JpcHRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFyc2VPYmplY3RKU09OICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBsZXQgZmllbGRzO1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25JbmZvcy5oYXMoc3Vic2NyaXB0aW9uSWQpKSB7XG4gICAgICAgICAgZmllbGRzID0gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQoc3Vic2NyaXB0aW9uSWQpLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTiwgZmllbGRzKTtcbiAgICAgICAgaWYgKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OKSB7XG4gICAgICAgICAgcmVzcG9uc2VbJ29yaWdpbmFsJ10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OLCBmaWVsZHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBDbGllbnQucHVzaFJlc3BvbnNlKHRoaXMucGFyc2VXZWJTb2NrZXQsIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XG4gICAgfTtcbiAgfVxuXG4gIF90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTjogYW55LCBmaWVsZHM6IGFueSk6IEZsYXR0ZW5lZE9iamVjdERhdGEge1xuICAgIGlmICghZmllbGRzKSB7XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RKU09OO1xuICAgIH1cbiAgICBjb25zdCBsaW1pdGVkUGFyc2VPYmplY3QgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGRhZmF1bHRGaWVsZHMpIHtcbiAgICAgIGxpbWl0ZWRQYXJzZU9iamVjdFtmaWVsZF0gPSBwYXJzZU9iamVjdEpTT05bZmllbGRdO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgaWYgKGZpZWxkIGluIHBhcnNlT2JqZWN0SlNPTikge1xuICAgICAgICBsaW1pdGVkUGFyc2VPYmplY3RbZmllbGRdID0gcGFyc2VPYmplY3RKU09OW2ZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbWl0ZWRQYXJzZU9iamVjdDtcbiAgfVxufVxuXG5leHBvcnQgeyBDbGllbnQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Id.js b/lib/LiveQuery/Id.js deleted file mode 100644 index 379e29b88d..0000000000 --- a/lib/LiveQuery/Id.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; - -class Id { - constructor(className, objectId) { - this.className = className; - this.objectId = objectId; - } - - toString() { - return this.className + ':' + this.objectId; - } - - static fromString(str) { - var split = str.split(':'); - - if (split.length !== 2) { - throw new TypeError('Cannot create Id object from this string'); - } - - return new Id(split[0], split[1]); - } - -} - -module.exports = Id; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvSWQuanMiXSwibmFtZXMiOlsiSWQiLCJjb25zdHJ1Y3RvciIsImNsYXNzTmFtZSIsIm9iamVjdElkIiwidG9TdHJpbmciLCJmcm9tU3RyaW5nIiwic3RyIiwic3BsaXQiLCJsZW5ndGgiLCJUeXBlRXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEVBQU4sQ0FBUztBQUlQQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLFFBQXBCLEVBQXNDO0FBQy9DLFNBQUtELFNBQUwsR0FBaUJBLFNBQWpCO0FBQ0EsU0FBS0MsUUFBTCxHQUFnQkEsUUFBaEI7QUFDRDs7QUFDREMsRUFBQUEsUUFBUSxHQUFXO0FBQ2pCLFdBQU8sS0FBS0YsU0FBTCxHQUFpQixHQUFqQixHQUF1QixLQUFLQyxRQUFuQztBQUNEOztBQUVELFNBQU9FLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQStCO0FBQzdCLFFBQUlDLEtBQUssR0FBR0QsR0FBRyxDQUFDQyxLQUFKLENBQVUsR0FBVixDQUFaOztBQUNBLFFBQUlBLEtBQUssQ0FBQ0MsTUFBTixLQUFpQixDQUFyQixFQUF3QjtBQUN0QixZQUFNLElBQUlDLFNBQUosQ0FBYywwQ0FBZCxDQUFOO0FBQ0Q7O0FBQ0QsV0FBTyxJQUFJVCxFQUFKLENBQU9PLEtBQUssQ0FBQyxDQUFELENBQVosRUFBaUJBLEtBQUssQ0FBQyxDQUFELENBQXRCLENBQVA7QUFDRDs7QUFsQk07O0FBcUJURyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLEVBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgSWQge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgb2JqZWN0SWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6IHN0cmluZykge1xuICAgIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIHRoaXMub2JqZWN0SWQgPSBvYmplY3RJZDtcbiAgfVxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNsYXNzTmFtZSArICc6JyArIHRoaXMub2JqZWN0SWQ7XG4gIH1cblxuICBzdGF0aWMgZnJvbVN0cmluZyhzdHI6IHN0cmluZykge1xuICAgIHZhciBzcGxpdCA9IHN0ci5zcGxpdCgnOicpO1xuICAgIGlmIChzcGxpdC5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjcmVhdGUgSWQgb2JqZWN0IGZyb20gdGhpcyBzdHJpbmcnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJZChzcGxpdFswXSwgc3BsaXRbMV0pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSWQ7XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseCloudCodePublisher.js b/lib/LiveQuery/ParseCloudCodePublisher.js deleted file mode 100644 index 974770a79f..0000000000 --- a/lib/LiveQuery/ParseCloudCodePublisher.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseCloudCodePublisher = void 0; - -var _ParsePubSub = require("./ParsePubSub"); - -var _node = _interopRequireDefault(require("parse/node")); - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseCloudCodePublisher { - // config object of the publisher, right now it only contains the redisURL, - // but we may extend it later. - constructor(config = {}) { - this.parsePublisher = _ParsePubSub.ParsePubSub.createPublisher(config); - } - - onCloudCodeAfterSave(request) { - this._onCloudCodeMessage(_node.default.applicationId + 'afterSave', request); - } - - onCloudCodeAfterDelete(request) { - this._onCloudCodeMessage(_node.default.applicationId + 'afterDelete', request); - } // Request is the request object from cloud code functions. request.object is a ParseObject. - - - _onCloudCodeMessage(type, request) { - _logger.default.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original); // We need the full JSON which includes className - - - const message = { - currentParseObject: request.object._toFullJSON() - }; - - if (request.original) { - message.originalParseObject = request.original._toFullJSON(); - } - - this.parsePublisher.publish(type, JSON.stringify(message)); - } - -} - -exports.ParseCloudCodePublisher = ParseCloudCodePublisher; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIuanMiXSwibmFtZXMiOlsiUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsInBhcnNlUHVibGlzaGVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVQdWJsaXNoZXIiLCJvbkNsb3VkQ29kZUFmdGVyU2F2ZSIsInJlcXVlc3QiLCJfb25DbG91ZENvZGVNZXNzYWdlIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwib25DbG91ZENvZGVBZnRlckRlbGV0ZSIsInR5cGUiLCJsb2dnZXIiLCJ2ZXJib3NlIiwib2JqZWN0Iiwib3JpZ2luYWwiLCJtZXNzYWdlIiwiY3VycmVudFBhcnNlT2JqZWN0IiwiX3RvRnVsbEpTT04iLCJvcmlnaW5hbFBhcnNlT2JqZWN0IiwicHVibGlzaCIsIkpTT04iLCJzdHJpbmdpZnkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHVCQUFOLENBQThCO0FBRzVCO0FBQ0E7QUFDQUMsRUFBQUEsV0FBVyxDQUFDQyxNQUFXLEdBQUcsRUFBZixFQUFtQjtBQUM1QixTQUFLQyxjQUFMLEdBQXNCQyx5QkFBWUMsZUFBWixDQUE0QkgsTUFBNUIsQ0FBdEI7QUFDRDs7QUFFREksRUFBQUEsb0JBQW9CLENBQUNDLE9BQUQsRUFBcUI7QUFDdkMsU0FBS0MsbUJBQUwsQ0FBeUJDLGNBQU1DLGFBQU4sR0FBc0IsV0FBL0MsRUFBNERILE9BQTVEO0FBQ0Q7O0FBRURJLEVBQUFBLHNCQUFzQixDQUFDSixPQUFELEVBQXFCO0FBQ3pDLFNBQUtDLG1CQUFMLENBQXlCQyxjQUFNQyxhQUFOLEdBQXNCLGFBQS9DLEVBQThESCxPQUE5RDtBQUNELEdBZjJCLENBaUI1Qjs7O0FBQ0FDLEVBQUFBLG1CQUFtQixDQUFDSSxJQUFELEVBQWVMLE9BQWYsRUFBbUM7QUFDcERNLG9CQUFPQyxPQUFQLENBQ0UsMERBREYsRUFFRVAsT0FBTyxDQUFDUSxNQUZWLEVBR0VSLE9BQU8sQ0FBQ1MsUUFIVixFQURvRCxDQU1wRDs7O0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RDLE1BQUFBLGtCQUFrQixFQUFFWCxPQUFPLENBQUNRLE1BQVIsQ0FBZUksV0FBZjtBQUROLEtBQWhCOztBQUdBLFFBQUlaLE9BQU8sQ0FBQ1MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsT0FBTyxDQUFDRyxtQkFBUixHQUE4QmIsT0FBTyxDQUFDUyxRQUFSLENBQWlCRyxXQUFqQixFQUE5QjtBQUNEOztBQUNELFNBQUtoQixjQUFMLENBQW9Ca0IsT0FBcEIsQ0FBNEJULElBQTVCLEVBQWtDVSxJQUFJLENBQUNDLFNBQUwsQ0FBZU4sT0FBZixDQUFsQztBQUNEOztBQWhDMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZVB1YlN1YiB9IGZyb20gJy4vUGFyc2VQdWJTdWInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuXG5jbGFzcyBQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlciB7XG4gIHBhcnNlUHVibGlzaGVyOiBPYmplY3Q7XG5cbiAgLy8gY29uZmlnIG9iamVjdCBvZiB0aGUgcHVibGlzaGVyLCByaWdodCBub3cgaXQgb25seSBjb250YWlucyB0aGUgcmVkaXNVUkwsXG4gIC8vIGJ1dCB3ZSBtYXkgZXh0ZW5kIGl0IGxhdGVyLlxuICBjb25zdHJ1Y3Rvcihjb25maWc6IGFueSA9IHt9KSB7XG4gICAgdGhpcy5wYXJzZVB1Ymxpc2hlciA9IFBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG5cbiAgb25DbG91ZENvZGVBZnRlclNhdmUocmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5fb25DbG91ZENvZGVNZXNzYWdlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJywgcmVxdWVzdCk7XG4gIH1cblxuICBvbkNsb3VkQ29kZUFmdGVyRGVsZXRlKHJlcXVlc3Q6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2xvdWRDb2RlTWVzc2FnZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJywgcmVxdWVzdCk7XG4gIH1cblxuICAvLyBSZXF1ZXN0IGlzIHRoZSByZXF1ZXN0IG9iamVjdCBmcm9tIGNsb3VkIGNvZGUgZnVuY3Rpb25zLiByZXF1ZXN0Lm9iamVjdCBpcyBhIFBhcnNlT2JqZWN0LlxuICBfb25DbG91ZENvZGVNZXNzYWdlKHR5cGU6IHN0cmluZywgcmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUmF3IHJlcXVlc3QgZnJvbSBjbG91ZCBjb2RlIGN1cnJlbnQgOiAlaiB8IG9yaWdpbmFsIDogJWonLFxuICAgICAgcmVxdWVzdC5vYmplY3QsXG4gICAgICByZXF1ZXN0Lm9yaWdpbmFsXG4gICAgKTtcbiAgICAvLyBXZSBuZWVkIHRoZSBmdWxsIEpTT04gd2hpY2ggaW5jbHVkZXMgY2xhc3NOYW1lXG4gICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgIGN1cnJlbnRQYXJzZU9iamVjdDogcmVxdWVzdC5vYmplY3QuX3RvRnVsbEpTT04oKSxcbiAgICB9O1xuICAgIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgICBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgPSByZXF1ZXN0Lm9yaWdpbmFsLl90b0Z1bGxKU09OKCk7XG4gICAgfVxuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIucHVibGlzaCh0eXBlLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlKSk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/ParseLiveQueryServer.js b/lib/LiveQuery/ParseLiveQueryServer.js deleted file mode 100644 index 921c301c59..0000000000 --- a/lib/LiveQuery/ParseLiveQueryServer.js +++ /dev/null @@ -1,847 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseLiveQueryServer = void 0; - -var _tv = _interopRequireDefault(require("tv4")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _Subscription = require("./Subscription"); - -var _Client = require("./Client"); - -var _ParseWebSocketServer = require("./ParseWebSocketServer"); - -var _logger = _interopRequireDefault(require("../logger")); - -var _RequestSchema = _interopRequireDefault(require("./RequestSchema")); - -var _QueryTools = require("./QueryTools"); - -var _ParsePubSub = require("./ParsePubSub"); - -var _SchemaController = _interopRequireDefault(require("../Controllers/SchemaController")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _uuid = require("uuid"); - -var _triggers = require("../triggers"); - -var _Auth = require("../Auth"); - -var _Controllers = require("../Controllers"); - -var _lruCache = _interopRequireDefault(require("lru-cache")); - -var _UsersRouter = _interopRequireDefault(require("../Routers/UsersRouter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseLiveQueryServer { - // className -> (queryHash -> subscription) - // The subscriber we use to get object update from publisher - constructor(server, config = {}, parseServerConfig = {}) { - this.server = server; - this.clients = new Map(); - this.subscriptions = new Map(); - this.config = config; - config.appId = config.appId || _node.default.applicationId; - config.masterKey = config.masterKey || _node.default.masterKey; // Store keys, convert obj to map - - const keyPairs = config.keyPairs || {}; - this.keyPairs = new Map(); - - for (const key of Object.keys(keyPairs)) { - this.keyPairs.set(key, keyPairs[key]); - } - - _logger.default.verbose('Support key pairs', this.keyPairs); // Initialize Parse - - - _node.default.Object.disableSingleInstance(); - - const serverURL = config.serverURL || _node.default.serverURL; - _node.default.serverURL = serverURL; - - _node.default.initialize(config.appId, _node.default.javaScriptKey, config.masterKey); // The cache controller is a proper cache controller - // with access to User and Roles - - - this.cacheController = (0, _Controllers.getCacheController)(parseServerConfig); - config.cacheTimeout = config.cacheTimeout || 5 * 1000; // 5s - // This auth cache stores the promises for each auth resolution. - // The main benefit is to be able to reuse the same user / session token resolution. - - this.authCache = new _lruCache.default({ - max: 500, - // 500 concurrent - maxAge: config.cacheTimeout - }); // Initialize websocket server - - this.parseWebSocketServer = new _ParseWebSocketServer.ParseWebSocketServer(server, parseWebsocket => this._onConnect(parseWebsocket), config); // Initialize subscriber - - this.subscriber = _ParsePubSub.ParsePubSub.createSubscriber(config); - this.subscriber.subscribe(_node.default.applicationId + 'afterSave'); - this.subscriber.subscribe(_node.default.applicationId + 'afterDelete'); // Register message handler for subscriber. When publisher get messages, it will publish message - // to the subscribers and the handler will be called. - - this.subscriber.on('message', (channel, messageStr) => { - _logger.default.verbose('Subscribe messsage %j', messageStr); - - let message; - - try { - message = JSON.parse(messageStr); - } catch (e) { - _logger.default.error('unable to parse message', messageStr, e); - - return; - } - - this._inflateParseObject(message); - - if (channel === _node.default.applicationId + 'afterSave') { - this._onAfterSave(message); - } else if (channel === _node.default.applicationId + 'afterDelete') { - this._onAfterDelete(message); - } else { - _logger.default.error('Get message %s from unknown channel %j', message, channel); - } - }); - } // Message is the JSON object from publisher. Message.currentParseObject is the ParseObject JSON after changes. - // Message.originalParseObject is the original ParseObject JSON. - - - _inflateParseObject(message) { - // Inflate merged object - const currentParseObject = message.currentParseObject; - - _UsersRouter.default.removeHiddenProperties(currentParseObject); - - let className = currentParseObject.className; - let parseObject = new _node.default.Object(className); - - parseObject._finishFetch(currentParseObject); - - message.currentParseObject = parseObject; // Inflate original object - - const originalParseObject = message.originalParseObject; - - if (originalParseObject) { - _UsersRouter.default.removeHiddenProperties(originalParseObject); - - className = originalParseObject.className; - parseObject = new _node.default.Object(className); - - parseObject._finishFetch(originalParseObject); - - message.originalParseObject = parseObject; - } - } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. - // Message.originalParseObject is the original ParseObject. - - - _onAfterDelete(message) { - _logger.default.verbose(_node.default.applicationId + 'afterDelete is triggered'); - - let deletedParseObject = message.currentParseObject.toJSON(); - const classLevelPermissions = message.classLevelPermissions; - const className = deletedParseObject.className; - - _logger.default.verbose('ClassName: %j | ObjectId: %s', className, deletedParseObject.id); - - _logger.default.verbose('Current client number : %d', this.clients.size); - - const classSubscriptions = this.subscriptions.get(className); - - if (typeof classSubscriptions === 'undefined') { - _logger.default.debug('Can not find subscriptions under this class ' + className); - - return; - } - - for (const subscription of classSubscriptions.values()) { - const isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription); - - if (!isSubscriptionMatched) { - continue; - } - - for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { - const client = this.clients.get(clientId); - - if (typeof client === 'undefined') { - continue; - } - - for (const requestId of requestIds) { - const acl = message.currentParseObject.getACL(); // Check CLP - - const op = this._getCLPOperation(subscription.query); - - let res = {}; - - this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { - // Check ACL - return this._matchesACL(acl, client, requestId); - }).then(isMatched => { - if (!isMatched) { - return null; - } - - res = { - event: 'Delete', - sessionToken: client.sessionToken, - object: deletedParseObject, - clients: this.clients.size, - subscriptions: this.subscriptions.size, - useMasterKey: client.hasMasterKey, - installationId: client.installationId, - sendEvent: true - }; - return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); - }).then(() => { - if (!res.sendEvent) { - return; - } - - if (res.object && typeof res.object.toJSON === 'function') { - deletedParseObject = res.object.toJSON(); - deletedParseObject.className = className; - } - - client.pushDelete(requestId, deletedParseObject); - }).catch(error => { - _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); - - _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); - }); - } - } - } - } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. - // Message.originalParseObject is the original ParseObject. - - - _onAfterSave(message) { - _logger.default.verbose(_node.default.applicationId + 'afterSave is triggered'); - - let originalParseObject = null; - - if (message.originalParseObject) { - originalParseObject = message.originalParseObject.toJSON(); - } - - const classLevelPermissions = message.classLevelPermissions; - let currentParseObject = message.currentParseObject.toJSON(); - const className = currentParseObject.className; - - _logger.default.verbose('ClassName: %s | ObjectId: %s', className, currentParseObject.id); - - _logger.default.verbose('Current client number : %d', this.clients.size); - - const classSubscriptions = this.subscriptions.get(className); - - if (typeof classSubscriptions === 'undefined') { - _logger.default.debug('Can not find subscriptions under this class ' + className); - - return; - } - - for (const subscription of classSubscriptions.values()) { - const isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription); - - const isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription); - - for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { - const client = this.clients.get(clientId); - - if (typeof client === 'undefined') { - continue; - } - - for (const requestId of requestIds) { - // Set orignal ParseObject ACL checking promise, if the object does not match - // subscription, we do not need to check ACL - let originalACLCheckingPromise; - - if (!isOriginalSubscriptionMatched) { - originalACLCheckingPromise = Promise.resolve(false); - } else { - let originalACL; - - if (message.originalParseObject) { - originalACL = message.originalParseObject.getACL(); - } - - originalACLCheckingPromise = this._matchesACL(originalACL, client, requestId); - } // Set current ParseObject ACL checking promise, if the object does not match - // subscription, we do not need to check ACL - - - let currentACLCheckingPromise; - let res = {}; - - if (!isCurrentSubscriptionMatched) { - currentACLCheckingPromise = Promise.resolve(false); - } else { - const currentACL = message.currentParseObject.getACL(); - currentACLCheckingPromise = this._matchesACL(currentACL, client, requestId); - } - - const op = this._getCLPOperation(subscription.query); - - this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { - return Promise.all([originalACLCheckingPromise, currentACLCheckingPromise]); - }).then(([isOriginalMatched, isCurrentMatched]) => { - _logger.default.verbose('Original %j | Current %j | Match: %s, %s, %s, %s | Query: %s', originalParseObject, currentParseObject, isOriginalSubscriptionMatched, isCurrentSubscriptionMatched, isOriginalMatched, isCurrentMatched, subscription.hash); // Decide event type - - - let type; - - if (isOriginalMatched && isCurrentMatched) { - type = 'Update'; - } else if (isOriginalMatched && !isCurrentMatched) { - type = 'Leave'; - } else if (!isOriginalMatched && isCurrentMatched) { - if (originalParseObject) { - type = 'Enter'; - } else { - type = 'Create'; - } - } else { - return null; - } - - message.event = type; - res = { - event: type, - sessionToken: client.sessionToken, - object: currentParseObject, - original: originalParseObject, - clients: this.clients.size, - subscriptions: this.subscriptions.size, - useMasterKey: client.hasMasterKey, - installationId: client.installationId, - sendEvent: true - }; - return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); - }).then(() => { - if (!res.sendEvent) { - return; - } - - if (res.object && typeof res.object.toJSON === 'function') { - currentParseObject = res.object.toJSON(); - currentParseObject.className = res.object.className || className; - } - - if (res.original && typeof res.original.toJSON === 'function') { - originalParseObject = res.original.toJSON(); - originalParseObject.className = res.original.className || className; - } - - const functionName = 'push' + message.event; - - if (client[functionName]) { - client[functionName](requestId, currentParseObject, originalParseObject); - } - }, error => { - _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); - - _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); - }); - } - } - } - } - - _onConnect(parseWebsocket) { - parseWebsocket.on('message', request => { - if (typeof request === 'string') { - try { - request = JSON.parse(request); - } catch (e) { - _logger.default.error('unable to parse request', request, e); - - return; - } - } - - _logger.default.verbose('Request: %j', request); // Check whether this request is a valid request, return error directly if not - - - if (!_tv.default.validate(request, _RequestSchema.default['general']) || !_tv.default.validate(request, _RequestSchema.default[request.op])) { - _Client.Client.pushError(parseWebsocket, 1, _tv.default.error.message); - - _logger.default.error('Connect message error %s', _tv.default.error.message); - - return; - } - - switch (request.op) { - case 'connect': - this._handleConnect(parseWebsocket, request); - - break; - - case 'subscribe': - this._handleSubscribe(parseWebsocket, request); - - break; - - case 'update': - this._handleUpdateSubscription(parseWebsocket, request); - - break; - - case 'unsubscribe': - this._handleUnsubscribe(parseWebsocket, request); - - break; - - default: - _Client.Client.pushError(parseWebsocket, 3, 'Get unknown operation'); - - _logger.default.error('Get unknown operation', request.op); - - } - }); - parseWebsocket.on('disconnect', () => { - _logger.default.info(`Client disconnect: ${parseWebsocket.clientId}`); - - const clientId = parseWebsocket.clientId; - - if (!this.clients.has(clientId)) { - (0, _triggers.runLiveQueryEventHandlers)({ - event: 'ws_disconnect_error', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - error: `Unable to find client ${clientId}` - }); - - _logger.default.error(`Can not find client ${clientId} on disconnect`); - - return; - } // Delete client - - - const client = this.clients.get(clientId); - this.clients.delete(clientId); // Delete client from subscriptions - - for (const [requestId, subscriptionInfo] of _lodash.default.entries(client.subscriptionInfos)) { - const subscription = subscriptionInfo.subscription; - subscription.deleteClientSubscription(clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions - - const classSubscriptions = this.subscriptions.get(subscription.className); - - if (!subscription.hasSubscribingClient()) { - classSubscriptions.delete(subscription.hash); - } // If there is no subscriptions under this class, remove it from subscriptions - - - if (classSubscriptions.size === 0) { - this.subscriptions.delete(subscription.className); - } - } - - _logger.default.verbose('Current clients %d', this.clients.size); - - _logger.default.verbose('Current subscriptions %d', this.subscriptions.size); - - (0, _triggers.runLiveQueryEventHandlers)({ - event: 'ws_disconnect', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - useMasterKey: client.hasMasterKey, - installationId: client.installationId - }); - }); - (0, _triggers.runLiveQueryEventHandlers)({ - event: 'ws_connect', - clients: this.clients.size, - subscriptions: this.subscriptions.size - }); - } - - _matchesSubscription(parseObject, subscription) { - // Object is undefined or null, not match - if (!parseObject) { - return false; - } - - return (0, _QueryTools.matchesQuery)(parseObject, subscription.query); - } - - getAuthForSessionToken(sessionToken) { - if (!sessionToken) { - return Promise.resolve({}); - } - - const fromCache = this.authCache.get(sessionToken); - - if (fromCache) { - return fromCache; - } - - const authPromise = (0, _Auth.getAuthForSessionToken)({ - cacheController: this.cacheController, - sessionToken: sessionToken - }).then(auth => { - return { - auth, - userId: auth && auth.user && auth.user.id - }; - }).catch(error => { - // There was an error with the session token - const result = {}; - - if (error && error.code === _node.default.Error.INVALID_SESSION_TOKEN) { - result.error = error; - this.authCache.set(sessionToken, Promise.resolve(result), this.config.cacheTimeout); - } else { - this.authCache.del(sessionToken); - } - - return result; - }); - this.authCache.set(sessionToken, authPromise); - return authPromise; - } - - async _matchesCLP(classLevelPermissions, object, client, requestId, op) { - // try to match on user first, less expensive than with roles - const subscriptionInfo = client.getSubscriptionInfo(requestId); - const aclGroup = ['*']; - let userId; - - if (typeof subscriptionInfo !== 'undefined') { - const { - userId - } = await this.getAuthForSessionToken(subscriptionInfo.sessionToken); - - if (userId) { - aclGroup.push(userId); - } - } - - try { - await _SchemaController.default.validatePermission(classLevelPermissions, object.className, aclGroup, op); - return true; - } catch (e) { - _logger.default.verbose(`Failed matching CLP for ${object.id} ${userId} ${e}`); - - return false; - } // TODO: handle roles permissions - // Object.keys(classLevelPermissions).forEach((key) => { - // const perm = classLevelPermissions[key]; - // Object.keys(perm).forEach((key) => { - // if (key.indexOf('role')) - // }); - // }) - // // it's rejected here, check the roles - // var rolesQuery = new Parse.Query(Parse.Role); - // rolesQuery.equalTo("users", user); - // return rolesQuery.find({useMasterKey:true}); - - } - - _getCLPOperation(query) { - return typeof query === 'object' && Object.keys(query).length == 1 && typeof query.objectId === 'string' ? 'get' : 'find'; - } - - async _verifyACL(acl, token) { - if (!token) { - return false; - } - - const { - auth, - userId - } = await this.getAuthForSessionToken(token); // Getting the session token failed - // This means that no additional auth is available - // At this point, just bail out as no additional visibility can be inferred. - - if (!auth || !userId) { - return false; - } - - const isSubscriptionSessionTokenMatched = acl.getReadAccess(userId); - - if (isSubscriptionSessionTokenMatched) { - return true; - } // Check if the user has any roles that match the ACL - - - return Promise.resolve().then(async () => { - // Resolve false right away if the acl doesn't have any roles - const acl_has_roles = Object.keys(acl.permissionsById).some(key => key.startsWith('role:')); - - if (!acl_has_roles) { - return false; - } - - const roleNames = await auth.getUserRoles(); // Finally, see if any of the user's roles allow them read access - - for (const role of roleNames) { - // We use getReadAccess as `role` is in the form `role:roleName` - if (acl.getReadAccess(role)) { - return true; - } - } - - return false; - }).catch(() => { - return false; - }); - } - - async _matchesACL(acl, client, requestId) { - // Return true directly if ACL isn't present, ACL is public read, or client has master key - if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) { - return true; - } // Check subscription sessionToken matches ACL first - - - const subscriptionInfo = client.getSubscriptionInfo(requestId); - - if (typeof subscriptionInfo === 'undefined') { - return false; - } - - const subscriptionToken = subscriptionInfo.sessionToken; - const clientSessionToken = client.sessionToken; - - if (await this._verifyACL(acl, subscriptionToken)) { - return true; - } - - if (await this._verifyACL(acl, clientSessionToken)) { - return true; - } - - return false; - } - - async _handleConnect(parseWebsocket, request) { - if (!this._validateKeys(request, this.keyPairs)) { - _Client.Client.pushError(parseWebsocket, 4, 'Key in request is not valid'); - - _logger.default.error('Key in request is not valid'); - - return; - } - - const hasMasterKey = this._hasMasterKey(request, this.keyPairs); - - const clientId = (0, _uuid.v4)(); - const client = new _Client.Client(clientId, parseWebsocket, hasMasterKey, request.sessionToken, request.installationId); - - try { - const req = { - client, - event: 'connect', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - sessionToken: request.sessionToken, - useMasterKey: client.hasMasterKey, - installationId: request.installationId - }; - await (0, _triggers.maybeRunConnectTrigger)('beforeConnect', req); - parseWebsocket.clientId = clientId; - this.clients.set(parseWebsocket.clientId, client); - - _logger.default.info(`Create new client: ${parseWebsocket.clientId}`); - - client.pushConnect(); - (0, _triggers.runLiveQueryEventHandlers)(req); - } catch (error) { - _Client.Client.pushError(parseWebsocket, error.code || 141, error.message || error, false); - - _logger.default.error(`Failed running beforeConnect for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(error)); - } - } - - _hasMasterKey(request, validKeyPairs) { - if (!validKeyPairs || validKeyPairs.size == 0 || !validKeyPairs.has('masterKey')) { - return false; - } - - if (!request || !Object.prototype.hasOwnProperty.call(request, 'masterKey')) { - return false; - } - - return request.masterKey === validKeyPairs.get('masterKey'); - } - - _validateKeys(request, validKeyPairs) { - if (!validKeyPairs || validKeyPairs.size == 0) { - return true; - } - - let isValid = false; - - for (const [key, secret] of validKeyPairs) { - if (!request[key] || request[key] !== secret) { - continue; - } - - isValid = true; - break; - } - - return isValid; - } - - async _handleSubscribe(parseWebsocket, request) { - // If we can not find this client, return error to client - if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { - _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before subscribing'); - - _logger.default.error('Can not find this client, make sure you connect to server before subscribing'); - - return; - } - - const client = this.clients.get(parseWebsocket.clientId); - const className = request.query.className; - - try { - await (0, _triggers.maybeRunSubscribeTrigger)('beforeSubscribe', className, request); // Get subscription from subscriptions, create one if necessary - - const subscriptionHash = (0, _QueryTools.queryHash)(request.query); // Add className to subscriptions if necessary - - if (!this.subscriptions.has(className)) { - this.subscriptions.set(className, new Map()); - } - - const classSubscriptions = this.subscriptions.get(className); - let subscription; - - if (classSubscriptions.has(subscriptionHash)) { - subscription = classSubscriptions.get(subscriptionHash); - } else { - subscription = new _Subscription.Subscription(className, request.query.where, subscriptionHash); - classSubscriptions.set(subscriptionHash, subscription); - } // Add subscriptionInfo to client - - - const subscriptionInfo = { - subscription: subscription - }; // Add selected fields, sessionToken and installationId for this subscription if necessary - - if (request.query.fields) { - subscriptionInfo.fields = request.query.fields; - } - - if (request.sessionToken) { - subscriptionInfo.sessionToken = request.sessionToken; - } - - client.addSubscriptionInfo(request.requestId, subscriptionInfo); // Add clientId to subscription - - subscription.addClientSubscription(parseWebsocket.clientId, request.requestId); - client.pushSubscribe(request.requestId); - - _logger.default.verbose(`Create client ${parseWebsocket.clientId} new subscription: ${request.requestId}`); - - _logger.default.verbose('Current client number: %d', this.clients.size); - - (0, _triggers.runLiveQueryEventHandlers)({ - client, - event: 'subscribe', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - sessionToken: request.sessionToken, - useMasterKey: client.hasMasterKey, - installationId: client.installationId - }); - } catch (e) { - _Client.Client.pushError(parseWebsocket, e.code || 141, e.message || e, false, request.requestId); - - _logger.default.error(`Failed running beforeSubscribe on ${className} for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(e)); - } - } - - _handleUpdateSubscription(parseWebsocket, request) { - this._handleUnsubscribe(parseWebsocket, request, false); - - this._handleSubscribe(parseWebsocket, request); - } - - _handleUnsubscribe(parseWebsocket, request, notifyClient = true) { - // If we can not find this client, return error to client - if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { - _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing'); - - _logger.default.error('Can not find this client, make sure you connect to server before unsubscribing'); - - return; - } - - const requestId = request.requestId; - const client = this.clients.get(parseWebsocket.clientId); - - if (typeof client === 'undefined') { - _Client.Client.pushError(parseWebsocket, 2, 'Cannot find client with clientId ' + parseWebsocket.clientId + '. Make sure you connect to live query server before unsubscribing.'); - - _logger.default.error('Can not find this client ' + parseWebsocket.clientId); - - return; - } - - const subscriptionInfo = client.getSubscriptionInfo(requestId); - - if (typeof subscriptionInfo === 'undefined') { - _Client.Client.pushError(parseWebsocket, 2, 'Cannot find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId + '. Make sure you subscribe to live query server before unsubscribing.'); - - _logger.default.error('Can not find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId); - - return; - } // Remove subscription from client - - - client.deleteSubscriptionInfo(requestId); // Remove client from subscription - - const subscription = subscriptionInfo.subscription; - const className = subscription.className; - subscription.deleteClientSubscription(parseWebsocket.clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions - - const classSubscriptions = this.subscriptions.get(className); - - if (!subscription.hasSubscribingClient()) { - classSubscriptions.delete(subscription.hash); - } // If there is no subscriptions under this class, remove it from subscriptions - - - if (classSubscriptions.size === 0) { - this.subscriptions.delete(className); - } - - (0, _triggers.runLiveQueryEventHandlers)({ - client, - event: 'unsubscribe', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - sessionToken: subscriptionInfo.sessionToken, - useMasterKey: client.hasMasterKey, - installationId: client.installationId - }); - - if (!notifyClient) { - return; - } - - client.pushUnsubscribe(request.requestId); - - _logger.default.verbose(`Delete client: ${parseWebsocket.clientId} | subscription: ${request.requestId}`); - } - -} - -exports.ParseLiveQueryServer = ParseLiveQueryServer; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VMaXZlUXVlcnlTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsImNvbmZpZyIsInBhcnNlU2VydmVyQ29uZmlnIiwiY2xpZW50cyIsIk1hcCIsInN1YnNjcmlwdGlvbnMiLCJhcHBJZCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsIm1hc3RlcktleSIsImtleVBhaXJzIiwia2V5IiwiT2JqZWN0Iiwia2V5cyIsInNldCIsImxvZ2dlciIsInZlcmJvc2UiLCJkaXNhYmxlU2luZ2xlSW5zdGFuY2UiLCJzZXJ2ZXJVUkwiLCJpbml0aWFsaXplIiwiamF2YVNjcmlwdEtleSIsImNhY2hlQ29udHJvbGxlciIsImNhY2hlVGltZW91dCIsImF1dGhDYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsInBhcnNlV2ViU29ja2V0U2VydmVyIiwiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJwYXJzZVdlYnNvY2tldCIsIl9vbkNvbm5lY3QiLCJzdWJzY3JpYmVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVTdWJzY3JpYmVyIiwic3Vic2NyaWJlIiwib24iLCJjaGFubmVsIiwibWVzc2FnZVN0ciIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJlIiwiZXJyb3IiLCJfaW5mbGF0ZVBhcnNlT2JqZWN0IiwiX29uQWZ0ZXJTYXZlIiwiX29uQWZ0ZXJEZWxldGUiLCJjdXJyZW50UGFyc2VPYmplY3QiLCJVc2VyUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsImNsYXNzTmFtZSIsInBhcnNlT2JqZWN0IiwiX2ZpbmlzaEZldGNoIiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImRlbGV0ZWRQYXJzZU9iamVjdCIsInRvSlNPTiIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlkIiwic2l6ZSIsImNsYXNzU3Vic2NyaXB0aW9ucyIsImdldCIsImRlYnVnIiwic3Vic2NyaXB0aW9uIiwidmFsdWVzIiwiaXNTdWJzY3JpcHRpb25NYXRjaGVkIiwiX21hdGNoZXNTdWJzY3JpcHRpb24iLCJjbGllbnRJZCIsInJlcXVlc3RJZHMiLCJfIiwiZW50cmllcyIsImNsaWVudFJlcXVlc3RJZHMiLCJjbGllbnQiLCJyZXF1ZXN0SWQiLCJhY2wiLCJnZXRBQ0wiLCJvcCIsIl9nZXRDTFBPcGVyYXRpb24iLCJxdWVyeSIsInJlcyIsIl9tYXRjaGVzQ0xQIiwidGhlbiIsIl9tYXRjaGVzQUNMIiwiaXNNYXRjaGVkIiwiZXZlbnQiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3QiLCJ1c2VNYXN0ZXJLZXkiLCJoYXNNYXN0ZXJLZXkiLCJpbnN0YWxsYXRpb25JZCIsInNlbmRFdmVudCIsInB1c2hEZWxldGUiLCJjYXRjaCIsIkNsaWVudCIsInB1c2hFcnJvciIsInBhcnNlV2ViU29ja2V0IiwiY29kZSIsInN0cmluZ2lmeSIsImlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkIiwiaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCIsIm9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvcmlnaW5hbEFDTCIsImN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UiLCJjdXJyZW50QUNMIiwiYWxsIiwiaXNPcmlnaW5hbE1hdGNoZWQiLCJpc0N1cnJlbnRNYXRjaGVkIiwiaGFzaCIsInR5cGUiLCJvcmlnaW5hbCIsImZ1bmN0aW9uTmFtZSIsInJlcXVlc3QiLCJ0djQiLCJ2YWxpZGF0ZSIsIlJlcXVlc3RTY2hlbWEiLCJfaGFuZGxlQ29ubmVjdCIsIl9oYW5kbGVTdWJzY3JpYmUiLCJfaGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uIiwiX2hhbmRsZVVuc3Vic2NyaWJlIiwiaW5mbyIsImhhcyIsImRlbGV0ZSIsInN1YnNjcmlwdGlvbkluZm8iLCJzdWJzY3JpcHRpb25JbmZvcyIsImRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbiIsImhhc1N1YnNjcmliaW5nQ2xpZW50IiwiZ2V0QXV0aEZvclNlc3Npb25Ub2tlbiIsImZyb21DYWNoZSIsImF1dGhQcm9taXNlIiwiYXV0aCIsInVzZXJJZCIsInVzZXIiLCJyZXN1bHQiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsImRlbCIsImdldFN1YnNjcmlwdGlvbkluZm8iLCJhY2xHcm91cCIsInB1c2giLCJTY2hlbWFDb250cm9sbGVyIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwibGVuZ3RoIiwib2JqZWN0SWQiLCJfdmVyaWZ5QUNMIiwidG9rZW4iLCJpc1N1YnNjcmlwdGlvblNlc3Npb25Ub2tlbk1hdGNoZWQiLCJnZXRSZWFkQWNjZXNzIiwiYWNsX2hhc19yb2xlcyIsInBlcm1pc3Npb25zQnlJZCIsInNvbWUiLCJzdGFydHNXaXRoIiwicm9sZU5hbWVzIiwiZ2V0VXNlclJvbGVzIiwicm9sZSIsImdldFB1YmxpY1JlYWRBY2Nlc3MiLCJzdWJzY3JpcHRpb25Ub2tlbiIsImNsaWVudFNlc3Npb25Ub2tlbiIsIl92YWxpZGF0ZUtleXMiLCJfaGFzTWFzdGVyS2V5IiwicmVxIiwicHVzaENvbm5lY3QiLCJ2YWxpZEtleVBhaXJzIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaXNWYWxpZCIsInNlY3JldCIsInN1YnNjcmlwdGlvbkhhc2giLCJTdWJzY3JpcHRpb24iLCJ3aGVyZSIsImZpZWxkcyIsImFkZFN1YnNjcmlwdGlvbkluZm8iLCJhZGRDbGllbnRTdWJzY3JpcHRpb24iLCJwdXNoU3Vic2NyaWJlIiwibm90aWZ5Q2xpZW50IiwiZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyIsInB1c2hVbnN1YnNjcmliZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQU1BOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEsb0JBQU4sQ0FBMkI7QUFFekI7QUFJ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S3BELGFBQUwsQ0FBbUJvSCxNQUFuQixDQUEwQnhFLFNBQTFCO0FBQ0Q7O0FBQ0QsNkNBQTBCO0FBQ3hCcUIsTUFBQUEsTUFEd0I7QUFFeEJZLE1BQUFBLEtBQUssRUFBRSxhQUZpQjtBQUd4Qi9FLE1BQUFBLE9BQU8sRUFBRSxLQUFLQSxPQUFMLENBQWFzRCxJQUhFO0FBSXhCcEQsTUFBQUEsYUFBYSxFQUFFLEtBQUtBLGFBQUwsQ0FBbUJvRCxJQUpWO0FBS3hCMEIsTUFBQUEsWUFBWSxFQUFFdUMsZ0JBQWdCLENBQUN2QyxZQUxQO0FBTXhCRSxNQUFBQSxZQUFZLEVBQUVmLE1BQU0sQ0FBQ2dCLFlBTkc7QUFPeEJDLE1BQUFBLGNBQWMsRUFBRWpCLE1BQU0sQ0FBQ2lCO0FBUEMsS0FBMUI7O0FBVUEsUUFBSSxDQUFDdUYsWUFBTCxFQUFtQjtBQUNqQjtBQUNEOztBQUVEeEcsSUFBQUEsTUFBTSxDQUFDMEcsZUFBUCxDQUF1QmpFLE9BQU8sQ0FBQ3hDLFNBQS9COztBQUVBeEQsb0JBQU9DLE9BQVAsQ0FDRyxrQkFBaUJhLGNBQWMsQ0FBQ29DLFFBQVMsb0JBQW1COEMsT0FBTyxDQUFDeEMsU0FBVSxFQURqRjtBQUdEOztBQXJ4QndCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR2NCBmcm9tICd0djQnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAnLi9TdWJzY3JpcHRpb24nO1xuaW1wb3J0IHsgQ2xpZW50IH0gZnJvbSAnLi9DbGllbnQnO1xuaW1wb3J0IHsgUGFyc2VXZWJTb2NrZXRTZXJ2ZXIgfSBmcm9tICcuL1BhcnNlV2ViU29ja2V0U2VydmVyJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCBSZXF1ZXN0U2NoZW1hIGZyb20gJy4vUmVxdWVzdFNjaGVtYSc7XG5pbXBvcnQgeyBtYXRjaGVzUXVlcnksIHF1ZXJ5SGFzaCB9IGZyb20gJy4vUXVlcnlUb29scyc7XG5pbXBvcnQgeyBQYXJzZVB1YlN1YiB9IGZyb20gJy4vUGFyc2VQdWJTdWInO1xuaW1wb3J0IFNjaGVtYUNvbnRyb2xsZXIgZnJvbSAnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5pbXBvcnQge1xuICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzLFxuICBtYXliZVJ1bkNvbm5lY3RUcmlnZ2VyLFxuICBtYXliZVJ1blN1YnNjcmliZVRyaWdnZXIsXG4gIG1heWJlUnVuQWZ0ZXJFdmVudFRyaWdnZXIsXG59IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCB7IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4sIEF1dGggfSBmcm9tICcuLi9BdXRoJztcbmltcG9ydCB7IGdldENhY2hlQ29udHJvbGxlciB9IGZyb20gJy4uL0NvbnRyb2xsZXJzJztcbmltcG9ydCBMUlUgZnJvbSAnbHJ1LWNhY2hlJztcbmltcG9ydCBVc2VyUm91dGVyIGZyb20gJy4uL1JvdXRlcnMvVXNlcnNSb3V0ZXInO1xuXG5jbGFzcyBQYXJzZUxpdmVRdWVyeVNlcnZlciB7XG4gIGNsaWVudHM6IE1hcDtcbiAgLy8gY2xhc3NOYW1lIC0+IChxdWVyeUhhc2ggLT4gc3Vic2NyaXB0aW9uKVxuICBzdWJzY3JpcHRpb25zOiBPYmplY3Q7XG4gIHBhcnNlV2ViU29ja2V0U2VydmVyOiBPYmplY3Q7XG4gIGtleVBhaXJzOiBhbnk7XG4gIC8vIFRoZSBzdWJzY3JpYmVyIHdlIHVzZSB0byBnZXQgb2JqZWN0IHVwZGF0ZSBmcm9tIHB1Ymxpc2hlclxuICBzdWJzY3JpYmVyOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3Ioc2VydmVyOiBhbnksIGNvbmZpZzogYW55ID0ge30sIHBhcnNlU2VydmVyQ29uZmlnOiBhbnkgPSB7fSkge1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuICAgIHRoaXMuY2xpZW50cyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG5cbiAgICBjb25maWcuYXBwSWQgPSBjb25maWcuYXBwSWQgfHwgUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgICBjb25maWcubWFzdGVyS2V5ID0gY29uZmlnLm1hc3RlcktleSB8fCBQYXJzZS5tYXN0ZXJLZXk7XG5cbiAgICAvLyBTdG9yZSBrZXlzLCBjb252ZXJ0IG9iaiB0byBtYXBcbiAgICBjb25zdCBrZXlQYWlycyA9IGNvbmZpZy5rZXlQYWlycyB8fCB7fTtcbiAgICB0aGlzLmtleVBhaXJzID0gbmV3IE1hcCgpO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGtleVBhaXJzKSkge1xuICAgICAgdGhpcy5rZXlQYWlycy5zZXQoa2V5LCBrZXlQYWlyc1trZXldKTtcbiAgICB9XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ1N1cHBvcnQga2V5IHBhaXJzJywgdGhpcy5rZXlQYWlycyk7XG5cbiAgICAvLyBJbml0aWFsaXplIFBhcnNlXG4gICAgUGFyc2UuT2JqZWN0LmRpc2FibGVTaW5nbGVJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHNlcnZlclVSTCA9IGNvbmZpZy5zZXJ2ZXJVUkwgfHwgUGFyc2Uuc2VydmVyVVJMO1xuICAgIFBhcnNlLnNlcnZlclVSTCA9IHNlcnZlclVSTDtcbiAgICBQYXJzZS5pbml0aWFsaXplKGNvbmZpZy5hcHBJZCwgUGFyc2UuamF2YVNjcmlwdEtleSwgY29uZmlnLm1hc3RlcktleSk7XG5cbiAgICAvLyBUaGUgY2FjaGUgY29udHJvbGxlciBpcyBhIHByb3BlciBjYWNoZSBjb250cm9sbGVyXG4gICAgLy8gd2l0aCBhY2Nlc3MgdG8gVXNlciBhbmQgUm9sZXNcbiAgICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGdldENhY2hlQ29udHJvbGxlcihwYXJzZVNlcnZlckNvbmZpZyk7XG5cbiAgICBjb25maWcuY2FjaGVUaW1lb3V0ID0gY29uZmlnLmNhY2hlVGltZW91dCB8fCA1ICogMTAwMDsgLy8gNXNcblxuICAgIC8vIFRoaXMgYXV0aCBjYWNoZSBzdG9yZXMgdGhlIHByb21pc2VzIGZvciBlYWNoIGF1dGggcmVzb2x1dGlvbi5cbiAgICAvLyBUaGUgbWFpbiBiZW5lZml0IGlzIHRvIGJlIGFibGUgdG8gcmV1c2UgdGhlIHNhbWUgdXNlciAvIHNlc3Npb24gdG9rZW4gcmVzb2x1dGlvbi5cbiAgICB0aGlzLmF1dGhDYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiA1MDAsIC8vIDUwMCBjb25jdXJyZW50XG4gICAgICBtYXhBZ2U6IGNvbmZpZy5jYWNoZVRpbWVvdXQsXG4gICAgfSk7XG4gICAgLy8gSW5pdGlhbGl6ZSB3ZWJzb2NrZXQgc2VydmVyXG4gICAgdGhpcy5wYXJzZVdlYlNvY2tldFNlcnZlciA9IG5ldyBQYXJzZVdlYlNvY2tldFNlcnZlcihcbiAgICAgIHNlcnZlcixcbiAgICAgIHBhcnNlV2Vic29ja2V0ID0+IHRoaXMuX29uQ29ubmVjdChwYXJzZVdlYnNvY2tldCksXG4gICAgICBjb25maWdcbiAgICApO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBzdWJzY3JpYmVyXG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICAgIHRoaXMuc3Vic2NyaWJlci5zdWJzY3JpYmUoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUnKTtcbiAgICB0aGlzLnN1YnNjcmliZXIuc3Vic2NyaWJlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUnKTtcbiAgICAvLyBSZWdpc3RlciBtZXNzYWdlIGhhbmRsZXIgZm9yIHN1YnNjcmliZXIuIFdoZW4gcHVibGlzaGVyIGdldCBtZXNzYWdlcywgaXQgd2lsbCBwdWJsaXNoIG1lc3NhZ2VcbiAgICAvLyB0byB0aGUgc3Vic2NyaWJlcnMgYW5kIHRoZSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkLlxuICAgIHRoaXMuc3Vic2NyaWJlci5vbignbWVzc2FnZScsIChjaGFubmVsLCBtZXNzYWdlU3RyKSA9PiB7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnU3Vic2NyaWJlIG1lc3NzYWdlICVqJywgbWVzc2FnZVN0cik7XG4gICAgICBsZXQgbWVzc2FnZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1lc3NhZ2UgPSBKU09OLnBhcnNlKG1lc3NhZ2VTdHIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSBtZXNzYWdlJywgbWVzc2FnZVN0ciwgZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2luZmxhdGVQYXJzZU9iamVjdChtZXNzYWdlKTtcbiAgICAgIGlmIChjaGFubmVsID09PSBQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyU2F2ZScpIHtcbiAgICAgICAgdGhpcy5fb25BZnRlclNhdmUobWVzc2FnZSk7XG4gICAgICB9IGVsc2UgaWYgKGNoYW5uZWwgPT09IFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUnKSB7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJEZWxldGUobWVzc2FnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCBtZXNzYWdlICVzIGZyb20gdW5rbm93biBjaGFubmVsICVqJywgbWVzc2FnZSwgY2hhbm5lbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlci4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IEpTT04gYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdCBKU09OLlxuICBfaW5mbGF0ZVBhcnNlT2JqZWN0KG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIC8vIEluZmxhdGUgbWVyZ2VkIG9iamVjdFxuICAgIGNvbnN0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0O1xuICAgIFVzZXJSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyhjdXJyZW50UGFyc2VPYmplY3QpO1xuICAgIGxldCBjbGFzc05hbWUgPSBjdXJyZW50UGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxldCBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICBwYXJzZU9iamVjdC5fZmluaXNoRmV0Y2goY3VycmVudFBhcnNlT2JqZWN0KTtcbiAgICBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIC8vIEluZmxhdGUgb3JpZ2luYWwgb2JqZWN0XG4gICAgY29uc3Qgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgICBpZiAob3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgVXNlclJvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKG9yaWdpbmFsUGFyc2VPYmplY3QpO1xuICAgICAgY2xhc3NOYW1lID0gb3JpZ2luYWxQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgICBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICAgIHBhcnNlT2JqZWN0Ll9maW5pc2hGZXRjaChvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgIG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIH1cbiAgfVxuXG4gIC8vIE1lc3NhZ2UgaXMgdGhlIEpTT04gb2JqZWN0IGZyb20gcHVibGlzaGVyIGFmdGVyIGluZmxhdGVkLiBNZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCBpcyB0aGUgUGFyc2VPYmplY3QgYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdC5cbiAgX29uQWZ0ZXJEZWxldGUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZSBpcyB0cmlnZ2VyZWQnKTtcblxuICAgIGxldCBkZWxldGVkUGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICBjb25zdCBjbGFzc0xldmVsUGVybWlzc2lvbnMgPSBtZXNzYWdlLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICBjb25zdCBjbGFzc05hbWUgPSBkZWxldGVkUGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDbGFzc05hbWU6ICVqIHwgT2JqZWN0SWQ6ICVzJywgY2xhc3NOYW1lLCBkZWxldGVkUGFyc2VPYmplY3QuaWQpO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXIgOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcblxuICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICBpZiAodHlwZW9mIGNsYXNzU3Vic2NyaXB0aW9ucyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2FuIG5vdCBmaW5kIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcyAnICsgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2YgY2xhc3NTdWJzY3JpcHRpb25zLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBpc1N1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKGRlbGV0ZWRQYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIGlmICghaXNTdWJzY3JpcHRpb25NYXRjaGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICBjb25zdCBhY2wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAvLyBDaGVjayBDTFBcbiAgICAgICAgICBjb25zdCBvcCA9IHRoaXMuX2dldENMUE9wZXJhdGlvbihzdWJzY3JpcHRpb24ucXVlcnkpO1xuICAgICAgICAgIGxldCByZXMgPSB7fTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gQ2hlY2sgQUNMXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXRjaGVzQUNMKGFjbCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKGlzTWF0Y2hlZCA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNNYXRjaGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiAnRGVsZXRlJyxcbiAgICAgICAgICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBkZWxldGVkUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgICAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgc2VuZEV2ZW50OiB0cnVlLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICByZXR1cm4gbWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlcignYWZ0ZXJFdmVudCcsIGNsYXNzTmFtZSwgcmVzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghcmVzLnNlbmRFdmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVzLm9iamVjdCAmJiB0eXBlb2YgcmVzLm9iamVjdC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBkZWxldGVkUGFyc2VPYmplY3QgPSByZXMub2JqZWN0LnRvSlNPTigpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZWRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2xpZW50LnB1c2hEZWxldGUocmVxdWVzdElkLCBkZWxldGVkUGFyc2VPYmplY3QpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgICAgICAgICAgY2xpZW50LnBhcnNlV2ViU29ja2V0LFxuICAgICAgICAgICAgICAgIGVycm9yLmNvZGUgfHwgMTQxLFxuICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTWVzc2FnZSBpcyB0aGUgSlNPTiBvYmplY3QgZnJvbSBwdWJsaXNoZXIgYWZ0ZXIgaW5mbGF0ZWQuIE1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0IGlzIHRoZSBQYXJzZU9iamVjdCBhZnRlciBjaGFuZ2VzLlxuICAvLyBNZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgaXMgdGhlIG9yaWdpbmFsIFBhcnNlT2JqZWN0LlxuICBfb25BZnRlclNhdmUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUgaXMgdHJpZ2dlcmVkJyk7XG5cbiAgICBsZXQgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG51bGw7XG4gICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICB9XG4gICAgY29uc3QgY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gbWVzc2FnZS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgbGV0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LnRvSlNPTigpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0NsYXNzTmFtZTogJXMgfCBPYmplY3RJZDogJXMnLCBjbGFzc05hbWUsIGN1cnJlbnRQYXJzZU9iamVjdC5pZCk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50IG51bWJlciA6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICh0eXBlb2YgY2xhc3NTdWJzY3JpcHRpb25zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9ucyB1bmRlciB0aGlzIGNsYXNzICcgKyBjbGFzc05hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHN1YnNjcmlwdGlvbiBvZiBjbGFzc1N1YnNjcmlwdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkID0gdGhpcy5fbWF0Y2hlc1N1YnNjcmlwdGlvbihcbiAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgY29uc3QgaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCA9IHRoaXMuX21hdGNoZXNTdWJzY3JpcHRpb24oXG4gICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICAvLyBTZXQgb3JpZ25hbCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlO1xuICAgICAgICAgIGlmICghaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG9yaWdpbmFsQUNMO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgICAgICAgICBvcmlnaW5hbEFDTCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gdGhpcy5fbWF0Y2hlc0FDTChvcmlnaW5hbEFDTCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTZXQgY3VycmVudCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2U7XG4gICAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICAgIGlmICghaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCkge1xuICAgICAgICAgICAgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRBQ0wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UgPSB0aGlzLl9tYXRjaGVzQUNMKGN1cnJlbnRBQ0wsIGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgb3AgPSB0aGlzLl9nZXRDTFBPcGVyYXRpb24oc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSwgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKChbaXNPcmlnaW5hbE1hdGNoZWQsIGlzQ3VycmVudE1hdGNoZWRdKSA9PiB7XG4gICAgICAgICAgICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgICAgICdPcmlnaW5hbCAlaiB8IEN1cnJlbnQgJWogfCBNYXRjaDogJXMsICVzLCAlcywgJXMgfCBRdWVyeTogJXMnLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICAgIGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkLFxuICAgICAgICAgICAgICAgIGlzQ3VycmVudFN1YnNjcmlwdGlvbk1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNPcmlnaW5hbE1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNDdXJyZW50TWF0Y2hlZCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uaGFzaFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAvLyBEZWNpZGUgZXZlbnQgdHlwZVxuICAgICAgICAgICAgICBsZXQgdHlwZTtcbiAgICAgICAgICAgICAgaWYgKGlzT3JpZ2luYWxNYXRjaGVkICYmIGlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ1VwZGF0ZSc7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPcmlnaW5hbE1hdGNoZWQgJiYgIWlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ0xlYXZlJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNPcmlnaW5hbE1hdGNoZWQgJiYgaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICB0eXBlID0gJ0VudGVyJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdHlwZSA9ICdDcmVhdGUnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBtZXNzYWdlLmV2ZW50ID0gdHlwZTtcbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiB0eXBlLFxuICAgICAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogY2xpZW50LnNlc3Npb25Ub2tlbixcbiAgICAgICAgICAgICAgICBvYmplY3Q6IGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbDogb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBzZW5kRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHJldHVybiBtYXliZVJ1bkFmdGVyRXZlbnRUcmlnZ2VyKCdhZnRlckV2ZW50JywgY2xhc3NOYW1lLCByZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXMuc2VuZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXMub2JqZWN0ICYmIHR5cGVvZiByZXMub2JqZWN0LnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0ID0gcmVzLm9iamVjdC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSByZXMub2JqZWN0LmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcy5vcmlnaW5hbCAmJiB0eXBlb2YgcmVzLm9yaWdpbmFsLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IHJlcy5vcmlnaW5hbC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QuY2xhc3NOYW1lID0gcmVzLm9yaWdpbmFsLmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9ICdwdXNoJyArIG1lc3NhZ2UuZXZlbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGNsaWVudFtmdW5jdGlvbk5hbWVdKSB7XG4gICAgICAgICAgICAgICAgICBjbGllbnRbZnVuY3Rpb25OYW1lXShyZXF1ZXN0SWQsIGN1cnJlbnRQYXJzZU9iamVjdCwgb3JpZ2luYWxQYXJzZU9iamVjdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgICAgICAgICAgIGNsaWVudC5wYXJzZVdlYlNvY2tldCxcbiAgICAgICAgICAgICAgICAgIGVycm9yLmNvZGUgfHwgMTQxLFxuICAgICAgICAgICAgICAgICAgZXJyb3IubWVzc2FnZSB8fCBlcnJvcixcbiAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVycm9yKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfb25Db25uZWN0KHBhcnNlV2Vic29ja2V0OiBhbnkpOiB2b2lkIHtcbiAgICBwYXJzZVdlYnNvY2tldC5vbignbWVzc2FnZScsIHJlcXVlc3QgPT4ge1xuICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0ID09PSAnc3RyaW5nJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlcXVlc3QgPSBKU09OLnBhcnNlKHJlcXVlc3QpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCd1bmFibGUgdG8gcGFyc2UgcmVxdWVzdCcsIHJlcXVlc3QsIGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ1JlcXVlc3Q6ICVqJywgcmVxdWVzdCk7XG5cbiAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhpcyByZXF1ZXN0IGlzIGEgdmFsaWQgcmVxdWVzdCwgcmV0dXJuIGVycm9yIGRpcmVjdGx5IGlmIG5vdFxuICAgICAgaWYgKFxuICAgICAgICAhdHY0LnZhbGlkYXRlKHJlcXVlc3QsIFJlcXVlc3RTY2hlbWFbJ2dlbmVyYWwnXSkgfHxcbiAgICAgICAgIXR2NC52YWxpZGF0ZShyZXF1ZXN0LCBSZXF1ZXN0U2NoZW1hW3JlcXVlc3Qub3BdKVxuICAgICAgKSB7XG4gICAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDEsIHR2NC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdDb25uZWN0IG1lc3NhZ2UgZXJyb3IgJXMnLCB0djQuZXJyb3IubWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChyZXF1ZXN0Lm9wKSB7XG4gICAgICAgIGNhc2UgJ2Nvbm5lY3QnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZUNvbm5lY3QocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdzdWJzY3JpYmUnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZVN1YnNjcmliZShwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3VwZGF0ZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndW5zdWJzY3JpYmUnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCAzLCAnR2V0IHVua25vd24gb3BlcmF0aW9uJyk7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdHZXQgdW5rbm93biBvcGVyYXRpb24nLCByZXF1ZXN0Lm9wKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHBhcnNlV2Vic29ja2V0Lm9uKCdkaXNjb25uZWN0JywgKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYENsaWVudCBkaXNjb25uZWN0OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfWApO1xuICAgICAgY29uc3QgY2xpZW50SWQgPSBwYXJzZVdlYnNvY2tldC5jbGllbnRJZDtcbiAgICAgIGlmICghdGhpcy5jbGllbnRzLmhhcyhjbGllbnRJZCkpIHtcbiAgICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICAgICAgZXZlbnQ6ICd3c19kaXNjb25uZWN0X2Vycm9yJyxcbiAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICBlcnJvcjogYFVuYWJsZSB0byBmaW5kIGNsaWVudCAke2NsaWVudElkfWAsXG4gICAgICAgIH0pO1xuICAgICAgICBsb2dnZXIuZXJyb3IoYENhbiBub3QgZmluZCBjbGllbnQgJHtjbGllbnRJZH0gb24gZGlzY29ubmVjdGApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIERlbGV0ZSBjbGllbnRcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQoY2xpZW50SWQpO1xuICAgICAgdGhpcy5jbGllbnRzLmRlbGV0ZShjbGllbnRJZCk7XG5cbiAgICAgIC8vIERlbGV0ZSBjbGllbnQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICBmb3IgKGNvbnN0IFtyZXF1ZXN0SWQsIHN1YnNjcmlwdGlvbkluZm9dIG9mIF8uZW50cmllcyhjbGllbnQuc3Vic2NyaXB0aW9uSW5mb3MpKSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHN1YnNjcmlwdGlvbkluZm8uc3Vic2NyaXB0aW9uO1xuICAgICAgICBzdWJzY3JpcHRpb24uZGVsZXRlQ2xpZW50U3Vic2NyaXB0aW9uKGNsaWVudElkLCByZXF1ZXN0SWQpO1xuXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNsaWVudCB3aGljaCBpcyBzdWJzY3JpYmluZyB0aGlzIHN1YnNjcmlwdGlvbiwgcmVtb3ZlIGl0IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgICAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KHN1YnNjcmlwdGlvbi5jbGFzc05hbWUpO1xuICAgICAgICBpZiAoIXN1YnNjcmlwdGlvbi5oYXNTdWJzY3JpYmluZ0NsaWVudCgpKSB7XG4gICAgICAgICAgY2xhc3NTdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uaGFzaCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gc3Vic2NyaXB0aW9ucyB1bmRlciB0aGlzIGNsYXNzLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uLmNsYXNzTmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50cyAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcbiAgICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IHN1YnNjcmlwdGlvbnMgJWQnLCB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSk7XG4gICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgZXZlbnQ6ICd3c19kaXNjb25uZWN0JyxcbiAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgZXZlbnQ6ICd3c19jb25uZWN0JyxcbiAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgfSk7XG4gIH1cblxuICBfbWF0Y2hlc1N1YnNjcmlwdGlvbihwYXJzZU9iamVjdDogYW55LCBzdWJzY3JpcHRpb246IGFueSk6IGJvb2xlYW4ge1xuICAgIC8vIE9iamVjdCBpcyB1bmRlZmluZWQgb3IgbnVsbCwgbm90IG1hdGNoXG4gICAgaWYgKCFwYXJzZU9iamVjdCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hlc1F1ZXJ5KHBhcnNlT2JqZWN0LCBzdWJzY3JpcHRpb24ucXVlcnkpO1xuICB9XG5cbiAgZ2V0QXV0aEZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW46ID9zdHJpbmcpOiBQcm9taXNlPHsgYXV0aDogP0F1dGgsIHVzZXJJZDogP3N0cmluZyB9PiB7XG4gICAgaWYgKCFzZXNzaW9uVG9rZW4pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ2FjaGUgPSB0aGlzLmF1dGhDYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAoZnJvbUNhY2hlKSB7XG4gICAgICByZXR1cm4gZnJvbUNhY2hlO1xuICAgIH1cbiAgICBjb25zdCBhdXRoUHJvbWlzZSA9IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgY2FjaGVDb250cm9sbGVyOiB0aGlzLmNhY2hlQ29udHJvbGxlcixcbiAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgIH0pXG4gICAgICAudGhlbihhdXRoID0+IHtcbiAgICAgICAgcmV0dXJuIHsgYXV0aCwgdXNlcklkOiBhdXRoICYmIGF1dGgudXNlciAmJiBhdXRoLnVzZXIuaWQgfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvLyBUaGVyZSB3YXMgYW4gZXJyb3Igd2l0aCB0aGUgc2Vzc2lvbiB0b2tlblxuICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTikge1xuICAgICAgICAgIHJlc3VsdC5lcnJvciA9IGVycm9yO1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLnNldChzZXNzaW9uVG9rZW4sIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLCB0aGlzLmNvbmZpZy5jYWNoZVRpbWVvdXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLmRlbChzZXNzaW9uVG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB0aGlzLmF1dGhDYWNoZS5zZXQoc2Vzc2lvblRva2VuLCBhdXRoUHJvbWlzZSk7XG4gICAgcmV0dXJuIGF1dGhQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgX21hdGNoZXNDTFAoXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55LFxuICAgIG9iamVjdDogYW55LFxuICAgIGNsaWVudDogYW55LFxuICAgIHJlcXVlc3RJZDogbnVtYmVyLFxuICAgIG9wOiBzdHJpbmdcbiAgKTogYW55IHtcbiAgICAvLyB0cnkgdG8gbWF0Y2ggb24gdXNlciBmaXJzdCwgbGVzcyBleHBlbnNpdmUgdGhhbiB3aXRoIHJvbGVzXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgY29uc3QgYWNsR3JvdXAgPSBbJyonXTtcbiAgICBsZXQgdXNlcklkO1xuICAgIGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSW5mbyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnN0IHsgdXNlcklkIH0gPSBhd2FpdCB0aGlzLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4pO1xuICAgICAgaWYgKHVzZXJJZCkge1xuICAgICAgICBhY2xHcm91cC5wdXNoKHVzZXJJZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBTY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihcbiAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICBvYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgb3BcbiAgICAgICk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZShgRmFpbGVkIG1hdGNoaW5nIENMUCBmb3IgJHtvYmplY3QuaWR9ICR7dXNlcklkfSAke2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFRPRE86IGhhbmRsZSByb2xlcyBwZXJtaXNzaW9uc1xuICAgIC8vIE9iamVjdC5rZXlzKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgLy8gICBjb25zdCBwZXJtID0gY2xhc3NMZXZlbFBlcm1pc3Npb25zW2tleV07XG4gICAgLy8gICBPYmplY3Qua2V5cyhwZXJtKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAvLyAgICAgaWYgKGtleS5pbmRleE9mKCdyb2xlJykpXG4gICAgLy8gICB9KTtcbiAgICAvLyB9KVxuICAgIC8vIC8vIGl0J3MgcmVqZWN0ZWQgaGVyZSwgY2hlY2sgdGhlIHJvbGVzXG4gICAgLy8gdmFyIHJvbGVzUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoUGFyc2UuUm9sZSk7XG4gICAgLy8gcm9sZXNRdWVyeS5lcXVhbFRvKFwidXNlcnNcIiwgdXNlcik7XG4gICAgLy8gcmV0dXJuIHJvbGVzUXVlcnkuZmluZCh7dXNlTWFzdGVyS2V5OnRydWV9KTtcbiAgfVxuXG4gIF9nZXRDTFBPcGVyYXRpb24ocXVlcnk6IGFueSkge1xuICAgIHJldHVybiB0eXBlb2YgcXVlcnkgPT09ICdvYmplY3QnICYmXG4gICAgICBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoID09IDEgJiZcbiAgICAgIHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZydcbiAgICAgID8gJ2dldCdcbiAgICAgIDogJ2ZpbmQnO1xuICB9XG5cbiAgYXN5bmMgX3ZlcmlmeUFDTChhY2w6IGFueSwgdG9rZW46IHN0cmluZykge1xuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGF1dGgsIHVzZXJJZCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHRva2VuKTtcblxuICAgIC8vIEdldHRpbmcgdGhlIHNlc3Npb24gdG9rZW4gZmFpbGVkXG4gICAgLy8gVGhpcyBtZWFucyB0aGF0IG5vIGFkZGl0aW9uYWwgYXV0aCBpcyBhdmFpbGFibGVcbiAgICAvLyBBdCB0aGlzIHBvaW50LCBqdXN0IGJhaWwgb3V0IGFzIG5vIGFkZGl0aW9uYWwgdmlzaWJpbGl0eSBjYW4gYmUgaW5mZXJyZWQuXG4gICAgaWYgKCFhdXRoIHx8ICF1c2VySWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkID0gYWNsLmdldFJlYWRBY2Nlc3ModXNlcklkKTtcbiAgICBpZiAoaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBoYXMgYW55IHJvbGVzIHRoYXQgbWF0Y2ggdGhlIEFDTFxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBSZXNvbHZlIGZhbHNlIHJpZ2h0IGF3YXkgaWYgdGhlIGFjbCBkb2Vzbid0IGhhdmUgYW55IHJvbGVzXG4gICAgICAgIGNvbnN0IGFjbF9oYXNfcm9sZXMgPSBPYmplY3Qua2V5cyhhY2wucGVybWlzc2lvbnNCeUlkKS5zb21lKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgncm9sZTonKSk7XG4gICAgICAgIGlmICghYWNsX2hhc19yb2xlcykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IGF1dGguZ2V0VXNlclJvbGVzKCk7XG4gICAgICAgIC8vIEZpbmFsbHksIHNlZSBpZiBhbnkgb2YgdGhlIHVzZXIncyByb2xlcyBhbGxvdyB0aGVtIHJlYWQgYWNjZXNzXG4gICAgICAgIGZvciAoY29uc3Qgcm9sZSBvZiByb2xlTmFtZXMpIHtcbiAgICAgICAgICAvLyBXZSB1c2UgZ2V0UmVhZEFjY2VzcyBhcyBgcm9sZWAgaXMgaW4gdGhlIGZvcm0gYHJvbGU6cm9sZU5hbWVgXG4gICAgICAgICAgaWYgKGFjbC5nZXRSZWFkQWNjZXNzKHJvbGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgX21hdGNoZXNBQ0woYWNsOiBhbnksIGNsaWVudDogYW55LCByZXF1ZXN0SWQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIC8vIFJldHVybiB0cnVlIGRpcmVjdGx5IGlmIEFDTCBpc24ndCBwcmVzZW50LCBBQ0wgaXMgcHVibGljIHJlYWQsIG9yIGNsaWVudCBoYXMgbWFzdGVyIGtleVxuICAgIGlmICghYWNsIHx8IGFjbC5nZXRQdWJsaWNSZWFkQWNjZXNzKCkgfHwgY2xpZW50Lmhhc01hc3RlcktleSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENoZWNrIHN1YnNjcmlwdGlvbiBzZXNzaW9uVG9rZW4gbWF0Y2hlcyBBQ0wgZmlyc3RcbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uVG9rZW4gPSBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbjtcbiAgICBjb25zdCBjbGllbnRTZXNzaW9uVG9rZW4gPSBjbGllbnQuc2Vzc2lvblRva2VuO1xuXG4gICAgaWYgKGF3YWl0IHRoaXMuX3ZlcmlmeUFDTChhY2wsIHN1YnNjcmlwdGlvblRva2VuKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGF3YWl0IHRoaXMuX3ZlcmlmeUFDTChhY2wsIGNsaWVudFNlc3Npb25Ub2tlbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVDb25uZWN0KHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgaWYgKCF0aGlzLl92YWxpZGF0ZUtleXMocmVxdWVzdCwgdGhpcy5rZXlQYWlycykpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDQsICdLZXkgaW4gcmVxdWVzdCBpcyBub3QgdmFsaWQnKTtcbiAgICAgIGxvZ2dlci5lcnJvcignS2V5IGluIHJlcXVlc3QgaXMgbm90IHZhbGlkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhhc01hc3RlcktleSA9IHRoaXMuX2hhc01hc3RlcktleShyZXF1ZXN0LCB0aGlzLmtleVBhaXJzKTtcbiAgICBjb25zdCBjbGllbnRJZCA9IHV1aWR2NCgpO1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoXG4gICAgICBjbGllbnRJZCxcbiAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgaGFzTWFzdGVyS2V5LFxuICAgICAgcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICByZXF1ZXN0Lmluc3RhbGxhdGlvbklkXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICBjbGllbnQsXG4gICAgICAgIGV2ZW50OiAnY29ubmVjdCcsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiByZXF1ZXN0LnNlc3Npb25Ub2tlbixcbiAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogcmVxdWVzdC5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBhd2FpdCBtYXliZVJ1bkNvbm5lY3RUcmlnZ2VyKCdiZWZvcmVDb25uZWN0JywgcmVxKTtcbiAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkID0gY2xpZW50SWQ7XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkLCBjbGllbnQpO1xuICAgICAgbG9nZ2VyLmluZm8oYENyZWF0ZSBuZXcgY2xpZW50OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfWApO1xuICAgICAgY2xpZW50LnB1c2hDb25uZWN0KCk7XG4gICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHJlcSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIGVycm9yLmNvZGUgfHwgMTQxLCBlcnJvci5tZXNzYWdlIHx8IGVycm9yLCBmYWxzZSk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgcnVubmluZyBiZWZvcmVDb25uZWN0IGZvciBzZXNzaW9uICR7cmVxdWVzdC5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgX2hhc01hc3RlcktleShyZXF1ZXN0OiBhbnksIHZhbGlkS2V5UGFpcnM6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICghdmFsaWRLZXlQYWlycyB8fCB2YWxpZEtleVBhaXJzLnNpemUgPT0gMCB8fCAhdmFsaWRLZXlQYWlycy5oYXMoJ21hc3RlcktleScpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghcmVxdWVzdCB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlcXVlc3QsICdtYXN0ZXJLZXknKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gcmVxdWVzdC5tYXN0ZXJLZXkgPT09IHZhbGlkS2V5UGFpcnMuZ2V0KCdtYXN0ZXJLZXknKTtcbiAgfVxuXG4gIF92YWxpZGF0ZUtleXMocmVxdWVzdDogYW55LCB2YWxpZEtleVBhaXJzOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkS2V5UGFpcnMgfHwgdmFsaWRLZXlQYWlycy5zaXplID09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsZXQgaXNWYWxpZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgW2tleSwgc2VjcmV0XSBvZiB2YWxpZEtleVBhaXJzKSB7XG4gICAgICBpZiAoIXJlcXVlc3Rba2V5XSB8fCByZXF1ZXN0W2tleV0gIT09IHNlY3JldCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBpc1ZhbGlkO1xuICB9XG5cbiAgYXN5bmMgX2hhbmRsZVN1YnNjcmliZShwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIC8vIElmIHdlIGNhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgcmV0dXJuIGVycm9yIHRvIGNsaWVudFxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhcnNlV2Vic29ja2V0LCAnY2xpZW50SWQnKSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHN1YnNjcmliaW5nJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcignQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSBzdWJzY3JpYmluZycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSByZXF1ZXN0LnF1ZXJ5LmNsYXNzTmFtZTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgbWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyKCdiZWZvcmVTdWJzY3JpYmUnLCBjbGFzc05hbWUsIHJlcXVlc3QpO1xuXG4gICAgICAvLyBHZXQgc3Vic2NyaXB0aW9uIGZyb20gc3Vic2NyaXB0aW9ucywgY3JlYXRlIG9uZSBpZiBuZWNlc3NhcnlcbiAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbkhhc2ggPSBxdWVyeUhhc2gocmVxdWVzdC5xdWVyeSk7XG4gICAgICAvLyBBZGQgY2xhc3NOYW1lIHRvIHN1YnNjcmlwdGlvbnMgaWYgbmVjZXNzYXJ5XG5cbiAgICAgIGlmICghdGhpcy5zdWJzY3JpcHRpb25zLmhhcyhjbGFzc05hbWUpKSB7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5zZXQoY2xhc3NOYW1lLCBuZXcgTWFwKCkpO1xuICAgICAgfVxuICAgICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgICAgbGV0IHN1YnNjcmlwdGlvbjtcbiAgICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuaGFzKHN1YnNjcmlwdGlvbkhhc2gpKSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbiA9IGNsYXNzU3Vic2NyaXB0aW9ucy5nZXQoc3Vic2NyaXB0aW9uSGFzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKGNsYXNzTmFtZSwgcmVxdWVzdC5xdWVyeS53aGVyZSwgc3Vic2NyaXB0aW9uSGFzaCk7XG4gICAgICAgIGNsYXNzU3Vic2NyaXB0aW9ucy5zZXQoc3Vic2NyaXB0aW9uSGFzaCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIH1cblxuICAgICAgLy8gQWRkIHN1YnNjcmlwdGlvbkluZm8gdG8gY2xpZW50XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0ge1xuICAgICAgICBzdWJzY3JpcHRpb246IHN1YnNjcmlwdGlvbixcbiAgICAgIH07XG4gICAgICAvLyBBZGQgc2VsZWN0ZWQgZmllbGRzLCBzZXNzaW9uVG9rZW4gYW5kIGluc3RhbGxhdGlvbklkIGZvciB0aGlzIHN1YnNjcmlwdGlvbiBpZiBuZWNlc3NhcnlcbiAgICAgIGlmIChyZXF1ZXN0LnF1ZXJ5LmZpZWxkcykge1xuICAgICAgICBzdWJzY3JpcHRpb25JbmZvLmZpZWxkcyA9IHJlcXVlc3QucXVlcnkuZmllbGRzO1xuICAgICAgfVxuICAgICAgaWYgKHJlcXVlc3Quc2Vzc2lvblRva2VuKSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuID0gcmVxdWVzdC5zZXNzaW9uVG9rZW47XG4gICAgICB9XG4gICAgICBjbGllbnQuYWRkU3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0LnJlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mbyk7XG5cbiAgICAgIC8vIEFkZCBjbGllbnRJZCB0byBzdWJzY3JpcHRpb25cbiAgICAgIHN1YnNjcmlwdGlvbi5hZGRDbGllbnRTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQsIHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgICAgY2xpZW50LnB1c2hTdWJzY3JpYmUocmVxdWVzdC5yZXF1ZXN0SWQpO1xuXG4gICAgICBsb2dnZXIudmVyYm9zZShcbiAgICAgICAgYENyZWF0ZSBjbGllbnQgJHtwYXJzZVdlYnNvY2tldC5jbGllbnRJZH0gbmV3IHN1YnNjcmlwdGlvbjogJHtyZXF1ZXN0LnJlcXVlc3RJZH1gXG4gICAgICApO1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50IG51bWJlcjogJWQnLCB0aGlzLmNsaWVudHMuc2l6ZSk7XG4gICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgY2xpZW50LFxuICAgICAgICBldmVudDogJ3N1YnNjcmliZScsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiByZXF1ZXN0LnNlc3Npb25Ub2tlbixcbiAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgZS5jb2RlIHx8IDE0MSwgZS5tZXNzYWdlIHx8IGUsIGZhbHNlLCByZXF1ZXN0LnJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgcnVubmluZyBiZWZvcmVTdWJzY3JpYmUgb24gJHtjbGFzc05hbWV9IGZvciBzZXNzaW9uICR7cmVxdWVzdC5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShlKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfaGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgdGhpcy5faGFuZGxlVW5zdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QsIGZhbHNlKTtcbiAgICB0aGlzLl9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICB9XG5cbiAgX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSwgbm90aWZ5Q2xpZW50OiBib29sZWFuID0gdHJ1ZSk6IGFueSB7XG4gICAgLy8gSWYgd2UgY2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCByZXR1cm4gZXJyb3IgdG8gY2xpZW50XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGFyc2VXZWJzb2NrZXQsICdjbGllbnRJZCcpKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgdW5zdWJzY3JpYmluZydcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0SWQgPSByZXF1ZXN0LnJlcXVlc3RJZDtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIGNsaWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAyLFxuICAgICAgICAnQ2Fubm90IGZpbmQgY2xpZW50IHdpdGggY2xpZW50SWQgJyArXG4gICAgICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgK1xuICAgICAgICAgICcuIE1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBsaXZlIHF1ZXJ5IHNlcnZlciBiZWZvcmUgdW5zdWJzY3JpYmluZy4nXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQgJyArIHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0Nhbm5vdCBmaW5kIHN1YnNjcmlwdGlvbiB3aXRoIGNsaWVudElkICcgK1xuICAgICAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkICtcbiAgICAgICAgICAnIHN1YnNjcmlwdGlvbklkICcgK1xuICAgICAgICAgIHJlcXVlc3RJZCArXG4gICAgICAgICAgJy4gTWFrZSBzdXJlIHlvdSBzdWJzY3JpYmUgdG8gbGl2ZSBxdWVyeSBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcuJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgJ0NhbiBub3QgZmluZCBzdWJzY3JpcHRpb24gd2l0aCBjbGllbnRJZCAnICtcbiAgICAgICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCArXG4gICAgICAgICAgJyBzdWJzY3JpcHRpb25JZCAnICtcbiAgICAgICAgICByZXF1ZXN0SWRcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHN1YnNjcmlwdGlvbiBmcm9tIGNsaWVudFxuICAgIGNsaWVudC5kZWxldGVTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgLy8gUmVtb3ZlIGNsaWVudCBmcm9tIHN1YnNjcmlwdGlvblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHN1YnNjcmlwdGlvbkluZm8uc3Vic2NyaXB0aW9uO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHN1YnNjcmlwdGlvbi5jbGFzc05hbWU7XG4gICAgc3Vic2NyaXB0aW9uLmRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBjbGllbnQgd2hpY2ggaXMgc3Vic2NyaWJpbmcgdGhpcyBzdWJzY3JpcHRpb24sIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNsYXNzTmFtZSk7XG4gICAgaWYgKCFzdWJzY3JpcHRpb24uaGFzU3Vic2NyaWJpbmdDbGllbnQoKSkge1xuICAgICAgY2xhc3NTdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uaGFzaCk7XG4gICAgfVxuICAgIC8vIElmIHRoZXJlIGlzIG5vIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcywgcmVtb3ZlIGl0IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShjbGFzc05hbWUpO1xuICAgIH1cbiAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgIGNsaWVudCxcbiAgICAgIGV2ZW50OiAndW5zdWJzY3JpYmUnLFxuICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgIHNlc3Npb25Ub2tlbjogc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuXG4gICAgaWYgKCFub3RpZnlDbGllbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjbGllbnQucHVzaFVuc3Vic2NyaWJlKHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYERlbGV0ZSBjbGllbnQ6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9IHwgc3Vic2NyaXB0aW9uOiAke3JlcXVlc3QucmVxdWVzdElkfWBcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCB7IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIH07XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParsePubSub.js b/lib/LiveQuery/ParsePubSub.js deleted file mode 100644 index 87f2438cff..0000000000 --- a/lib/LiveQuery/ParsePubSub.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParsePubSub = void 0; - -var _AdapterLoader = require("../Adapters/AdapterLoader"); - -var _EventEmitterPubSub = require("../Adapters/PubSub/EventEmitterPubSub"); - -var _RedisPubSub = require("../Adapters/PubSub/RedisPubSub"); - -const ParsePubSub = {}; -exports.ParsePubSub = ParsePubSub; - -function useRedis(config) { - const redisURL = config.redisURL; - return typeof redisURL !== 'undefined' && redisURL !== ''; -} - -ParsePubSub.createPublisher = function (config) { - if (useRedis(config)) { - return _RedisPubSub.RedisPubSub.createPublisher(config); - } else { - const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); - - if (typeof adapter.createPublisher !== 'function') { - throw 'pubSubAdapter should have createPublisher()'; - } - - return adapter.createPublisher(config); - } -}; - -ParsePubSub.createSubscriber = function (config) { - if (useRedis(config)) { - return _RedisPubSub.RedisPubSub.createSubscriber(config); - } else { - const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); - - if (typeof adapter.createSubscriber !== 'function') { - throw 'pubSubAdapter should have createSubscriber()'; - } - - return adapter.createSubscriber(config); - } -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VQdWJTdWIuanMiXSwibmFtZXMiOlsiUGFyc2VQdWJTdWIiLCJ1c2VSZWRpcyIsImNvbmZpZyIsInJlZGlzVVJMIiwiY3JlYXRlUHVibGlzaGVyIiwiUmVkaXNQdWJTdWIiLCJhZGFwdGVyIiwicHViU3ViQWRhcHRlciIsIkV2ZW50RW1pdHRlclB1YlN1YiIsImNyZWF0ZVN1YnNjcmliZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFFQTs7QUFFQSxNQUFNQSxXQUFXLEdBQUcsRUFBcEI7OztBQUVBLFNBQVNDLFFBQVQsQ0FBa0JDLE1BQWxCLEVBQXdDO0FBQ3RDLFFBQU1DLFFBQVEsR0FBR0QsTUFBTSxDQUFDQyxRQUF4QjtBQUNBLFNBQU8sT0FBT0EsUUFBUCxLQUFvQixXQUFwQixJQUFtQ0EsUUFBUSxLQUFLLEVBQXZEO0FBQ0Q7O0FBRURILFdBQVcsQ0FBQ0ksZUFBWixHQUE4QixVQUFVRixNQUFWLEVBQTRCO0FBQ3hELE1BQUlELFFBQVEsQ0FBQ0MsTUFBRCxDQUFaLEVBQXNCO0FBQ3BCLFdBQU9HLHlCQUFZRCxlQUFaLENBQTRCRixNQUE1QixDQUFQO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsVUFBTUksT0FBTyxHQUFHLGdDQUFZSixNQUFNLENBQUNLLGFBQW5CLEVBQWtDQyxzQ0FBbEMsRUFBc0ROLE1BQXRELENBQWhCOztBQUNBLFFBQUksT0FBT0ksT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFlBQU0sNkNBQU47QUFDRDs7QUFDRCxXQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JGLE1BQXhCLENBQVA7QUFDRDtBQUNGLENBVkQ7O0FBWUFGLFdBQVcsQ0FBQ1MsZ0JBQVosR0FBK0IsVUFBVVAsTUFBVixFQUE2QjtBQUMxRCxNQUFJRCxRQUFRLENBQUNDLE1BQUQsQ0FBWixFQUFzQjtBQUNwQixXQUFPRyx5QkFBWUksZ0JBQVosQ0FBNkJQLE1BQTdCLENBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxVQUFNSSxPQUFPLEdBQUcsZ0NBQVlKLE1BQU0sQ0FBQ0ssYUFBbkIsRUFBa0NDLHNDQUFsQyxFQUFzRE4sTUFBdEQsQ0FBaEI7O0FBQ0EsUUFBSSxPQUFPSSxPQUFPLENBQUNHLGdCQUFmLEtBQW9DLFVBQXhDLEVBQW9EO0FBQ2xELFlBQU0sOENBQU47QUFDRDs7QUFDRCxXQUFPSCxPQUFPLENBQUNHLGdCQUFSLENBQXlCUCxNQUF6QixDQUFQO0FBQ0Q7QUFDRixDQVZEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlclB1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9FdmVudEVtaXR0ZXJQdWJTdWInO1xuXG5pbXBvcnQgeyBSZWRpc1B1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9SZWRpc1B1YlN1Yic7XG5cbmNvbnN0IFBhcnNlUHViU3ViID0ge307XG5cbmZ1bmN0aW9uIHVzZVJlZGlzKGNvbmZpZzogYW55KTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlZGlzVVJMID0gY29uZmlnLnJlZGlzVVJMO1xuICByZXR1cm4gdHlwZW9mIHJlZGlzVVJMICE9PSAndW5kZWZpbmVkJyAmJiByZWRpc1VSTCAhPT0gJyc7XG59XG5cblBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGlmICh1c2VSZWRpcyhjb25maWcpKSB7XG4gICAgcmV0dXJuIFJlZGlzUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93ICdwdWJTdWJBZGFwdGVyIHNob3VsZCBoYXZlIGNyZWF0ZVB1Ymxpc2hlcigpJztcbiAgICB9XG4gICAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG4gIH1cbn07XG5cblBhcnNlUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIgPSBmdW5jdGlvbiAoY29uZmlnOiBhbnkpOiB2b2lkIHtcbiAgaWYgKHVzZVJlZGlzKGNvbmZpZykpIHtcbiAgICByZXR1cm4gUmVkaXNQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVTdWJzY3JpYmVyKCknO1xuICAgIH1cbiAgICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IFBhcnNlUHViU3ViIH07XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseWebSocketServer.js b/lib/LiveQuery/ParseWebSocketServer.js deleted file mode 100644 index b7ab9d6099..0000000000 --- a/lib/LiveQuery/ParseWebSocketServer.js +++ /dev/null @@ -1,80 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseWebSocket = exports.ParseWebSocketServer = void 0; - -var _AdapterLoader = require("../Adapters/AdapterLoader"); - -var _WSAdapter = require("../Adapters/WebSocketServer/WSAdapter"); - -var _logger = _interopRequireDefault(require("../logger")); - -var _events = _interopRequireDefault(require("events")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseWebSocketServer { - constructor(server, onConnect, config) { - config.server = server; - const wss = (0, _AdapterLoader.loadAdapter)(config.wssAdapter, _WSAdapter.WSAdapter, config); - - wss.onListen = () => { - _logger.default.info('Parse LiveQuery Server starts running'); - }; - - wss.onConnection = ws => { - ws.on('error', error => { - _logger.default.error(error.message); - - _logger.default.error(JSON.stringify(ws)); - }); - onConnect(new ParseWebSocket(ws)); // Send ping to client periodically - - const pingIntervalId = setInterval(() => { - if (ws.readyState == ws.OPEN) { - ws.ping(); - } else { - clearInterval(pingIntervalId); - } - }, config.websocketTimeout || 10 * 1000); - }; - - wss.onError = error => { - _logger.default.error(error); - }; - - wss.start(); - this.server = wss; - } - - close() { - if (this.server && this.server.close) { - this.server.close(); - } - } - -} - -exports.ParseWebSocketServer = ParseWebSocketServer; - -class ParseWebSocket extends _events.default.EventEmitter { - constructor(ws) { - super(); - - ws.onmessage = request => this.emit('message', request && request.data ? request.data : request); - - ws.onclose = () => this.emit('disconnect'); - - this.ws = ws; - } - - send(message) { - this.ws.send(message); - } - -} - -exports.ParseWebSocket = ParseWebSocket; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VXZWJTb2NrZXRTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsIm9uQ29ubmVjdCIsImNvbmZpZyIsIndzcyIsIndzc0FkYXB0ZXIiLCJXU0FkYXB0ZXIiLCJvbkxpc3RlbiIsImxvZ2dlciIsImluZm8iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uIiwiZXJyb3IiLCJtZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsIlBhcnNlV2ViU29ja2V0IiwicGluZ0ludGVydmFsSWQiLCJzZXRJbnRlcnZhbCIsInJlYWR5U3RhdGUiLCJPUEVOIiwicGluZyIsImNsZWFySW50ZXJ2YWwiLCJ3ZWJzb2NrZXRUaW1lb3V0Iiwib25FcnJvciIsInN0YXJ0IiwiY2xvc2UiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJvbm1lc3NhZ2UiLCJyZXF1ZXN0IiwiZW1pdCIsImRhdGEiLCJvbmNsb3NlIiwic2VuZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsb0JBQU4sQ0FBMkI7QUFHaENDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFjQyxTQUFkLEVBQW1DQyxNQUFuQyxFQUEyQztBQUNwREEsSUFBQUEsTUFBTSxDQUFDRixNQUFQLEdBQWdCQSxNQUFoQjtBQUNBLFVBQU1HLEdBQUcsR0FBRyxnQ0FBWUQsTUFBTSxDQUFDRSxVQUFuQixFQUErQkMsb0JBQS9CLEVBQTBDSCxNQUExQyxDQUFaOztBQUNBQyxJQUFBQSxHQUFHLENBQUNHLFFBQUosR0FBZSxNQUFNO0FBQ25CQyxzQkFBT0MsSUFBUCxDQUFZLHVDQUFaO0FBQ0QsS0FGRDs7QUFHQUwsSUFBQUEsR0FBRyxDQUFDTSxZQUFKLEdBQW1CQyxFQUFFLElBQUk7QUFDdkJBLE1BQUFBLEVBQUUsQ0FBQ0MsRUFBSCxDQUFNLE9BQU4sRUFBZUMsS0FBSyxJQUFJO0FBQ3RCTCx3QkFBT0ssS0FBUCxDQUFhQSxLQUFLLENBQUNDLE9BQW5COztBQUNBTix3QkFBT0ssS0FBUCxDQUFhRSxJQUFJLENBQUNDLFNBQUwsQ0FBZUwsRUFBZixDQUFiO0FBQ0QsT0FIRDtBQUlBVCxNQUFBQSxTQUFTLENBQUMsSUFBSWUsY0FBSixDQUFtQk4sRUFBbkIsQ0FBRCxDQUFULENBTHVCLENBTXZCOztBQUNBLFlBQU1PLGNBQWMsR0FBR0MsV0FBVyxDQUFDLE1BQU07QUFDdkMsWUFBSVIsRUFBRSxDQUFDUyxVQUFILElBQWlCVCxFQUFFLENBQUNVLElBQXhCLEVBQThCO0FBQzVCVixVQUFBQSxFQUFFLENBQUNXLElBQUg7QUFDRCxTQUZELE1BRU87QUFDTEMsVUFBQUEsYUFBYSxDQUFDTCxjQUFELENBQWI7QUFDRDtBQUNGLE9BTmlDLEVBTS9CZixNQUFNLENBQUNxQixnQkFBUCxJQUEyQixLQUFLLElBTkQsQ0FBbEM7QUFPRCxLQWREOztBQWVBcEIsSUFBQUEsR0FBRyxDQUFDcUIsT0FBSixHQUFjWixLQUFLLElBQUk7QUFDckJMLHNCQUFPSyxLQUFQLENBQWFBLEtBQWI7QUFDRCxLQUZEOztBQUdBVCxJQUFBQSxHQUFHLENBQUNzQixLQUFKO0FBQ0EsU0FBS3pCLE1BQUwsR0FBY0csR0FBZDtBQUNEOztBQUVEdUIsRUFBQUEsS0FBSyxHQUFHO0FBQ04sUUFBSSxLQUFLMUIsTUFBTCxJQUFlLEtBQUtBLE1BQUwsQ0FBWTBCLEtBQS9CLEVBQXNDO0FBQ3BDLFdBQUsxQixNQUFMLENBQVkwQixLQUFaO0FBQ0Q7QUFDRjs7QUFuQytCOzs7O0FBc0MzQixNQUFNVixjQUFOLFNBQTZCVyxnQkFBT0MsWUFBcEMsQ0FBaUQ7QUFHdEQ3QixFQUFBQSxXQUFXLENBQUNXLEVBQUQsRUFBVTtBQUNuQjs7QUFDQUEsSUFBQUEsRUFBRSxDQUFDbUIsU0FBSCxHQUFlQyxPQUFPLElBQ3BCLEtBQUtDLElBQUwsQ0FBVSxTQUFWLEVBQXFCRCxPQUFPLElBQUlBLE9BQU8sQ0FBQ0UsSUFBbkIsR0FBMEJGLE9BQU8sQ0FBQ0UsSUFBbEMsR0FBeUNGLE9BQTlELENBREY7O0FBRUFwQixJQUFBQSxFQUFFLENBQUN1QixPQUFILEdBQWEsTUFBTSxLQUFLRixJQUFMLENBQVUsWUFBVixDQUFuQjs7QUFDQSxTQUFLckIsRUFBTCxHQUFVQSxFQUFWO0FBQ0Q7O0FBRUR3QixFQUFBQSxJQUFJLENBQUNyQixPQUFELEVBQXFCO0FBQ3ZCLFNBQUtILEVBQUwsQ0FBUXdCLElBQVIsQ0FBYXJCLE9BQWI7QUFDRDs7QUFicUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsb2FkQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgV1NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvV2ViU29ja2V0U2VydmVyL1dTQWRhcHRlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZVdlYlNvY2tldFNlcnZlciB7XG4gIHNlcnZlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBvbkNvbm5lY3Q6IEZ1bmN0aW9uLCBjb25maWcpIHtcbiAgICBjb25maWcuc2VydmVyID0gc2VydmVyO1xuICAgIGNvbnN0IHdzcyA9IGxvYWRBZGFwdGVyKGNvbmZpZy53c3NBZGFwdGVyLCBXU0FkYXB0ZXIsIGNvbmZpZyk7XG4gICAgd3NzLm9uTGlzdGVuID0gKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oJ1BhcnNlIExpdmVRdWVyeSBTZXJ2ZXIgc3RhcnRzIHJ1bm5pbmcnKTtcbiAgICB9O1xuICAgIHdzcy5vbkNvbm5lY3Rpb24gPSB3cyA9PiB7XG4gICAgICB3cy5vbignZXJyb3InLCBlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKEpTT04uc3RyaW5naWZ5KHdzKSk7XG4gICAgICB9KTtcbiAgICAgIG9uQ29ubmVjdChuZXcgUGFyc2VXZWJTb2NrZXQod3MpKTtcbiAgICAgIC8vIFNlbmQgcGluZyB0byBjbGllbnQgcGVyaW9kaWNhbGx5XG4gICAgICBjb25zdCBwaW5nSW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT0gd3MuT1BFTikge1xuICAgICAgICAgIHdzLnBpbmcoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbElkKTtcbiAgICAgICAgfVxuICAgICAgfSwgY29uZmlnLndlYnNvY2tldFRpbWVvdXQgfHwgMTAgKiAxMDAwKTtcbiAgICB9O1xuICAgIHdzcy5vbkVycm9yID0gZXJyb3IgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICB9O1xuICAgIHdzcy5zdGFydCgpO1xuICAgIHRoaXMuc2VydmVyID0gd3NzO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuc2VydmVyICYmIHRoaXMuc2VydmVyLmNsb3NlKSB7XG4gICAgICB0aGlzLnNlcnZlci5jbG9zZSgpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VXZWJTb2NrZXQgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgd3M6IGFueTtcblxuICBjb25zdHJ1Y3Rvcih3czogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB3cy5vbm1lc3NhZ2UgPSByZXF1ZXN0ID0+XG4gICAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCByZXF1ZXN0ICYmIHJlcXVlc3QuZGF0YSA/IHJlcXVlc3QuZGF0YSA6IHJlcXVlc3QpO1xuICAgIHdzLm9uY2xvc2UgPSAoKSA9PiB0aGlzLmVtaXQoJ2Rpc2Nvbm5lY3QnKTtcbiAgICB0aGlzLndzID0gd3M7XG4gIH1cblxuICBzZW5kKG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIHRoaXMud3Muc2VuZChtZXNzYWdlKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/QueryTools.js b/lib/LiveQuery/QueryTools.js deleted file mode 100644 index 58b13135f2..0000000000 --- a/lib/LiveQuery/QueryTools.js +++ /dev/null @@ -1,407 +0,0 @@ -"use strict"; - -var equalObjects = require('./equalObjects'); - -var Id = require('./Id'); - -var Parse = require('parse/node'); -/** - * Query Hashes are deterministic hashes for Parse Queries. - * Any two queries that have the same set of constraints will produce the same - * hash. This lets us reliably group components by the queries they depend upon, - * and quickly determine if a query has changed. - */ - -/** - * Convert $or queries into an array of where conditions - */ - - -function flattenOrQueries(where) { - if (!Object.prototype.hasOwnProperty.call(where, '$or')) { - return where; - } - - var accum = []; - - for (var i = 0; i < where.$or.length; i++) { - accum = accum.concat(where.$or[i]); - } - - return accum; -} -/** - * Deterministically turns an object into a string. Disregards ordering - */ - - -function stringify(object) { - if (typeof object !== 'object' || object === null) { - if (typeof object === 'string') { - return '"' + object.replace(/\|/g, '%|') + '"'; - } - - return object + ''; - } - - if (Array.isArray(object)) { - var copy = object.map(stringify); - copy.sort(); - return '[' + copy.join(',') + ']'; - } - - var sections = []; - var keys = Object.keys(object); - keys.sort(); - - for (var k = 0; k < keys.length; k++) { - sections.push(stringify(keys[k]) + ':' + stringify(object[keys[k]])); - } - - return '{' + sections.join(',') + '}'; -} -/** - * Generate a hash from a query, with unique fields for columns, values, order, - * skip, and limit. - */ - - -function queryHash(query) { - if (query instanceof Parse.Query) { - query = { - className: query.className, - where: query._where - }; - } - - var where = flattenOrQueries(query.where || {}); - var columns = []; - var values = []; - var i; - - if (Array.isArray(where)) { - var uniqueColumns = {}; - - for (i = 0; i < where.length; i++) { - var subValues = {}; - var keys = Object.keys(where[i]); - keys.sort(); - - for (var j = 0; j < keys.length; j++) { - subValues[keys[j]] = where[i][keys[j]]; - uniqueColumns[keys[j]] = true; - } - - values.push(subValues); - } - - columns = Object.keys(uniqueColumns); - columns.sort(); - } else { - columns = Object.keys(where); - columns.sort(); - - for (i = 0; i < columns.length; i++) { - values.push(where[columns[i]]); - } - } - - var sections = [columns.join(','), stringify(values)]; - return query.className + ':' + sections.join('|'); -} -/** - * contains -- Determines if an object is contained in a list with special handling for Parse pointers. - */ - - -function contains(haystack, needle) { - if (needle && needle.__type && needle.__type === 'Pointer') { - for (const i in haystack) { - const ptr = haystack[i]; - - if (typeof ptr === 'string' && ptr === needle.objectId) { - return true; - } - - if (ptr.className === needle.className && ptr.objectId === needle.objectId) { - return true; - } - } - - return false; - } - - return haystack.indexOf(needle) > -1; -} -/** - * matchesQuery -- Determines if an object would be returned by a Parse Query - * It's a lightweight, where-clause only implementation of a full query engine. - * Since we find queries that match objects, rather than objects that match - * queries, we can avoid building a full-blown query tool. - */ - - -function matchesQuery(object, query) { - if (query instanceof Parse.Query) { - var className = object.id instanceof Id ? object.id.className : object.className; - - if (className !== query.className) { - return false; - } - - return matchesQuery(object, query._where); - } - - for (var field in query) { - if (!matchesKeyConstraints(object, field, query[field])) { - return false; - } - } - - return true; -} - -function equalObjectsGeneric(obj, compareTo, eqlFn) { - if (Array.isArray(obj)) { - for (var i = 0; i < obj.length; i++) { - if (eqlFn(obj[i], compareTo)) { - return true; - } - } - - return false; - } - - return eqlFn(obj, compareTo); -} -/** - * Determines whether an object matches a single key's constraints - */ - - -function matchesKeyConstraints(object, key, constraints) { - if (constraints === null) { - return false; - } - - if (key.indexOf('.') >= 0) { - // Key references a subobject - var keyComponents = key.split('.'); - var subObjectKey = keyComponents[0]; - var keyRemainder = keyComponents.slice(1).join('.'); - return matchesKeyConstraints(object[subObjectKey] || {}, keyRemainder, constraints); - } - - var i; - - if (key === '$or') { - for (i = 0; i < constraints.length; i++) { - if (matchesQuery(object, constraints[i])) { - return true; - } - } - - return false; - } - - if (key === '$relatedTo') { - // Bail! We can't handle relational queries locally - return false; - } // Decode Date JSON value - - - if (object[key] && object[key].__type == 'Date') { - object[key] = new Date(object[key].iso); - } // Equality (or Array contains) cases - - - if (typeof constraints !== 'object') { - if (Array.isArray(object[key])) { - return object[key].indexOf(constraints) > -1; - } - - return object[key] === constraints; - } - - var compareTo; - - if (constraints.__type) { - if (constraints.__type === 'Pointer') { - return equalObjectsGeneric(object[key], constraints, function (obj, ptr) { - return typeof obj !== 'undefined' && ptr.className === obj.className && ptr.objectId === obj.objectId; - }); - } - - return equalObjectsGeneric(object[key], Parse._decode(key, constraints), equalObjects); - } // More complex cases - - - for (var condition in constraints) { - compareTo = constraints[condition]; - - if (compareTo.__type) { - compareTo = Parse._decode(key, compareTo); - } - - switch (condition) { - case '$lt': - if (object[key] >= compareTo) { - return false; - } - - break; - - case '$lte': - if (object[key] > compareTo) { - return false; - } - - break; - - case '$gt': - if (object[key] <= compareTo) { - return false; - } - - break; - - case '$gte': - if (object[key] < compareTo) { - return false; - } - - break; - - case '$ne': - if (equalObjects(object[key], compareTo)) { - return false; - } - - break; - - case '$in': - if (!contains(compareTo, object[key])) { - return false; - } - - break; - - case '$nin': - if (contains(compareTo, object[key])) { - return false; - } - - break; - - case '$all': - for (i = 0; i < compareTo.length; i++) { - if (object[key].indexOf(compareTo[i]) < 0) { - return false; - } - } - - break; - - case '$exists': - { - const propertyExists = typeof object[key] !== 'undefined'; - const existenceIsRequired = constraints['$exists']; - - if (typeof constraints['$exists'] !== 'boolean') { - // The SDK will never submit a non-boolean for $exists, but if someone - // tries to submit a non-boolean for $exits outside the SDKs, just ignore it. - break; - } - - if (!propertyExists && existenceIsRequired || propertyExists && !existenceIsRequired) { - return false; - } - - break; - } - - case '$regex': - if (typeof compareTo === 'object') { - return compareTo.test(object[key]); - } // JS doesn't support perl-style escaping - - - var expString = ''; - var escapeEnd = -2; - var escapeStart = compareTo.indexOf('\\Q'); - - while (escapeStart > -1) { - // Add the unescaped portion - expString += compareTo.substring(escapeEnd + 2, escapeStart); - escapeEnd = compareTo.indexOf('\\E', escapeStart); - - if (escapeEnd > -1) { - expString += compareTo.substring(escapeStart + 2, escapeEnd).replace(/\\\\\\\\E/g, '\\E').replace(/\W/g, '\\$&'); - } - - escapeStart = compareTo.indexOf('\\Q', escapeEnd); - } - - expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2)); - var exp = new RegExp(expString, constraints.$options || ''); - - if (!exp.test(object[key])) { - return false; - } - - break; - - case '$nearSphere': - if (!compareTo || !object[key]) { - return false; - } - - var distance = compareTo.radiansTo(object[key]); - var max = constraints.$maxDistance || Infinity; - return distance <= max; - - case '$within': - if (!compareTo || !object[key]) { - return false; - } - - var southWest = compareTo.$box[0]; - var northEast = compareTo.$box[1]; - - if (southWest.latitude > northEast.latitude || southWest.longitude > northEast.longitude) { - // Invalid box, crosses the date line - return false; - } - - return object[key].latitude > southWest.latitude && object[key].latitude < northEast.latitude && object[key].longitude > southWest.longitude && object[key].longitude < northEast.longitude; - - case '$options': - // Not a query type, but a way to add options to $regex. Ignore and - // avoid the default - break; - - case '$maxDistance': - // Not a query type, but a way to add a cap to $nearSphere. Ignore and - // avoid the default - break; - - case '$select': - return false; - - case '$dontSelect': - return false; - - default: - return false; - } - } - - return true; -} - -var QueryTools = { - queryHash: queryHash, - matchesQuery: matchesQuery -}; -module.exports = QueryTools; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUXVlcnlUb29scy5qcyJdLCJuYW1lcyI6WyJlcXVhbE9iamVjdHMiLCJyZXF1aXJlIiwiSWQiLCJQYXJzZSIsImZsYXR0ZW5PclF1ZXJpZXMiLCJ3aGVyZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFjY3VtIiwiaSIsIiRvciIsImxlbmd0aCIsImNvbmNhdCIsInN0cmluZ2lmeSIsIm9iamVjdCIsInJlcGxhY2UiLCJBcnJheSIsImlzQXJyYXkiLCJjb3B5IiwibWFwIiwic29ydCIsImpvaW4iLCJzZWN0aW9ucyIsImtleXMiLCJrIiwicHVzaCIsInF1ZXJ5SGFzaCIsInF1ZXJ5IiwiUXVlcnkiLCJjbGFzc05hbWUiLCJfd2hlcmUiLCJjb2x1bW5zIiwidmFsdWVzIiwidW5pcXVlQ29sdW1ucyIsInN1YlZhbHVlcyIsImoiLCJjb250YWlucyIsImhheXN0YWNrIiwibmVlZGxlIiwiX190eXBlIiwicHRyIiwib2JqZWN0SWQiLCJpbmRleE9mIiwibWF0Y2hlc1F1ZXJ5IiwiaWQiLCJmaWVsZCIsIm1hdGNoZXNLZXlDb25zdHJhaW50cyIsImVxdWFsT2JqZWN0c0dlbmVyaWMiLCJvYmoiLCJjb21wYXJlVG8iLCJlcWxGbiIsImtleSIsImNvbnN0cmFpbnRzIiwia2V5Q29tcG9uZW50cyIsInNwbGl0Iiwic3ViT2JqZWN0S2V5Iiwia2V5UmVtYWluZGVyIiwic2xpY2UiLCJEYXRlIiwiaXNvIiwiX2RlY29kZSIsImNvbmRpdGlvbiIsInByb3BlcnR5RXhpc3RzIiwiZXhpc3RlbmNlSXNSZXF1aXJlZCIsInRlc3QiLCJleHBTdHJpbmciLCJlc2NhcGVFbmQiLCJlc2NhcGVTdGFydCIsInN1YnN0cmluZyIsIk1hdGgiLCJtYXgiLCJleHAiLCJSZWdFeHAiLCIkb3B0aW9ucyIsImRpc3RhbmNlIiwicmFkaWFuc1RvIiwiJG1heERpc3RhbmNlIiwiSW5maW5pdHkiLCJzb3V0aFdlc3QiLCIkYm94Iiwibm9ydGhFYXN0IiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJRdWVyeVRvb2xzIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxFQUFFLEdBQUdELE9BQU8sQ0FBQyxNQUFELENBQWhCOztBQUNBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBbkI7QUFFQTs7Ozs7OztBQU9BOzs7OztBQUdBLFNBQVNHLGdCQUFULENBQTBCQyxLQUExQixFQUFpQztBQUMvQixNQUFJLENBQUNDLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDSixLQUFyQyxFQUE0QyxLQUE1QyxDQUFMLEVBQXlEO0FBQ3ZELFdBQU9BLEtBQVA7QUFDRDs7QUFDRCxNQUFJSyxLQUFLLEdBQUcsRUFBWjs7QUFDQSxPQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdOLEtBQUssQ0FBQ08sR0FBTixDQUFVQyxNQUE5QixFQUFzQ0YsQ0FBQyxFQUF2QyxFQUEyQztBQUN6Q0QsSUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNJLE1BQU4sQ0FBYVQsS0FBSyxDQUFDTyxHQUFOLENBQVVELENBQVYsQ0FBYixDQUFSO0FBQ0Q7O0FBQ0QsU0FBT0QsS0FBUDtBQUNEO0FBRUQ7Ozs7O0FBR0EsU0FBU0ssU0FBVCxDQUFtQkMsTUFBbkIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQWxCLElBQThCQSxNQUFNLEtBQUssSUFBN0MsRUFBbUQ7QUFDakQsUUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQXRCLEVBQWdDO0FBQzlCLGFBQU8sTUFBTUEsTUFBTSxDQUFDQyxPQUFQLENBQWUsS0FBZixFQUFzQixJQUF0QixDQUFOLEdBQW9DLEdBQTNDO0FBQ0Q7O0FBQ0QsV0FBT0QsTUFBTSxHQUFHLEVBQWhCO0FBQ0Q7O0FBQ0QsTUFB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ZXF1YWxPYmplY3RzJyk7XG52YXIgSWQgPSByZXF1aXJlKCcuL0lkJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5cbi8qKlxuICogUXVlcnkgSGFzaGVzIGFyZSBkZXRlcm1pbmlzdGljIGhhc2hlcyBmb3IgUGFyc2UgUXVlcmllcy5cbiAqIEFueSB0d28gcXVlcmllcyB0aGF0IGhhdmUgdGhlIHNhbWUgc2V0IG9mIGNvbnN0cmFpbnRzIHdpbGwgcHJvZHVjZSB0aGUgc2FtZVxuICogaGFzaC4gVGhpcyBsZXRzIHVzIHJlbGlhYmx5IGdyb3VwIGNvbXBvbmVudHMgYnkgdGhlIHF1ZXJpZXMgdGhleSBkZXBlbmQgdXBvbixcbiAqIGFuZCBxdWlja2x5IGRldGVybWluZSBpZiBhIHF1ZXJ5IGhhcyBjaGFuZ2VkLlxuICovXG5cbi8qKlxuICogQ29udmVydCAkb3IgcXVlcmllcyBpbnRvIGFuIGFycmF5IG9mIHdoZXJlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZmxhdHRlbk9yUXVlcmllcyh3aGVyZSkge1xuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh3aGVyZSwgJyRvcicpKSB7XG4gICAgcmV0dXJuIHdoZXJlO1xuICB9XG4gIHZhciBhY2N1bSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHdoZXJlLiRvci5sZW5ndGg7IGkrKykge1xuICAgIGFjY3VtID0gYWNjdW0uY29uY2F0KHdoZXJlLiRvcltpXSk7XG4gIH1cbiAgcmV0dXJuIGFjY3VtO1xufVxuXG4vKipcbiAqIERldGVybWluaXN0aWNhbGx5IHR1cm5zIGFuIG9iamVjdCBpbnRvIGEgc3RyaW5nLiBEaXNyZWdhcmRzIG9yZGVyaW5nXG4gKi9cbmZ1bmN0aW9uIHN0cmluZ2lmeShvYmplY3QpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcgfHwgb2JqZWN0ID09PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gJ1wiJyArIG9iamVjdC5yZXBsYWNlKC9cXHwvZywgJyV8JykgKyAnXCInO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0ICsgJyc7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgIHZhciBjb3B5ID0gb2JqZWN0Lm1hcChzdHJpbmdpZnkpO1xuICAgIGNvcHkuc29ydCgpO1xuICAgIHJldHVybiAnWycgKyBjb3B5LmpvaW4oJywnKSArICddJztcbiAgfVxuICB2YXIgc2VjdGlvbnMgPSBbXTtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICBrZXlzLnNvcnQoKTtcbiAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgc2VjdGlvbnMucHVzaChzdHJpbmdpZnkoa2V5c1trXSkgKyAnOicgKyBzdHJpbmdpZnkob2JqZWN0W2tleXNba11dKSk7XG4gIH1cbiAgcmV0dXJuICd7JyArIHNlY3Rpb25zLmpvaW4oJywnKSArICd9Jztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIGhhc2ggZnJvbSBhIHF1ZXJ5LCB3aXRoIHVuaXF1ZSBmaWVsZHMgZm9yIGNvbHVtbnMsIHZhbHVlcywgb3JkZXIsXG4gKiBza2lwLCBhbmQgbGltaXQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5SGFzaChxdWVyeSkge1xuICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgIHF1ZXJ5ID0ge1xuICAgICAgY2xhc3NOYW1lOiBxdWVyeS5jbGFzc05hbWUsXG4gICAgICB3aGVyZTogcXVlcnkuX3doZXJlLFxuICAgIH07XG4gIH1cbiAgdmFyIHdoZXJlID0gZmxhdHRlbk9yUXVlcmllcyhxdWVyeS53aGVyZSB8fCB7fSk7XG4gIHZhciBjb2x1bW5zID0gW107XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIGk7XG4gIGlmIChBcnJheS5pc0FycmF5KHdoZXJlKSkge1xuICAgIHZhciB1bmlxdWVDb2x1bW5zID0ge307XG4gICAgZm9yIChpID0gMDsgaSA8IHdoZXJlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc3ViVmFsdWVzID0ge307XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHdoZXJlW2ldKTtcbiAgICAgIGtleXMuc29ydCgpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHN1YlZhbHVlc1trZXlzW2pdXSA9IHdoZXJlW2ldW2tleXNbal1dO1xuICAgICAgICB1bmlxdWVDb2x1bW5zW2tleXNbal1dID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhbHVlcy5wdXNoKHN1YlZhbHVlcyk7XG4gICAgfVxuICAgIGNvbHVtbnMgPSBPYmplY3Qua2V5cyh1bmlxdWVDb2x1bW5zKTtcbiAgICBjb2x1bW5zLnNvcnQoKTtcbiAgfSBlbHNlIHtcbiAgICBjb2x1bW5zID0gT2JqZWN0LmtleXMod2hlcmUpO1xuICAgIGNvbHVtbnMuc29ydCgpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb2x1bW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZXMucHVzaCh3aGVyZVtjb2x1bW5zW2ldXSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNlY3Rpb25zID0gW2NvbHVtbnMuam9pbignLCcpLCBzdHJpbmdpZnkodmFsdWVzKV07XG5cbiAgcmV0dXJuIHF1ZXJ5LmNsYXNzTmFtZSArICc6JyArIHNlY3Rpb25zLmpvaW4oJ3wnKTtcbn1cblxuLyoqXG4gKiBjb250YWlucyAtLSBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBpcyBjb250YWluZWQgaW4gYSBsaXN0IHdpdGggc3BlY2lhbCBoYW5kbGluZyBmb3IgUGFyc2UgcG9pbnRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5zKGhheXN0YWNrOiBBcnJheSwgbmVlZGxlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKG5lZWRsZSAmJiBuZWVkbGUuX190eXBlICYmIG5lZWRsZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgIGZvciAoY29uc3QgaSBpbiBoYXlzdGFjaykge1xuICAgICAgY29uc3QgcHRyID0gaGF5c3RhY2tbaV07XG4gICAgICBpZiAodHlwZW9mIHB0ciA9PT0gJ3N0cmluZycgJiYgcHRyID09PSBuZWVkbGUub2JqZWN0SWQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAocHRyLmNsYXNzTmFtZSA9PT0gbmVlZGxlLmNsYXNzTmFtZSAmJiBwdHIub2JqZWN0SWQgPT09IG5lZWRsZS5vYmplY3RJZCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBoYXlzdGFjay5pbmRleE9mKG5lZWRsZSkgPiAtMTtcbn1cbi8qKlxuICogbWF0Y2hlc1F1ZXJ5IC0tIERldGVybWluZXMgaWYgYW4gb2JqZWN0IHdvdWxkIGJlIHJldHVybmVkIGJ5IGEgUGFyc2UgUXVlcnlcbiAqIEl0J3MgYSBsaWdodHdlaWdodCwgd2hlcmUtY2xhdXNlIG9ubHkgaW1wbGVtZW50YXRpb24gb2YgYSBmdWxsIHF1ZXJ5IGVuZ2luZS5cbiAqIFNpbmNlIHdlIGZpbmQgcXVlcmllcyB0aGF0IG1hdGNoIG9iamVjdHMsIHJhdGhlciB0aGFuIG9iamVjdHMgdGhhdCBtYXRjaFxuICogcXVlcmllcywgd2UgY2FuIGF2b2lkIGJ1aWxkaW5nIGEgZnVsbC1ibG93biBxdWVyeSB0b29sLlxuICovXG5mdW5jdGlvbiBtYXRjaGVzUXVlcnkob2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKHF1ZXJ5IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gb2JqZWN0LmlkIGluc3RhbmNlb2YgSWQgPyBvYmplY3QuaWQuY2xhc3NOYW1lIDogb2JqZWN0LmNsYXNzTmFtZTtcbiAgICBpZiAoY2xhc3NOYW1lICE9PSBxdWVyeS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShvYmplY3QsIHF1ZXJ5Ll93aGVyZSk7XG4gIH1cbiAgZm9yICh2YXIgZmllbGQgaW4gcXVlcnkpIHtcbiAgICBpZiAoIW1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGZpZWxkLCBxdWVyeVtmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBlcXVhbE9iamVjdHNHZW5lcmljKG9iaiwgY29tcGFyZVRvLCBlcWxGbikge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcWxGbihvYmpbaV0sIGNvbXBhcmVUbykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBlcWxGbihvYmosIGNvbXBhcmVUbyk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9iamVjdCBtYXRjaGVzIGEgc2luZ2xlIGtleSdzIGNvbnN0cmFpbnRzXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGtleSwgY29uc3RyYWludHMpIHtcbiAgaWYgKGNvbnN0cmFpbnRzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkuaW5kZXhPZignLicpID49IDApIHtcbiAgICAvLyBLZXkgcmVmZXJlbmNlcyBhIHN1Ym9iamVjdFxuICAgIHZhciBrZXlDb21wb25lbnRzID0ga2V5LnNwbGl0KCcuJyk7XG4gICAgdmFyIHN1Yk9iamVjdEtleSA9IGtleUNvbXBvbmVudHNbMF07XG4gICAgdmFyIGtleVJlbWFpbmRlciA9IGtleUNvbXBvbmVudHMuc2xpY2UoMSkuam9pbignLicpO1xuICAgIHJldHVybiBtYXRjaGVzS2V5Q29uc3RyYWludHMob2JqZWN0W3N1Yk9iamVjdEtleV0gfHwge30sIGtleVJlbWFpbmRlciwgY29uc3RyYWludHMpO1xuICB9XG4gIHZhciBpO1xuICBpZiAoa2V5ID09PSAnJG9yJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1hdGNoZXNRdWVyeShvYmplY3QsIGNvbnN0cmFpbnRzW2ldKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkgPT09ICckcmVsYXRlZFRvJykge1xuICAgIC8vIEJhaWwhIFdlIGNhbid0IGhhbmRsZSByZWxhdGlvbmFsIHF1ZXJpZXMgbG9jYWxseVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBEZWNvZGUgRGF0ZSBKU09OIHZhbHVlXG4gIGlmIChvYmplY3Rba2V5XSAmJiBvYmplY3Rba2V5XS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgb2JqZWN0W2tleV0gPSBuZXcgRGF0ZShvYmplY3Rba2V5XS5pc28pO1xuICB9XG4gIC8vIEVxdWFsaXR5IChvciBBcnJheSBjb250YWlucykgY2FzZXNcbiAgaWYgKHR5cGVvZiBjb25zdHJhaW50cyAhPT0gJ29iamVjdCcpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3Rba2V5XSkpIHtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XS5pbmRleE9mKGNvbnN0cmFpbnRzKSA+IC0xO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IGNvbnN0cmFpbnRzO1xuICB9XG4gIHZhciBjb21wYXJlVG87XG4gIGlmIChjb25zdHJhaW50cy5fX3R5cGUpIHtcbiAgICBpZiAoY29uc3RyYWludHMuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiBlcXVhbE9iamVjdHNHZW5lcmljKG9iamVjdFtrZXldLCBjb25zdHJhaW50cywgZnVuY3Rpb24gKG9iaiwgcHRyKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgdHlwZW9mIG9iaiAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICBwdHIuY2xhc3NOYW1lID09PSBvYmouY2xhc3NOYW1lICYmXG4gICAgICAgICAgcHRyLm9iamVjdElkID09PSBvYmoub2JqZWN0SWRcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBlcXVhbE9iamVjdHNHZW5lcmljKG9iamVjdFtrZXldLCBQYXJzZS5fZGVjb2RlKGtleSwgY29uc3RyYWludHMpLCBlcXVhbE9iamVjdHMpO1xuICB9XG4gIC8vIE1vcmUgY29tcGxleCBjYXNlc1xuICBmb3IgKHZhciBjb25kaXRpb24gaW4gY29uc3RyYWludHMpIHtcbiAgICBjb21wYXJlVG8gPSBjb25zdHJhaW50c1tjb25kaXRpb25dO1xuICAgIGlmIChjb21wYXJlVG8uX190eXBlKSB7XG4gICAgICBjb21wYXJlVG8gPSBQYXJzZS5fZGVjb2RlKGtleSwgY29tcGFyZVRvKTtcbiAgICB9XG4gICAgc3dpdGNoIChjb25kaXRpb24pIHtcbiAgICAgIGNhc2UgJyRsdCc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA+PSBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbHRlJzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldID4gY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGd0JzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldIDw9IGNvbXBhcmVUbykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRndGUnOlxuICAgICAgICBpZiAob2JqZWN0W2tleV0gPCBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbmUnOlxuICAgICAgICBpZiAoZXF1YWxPYmplY3RzKG9iamVjdFtrZXldLCBjb21wYXJlVG8pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGluJzpcbiAgICAgICAgaWYgKCFjb250YWlucyhjb21wYXJlVG8sIG9iamVjdFtrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRuaW4nOlxuICAgICAgICBpZiAoY29udGFpbnMoY29tcGFyZVRvLCBvYmplY3Rba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckYWxsJzpcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvbXBhcmVUby5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChvYmplY3Rba2V5XS5pbmRleE9mKGNvbXBhcmVUb1tpXSkgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGV4aXN0cyc6IHtcbiAgICAgICAgY29uc3QgcHJvcGVydHlFeGlzdHMgPSB0eXBlb2Ygb2JqZWN0W2tleV0gIT09ICd1bmRlZmluZWQnO1xuICAgICAgICBjb25zdCBleGlzdGVuY2VJc1JlcXVpcmVkID0gY29uc3RyYWludHNbJyRleGlzdHMnXTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zdHJhaW50c1snJGV4aXN0cyddICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAvLyBUaGUgU0RLIHdpbGwgbmV2ZXIgc3VibWl0IGEgbm9uLWJvb2xlYW4gZm9yICRleGlzdHMsIGJ1dCBpZiBzb21lb25lXG4gICAgICAgICAgLy8gdHJpZXMgdG8gc3VibWl0IGEgbm9uLWJvb2xlYW4gZm9yICRleGl0cyBvdXRzaWRlIHRoZSBTREtzLCBqdXN0IGlnbm9yZSBpdC5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoKCFwcm9wZXJ0eUV4aXN0cyAmJiBleGlzdGVuY2VJc1JlcXVpcmVkKSB8fCAocHJvcGVydHlFeGlzdHMgJiYgIWV4aXN0ZW5jZUlzUmVxdWlyZWQpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJHJlZ2V4JzpcbiAgICAgICAgaWYgKHR5cGVvZiBjb21wYXJlVG8gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbXBhcmVUby50ZXN0KG9iamVjdFtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBKUyBkb2Vzbid0IHN1cHBvcnQgcGVybC1zdHlsZSBlc2NhcGluZ1xuICAgICAgICB2YXIgZXhwU3RyaW5nID0gJyc7XG4gICAgICAgIHZhciBlc2NhcGVFbmQgPSAtMjtcbiAgICAgICAgdmFyIGVzY2FwZVN0YXJ0ID0gY29tcGFyZVRvLmluZGV4T2YoJ1xcXFxRJyk7XG4gICAgICAgIHdoaWxlIChlc2NhcGVTdGFydCA+IC0xKSB7XG4gICAgICAgICAgLy8gQWRkIHRoZSB1bmVzY2FwZWQgcG9ydGlvblxuICAgICAgICAgIGV4cFN0cmluZyArPSBjb21wYXJlVG8uc3Vic3RyaW5nKGVzY2FwZUVuZCArIDIsIGVzY2FwZVN0YXJ0KTtcbiAgICAgICAgICBlc2NhcGVFbmQgPSBjb21wYXJlVG8uaW5kZXhPZignXFxcXEUnLCBlc2NhcGVTdGFydCk7XG4gICAgICAgICAgaWYgKGVzY2FwZUVuZCA+IC0xKSB7XG4gICAgICAgICAgICBleHBTdHJpbmcgKz0gY29tcGFyZVRvXG4gICAgICAgICAgICAgIC5zdWJzdHJpbmcoZXNjYXBlU3RhcnQgKyAyLCBlc2NhcGVFbmQpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXFxcXFxcXFxcXFxcRS9nLCAnXFxcXEUnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFxXL2csICdcXFxcJCYnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlc2NhcGVTdGFydCA9IGNvbXBhcmVUby5pbmRleE9mKCdcXFxcUScsIGVzY2FwZUVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwU3RyaW5nICs9IGNvbXBhcmVUby5zdWJzdHJpbmcoTWF0aC5tYXgoZXNjYXBlU3RhcnQsIGVzY2FwZUVuZCArIDIpKTtcbiAgICAgICAgdmFyIGV4cCA9IG5ldyBSZWdFeHAoZXhwU3RyaW5nLCBjb25zdHJhaW50cy4kb3B0aW9ucyB8fCAnJyk7XG4gICAgICAgIGlmICghZXhwLnRlc3Qob2JqZWN0W2tleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG5lYXJTcGhlcmUnOlxuICAgICAgICBpZiAoIWNvbXBhcmVUbyB8fCAhb2JqZWN0W2tleV0pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRpc3RhbmNlID0gY29tcGFyZVRvLnJhZGlhbnNUbyhvYmplY3Rba2V5XSk7XG4gICAgICAgIHZhciBtYXggPSBjb25zdHJhaW50cy4kbWF4RGlzdGFuY2UgfHwgSW5maW5pdHk7XG4gICAgICAgIHJldHVybiBkaXN0YW5jZSA8PSBtYXg7XG4gICAgICBjYXNlICckd2l0aGluJzpcbiAgICAgICAgaWYgKCFjb21wYXJlVG8gfHwgIW9iamVjdFtrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzb3V0aFdlc3QgPSBjb21wYXJlVG8uJGJveFswXTtcbiAgICAgICAgdmFyIG5vcnRoRWFzdCA9IGNvbXBhcmVUby4kYm94WzFdO1xuICAgICAgICBpZiAoc291dGhXZXN0LmxhdGl0dWRlID4gbm9ydGhFYXN0LmxhdGl0dWRlIHx8IHNvdXRoV2VzdC5sb25naXR1ZGUgPiBub3J0aEVhc3QubG9uZ2l0dWRlKSB7XG4gICAgICAgICAgLy8gSW52YWxpZCBib3gsIGNyb3NzZXMgdGhlIGRhdGUgbGluZVxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIG9iamVjdFtrZXldLmxhdGl0dWRlID4gc291dGhXZXN0LmxhdGl0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubGF0aXR1ZGUgPCBub3J0aEVhc3QubGF0aXR1ZGUgJiZcbiAgICAgICAgICBvYmplY3Rba2V5XS5sb25naXR1ZGUgPiBzb3V0aFdlc3QubG9uZ2l0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubG9uZ2l0dWRlIDwgbm9ydGhFYXN0LmxvbmdpdHVkZVxuICAgICAgICApO1xuICAgICAgY2FzZSAnJG9wdGlvbnMnOlxuICAgICAgICAvLyBOb3QgYSBxdWVyeSB0eXBlLCBidXQgYSB3YXkgdG8gYWRkIG9wdGlvbnMgdG8gJHJlZ2V4LiBJZ25vcmUgYW5kXG4gICAgICAgIC8vIGF2b2lkIHRoZSBkZWZhdWx0XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG1heERpc3RhbmNlJzpcbiAgICAgICAgLy8gTm90IGEgcXVlcnkgdHlwZSwgYnV0IGEgd2F5IHRvIGFkZCBhIGNhcCB0byAkbmVhclNwaGVyZS4gSWdub3JlIGFuZFxuICAgICAgICAvLyBhdm9pZCB0aGUgZGVmYXVsdFxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRzZWxlY3QnOlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBjYXNlICckZG9udFNlbGVjdCc6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbnZhciBRdWVyeVRvb2xzID0ge1xuICBxdWVyeUhhc2g6IHF1ZXJ5SGFzaCxcbiAgbWF0Y2hlc1F1ZXJ5OiBtYXRjaGVzUXVlcnksXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFF1ZXJ5VG9vbHM7XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/RequestSchema.js b/lib/LiveQuery/RequestSchema.js deleted file mode 100644 index 08cb08c4c0..0000000000 --- a/lib/LiveQuery/RequestSchema.js +++ /dev/null @@ -1,146 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; -const general = { - title: 'General request schema', - type: 'object', - properties: { - op: { - type: 'string', - enum: ['connect', 'subscribe', 'unsubscribe', 'update'] - } - }, - required: ['op'] -}; -const connect = { - title: 'Connect operation schema', - type: 'object', - properties: { - op: 'connect', - applicationId: { - type: 'string' - }, - javascriptKey: { - type: 'string' - }, - masterKey: { - type: 'string' - }, - clientKey: { - type: 'string' - }, - windowsKey: { - type: 'string' - }, - restAPIKey: { - type: 'string' - }, - sessionToken: { - type: 'string' - }, - installationId: { - type: 'string' - } - }, - required: ['op', 'applicationId'], - additionalProperties: false -}; -const subscribe = { - title: 'Subscribe operation schema', - type: 'object', - properties: { - op: 'subscribe', - requestId: { - type: 'number' - }, - query: { - title: 'Query field schema', - type: 'object', - properties: { - className: { - type: 'string' - }, - where: { - type: 'object' - }, - fields: { - type: 'array', - items: { - type: 'string' - }, - minItems: 1, - uniqueItems: true - } - }, - required: ['where', 'className'], - additionalProperties: false - }, - sessionToken: { - type: 'string' - } - }, - required: ['op', 'requestId', 'query'], - additionalProperties: false -}; -const update = { - title: 'Update operation schema', - type: 'object', - properties: { - op: 'update', - requestId: { - type: 'number' - }, - query: { - title: 'Query field schema', - type: 'object', - properties: { - className: { - type: 'string' - }, - where: { - type: 'object' - }, - fields: { - type: 'array', - items: { - type: 'string' - }, - minItems: 1, - uniqueItems: true - } - }, - required: ['where', 'className'], - additionalProperties: false - }, - sessionToken: { - type: 'string' - } - }, - required: ['op', 'requestId', 'query'], - additionalProperties: false -}; -const unsubscribe = { - title: 'Unsubscribe operation schema', - type: 'object', - properties: { - op: 'unsubscribe', - requestId: { - type: 'number' - } - }, - required: ['op', 'requestId'], - additionalProperties: false -}; -const RequestSchema = { - general: general, - connect: connect, - subscribe: subscribe, - update: update, - unsubscribe: unsubscribe -}; -var _default = RequestSchema; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUmVxdWVzdFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJnZW5lcmFsIiwidGl0bGUiLCJ0eXBlIiwicHJvcGVydGllcyIsIm9wIiwiZW51bSIsInJlcXVpcmVkIiwiY29ubmVjdCIsImFwcGxpY2F0aW9uSWQiLCJqYXZhc2NyaXB0S2V5IiwibWFzdGVyS2V5IiwiY2xpZW50S2V5Iiwid2luZG93c0tleSIsInJlc3RBUElLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwic3Vic2NyaWJlIiwicmVxdWVzdElkIiwicXVlcnkiLCJjbGFzc05hbWUiLCJ3aGVyZSIsImZpZWxkcyIsIml0ZW1zIiwibWluSXRlbXMiLCJ1bmlxdWVJdGVtcyIsInVwZGF0ZSIsInVuc3Vic2NyaWJlIiwiUmVxdWVzdFNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2RDLEVBQUFBLEtBQUssRUFBRSx3QkFETztBQUVkQyxFQUFBQSxJQUFJLEVBQUUsUUFGUTtBQUdkQyxFQUFBQSxVQUFVLEVBQUU7QUFDVkMsSUFBQUEsRUFBRSxFQUFFO0FBQ0ZGLE1BQUFBLElBQUksRUFBRSxRQURKO0FBRUZHLE1BQUFBLElBQUksRUFBRSxDQUFDLFNBQUQsRUFBWSxXQUFaLEVBQXlCLGFBQXpCLEVBQXdDLFFBQXhDO0FBRko7QUFETSxHQUhFO0FBU2RDLEVBQUFBLFFBQVEsRUFBRSxDQUFDLElBQUQ7QUFUSSxDQUFoQjtBQVlBLE1BQU1DLE9BQU8sR0FBRztBQUNkTixFQUFBQSxLQUFLLEVBQUUsMEJBRE87QUFFZEMsRUFBQUEsSUFBSSxFQUFFLFFBRlE7QUFHZEMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxTQURNO0FBRVZJLElBQUFBLGFBQWEsRUFBRTtBQUNiTixNQUFBQSxJQUFJLEVBQUU7QUFETyxLQUZMO0FBS1ZPLElBQUFBLGFBQWEs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LENBTEo7QUFNTkMsVUFBQUEsV0FBVyxFQUFFO0FBTlA7QUFQRSxPQUhQO0FBbUJMbkIsTUFBQUEsUUFBUSxFQUFFLENBQUMsT0FBRCxFQUFVLFdBQVYsQ0FuQkw7QUFvQkxVLE1BQUFBLG9CQUFvQixFQUFFO0FBcEJqQixLQUxHO0FBMkJWRixJQUFBQSxZQUFZLEVBQUU7QUFDWlosTUFBQUEsSUFBSSxFQUFFO0FBRE07QUEzQkosR0FIQztBQWtDYkksRUFBQUEsUUFBUSxFQUFFLENBQUMsSUFBRCxFQUFPLFdBQVAsRUFBb0IsT0FBcEIsQ0FsQ0c7QUFtQ2JVLEVBQUFBLG9CQUFvQixFQUFFO0FBbkNULENBQWY7QUFzQ0EsTUFBTVcsV0FBVyxHQUFHO0FBQ2xCMUIsRUFBQUEsS0FBSyxFQUFFLDhCQURXO0FBRWxCQyxFQUFBQSxJQUFJLEVBQUUsUUFGWTtBQUdsQkMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxhQURNO0FBRVZjLElBQUFBLFNBQVMsRUFBRTtBQUNUaEIsTUFBQUEsSUFBSSxFQUFFO0FBREc7QUFGRCxHQUhNO0FBU2xCSSxFQUFBQSxRQUFRLEVBQUUsQ0FBQyxJQUFELEVBQU8sV0FBUCxDQVRRO0FBVWxCVSxFQUFBQSxvQkFBb0IsRUFBRTtBQVZKLENBQXBCO0FBYUEsTUFBTVksYUFBYSxHQUFHO0FBQ3BCNUIsRUFBQUEsT0FBTyxFQUFFQSxPQURXO0FBRXBCTyxFQUFBQSxPQUFPLEVBQUVBLE9BRlc7QUFHcEJVLEVBQUFBLFNBQVMsRUFBRUEsU0FIUztBQUlwQlMsRUFBQUEsTUFBTSxFQUFFQSxNQUpZO0FBS3BCQyxFQUFBQSxXQUFXLEVBQUVBO0FBTE8sQ0FBdEI7ZUFRZUMsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGdlbmVyYWwgPSB7XG4gIHRpdGxlOiAnR2VuZXJhbCByZXF1ZXN0IHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW51bTogWydjb25uZWN0JywgJ3N1YnNjcmliZScsICd1bnN1YnNjcmliZScsICd1cGRhdGUnXSxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCddLFxufTtcblxuY29uc3QgY29ubmVjdCA9IHtcbiAgdGl0bGU6ICdDb25uZWN0IG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnY29ubmVjdCcsXG4gICAgYXBwbGljYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBqYXZhc2NyaXB0S2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIG1hc3RlcktleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBjbGllbnRLZXk6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIH0sXG4gICAgd2luZG93c0tleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICByZXN0QVBJS2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBpbnN0YWxsYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAnYXBwbGljYXRpb25JZCddLFxuICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG59O1xuXG5jb25zdCBzdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnU3Vic2NyaWJlIG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnc3Vic2NyaWJlJyxcbiAgICByZXF1ZXN0SWQ6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgIH0sXG4gICAgcXVlcnk6IHtcbiAgICAgIHRpdGxlOiAnUXVlcnkgZmllbGQgc2NoZW1hJyxcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBjbGFzc05hbWU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgfSxcbiAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgfSxcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczoge1xuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtaW5JdGVtczogMSxcbiAgICAgICAgICB1bmlxdWVJdGVtczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWyd3aGVyZScsICdjbGFzc05hbWUnXSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAncmVxdWVzdElkJywgJ3F1ZXJ5J10sXG4gIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbn07XG5cbmNvbnN0IHVwZGF0ZSA9IHtcbiAgdGl0bGU6ICdVcGRhdGUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1cGRhdGUnLFxuICAgIHJlcXVlc3RJZDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgfSxcbiAgICBxdWVyeToge1xuICAgICAgdGl0bGU6ICdRdWVyeSBmaWVsZCBzY2hlbWEnLFxuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGNsYXNzTmFtZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICB9LFxuICAgICAgICB3aGVyZToge1xuICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICB9LFxuICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1pbkl0ZW1zOiAxLFxuICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3doZXJlJywgJ2NsYXNzTmFtZSddLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIH0sXG4gICAgc2Vzc2lvblRva2VuOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnLCAncXVlcnknXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgdW5zdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnVW5zdWJzY3JpYmUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1bnN1YnNjcmliZScsXG4gICAgcmVxdWVzdElkOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgUmVxdWVzdFNjaGVtYSA9IHtcbiAgZ2VuZXJhbDogZ2VuZXJhbCxcbiAgY29ubmVjdDogY29ubmVjdCxcbiAgc3Vic2NyaWJlOiBzdWJzY3JpYmUsXG4gIHVwZGF0ZTogdXBkYXRlLFxuICB1bnN1YnNjcmliZTogdW5zdWJzY3JpYmUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0U2NoZW1hO1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/SessionTokenCache.js b/lib/LiveQuery/SessionTokenCache.js deleted file mode 100644 index 07a9a06965..0000000000 --- a/lib/LiveQuery/SessionTokenCache.js +++ /dev/null @@ -1,67 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SessionTokenCache = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _lruCache = _interopRequireDefault(require("lru-cache")); - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function userForSessionToken(sessionToken) { - var q = new _node.default.Query('_Session'); - q.equalTo('sessionToken', sessionToken); - return q.first({ - useMasterKey: true - }).then(function (session) { - if (!session) { - return Promise.reject('No session found for session token'); - } - - return session.get('user'); - }); -} - -class SessionTokenCache { - constructor(timeout = 30 * 24 * 60 * 60 * 1000, maxSize = 10000) { - this.cache = new _lruCache.default({ - max: maxSize, - maxAge: timeout - }); - } - - getUserId(sessionToken) { - if (!sessionToken) { - return Promise.reject('Empty sessionToken'); - } - - const userId = this.cache.get(sessionToken); - - if (userId) { - _logger.default.verbose('Fetch userId %s of sessionToken %s from Cache', userId, sessionToken); - - return Promise.resolve(userId); - } - - return userForSessionToken(sessionToken).then(user => { - _logger.default.verbose('Fetch userId %s of sessionToken %s from Parse', user.id, sessionToken); - - const userId = user.id; - this.cache.set(sessionToken, userId); - return Promise.resolve(userId); - }, error => { - _logger.default.error('Can not fetch userId for sessionToken %j, error %j', sessionToken, error); - - return Promise.reject(error); - }); - } - -} - -exports.SessionTokenCache = SessionTokenCache; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU2Vzc2lvblRva2VuQ2FjaGUuanMiXSwibmFtZXMiOlsidXNlckZvclNlc3Npb25Ub2tlbiIsInNlc3Npb25Ub2tlbiIsInEiLCJQYXJzZSIsIlF1ZXJ5IiwiZXF1YWxUbyIsImZpcnN0IiwidXNlTWFzdGVyS2V5IiwidGhlbiIsInNlc3Npb24iLCJQcm9taXNlIiwicmVqZWN0IiwiZ2V0IiwiU2Vzc2lvblRva2VuQ2FjaGUiLCJjb25zdHJ1Y3RvciIsInRpbWVvdXQiLCJtYXhTaXplIiwiY2FjaGUiLCJMUlUiLCJtYXgiLCJtYXhBZ2UiLCJnZXRVc2VySWQiLCJ1c2VySWQiLCJsb2dnZXIiLCJ2ZXJib3NlIiwicmVzb2x2ZSIsInVzZXIiLCJpZCIsInNldCIsImVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxTQUFTQSxtQkFBVCxDQUE2QkMsWUFBN0IsRUFBMkM7QUFDekMsTUFBSUMsQ0FBQyxHQUFHLElBQUlDLGNBQU1DLEtBQVYsQ0FBZ0IsVUFBaEIsQ0FBUjtBQUNBRixFQUFBQSxDQUFDLENBQUNHLE9BQUYsQ0FBVSxjQUFWLEVBQTBCSixZQUExQjtBQUNBLFNBQU9DLENBQUMsQ0FBQ0ksS0FBRixDQUFRO0FBQUVDLElBQUFBLFlBQVksRUFBRTtBQUFoQixHQUFSLEVBQWdDQyxJQUFoQyxDQUFxQyxVQUFVQyxPQUFWLEVBQW1CO0FBQzdELFFBQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osYUFBT0MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0NBQWYsQ0FBUDtBQUNEOztBQUNELFdBQU9GLE9BQU8sQ0FBQ0csR0FBUixDQUFZLE1BQVosQ0FBUDtBQUNELEdBTE0sQ0FBUDtBQU1EOztBQUVELE1BQU1DLGlCQUFOLENBQXdCO0FBR3RCQyxFQUFBQSxXQUFXLENBQUNDLE9BQWUsR0FBRyxLQUFLLEVBQUwsR0FBVSxFQUFWLEdBQWUsRUFBZixHQUFvQixJQUF2QyxFQUE2Q0MsT0FBZSxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxpQkFBSixDQUFRO0FBQ25CQyxNQUFBQSxHQUFHLEVBQUVILE9BRGM7QUFFbkJJLE1BQUFBLE1BQU0sRUFBRUw7QUFGVyxLQUFSLENBQWI7QUFJRDs7QUFFRE0sRUFBQUEsU0FBUyxDQUFDcEIsWUFBRCxFQUE0QjtBQUNuQyxRQUFJLENBQUNBLFlBQUwsRUFBbUI7QUFDakIsYUFBT1MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0JBQWYsQ0FBUDtBQUNEOztBQUNELFVBQU1XLE1BQU0sR0FBRyxLQUFLTCxLQUFMLENBQVdMLEdBQVgsQ0FBZVgsWUFBZixDQUFmOztBQUNBLFFBQUlxQixNQUFKLEVBQVk7QUFDVkMsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUYsTUFBaEUsRUFBd0VyQixZQUF4RTs7QUFDQSxhQUFPUyxPQUFPLENBQUNlLE9BQVIsQ0FBZ0JILE1BQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPdEIsbUJBQW1CLENBQUNDLFlBQUQsQ0FBbkIsQ0FBa0NPLElBQWxDLENBQ0xrQixJQUFJLElBQUk7QUFDTkgsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUUsSUFBSSxDQUFDQyxFQUFyRSxFQUF5RTFCLFlBQXpFOztBQUNBLFlBQU1xQixNQUFNLEdBQUdJLElBQUksQ0FBQ0MsRUFBcEI7QUFDQSxXQUFLVixLQUFMLENBQVdXLEdBQVgsQ0FBZTNCLFlBQWYsRUFBNkJxQixNQUE3QjtBQUNBLGFBQU9aLE9BQU8sQ0FBQ2UsT0FBUixDQUFnQkgsTUFBaEIsQ0FBUDtBQUNELEtBTkksRUFPTE8sS0FBSyxJQUFJO0FBQ1BOLHNCQUFPTSxLQUFQLENBQWEsb0RBQWIsRUFBbUU1QixZQUFuRSxFQUFpRjRCLEtBQWpGOztBQUNBLGFBQU9uQixPQUFPLENBQUNDLE1BQVIsQ0FBZWtCLEtBQWYsQ0FBUDtBQUNELEtBVkksQ0FBUDtBQVlEOztBQS9CcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgTFJVIGZyb20gJ2xydS1jYWNoZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIHVzZXJGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuKSB7XG4gIHZhciBxID0gbmV3IFBhcnNlLlF1ZXJ5KCdfU2Vzc2lvbicpO1xuICBxLmVxdWFsVG8oJ3Nlc3Npb25Ub2tlbicsIHNlc3Npb25Ub2tlbik7XG4gIHJldHVybiBxLmZpcnN0KHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pLnRoZW4oZnVuY3Rpb24gKHNlc3Npb24pIHtcbiAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnTm8gc2Vzc2lvbiBmb3VuZCBmb3Igc2Vzc2lvbiB0b2tlbicpO1xuICAgIH1cbiAgICByZXR1cm4gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbiAgfSk7XG59XG5cbmNsYXNzIFNlc3Npb25Ub2tlbkNhY2hlIHtcbiAgY2FjaGU6IE9iamVjdDtcblxuICBjb25zdHJ1Y3Rvcih0aW1lb3V0OiBudW1iZXIgPSAzMCAqIDI0ICogNjAgKiA2MCAqIDEwMDAsIG1heFNpemU6IG51bWJlciA9IDEwMDAwKSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0aW1lb3V0LFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklkKHNlc3Npb25Ub2tlbjogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoIXNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdFbXB0eSBzZXNzaW9uVG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy5jYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlcklkKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnRmV0Y2ggdXNlcklkICVzIG9mIHNlc3Npb25Ub2tlbiAlcyBmcm9tIENhY2hlJywgdXNlcklkLCBzZXNzaW9uVG9rZW4pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgIH1cbiAgICByZXR1cm4gdXNlckZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pLnRoZW4oXG4gICAgICB1c2VyID0+IHtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0ZldGNoIHVzZXJJZCAlcyBvZiBzZXNzaW9uVG9rZW4gJXMgZnJvbSBQYXJzZScsIHVzZXIuaWQsIHNlc3Npb25Ub2tlbik7XG4gICAgICAgIGNvbnN0IHVzZXJJZCA9IHVzZXIuaWQ7XG4gICAgICAgIHRoaXMuY2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgdXNlcklkKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZldGNoIHVzZXJJZCBmb3Igc2Vzc2lvblRva2VuICVqLCBlcnJvciAlaicsIHNlc3Npb25Ub2tlbiwgZXJyb3IpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IHsgU2Vzc2lvblRva2VuQ2FjaGUgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Subscription.js b/lib/LiveQuery/Subscription.js deleted file mode 100644 index a424955752..0000000000 --- a/lib/LiveQuery/Subscription.js +++ /dev/null @@ -1,61 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Subscription = void 0; - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class Subscription { - // It is query condition eg query.where - constructor(className, query, queryHash) { - this.className = className; - this.query = query; - this.hash = queryHash; - this.clientRequestIds = new Map(); - } - - addClientSubscription(clientId, requestId) { - if (!this.clientRequestIds.has(clientId)) { - this.clientRequestIds.set(clientId, []); - } - - const requestIds = this.clientRequestIds.get(clientId); - requestIds.push(requestId); - } - - deleteClientSubscription(clientId, requestId) { - const requestIds = this.clientRequestIds.get(clientId); - - if (typeof requestIds === 'undefined') { - _logger.default.error('Can not find client %d to delete', clientId); - - return; - } - - const index = requestIds.indexOf(requestId); - - if (index < 0) { - _logger.default.error('Can not find client %d subscription %d to delete', clientId, requestId); - - return; - } - - requestIds.splice(index, 1); // Delete client reference if it has no subscription - - if (requestIds.length == 0) { - this.clientRequestIds.delete(clientId); - } - } - - hasSubscribingClient() { - return this.clientRequestIds.size > 0; - } - -} - -exports.Subscription = Subscription; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU3Vic2NyaXB0aW9uLmpzIl0sIm5hbWVzIjpbIlN1YnNjcmlwdGlvbiIsImNvbnN0cnVjdG9yIiwiY2xhc3NOYW1lIiwicXVlcnkiLCJxdWVyeUhhc2giLCJoYXNoIiwiY2xpZW50UmVxdWVzdElkcyIsIk1hcCIsImFkZENsaWVudFN1YnNjcmlwdGlvbiIsImNsaWVudElkIiwicmVxdWVzdElkIiwiaGFzIiwic2V0IiwicmVxdWVzdElkcyIsImdldCIsInB1c2giLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJsb2dnZXIiLCJlcnJvciIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsImxlbmd0aCIsImRlbGV0ZSIsImhhc1N1YnNjcmliaW5nQ2xpZW50Iiwic2l6ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBS0EsTUFBTUEsWUFBTixDQUFtQjtBQUNqQjtBQU1BQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLEtBQXBCLEVBQXNDQyxTQUF0QyxFQUF5RDtBQUNsRSxTQUFLRixTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLFNBQUtDLEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtFLElBQUwsR0FBWUQsU0FBWjtBQUNBLFNBQUtFLGdCQUFMLEdBQXdCLElBQUlDLEdBQUosRUFBeEI7QUFDRDs7QUFFREMsRUFBQUEscUJBQXFCLENBQUNDLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQy9ELFFBQUksQ0FBQyxLQUFLSixnQkFBTCxDQUFzQkssR0FBdEIsQ0FBMEJGLFFBQTFCLENBQUwsRUFBMEM7QUFDeEMsV0FBS0gsZ0JBQUwsQ0FBc0JNLEdBQXRCLENBQTBCSCxRQUExQixFQUFvQyxFQUFwQztBQUNEOztBQUNELFVBQU1JLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5CO0FBQ0FJLElBQUFBLFVBQVUsQ0FBQ0UsSUFBWCxDQUFnQkwsU0FBaEI7QUFDRDs7QUFFRE0sRUFBQUEsd0JBQXdCLENBQUNQLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQ2xFLFVBQU1HLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5COztBQUNBLFFBQUksT0FBT0ksVUFBUCxLQUFzQixXQUExQixFQUF1QztBQUNyQ0ksc0JBQU9DLEtBQVAsQ0FBYSxrQ0FBYixFQUFpRFQsUUFBakQ7O0FBQ0E7QUFDRDs7QUFFRCxVQUFNVSxLQUFLLEdBQUdOLFVBQVUsQ0FBQ08sT0FBWCxDQUFtQlYsU0FBbkIsQ0FBZDs7QUFDQSxRQUFJUyxLQUFLLEdBQUcsQ0FBWixFQUFlO0FBQ2JGLHNCQUFPQyxLQUFQLENBQWEsa0RBQWIsRUFBaUVULFFBQWpFLEVBQTJFQyxTQUEzRTs7QUFDQTtBQUNEOztBQUNERyxJQUFBQSxVQUFVLENBQUNRLE1BQVgsQ0FBa0JGLEtBQWxCLEVBQXlCLENBQXpCLEVBWmtFLENBYWxFOztBQUNBLFFBQUlOLFVBQVUsQ0FBQ1MsTUFBWCxJQUFxQixDQUF6QixFQUE0QjtBQUMxQixXQUFLaEIsZ0JBQUwsQ0FBc0JpQixNQUF0QixDQUE2QmQsUUFBN0I7QUFDRDtBQUNGOztBQUVEZSxFQUFBQSxvQkFBb0IsR0FBWTtBQUM5QixXQUFPLEtBQUtsQixnQkFBTCxDQUFzQm1CLElBQXRCLEdBQTZCLENBQXBDO0FBQ0Q7O0FBM0NnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcblxuZXhwb3J0IHR5cGUgRmxhdHRlbmVkT2JqZWN0RGF0YSA9IHsgW2F0dHI6IHN0cmluZ106IGFueSB9O1xuZXhwb3J0IHR5cGUgUXVlcnlEYXRhID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNsYXNzIFN1YnNjcmlwdGlvbiB7XG4gIC8vIEl0IGlzIHF1ZXJ5IGNvbmRpdGlvbiBlZyBxdWVyeS53aGVyZVxuICBxdWVyeTogUXVlcnlEYXRhO1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgaGFzaDogc3RyaW5nO1xuICBjbGllbnRSZXF1ZXN0SWRzOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBRdWVyeURhdGEsIHF1ZXJ5SGFzaDogc3RyaW5nKSB7XG4gICAgdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgdGhpcy5xdWVyeSA9IHF1ZXJ5O1xuICAgIHRoaXMuaGFzaCA9IHF1ZXJ5SGFzaDtcbiAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBhZGRDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQ6IG51bWJlciwgcmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50UmVxdWVzdElkcy5oYXMoY2xpZW50SWQpKSB7XG4gICAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMuc2V0KGNsaWVudElkLCBbXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICByZXF1ZXN0SWRzLnB1c2gocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihjbGllbnRJZDogbnVtYmVyLCByZXF1ZXN0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RJZHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCBjbGllbnQgJWQgdG8gZGVsZXRlJywgY2xpZW50SWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gcmVxdWVzdElkcy5pbmRleE9mKHJlcXVlc3RJZCk7XG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgY2xpZW50ICVkIHN1YnNjcmlwdGlvbiAlZCB0byBkZWxldGUnLCBjbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmVxdWVzdElkcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIC8vIERlbGV0ZSBjbGllbnQgcmVmZXJlbmNlIGlmIGl0IGhhcyBubyBzdWJzY3JpcHRpb25cbiAgICBpZiAocmVxdWVzdElkcy5sZW5ndGggPT0gMCkge1xuICAgICAgdGhpcy5jbGllbnRSZXF1ZXN0SWRzLmRlbGV0ZShjbGllbnRJZCk7XG4gICAgfVxuICB9XG5cbiAgaGFzU3Vic2NyaWJpbmdDbGllbnQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50UmVxdWVzdElkcy5zaXplID4gMDtcbiAgfVxufVxuXG5leHBvcnQgeyBTdWJzY3JpcHRpb24gfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/equalObjects.js b/lib/LiveQuery/equalObjects.js deleted file mode 100644 index 028cc134ac..0000000000 --- a/lib/LiveQuery/equalObjects.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -var toString = Object.prototype.toString; -/** - * Determines whether two objects represent the same primitive, special Parse - * type, or full Parse Object. - */ - -function equalObjects(a, b) { - if (typeof a !== typeof b) { - return false; - } - - if (typeof a !== 'object') { - return a === b; - } - - if (a === b) { - return true; - } - - if (toString.call(a) === '[object Date]') { - if (toString.call(b) === '[object Date]') { - return +a === +b; - } - - return false; - } - - if (Array.isArray(a)) { - if (Array.isArray(b)) { - if (a.length !== b.length) { - return false; - } - - for (var i = 0; i < a.length; i++) { - if (!equalObjects(a[i], b[i])) { - return false; - } - } - - return true; - } - - return false; - } - - if (Object.keys(a).length !== Object.keys(b).length) { - return false; - } - - for (var key in a) { - if (!equalObjects(a[key], b[key])) { - return false; - } - } - - return true; -} - -module.exports = equalObjects; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvZXF1YWxPYmplY3RzLmpzIl0sIm5hbWVzIjpbInRvU3RyaW5nIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiZXF1YWxPYmplY3RzIiwiYSIsImIiLCJjYWxsIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiaSIsImtleXMiLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxTQUFQLENBQWlCRixRQUFoQztBQUVBOzs7OztBQUlBLFNBQVNHLFlBQVQsQ0FBc0JDLENBQXRCLEVBQXlCQyxDQUF6QixFQUE0QjtBQUMxQixNQUFJLE9BQU9ELENBQVAsS0FBYSxPQUFPQyxDQUF4QixFQUEyQjtBQUN6QixXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJLE9BQU9ELENBQVAsS0FBYSxRQUFqQixFQUEyQjtBQUN6QixXQUFPQSxDQUFDLEtBQUtDLENBQWI7QUFDRDs7QUFDRCxNQUFJRCxDQUFDLEtBQUtDLENBQVYsRUFBYTtBQUNYLFdBQU8sSUFBUDtBQUNEOztBQUNELE1BQUlMLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRixDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLFFBQUlKLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRCxDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLGFBQU8sQ0FBQ0QsQ0FBRCxLQUFPLENBQUNDLENBQWY7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJRSxLQUFLLENBQUNDLE9BQU4sQ0FBY0osQ0FBZCxDQUFKLEVBQXNCO0FBQ3BCLFFBQUlHLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxDQUFkLENBQUosRUFBc0I7QUFDcEIsVUFBSUQsQ0FBQyxDQUFDSyxNQUFGLEtBQWFKLENBQUMsQ0FBQ0ksTUFBbkIsRUFBMkI7QUFDekIsZUFBTyxLQUFQO0FBQ0Q7O0FBQ0QsV0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHTixDQUFDLENBQUNLLE1BQXRCLEVBQThCQyxDQUFDLEVBQS9CLEVBQW1DO0FBQ2pDLFlBQUksQ0FBQ1AsWUFBWSxDQUFDQyxDQUFDLENBQUNNLENBQUQsQ0FBRixFQUFPTCxDQUFDLENBQUNLLENBQUQsQ0FBUixDQUFqQixFQUErQjtBQUM3QixpQkFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPLElBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJVCxNQUFNLENBQUNVLElBQVAsQ0FBWVAsQ0FBWixFQUFlSyxNQUFmLEtBQTBCUixNQUFNLENBQUNVLElBQVAsQ0FBWU4sQ0FBWixFQUFlSSxNQUE3QyxFQUFxRDtBQUNuRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxPQUFLLElBQUlHLEdBQVQsSUFBZ0JSLENBQWhCLEVBQW1CO0FBQ2pCLFFBQUksQ0FBQ0QsWUFBWSxDQUFDQyxDQUFDLENBQUNRLEdBQUQsQ0FBRixFQUFTUCxDQUFDLENBQUNPLEdBQUQsQ0FBVixDQUFqQixFQUFtQztBQUNqQyxhQUFPLEtBQVA7QUFDRDtBQUNGOztBQUNELFNBQU8sSUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLFlBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdHdvIG9iamVjdHMgcmVwcmVzZW50IHRoZSBzYW1lIHByaW1pdGl2ZSwgc3BlY2lhbCBQYXJzZVxuICogdHlwZSwgb3IgZnVsbCBQYXJzZSBPYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhhLCBiKSB7XG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBhICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBhID09PSBiO1xuICB9XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHRvU3RyaW5nLmNhbGwoYSkgPT09ICdbb2JqZWN0IERhdGVdJykge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKGIpID09PSAnW29iamVjdCBEYXRlXScpIHtcbiAgICAgIHJldHVybiArYSA9PT0gK2I7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGIpKSB7XG4gICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2ldLCBiW2ldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yICh2YXIga2V5IGluIGEpIHtcbiAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2tleV0sIGJba2V5XSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxPYmplY3RzO1xuIl19 \ No newline at end of file diff --git a/lib/Options/Definitions.js b/lib/Options/Definitions.js deleted file mode 100644 index 37d5b1bcd7..0000000000 --- a/lib/Options/Definitions.js +++ /dev/null @@ -1,531 +0,0 @@ -"use strict"; - -/* -**** GENERATED CODE **** -This code has been generated by resources/buildConfigDefinitions.js -Do not edit manually, but update Options/index.js -*/ -var parsers = require('./parsers'); - -module.exports.ParseServerOptions = { - accountLockout: { - env: 'PARSE_SERVER_ACCOUNT_LOCKOUT', - help: 'account lockout policy for failed login attempts', - action: parsers.objectParser - }, - allowClientClassCreation: { - env: 'PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION', - help: 'Enable (or disable) client class creation, defaults to true', - action: parsers.booleanParser, - default: true - }, - allowCustomObjectId: { - env: 'PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID', - help: 'Enable (or disable) custom objectId', - action: parsers.booleanParser, - default: false - }, - allowHeaders: { - env: 'PARSE_SERVER_ALLOW_HEADERS', - help: 'Add headers to Access-Control-Allow-Headers', - action: parsers.arrayParser - }, - allowOrigin: { - env: 'PARSE_SERVER_ALLOW_ORIGIN', - help: 'Sets the origin to Access-Control-Allow-Origin' - }, - analyticsAdapter: { - env: 'PARSE_SERVER_ANALYTICS_ADAPTER', - help: 'Adapter module for the analytics', - action: parsers.moduleOrObjectParser - }, - appId: { - env: 'PARSE_SERVER_APPLICATION_ID', - help: 'Your Parse Application ID', - required: true - }, - appName: { - env: 'PARSE_SERVER_APP_NAME', - help: 'Sets the app name' - }, - auth: { - env: 'PARSE_SERVER_AUTH_PROVIDERS', - help: 'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication', - action: parsers.objectParser - }, - cacheAdapter: { - env: 'PARSE_SERVER_CACHE_ADAPTER', - help: 'Adapter module for the cache', - action: parsers.moduleOrObjectParser - }, - cacheMaxSize: { - env: 'PARSE_SERVER_CACHE_MAX_SIZE', - help: 'Sets the maximum size for the in memory cache, defaults to 10000', - action: parsers.numberParser('cacheMaxSize'), - default: 10000 - }, - cacheTTL: { - env: 'PARSE_SERVER_CACHE_TTL', - help: 'Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds)', - action: parsers.numberParser('cacheTTL'), - default: 5000 - }, - clientKey: { - env: 'PARSE_SERVER_CLIENT_KEY', - help: 'Key for iOS, MacOS, tvOS clients' - }, - cloud: { - env: 'PARSE_SERVER_CLOUD', - help: 'Full path to your cloud code main.js' - }, - cluster: { - env: 'PARSE_SERVER_CLUSTER', - help: 'Run with cluster, optionally set the number of processes default to os.cpus().length', - action: parsers.numberOrBooleanParser - }, - collectionPrefix: { - env: 'PARSE_SERVER_COLLECTION_PREFIX', - help: 'A collection prefix for the classes', - default: '' - }, - customPages: { - env: 'PARSE_SERVER_CUSTOM_PAGES', - help: 'custom pages for password validation and reset', - action: parsers.objectParser, - default: {} - }, - databaseAdapter: { - env: 'PARSE_SERVER_DATABASE_ADAPTER', - help: 'Adapter module for the database', - action: parsers.moduleOrObjectParser - }, - databaseOptions: { - env: 'PARSE_SERVER_DATABASE_OPTIONS', - help: 'Options to pass to the mongodb client', - action: parsers.objectParser - }, - databaseURI: { - env: 'PARSE_SERVER_DATABASE_URI', - help: 'The full URI to your database. Supported databases are mongodb or postgres.', - required: true, - default: 'mongodb://localhost:27017/parse' - }, - directAccess: { - env: 'PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS', - help: 'Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production.', - action: parsers.booleanParser, - default: false - }, - dotNetKey: { - env: 'PARSE_SERVER_DOT_NET_KEY', - help: 'Key for Unity and .Net SDK' - }, - emailAdapter: { - env: 'PARSE_SERVER_EMAIL_ADAPTER', - help: 'Adapter module for email sending', - action: parsers.moduleOrObjectParser - }, - emailVerifyTokenValidityDuration: { - env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_VALIDITY_DURATION', - help: 'Email verification token validity duration, in seconds', - action: parsers.numberParser('emailVerifyTokenValidityDuration') - }, - enableAnonymousUsers: { - env: 'PARSE_SERVER_ENABLE_ANON_USERS', - help: 'Enable (or disable) anonymous users, defaults to true', - action: parsers.booleanParser, - default: true - }, - enableExpressErrorHandler: { - env: 'PARSE_SERVER_ENABLE_EXPRESS_ERROR_HANDLER', - help: 'Enables the default express error handler for all errors', - action: parsers.booleanParser, - default: false - }, - enableSingleSchemaCache: { - env: 'PARSE_SERVER_ENABLE_SINGLE_SCHEMA_CACHE', - help: 'Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request.', - action: parsers.booleanParser, - default: false - }, - encryptionKey: { - env: 'PARSE_SERVER_ENCRYPTION_KEY', - help: 'Key for encrypting your files' - }, - expireInactiveSessions: { - env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', - help: 'Sets wether we should expire the inactive sessions, defaults to true', - action: parsers.booleanParser, - default: true - }, - fileKey: { - env: 'PARSE_SERVER_FILE_KEY', - help: 'Key for your files' - }, - filesAdapter: { - env: 'PARSE_SERVER_FILES_ADAPTER', - help: 'Adapter module for the files sub-system', - action: parsers.moduleOrObjectParser - }, - graphQLPath: { - env: 'PARSE_SERVER_GRAPHQL_PATH', - help: 'Mount path for the GraphQL endpoint, defaults to /graphql', - default: '/graphql' - }, - graphQLSchema: { - env: 'PARSE_SERVER_GRAPH_QLSCHEMA', - help: 'Full path to your GraphQL custom schema.graphql file' - }, - host: { - env: 'PARSE_SERVER_HOST', - help: 'The host to serve ParseServer on, defaults to 0.0.0.0', - default: '0.0.0.0' - }, - idempotencyOptions: { - env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_OPTIONS', - help: 'Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production.', - action: parsers.objectParser, - default: {} - }, - javascriptKey: { - env: 'PARSE_SERVER_JAVASCRIPT_KEY', - help: 'Key for the Javascript SDK' - }, - jsonLogs: { - env: 'JSON_LOGS', - help: 'Log as structured JSON objects', - action: parsers.booleanParser - }, - liveQuery: { - env: 'PARSE_SERVER_LIVE_QUERY', - help: "parse-server's LiveQuery configuration object", - action: parsers.objectParser - }, - liveQueryServerOptions: { - env: 'PARSE_SERVER_LIVE_QUERY_SERVER_OPTIONS', - help: 'Live query server configuration options (will start the liveQuery server)', - action: parsers.objectParser - }, - loggerAdapter: { - env: 'PARSE_SERVER_LOGGER_ADAPTER', - help: 'Adapter module for the logging sub-system', - action: parsers.moduleOrObjectParser - }, - logLevel: { - env: 'PARSE_SERVER_LOG_LEVEL', - help: 'Sets the level for logs' - }, - logsFolder: { - env: 'PARSE_SERVER_LOGS_FOLDER', - help: "Folder for the logs (defaults to './logs'); set to null to disable file based logging", - default: './logs' - }, - masterKey: { - env: 'PARSE_SERVER_MASTER_KEY', - help: 'Your Parse Master Key', - required: true - }, - masterKeyIps: { - env: 'PARSE_SERVER_MASTER_KEY_IPS', - help: 'Restrict masterKey to be used by only these ips, defaults to [] (allow all ips)', - action: parsers.arrayParser, - default: [] - }, - maxLimit: { - env: 'PARSE_SERVER_MAX_LIMIT', - help: 'Max value for limit option on queries, defaults to unlimited', - action: parsers.numberParser('maxLimit') - }, - maxLogFiles: { - env: 'PARSE_SERVER_MAX_LOG_FILES', - help: "Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null)", - action: parsers.objectParser - }, - maxUploadSize: { - env: 'PARSE_SERVER_MAX_UPLOAD_SIZE', - help: 'Max file size for uploads, defaults to 20mb', - default: '20mb' - }, - middleware: { - env: 'PARSE_SERVER_MIDDLEWARE', - help: 'middleware for express server, can be string or function' - }, - mountGraphQL: { - env: 'PARSE_SERVER_MOUNT_GRAPHQL', - help: 'Mounts the GraphQL endpoint', - action: parsers.booleanParser, - default: false - }, - mountPath: { - env: 'PARSE_SERVER_MOUNT_PATH', - help: 'Mount path for the server, defaults to /parse', - default: '/parse' - }, - mountPlayground: { - env: 'PARSE_SERVER_MOUNT_PLAYGROUND', - help: 'Mounts the GraphQL Playground - never use this option in production', - action: parsers.booleanParser, - default: false - }, - objectIdSize: { - env: 'PARSE_SERVER_OBJECT_ID_SIZE', - help: "Sets the number of characters in generated object id's, default 10", - action: parsers.numberParser('objectIdSize'), - default: 10 - }, - passwordPolicy: { - env: 'PARSE_SERVER_PASSWORD_POLICY', - help: 'Password policy for enforcing password related rules', - action: parsers.objectParser - }, - playgroundPath: { - env: 'PARSE_SERVER_PLAYGROUND_PATH', - help: 'Mount path for the GraphQL Playground, defaults to /playground', - default: '/playground' - }, - port: { - env: 'PORT', - help: 'The port to run the ParseServer, defaults to 1337.', - action: parsers.numberParser('port'), - default: 1337 - }, - preserveFileName: { - env: 'PARSE_SERVER_PRESERVE_FILE_NAME', - help: 'Enable (or disable) the addition of a unique hash to the file names', - action: parsers.booleanParser, - default: false - }, - preventLoginWithUnverifiedEmail: { - env: 'PARSE_SERVER_PREVENT_LOGIN_WITH_UNVERIFIED_EMAIL', - help: 'Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false', - action: parsers.booleanParser, - default: false - }, - protectedFields: { - env: 'PARSE_SERVER_PROTECTED_FIELDS', - help: 'Protected fields that should be treated with extra security when fetching details.', - action: parsers.objectParser, - default: { - _User: { - '*': ['email'] - } - } - }, - publicServerURL: { - env: 'PARSE_PUBLIC_SERVER_URL', - help: 'Public URL to your parse server with http:// or https://.' - }, - push: { - env: 'PARSE_SERVER_PUSH', - help: 'Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications', - action: parsers.objectParser - }, - readOnlyMasterKey: { - env: 'PARSE_SERVER_READ_ONLY_MASTER_KEY', - help: 'Read-only key, which has the same capabilities as MasterKey without writes' - }, - restAPIKey: { - env: 'PARSE_SERVER_REST_API_KEY', - help: 'Key for REST calls' - }, - revokeSessionOnPasswordReset: { - env: 'PARSE_SERVER_REVOKE_SESSION_ON_PASSWORD_RESET', - help: "When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions.", - action: parsers.booleanParser, - default: true - }, - scheduledPush: { - env: 'PARSE_SERVER_SCHEDULED_PUSH', - help: 'Configuration for push scheduling, defaults to false.', - action: parsers.booleanParser, - default: false - }, - schemaCacheTTL: { - env: 'PARSE_SERVER_SCHEMA_CACHE_TTL', - help: 'The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable.', - action: parsers.numberParser('schemaCacheTTL'), - default: 5000 - }, - serverCloseComplete: { - env: 'PARSE_SERVER_SERVER_CLOSE_COMPLETE', - help: 'Callback when server has closed' - }, - serverStartComplete: { - env: 'PARSE_SERVER_SERVER_START_COMPLETE', - help: 'Callback when server has started' - }, - serverURL: { - env: 'PARSE_SERVER_URL', - help: 'URL to your parse server with http:// or https://.', - required: true - }, - sessionLength: { - env: 'PARSE_SERVER_SESSION_LENGTH', - help: 'Session duration, in seconds, defaults to 1 year', - action: parsers.numberParser('sessionLength'), - default: 31536000 - }, - silent: { - env: 'SILENT', - help: 'Disables console output', - action: parsers.booleanParser - }, - startLiveQueryServer: { - env: 'PARSE_SERVER_START_LIVE_QUERY_SERVER', - help: 'Starts the liveQuery server', - action: parsers.booleanParser - }, - userSensitiveFields: { - env: 'PARSE_SERVER_USER_SENSITIVE_FIELDS', - help: 'Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields', - action: parsers.arrayParser - }, - verbose: { - env: 'VERBOSE', - help: 'Set the logging to verbose', - action: parsers.booleanParser - }, - verifyUserEmails: { - env: 'PARSE_SERVER_VERIFY_USER_EMAILS', - help: 'Enable (or disable) user email validation, defaults to false', - action: parsers.booleanParser, - default: false - }, - webhookKey: { - env: 'PARSE_SERVER_WEBHOOK_KEY', - help: 'Key sent with outgoing webhook calls' - } -}; -module.exports.CustomPagesOptions = { - choosePassword: { - env: 'PARSE_SERVER_CUSTOM_PAGES_CHOOSE_PASSWORD', - help: 'choose password page path' - }, - invalidLink: { - env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_LINK', - help: 'invalid link page path' - }, - invalidVerificationLink: { - env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_VERIFICATION_LINK', - help: 'invalid verification link page path' - }, - linkSendFail: { - env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_FAIL', - help: 'verification link send fail page path' - }, - linkSendSuccess: { - env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_SUCCESS', - help: 'verification link send success page path' - }, - parseFrameURL: { - env: 'PARSE_SERVER_CUSTOM_PAGES_PARSE_FRAME_URL', - help: 'for masking user-facing pages' - }, - passwordResetSuccess: { - env: 'PARSE_SERVER_CUSTOM_PAGES_PASSWORD_RESET_SUCCESS', - help: 'password reset success page path' - }, - verifyEmailSuccess: { - env: 'PARSE_SERVER_CUSTOM_PAGES_VERIFY_EMAIL_SUCCESS', - help: 'verify email success page path' - } -}; -module.exports.LiveQueryOptions = { - classNames: { - env: 'PARSE_SERVER_LIVEQUERY_CLASSNAMES', - help: "parse-server's LiveQuery classNames", - action: parsers.arrayParser - }, - pubSubAdapter: { - env: 'PARSE_SERVER_LIVEQUERY_PUB_SUB_ADAPTER', - help: 'LiveQuery pubsub adapter', - action: parsers.moduleOrObjectParser - }, - redisOptions: { - env: 'PARSE_SERVER_LIVEQUERY_REDIS_OPTIONS', - help: "parse-server's LiveQuery redisOptions", - action: parsers.objectParser - }, - redisURL: { - env: 'PARSE_SERVER_LIVEQUERY_REDIS_URL', - help: "parse-server's LiveQuery redisURL" - }, - wssAdapter: { - env: 'PARSE_SERVER_LIVEQUERY_WSS_ADAPTER', - help: 'Adapter module for the WebSocketServer', - action: parsers.moduleOrObjectParser - } -}; -module.exports.LiveQueryServerOptions = { - appId: { - env: 'PARSE_LIVE_QUERY_SERVER_APP_ID', - help: 'This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId.' - }, - cacheTimeout: { - env: 'PARSE_LIVE_QUERY_SERVER_CACHE_TIMEOUT', - help: "Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds).", - action: parsers.numberParser('cacheTimeout') - }, - keyPairs: { - env: 'PARSE_LIVE_QUERY_SERVER_KEY_PAIRS', - help: 'A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details.', - action: parsers.objectParser - }, - logLevel: { - env: 'PARSE_LIVE_QUERY_SERVER_LOG_LEVEL', - help: 'This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO.' - }, - masterKey: { - env: 'PARSE_LIVE_QUERY_SERVER_MASTER_KEY', - help: 'This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey.' - }, - port: { - env: 'PARSE_LIVE_QUERY_SERVER_PORT', - help: 'The port to run the LiveQuery server, defaults to 1337.', - action: parsers.numberParser('port'), - default: 1337 - }, - pubSubAdapter: { - env: 'PARSE_LIVE_QUERY_SERVER_PUB_SUB_ADAPTER', - help: 'LiveQuery pubsub adapter', - action: parsers.moduleOrObjectParser - }, - redisOptions: { - env: 'PARSE_LIVE_QUERY_SERVER_REDIS_OPTIONS', - help: "parse-server's LiveQuery redisOptions", - action: parsers.objectParser - }, - redisURL: { - env: 'PARSE_LIVE_QUERY_SERVER_REDIS_URL', - help: "parse-server's LiveQuery redisURL" - }, - serverURL: { - env: 'PARSE_LIVE_QUERY_SERVER_SERVER_URL', - help: 'This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL.' - }, - websocketTimeout: { - env: 'PARSE_LIVE_QUERY_SERVER_WEBSOCKET_TIMEOUT', - help: 'Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s).', - action: parsers.numberParser('websocketTimeout') - }, - wssAdapter: { - env: 'PARSE_LIVE_QUERY_SERVER_WSS_ADAPTER', - help: 'Adapter module for the WebSocketServer', - action: parsers.moduleOrObjectParser - } -}; -module.exports.IdempotencyOptions = { - paths: { - env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_PATHS', - help: 'An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths.', - action: parsers.arrayParser, - default: [] - }, - ttl: { - env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_TTL', - help: 'The duration in seconds after which a request record is discarded from the database, defaults to 300s.', - action: parsers.numberParser('ttl'), - default: 300 - } -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL0RlZmluaXRpb25zLmpzIl0sIm5hbWVzIjpbInBhcnNlcnMiLCJyZXF1aXJlIiwibW9kdWxlIiwiZXhwb3J0cyIsIlBhcnNlU2VydmVyT3B0aW9ucyIsImFjY291bnRMb2Nrb3V0IiwiZW52IiwiaGVscCIsImFjdGlvbiIsIm9iamVjdFBhcnNlciIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsImJvb2xlYW5QYXJzZXIiLCJkZWZhdWx0IiwiYWxsb3dDdXN0b21PYmplY3RJZCIsImFsbG93SGVhZGVycyIsImFycmF5UGFyc2VyIiwiYWxsb3dPcmlnaW4iLCJhbmFseXRpY3NBZGFwdGVyIiwibW9kdWxlT3JPYmplY3RQYXJzZXIiLCJhcHBJZCIsInJlcXVpcmVkIiwiYXBwTmFtZSIsImF1dGgiLCJjYWNoZUFkYXB0ZXIiLCJjYWNoZU1heFNpemUiLCJudW1iZXJQYXJzZXIiLCJjYWNoZVRUTCIsImNsaWVudEtleSIsImNsb3VkIiwiY2x1c3RlciIsIm51bWJlck9yQm9vbGVhblBhcnNlciIsImNvbGxlY3Rpb25QcmVmaXgiLCJjdXN0b21QYWdlcyIsImRhdGFiYXNlQWRhcHRlciIsImRhdGFiYXNlT3B0aW9ucyIsImRhdGFiYXNlVVJJIiwiZGlyZWN0QWNjZXNzIiwiZG90TmV0S2V5IiwiZW1haWxBZGFwdGVyIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJlbmFibGVBbm9ueW1vdXNVc2VycyIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSIsImVuY3J5cHRpb25LZXkiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwiZmlsZUtleSIsImZpbGVzQWRhcHRlciIsImdyYXBoUUxQYXRoIiwiZ3JhcGhRTFNjaGVtYSIsImhvc3QiLCJpZGVtcG90ZW5jeU9wdGlvbnMiLCJqYXZhc2NyaXB0S2V5IiwianNvbkxvZ3MiLCJsaXZlUXVlcnkiLCJsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIiwibG9nZ2VyQWRhcHRlciIsImxvZ0xldmVsIiwibG9nc0ZvbGRlciIsIm1hc3RlcktleSIsIm1hc3RlcktleUlwcyIsIm1heExpbWl0IiwibWF4TG9nRmlsZXMiLCJtYXhVcGxvYWRTaXplIiwibWlkZGxld2FyZSIsIm1vdW50R3JhcGhRTCIsIm1vdW50UGF0aCIsIm1vdW50UGxheWdyb3VuZCIsIm9iamVjdElkU2l6ZSIsInBhc3N3b3JkUG9saWN5IiwicGxheWdyb3VuZFBhdGgiLCJwb3J0IiwicHJlc2VydmVGaWxlTmFtZSIsInByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwiLCJwcm90ZWN0ZWRGaWVsZHMiLCJfVXNlciIsInB1YmxpY1NlcnZlclVSTCIsInB1c2giLCJyZWFkT25seU1hc3RlcktleSIsInJlc3RBUElLZXkiLCJyZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0Iiwic2NoZWR1bGVkUHVzaCIsInNjaGVtYUNhY2hlVFRMIiwic2VydmVyQ2xvc2VDb21wbGV0ZSIsInNlcnZlclN0YXJ0Q29tcGxldGUiLCJzZXJ2ZXJVUkwiLCJzZXNzaW9uTGVuZ3RoIiwic2lsZW50Iiwic3RhcnRMaXZlUXVlcnlTZXJ2ZXIiLCJ1c2VyU2Vuc2l0aXZlRmllbGRzIiwidmVyYm9zZSIsInZlcmlmeVVzZXJFbWFpbHMiLCJ3ZWJob29rS2V5IiwiQ3VzdG9tUGFnZXNPcHRpb25zIiwiY2hvb3NlUGFzc3dvcmQiLCJpbnZhbGlkTGluayIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRGYWlsIiwibGlua1NlbmRTdWNjZXNzIiwicGFyc2VGcmFtZVVSTCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzIiwidmVyaWZ5RW1haWxTdWNjZXNzIiwiTGl2ZVF1ZXJ5T3B0aW9ucyIsImNsYXNzTmFtZXMiLCJwdWJTdWJBZGFwdGVyIiwicmVkaXNPcHRpb25zIiwicmVkaXNVUkwiLCJ3c3NBZGFwdGVyIiwiTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsImNhY2hlVGltZW91dCIsImtleVBhaXJzIiwid2Vic29ja2V0VGltZW91dCIsIklkZW1wb3RlbmN5T3B0aW9ucyIsInBhdGhzIiwidHRsIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7OztBQUtBLElBQUlBLE9BQU8sR0FBR0MsT0FBTyxDQUFDLFdBQUQsQ0FBckI7O0FBRUFDLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlQyxrQkFBZixHQUFvQztBQUNsQ0MsRUFBQUEsY0FBYyxFQUFFO0FBQ2RDLElBQUFBLEdBQUcsRUFBRSw4QkFEUztBQUVkQyxJQUFBQSxJQUFJLEVBQUUsa0RBRlE7QUFHZEMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUNTO0FBSEYsR0FEa0I7QUFNbENDLEVBQUFBLHdCQUF3QixFQUFFO0FBQ3hCSixJQUFBQSxHQUFHLEVBQUUsMENBRG1CO0FBRXhCQyxJQUFBQSxJQUFJLEVBQUUsNkRBRmtCO0FBR3hCQyxJQUFBQSxNQUFNLEVBQUVSLE9BQU8sQ0FBQ1csYUFIUTtBQUl4QkMsSUFBQUEsT0FBTyxFQUFFO0FBSmUsR0FOUTtBQVlsQ0MsRUFBQUEsbUJBQW1CLEVBQUU7QUFDbkJQLElBQUFBLEdBQUcsRUFBRSxxQ0FEYztBQUVuQkMsSUFBQUEsSUFBSSxFQUFFLHFDQUZhO0FBR25CQyxJQUFBQSxNQUFNLEVBQUVSLE9BQU8sQ0FBQ1csYUFIRztBQUluQkMsSUFBQUEsT0FBTyxFQUFFO0FBSlUsR0FaYTtBQWtCbENFLEVBQUFBLFlBQVksRUFBRTtBQUNaUixJQUFBQSxHQUFHLEVBQUUsNEJBRE87QUFFWkMsSUFBQUEsSUFBSSxFQUFFLDZDQUZNO0FBR1pDLElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDZTtBQUhKLEdBbEJvQjtBQXVCbENDLEVBQUFBLFdBQVcsRUFBRTtBQUNYVixJQUFBQSxHQUFHLEVBQUUsMkJBRE07QUFFWEMsSUFBQUEsSUFBSSxFQUFFO0FBRkssR0F2QnFCO0FBMkJsQ1UsRUFBQUEsZ0JBQWdCLEVBQUU7QUFDaEJYLElBQUFBLEdBQUcsRUFBRSxnQ0FEVztBQUVoQkMsSUFBQUEsSUFBSSxF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LElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDeUIsWUFBUixDQUFxQixrQkFBckI7QUFKUSxHQXJEb0I7QUEyRHRDaUYsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZwRyxJQUFBQSxHQUFHLEVBQUUscUNBREs7QUFFVkMsSUFBQUEsSUFBSSxFQUFFLHdDQUZJO0FBR1ZDLElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDa0I7QUFITjtBQTNEMEIsQ0FBeEM7QUFpRUFoQixNQUFNLENBQUNDLE9BQVAsQ0FBZTRHLGtCQUFmLEdBQW9DO0FBQ2xDQyxFQUFBQSxLQUFLLEVBQUU7QUFDTDFHLElBQUFBLEdBQUcsRUFBRSw2Q0FEQTtBQUVMQyxJQUFBQSxJQUFJLEVBQ0Ysa1hBSEc7QUFJTEMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUNlLFdBSlg7QUFLTEgsSUFBQUEsT0FBTyxFQUFFO0FBTEosR0FEMkI7QUFRbENxRyxFQUFBQSxHQUFHLEVBQUU7QUFDSDNHLElBQUFBLEdBQUcsRUFBRSwyQ0FERjtBQUVIQyxJQUFBQSxJQUFJLEVBQ0Ysd0dBSEM7QUFJSEMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUN5QixZQUFSLENBQXFCLEtBQXJCLENBSkw7QUFLSGIsSUFBQUEsT0FBTyxFQUFFO0FBTE47QUFSNkIsQ0FBcEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuKioqKiBHRU5FUkFURUQgQ09ERSAqKioqXG5UaGlzIGNvZGUgaGFzIGJlZW4gZ2VuZXJhdGVkIGJ5IHJlc291cmNlcy9idWlsZENvbmZpZ0RlZmluaXRpb25zLmpzXG5EbyBub3QgZWRpdCBtYW51YWxseSwgYnV0IHVwZGF0ZSBPcHRpb25zL2luZGV4LmpzXG4qL1xudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxubW9kdWxlLmV4cG9ydHMuUGFyc2VTZXJ2ZXJPcHRpb25zID0ge1xuICBhY2NvdW50TG9ja291dDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BQ0NPVU5UX0xPQ0tPVVQnLFxuICAgIGhlbHA6ICdhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DTElFTlRfQ0xBU1NfQ1JFQVRJT04nLFxuICAgIGhlbHA6ICdFbmFibGUgKG9yIGRpc2FibGUpIGNsaWVudCBjbGFzcyBjcmVhdGlvbiwgZGVmYXVsdHMgdG8gdHJ1ZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgYWxsb3dDdXN0b21PYmplY3RJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DVVNUT01fT0JKRUNUX0lEJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSBjdXN0b20gb2JqZWN0SWQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBhbGxvd0hlYWRlcnM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfSEVBREVSUycsXG4gICAgaGVscDogJ0FkZCBoZWFkZXJzIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgfSxcbiAgYWxsb3dPcmlnaW46IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfT1JJR0lOJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgb3JpZ2luIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsXG4gIH0sXG4gIGFuYWx5dGljc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQU5BTFlUSUNTX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBhcHBJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BUFBMSUNBVElPTl9JRCcsXG4gICAgaGVscDogJ1lvdXIgUGFyc2UgQXBwbGljYXRpb24gSUQnLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBhcHBOYW1lOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FQUF9OQU1FJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgYXBwIG5hbWUnLFxuICB9LFxuICBhdXRoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FVVEhfUFJPVklERVJTJyxcbiAgICBoZWxwOlxuICAgICAgJ0NvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBjYWNoZUFkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0FDSEVfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgY2FjaGVNYXhTaXplOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX01BWF9TSVpFJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignY2FjaGVNYXhTaXplJyksXG4gICAgZGVmYXVsdDogMTAwMDAsXG4gIH0sXG4gIGNhY2hlVFRMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX1RUTCcsXG4gICAgaGVscDogJ1NldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdjYWNoZVRUTCcpLFxuICAgIGRlZmF1bHQ6IDUwMDAsXG4gIH0sXG4gIGNsaWVudEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTElFTlRfS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMnLFxuICB9LFxuICBjbG91ZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTE9VRCcsXG4gICAgaGVscDogJ0Z1bGwgcGF0aCB0byB5b3VyIGNsb3VkIGNvZGUgbWFpbi5qcycsXG4gIH0sXG4gIGNsdXN0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0xVU1RFUicsXG4gICAgaGVscDogJ1J1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlck9yQm9vbGVhblBhcnNlcixcbiAgfSxcbiAgY29sbGVjdGlvblByZWZpeDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DT0xMRUNUSU9OX1BSRUZJWCcsXG4gICAgaGVscDogJ0EgY29sbGVjdGlvbiBwcmVmaXggZm9yIHRoZSBjbGFzc2VzJyxcbiAgICBkZWZhdWx0OiAnJyxcbiAgfSxcbiAgY3VzdG9tUGFnZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTJyxcbiAgICBoZWxwOiAnY3VzdG9tIHBhZ2VzIGZvciBwYXNzd29yZCB2YWxpZGF0aW9uIGFuZCByZXNldCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZGF0YWJhc2VBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0RBVEFCQVNFX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGRhdGFiYXNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIGRhdGFiYXNlT3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9EQVRBQkFTRV9PUFRJT05TJyxcbiAgICBoZWxwOiAnT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBtb25nb2RiIGNsaWVudCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgZGF0YWJhc2VVUkk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfREFUQUJBU0VfVVJJJyxcbiAgICBoZWxwOiAnVGhlIGZ1bGwgVVJJIHRvIHlvdXIgZGF0YWJhc2UuIFN1cHBvcnRlZCBkYXRhYmFzZXMgYXJlIG1vbmdvZGIgb3IgcG9zdGdyZXMuJyxcbiAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICBkZWZhdWx0OiAnbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZScsXG4gIH0sXG4gIGRpcmVjdEFjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MnLFxuICAgIGhlbHA6XG4gICAgICAnUmVwbGFjZSBIVFRQIEludGVyZmFjZSB3aGVuIHVzaW5nIEpTIFNESyBpbiBjdXJyZW50IG5vZGUgcnVudGltZSwgZGVmYXVsdHMgdG8gZmFsc2UuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGRvdE5ldEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9ET1RfTkVUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgVW5pdHkgYW5kIC5OZXQgU0RLJyxcbiAgfSxcbiAgZW1haWxBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VNQUlMX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTUFJTF9WRVJJRllfVE9LRU5fVkFMSURJVFlfRFVSQVRJT04nLFxuICAgIGhlbHA6ICdFbWFpbCB2ZXJpZmljYXRpb24gdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24sIGluIHNlY29uZHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ2VtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uJyksXG4gIH0sXG4gIGVuYWJsZUFub255bW91c1VzZXJzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQUJMRV9BTk9OX1VTRVJTJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSBhbm9ueW1vdXMgdXNlcnMsIGRlZmF1bHRzIHRvIHRydWUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG4gIGVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRU5BQkxFX0VYUFJFU1NfRVJST1JfSEFORExFUicsXG4gICAgaGVscDogJ0VuYWJsZXMgdGhlIGRlZmF1bHQgZXhwcmVzcyBlcnJvciBoYW5kbGVyIGZvciBhbGwgZXJyb3JzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRU5BQkxFX1NJTkdMRV9TQ0hFTUFfQ0FDSEUnLFxuICAgIGhlbHA6XG4gICAgICAnVXNlIGEgc2luZ2xlIHNjaGVtYSBjYWNoZSBzaGFyZWQgYWNyb3NzIHJlcXVlc3RzLiBSZWR1Y2VzIG51bWJlciBvZiBxdWVyaWVzIG1hZGUgdG8gX1NDSEVNQSwgZGVmYXVsdHMgdG8gZmFsc2UsIGkuZS4gdW5pcXVlIHNjaGVtYSBjYWNoZSBwZXIgcmVxdWVzdC4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBlbmNyeXB0aW9uS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQ1JZUFRJT05fS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciBlbmNyeXB0aW5nIHlvdXIgZmlsZXMnLFxuICB9LFxuICBleHBpcmVJbmFjdGl2ZVNlc3Npb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VYUElSRV9JTkFDVElWRV9TRVNTSU9OUycsXG4gICAgaGVscDogJ1NldHMgd2V0aGVyIHdlIHNob3VsZCBleHBpcmUgdGhlIGluYWN0aXZlIHNlc3Npb25zLCBkZWZhdWx0cyB0byB0cnVlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiB0cnVlLFxuICB9LFxuICBmaWxlS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVfS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciB5b3VyIGZpbGVzJyxcbiAgfSxcbiAgZmlsZXNBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVTX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGZpbGVzIHN1Yi1zeXN0ZW0nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgZ3JhcGhRTFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIJyxcbiAgICBoZWxwOiAnTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgZW5kcG9pbnQsIGRlZmF1bHRzIHRvIC9ncmFwaHFsJyxcbiAgICBkZWZhdWx0OiAnL2dyYXBocWwnLFxuICB9LFxuICBncmFwaFFMU2NoZW1hOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0dSQVBIX1FMU0NIRU1BJyxcbiAgICBoZWxwOiAnRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZScsXG4gIH0sXG4gIGhvc3Q6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfSE9TVCcsXG4gICAgaGVscDogJ1RoZSBob3N0IHRvIHNlcnZlIFBhcnNlU2VydmVyIG9uLCBkZWZhdWx0cyB0byAwLjAuMC4wJyxcbiAgICBkZWZhdWx0OiAnMC4wLjAuMCcsXG4gIH0sXG4gIGlkZW1wb3RlbmN5T3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfT1BUSU9OUycsXG4gICAgaGVscDpcbiAgICAgICdPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgamF2YXNjcmlwdEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9KQVZBU0NSSVBUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgdGhlIEphdmFzY3JpcHQgU0RLJyxcbiAgfSxcbiAganNvbkxvZ3M6IHtcbiAgICBlbnY6ICdKU09OX0xPR1MnLFxuICAgIGhlbHA6ICdMb2cgYXMgc3RydWN0dXJlZCBKU09OIG9iamVjdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRV9RVUVSWScsXG4gICAgaGVscDogXCJwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY29uZmlndXJhdGlvbiBvYmplY3RcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVfUVVFUllfU0VSVkVSX09QVElPTlMnLFxuICAgIGhlbHA6ICdMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsb2dnZXJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR0dFUl9BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTE9HX0xFVkVMJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbGV2ZWwgZm9yIGxvZ3MnLFxuICB9LFxuICBsb2dzRm9sZGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSJyxcbiAgICBoZWxwOiBcIkZvbGRlciBmb3IgdGhlIGxvZ3MgKGRlZmF1bHRzIHRvICcuL2xvZ3MnKTsgc2V0IHRvIG51bGwgdG8gZGlzYWJsZSBmaWxlIGJhc2VkIGxvZ2dpbmdcIixcbiAgICBkZWZhdWx0OiAnLi9sb2dzJyxcbiAgfSxcbiAgbWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BU1RFUl9LRVknLFxuICAgIGhlbHA6ICdZb3VyIFBhcnNlIE1hc3RlciBLZXknLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBtYXN0ZXJLZXlJcHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFTVEVSX0tFWV9JUFMnLFxuICAgIGhlbHA6ICdSZXN0cmljdCBtYXN0ZXJLZXkgdG8gYmUgdXNlZCBieSBvbmx5IHRoZXNlIGlwcywgZGVmYXVsdHMgdG8gW10gKGFsbG93IGFsbCBpcHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYXJyYXlQYXJzZXIsXG4gICAgZGVmYXVsdDogW10sXG4gIH0sXG4gIG1heExpbWl0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BWF9MSU1JVCcsXG4gICAgaGVscDogJ01heCB2YWx1ZSBmb3IgbGltaXQgb3B0aW9uIG9uIHF1ZXJpZXMsIGRlZmF1bHRzIHRvIHVubGltaXRlZCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignbWF4TGltaXQnKSxcbiAgfSxcbiAgbWF4TG9nRmlsZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFYX0xPR19GSUxFUycsXG4gICAgaGVscDpcbiAgICAgIFwiTWF4aW11bSBudW1iZXIgb2YgbG9ncyB0byBrZWVwLiBJZiBub3Qgc2V0LCBubyBsb2dzIHdpbGwgYmUgcmVtb3ZlZC4gVGhpcyBjYW4gYmUgYSBudW1iZXIgb2YgZmlsZXMgb3IgbnVtYmVyIG9mIGRheXMuIElmIHVzaW5nIGRheXMsIGFkZCAnZCcgYXMgdGhlIHN1ZmZpeC4gKGRlZmF1bHQ6IG51bGwpXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgbWF4VXBsb2FkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NQVhfVVBMT0FEX1NJWkUnLFxuICAgIGhlbHA6ICdNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iJyxcbiAgICBkZWZhdWx0OiAnMjBtYicsXG4gIH0sXG4gIG1pZGRsZXdhcmU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUlERExFV0FSRScsXG4gICAgaGVscDogJ21pZGRsZXdhcmUgZm9yIGV4cHJlc3Mgc2VydmVyLCBjYW4gYmUgc3RyaW5nIG9yIGZ1bmN0aW9uJyxcbiAgfSxcbiAgbW91bnRHcmFwaFFMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUwnLFxuICAgIGhlbHA6ICdNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBtb3VudFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTU9VTlRfUEFUSCcsXG4gICAgaGVscDogJ01vdW50IHBhdGggZm9yIHRoZSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIC9wYXJzZScsXG4gICAgZGVmYXVsdDogJy9wYXJzZScsXG4gIH0sXG4gIG1vdW50UGxheWdyb3VuZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NT1VOVF9QTEFZR1JPVU5EJyxcbiAgICBoZWxwOiAnTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvbicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIG9iamVjdElkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9PQkpFQ1RfSURfU0laRScsXG4gICAgaGVscDogXCJTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcIixcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdvYmplY3RJZFNpemUnKSxcbiAgICBkZWZhdWx0OiAxMCxcbiAgfSxcbiAgcGFzc3dvcmRQb2xpY3k6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFTU1dPUkRfUE9MSUNZJyxcbiAgICBoZWxwOiAnUGFzc3dvcmQgcG9saWN5IGZvciBlbmZvcmNpbmcgcGFzc3dvcmQgcmVsYXRlZCBydWxlcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgcGxheWdyb3VuZFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUExBWUdST1VORF9QQVRIJyxcbiAgICBoZWxwOiAnTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmQnLFxuICAgIGRlZmF1bHQ6ICcvcGxheWdyb3VuZCcsXG4gIH0sXG4gIHBvcnQ6IHtcbiAgICBlbnY6ICdQT1JUJyxcbiAgICBoZWxwOiAnVGhlIHBvcnQgdG8gcnVuIHRoZSBQYXJzZVNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3BvcnQnKSxcbiAgICBkZWZhdWx0OiAxMzM3LFxuICB9LFxuICBwcmVzZXJ2ZUZpbGVOYW1lOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BSRVNFUlZFX0ZJTEVfTkFNRScsXG4gICAgaGVscDogJ0VuYWJsZSAob3IgZGlzYWJsZSkgdGhlIGFkZGl0aW9uIG9mIGEgdW5pcXVlIGhhc2ggdG8gdGhlIGZpbGUgbmFtZXMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BSRVZFTlRfTE9HSU5fV0lUSF9VTlZFUklGSUVEX0VNQUlMJyxcbiAgICBoZWxwOlxuICAgICAgJ1ByZXZlbnQgdXNlciBmcm9tIGxvZ2luIGlmIGVtYWlsIGlzIG5vdCB2ZXJpZmllZCBhbmQgUEFSU0VfU0VSVkVSX1ZFUklGWV9VU0VSX0VNQUlMUyBpcyB0cnVlLCBkZWZhdWx0cyB0byBmYWxzZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIHByb3RlY3RlZEZpZWxkczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QUk9URUNURURfRklFTERTJyxcbiAgICBoZWxwOiAnUHJvdGVjdGVkIGZpZWxkcyB0aGF0IHNob3VsZCBiZSB0cmVhdGVkIHdpdGggZXh0cmEgc2VjdXJpdHkgd2hlbiBmZXRjaGluZyBkZXRhaWxzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7XG4gICAgICBfVXNlcjoge1xuICAgICAgICAnKic6IFsnZW1haWwnXSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAgcHVibGljU2VydmVyVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfUFVCTElDX1NFUlZFUl9VUkwnLFxuICAgIGhlbHA6ICdQdWJsaWMgVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy4nLFxuICB9LFxuICBwdXNoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BVU0gnLFxuICAgIGhlbHA6XG4gICAgICAnQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWFkT25seU1hc3RlcktleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9SRUFEX09OTFlfTUFTVEVSX0tFWScsXG4gICAgaGVscDogJ1JlYWQtb25seSBrZXksIHdoaWNoIGhhcyB0aGUgc2FtZSBjYXBhYmlsaXRpZXMgYXMgTWFzdGVyS2V5IHdpdGhvdXQgd3JpdGVzJyxcbiAgfSxcbiAgcmVzdEFQSUtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9SRVNUX0FQSV9LRVknLFxuICAgIGhlbHA6ICdLZXkgZm9yIFJFU1QgY2FsbHMnLFxuICB9LFxuICByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1JFVk9LRV9TRVNTSU9OX09OX1BBU1NXT1JEX1JFU0VUJyxcbiAgICBoZWxwOlxuICAgICAgXCJXaGVuIGEgdXNlciBjaGFuZ2VzIHRoZWlyIHBhc3N3b3JkLCBlaXRoZXIgdGhyb3VnaCB0aGUgcmVzZXQgcGFzc3dvcmQgZW1haWwgb3Igd2hpbGUgbG9nZ2VkIGluLCBhbGwgc2Vzc2lvbnMgYXJlIHJldm9rZWQgaWYgdGhpcyBpcyB0cnVlLiBTZXQgdG8gZmFsc2UgaWYgeW91IGRvbid0IHdhbnQgdG8gcmV2b2tlIHNlc3Npb25zLlwiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG4gIHNjaGVkdWxlZFB1c2g6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0NIRURVTEVEX1BVU0gnLFxuICAgIGhlbHA6ICdDb25maWd1cmF0aW9uIGZvciBwdXNoIHNjaGVkdWxpbmcsIGRlZmF1bHRzIHRvIGZhbHNlLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIHNjaGVtYUNhY2hlVFRMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NDSEVNQV9DQUNIRV9UVEwnLFxuICAgIGhlbHA6XG4gICAgICAnVGhlIFRUTCBmb3IgY2FjaGluZyB0aGUgc2NoZW1hIGZvciBvcHRpbWl6aW5nIHJlYWQvd3JpdGUgb3BlcmF0aW9ucy4gWW91IHNob3VsZCBwdXQgYSBsb25nIFRUTCB3aGVuIHlvdXIgREIgaXMgaW4gcHJvZHVjdGlvbi4gZGVmYXVsdCB0byA1MDAwOyBzZXQgMCB0byBkaXNhYmxlLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignc2NoZW1hQ2FjaGVUVEwnKSxcbiAgICBkZWZhdWx0OiA1MDAwLFxuICB9LFxuICBzZXJ2ZXJDbG9zZUNvbXBsZXRlOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NFUlZFUl9DTE9TRV9DT01QTEVURScsXG4gICAgaGVscDogJ0NhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBjbG9zZWQnLFxuICB9LFxuICBzZXJ2ZXJTdGFydENvbXBsZXRlOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NFUlZFUl9TVEFSVF9DT01QTEVURScsXG4gICAgaGVscDogJ0NhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBzdGFydGVkJyxcbiAgfSxcbiAgc2VydmVyVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1VSTCcsXG4gICAgaGVscDogJ1VSTCB0byB5b3VyIHBhcnNlIHNlcnZlciB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8uJyxcbiAgICByZXF1aXJlZDogdHJ1ZSxcbiAgfSxcbiAgc2Vzc2lvbkxlbmd0aDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9TRVNTSU9OX0xFTkdUSCcsXG4gICAgaGVscDogJ1Nlc3Npb24gZHVyYXRpb24sIGluIHNlY29uZHMsIGRlZmF1bHRzIHRvIDEgeWVhcicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignc2Vzc2lvbkxlbmd0aCcpLFxuICAgIGRlZmF1bHQ6IDMxNTM2MDAwLFxuICB9LFxuICBzaWxlbnQ6IHtcbiAgICBlbnY6ICdTSUxFTlQnLFxuICAgIGhlbHA6ICdEaXNhYmxlcyBjb25zb2xlIG91dHB1dCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gIH0sXG4gIHN0YXJ0TGl2ZVF1ZXJ5U2VydmVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NUQVJUX0xJVkVfUVVFUllfU0VSVkVSJyxcbiAgICBoZWxwOiAnU3RhcnRzIHRoZSBsaXZlUXVlcnkgc2VydmVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgdXNlclNlbnNpdGl2ZUZpZWxkczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9VU0VSX1NFTlNJVElWRV9GSUVMRFMnLFxuICAgIGhlbHA6XG4gICAgICAnUGVyc29uYWxseSBpZGVudGlmaWFibGUgaW5mb3JtYXRpb24gZmllbGRzIGluIHRoZSB1c2VyIHRhYmxlIHRoZSBzaG91bGQgYmUgcmVtb3ZlZCBmb3Igbm9uLWF1dGhvcml6ZWQgdXNlcnMuIERlcHJlY2F0ZWQgQHNlZSBwcm90ZWN0ZWRGaWVsZHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgfSxcbiAgdmVyYm9zZToge1xuICAgIGVudjogJ1ZFUkJPU0UnLFxuICAgIGhlbHA6ICdTZXQgdGhlIGxvZ2dpbmcgdG8gdmVyYm9zZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gIH0sXG4gIHZlcmlmeVVzZXJFbWFpbHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSB1c2VyIGVtYWlsIHZhbGlkYXRpb24sIGRlZmF1bHRzIHRvIGZhbHNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgd2ViaG9va0tleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9XRUJIT09LX0tFWScsXG4gICAgaGVscDogJ0tleSBzZW50IHdpdGggb3V0Z29pbmcgd2ViaG9vayBjYWxscycsXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuQ3VzdG9tUGFnZXNPcHRpb25zID0ge1xuICBjaG9vc2VQYXNzd29yZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfQ0hPT1NFX1BBU1NXT1JEJyxcbiAgICBoZWxwOiAnY2hvb3NlIHBhc3N3b3JkIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIGludmFsaWRMaW5rOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19JTlZBTElEX0xJTksnLFxuICAgIGhlbHA6ICdpbnZhbGlkIGxpbmsgcGFnZSBwYXRoJyxcbiAgfSxcbiAgaW52YWxpZFZlcmlmaWNhdGlvbkxpbms6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0lOVkFMSURfVkVSSUZJQ0FUSU9OX0xJTksnLFxuICAgIGhlbHA6ICdpbnZhbGlkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIGxpbmtTZW5kRmFpbDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfTElOS19TRU5EX0ZBSUwnLFxuICAgIGhlbHA6ICd2ZXJpZmljYXRpb24gbGluayBzZW5kIGZhaWwgcGFnZSBwYXRoJyxcbiAgfSxcbiAgbGlua1NlbmRTdWNjZXNzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19MSU5LX1NFTkRfU1VDQ0VTUycsXG4gICAgaGVscDogJ3ZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgc3VjY2VzcyBwYWdlIHBhdGgnLFxuICB9LFxuICBwYXJzZUZyYW1lVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19QQVJTRV9GUkFNRV9VUkwnLFxuICAgIGhlbHA6ICdmb3IgbWFza2luZyB1c2VyLWZhY2luZyBwYWdlcycsXG4gIH0sXG4gIHBhc3N3b3JkUmVzZXRTdWNjZXNzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19QQVNTV09SRF9SRVNFVF9TVUNDRVNTJyxcbiAgICBoZWxwOiAncGFzc3dvcmQgcmVzZXQgc3VjY2VzcyBwYWdlIHBhdGgnLFxuICB9LFxuICB2ZXJpZnlFbWFpbFN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX1ZFUklGWV9FTUFJTF9TVUNDRVNTJyxcbiAgICBoZWxwOiAndmVyaWZ5IGVtYWlsIHN1Y2Nlc3MgcGFnZSBwYXRoJyxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5MaXZlUXVlcnlPcHRpb25zID0ge1xuICBjbGFzc05hbWVzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9DTEFTU05BTUVTJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjbGFzc05hbWVzXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmFycmF5UGFyc2VyLFxuICB9LFxuICBwdWJTdWJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9QVUJfU1VCX0FEQVBURVInLFxuICAgIGhlbHA6ICdMaXZlUXVlcnkgcHVic3ViIGFkYXB0ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgcmVkaXNPcHRpb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9SRURJU19PUFRJT05TJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc1VSTDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9MSVZFUVVFUllfUkVESVNfVVJMJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc1VSTFwiLFxuICB9LFxuICB3c3NBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9XU1NfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyA9IHtcbiAgYXBwSWQ6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9BUFBfSUQnLFxuICAgIGhlbHA6XG4gICAgICAnVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBhcHBJZCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIGFwcElkLicsXG4gIH0sXG4gIGNhY2hlVGltZW91dDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0NBQ0hFX1RJTUVPVVQnLFxuICAgIGhlbHA6XG4gICAgICBcIk51bWJlciBpbiBtaWxsaXNlY29uZHMuIFdoZW4gY2xpZW50cyBwcm92aWRlIHRoZSBzZXNzaW9uVG9rZW4gdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIGZldGNoIGl0cyBQYXJzZVVzZXIncyBvYmplY3RJZCBmcm9tIHBhcnNlIHNlcnZlciBhbmQgc3RvcmUgaXQgaW4gdGhlIGNhY2hlLiBUaGUgdmFsdWUgZGVmaW5lcyB0aGUgZHVyYXRpb24gb2YgdGhlIGNhY2hlLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLCBkZWZhdWx0cyB0byA1ICogMTAwMCBtcyAoNSBzZWNvbmRzKS5cIixcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdjYWNoZVRpbWVvdXQnKSxcbiAgfSxcbiAga2V5UGFpcnM6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9LRVlfUEFJUlMnLFxuICAgIGhlbHA6XG4gICAgICAnQSBKU09OIG9iamVjdCB0aGF0IHNlcnZlcyBhcyBhIHdoaXRlbGlzdCBvZiBrZXlzLiBJdCBpcyB1c2VkIGZvciB2YWxpZGF0aW5nIGNsaWVudHMgd2hlbiB0aGV5IHRyeSB0byBjb25uZWN0IHRvIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9MT0dfTEVWRUwnLFxuICAgIGhlbHA6XG4gICAgICAnVGhpcyBzdHJpbmcgZGVmaW5lcyB0aGUgbG9nIGxldmVsIG9mIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBXZSBzdXBwb3J0IFZFUkJPU0UsIElORk8sIEVSUk9SLCBOT05FLCBkZWZhdWx0cyB0byBJTkZPLicsXG4gIH0sXG4gIG1hc3RlcktleToge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX01BU1RFUl9LRVknLFxuICAgIGhlbHA6XG4gICAgICAnVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBtYXN0ZXJLZXkgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBtYXN0ZXJLZXkuJyxcbiAgfSxcbiAgcG9ydDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1BPUlQnLFxuICAgIGhlbHA6ICdUaGUgcG9ydCB0byBydW4gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdwb3J0JyksXG4gICAgZGVmYXVsdDogMTMzNyxcbiAgfSxcbiAgcHViU3ViQWRhcHRlcjoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1BVQl9TVUJfQURBUFRFUicsXG4gICAgaGVscDogJ0xpdmVRdWVyeSBwdWJzdWIgYWRhcHRlcicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc09wdGlvbnM6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9SRURJU19PUFRJT05TJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc1VSTDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1JFRElTX1VSTCcsXG4gICAgaGVscDogXCJwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkxcIixcbiAgfSxcbiAgc2VydmVyVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfU0VSVkVSX1VSTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIHNlcnZlclVSTCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIHNlcnZlclVSTC4nLFxuICB9LFxuICB3ZWJzb2NrZXRUaW1lb3V0OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfV0VCU09DS0VUX1RJTUVPVVQnLFxuICAgIGhlbHA6XG4gICAgICAnTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHBpbmcvcG9uZyBmcmFtZXMuIFRoZSBXZWJTb2NrZXQgc2VydmVyIHNlbmRzIHBpbmcvcG9uZyBmcmFtZXMgdG8gdGhlIGNsaWVudHMgdG8ga2VlcCB0aGUgV2ViU29ja2V0IGFsaXZlLiBUaGlzIHZhbHVlIGRlZmluZXMgdGhlIGludGVydmFsIG9mIHRoZSBwaW5nL3BvbmcgZnJhbWUgZnJvbSB0aGUgc2VydmVyIHRvIGNsaWVudHMsIGRlZmF1bHRzIHRvIDEwICogMTAwMCBtcyAoMTAgcykuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCd3ZWJzb2NrZXRUaW1lb3V0JyksXG4gIH0sXG4gIHdzc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9XU1NfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuSWRlbXBvdGVuY3lPcHRpb25zID0ge1xuICBwYXRoczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfUEFUSFMnLFxuICAgIGhlbHA6XG4gICAgICAnQW4gYXJyYXkgb2YgcGF0aHMgZm9yIHdoaWNoIHRoZSBmZWF0dXJlIHNob3VsZCBiZSBlbmFibGVkLiBUaGUgbW91bnQgcGF0aCBtdXN0IG5vdCBiZSBpbmNsdWRlZCwgZm9yIGV4YW1wbGUgaW5zdGVhZCBvZiBgL3BhcnNlL2Z1bmN0aW9ucy9teUZ1bmN0aW9uYCBzcGVjaWZpeSBgZnVuY3Rpb25zL215RnVuY3Rpb25gLiBUaGUgZW50cmllcyBhcmUgaW50ZXJwcmV0ZWQgYXMgcmVndWxhciBleHByZXNzaW9uLCBmb3IgZXhhbXBsZSBgZnVuY3Rpb25zLy4qYCBtYXRjaGVzIGFsbCBmdW5jdGlvbnMsIGBqb2JzLy4qYCBtYXRjaGVzIGFsbCBqb2JzLCBgY2xhc3Nlcy8uKmAgbWF0Y2hlcyBhbGwgY2xhc3NlcywgYC4qYCBtYXRjaGVzIGFsbCBwYXRocy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgICBkZWZhdWx0OiBbXSxcbiAgfSxcbiAgdHRsOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VYUEVSSU1FTlRBTF9JREVNUE9URU5DWV9UVEwnLFxuICAgIGhlbHA6XG4gICAgICAnVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgYWZ0ZXIgd2hpY2ggYSByZXF1ZXN0IHJlY29yZCBpcyBkaXNjYXJkZWQgZnJvbSB0aGUgZGF0YWJhc2UsIGRlZmF1bHRzIHRvIDMwMHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCd0dGwnKSxcbiAgICBkZWZhdWx0OiAzMDAsXG4gIH0sXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Options/docs.js b/lib/Options/docs.js deleted file mode 100644 index 2e40b21790..0000000000 --- a/lib/Options/docs.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @interface ParseServerOptions - * @property {Any} accountLockout account lockout policy for failed login attempts - * @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true - * @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId - * @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers - * @property {String} allowOrigin Sets the origin to Access-Control-Allow-Origin - * @property {Adapter} analyticsAdapter Adapter module for the analytics - * @property {String} appId Your Parse Application ID - * @property {String} appName Sets the app name - * @property {Any} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication - * @property {Adapter} cacheAdapter Adapter module for the cache - * @property {Number} cacheMaxSize Sets the maximum size for the in memory cache, defaults to 10000 - * @property {Number} cacheTTL Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds) - * @property {String} clientKey Key for iOS, MacOS, tvOS clients - * @property {String} cloud Full path to your cloud code main.js - * @property {Number|Boolean} cluster Run with cluster, optionally set the number of processes default to os.cpus().length - * @property {String} collectionPrefix A collection prefix for the classes - * @property {CustomPagesOptions} customPages custom pages for password validation and reset - * @property {Adapter} databaseAdapter Adapter module for the database - * @property {Any} databaseOptions Options to pass to the mongodb client - * @property {String} databaseURI The full URI to your database. Supported databases are mongodb or postgres. - * @property {Boolean} directAccess Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production. - * @property {String} dotNetKey Key for Unity and .Net SDK - * @property {Adapter} emailAdapter Adapter module for email sending - * @property {Number} emailVerifyTokenValidityDuration Email verification token validity duration, in seconds - * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true - * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors - * @property {Boolean} enableSingleSchemaCache Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request. - * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true - * @property {String} fileKey Key for your files - * @property {Adapter} filesAdapter Adapter module for the files sub-system - * @property {String} graphQLPath Mount path for the GraphQL endpoint, defaults to /graphql - * @property {String} graphQLSchema Full path to your GraphQL custom schema.graphql file - * @property {String} host The host to serve ParseServer on, defaults to 0.0.0.0 - * @property {IdempotencyOptions} idempotencyOptions Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production. - * @property {String} javascriptKey Key for the Javascript SDK - * @property {Boolean} jsonLogs Log as structured JSON objects - * @property {LiveQueryOptions} liveQuery parse-server's LiveQuery configuration object - * @property {LiveQueryServerOptions} liveQueryServerOptions Live query server configuration options (will start the liveQuery server) - * @property {Adapter} loggerAdapter Adapter module for the logging sub-system - * @property {String} logLevel Sets the level for logs - * @property {String} logsFolder Folder for the logs (defaults to './logs'); set to null to disable file based logging - * @property {String} masterKey Your Parse Master Key - * @property {String[]} masterKeyIps Restrict masterKey to be used by only these ips, defaults to [] (allow all ips) - * @property {Number} maxLimit Max value for limit option on queries, defaults to unlimited - * @property {Number|String} maxLogFiles Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null) - * @property {String} maxUploadSize Max file size for uploads, defaults to 20mb - * @property {Union} middleware middleware for express server, can be string or function - * @property {Boolean} mountGraphQL Mounts the GraphQL endpoint - * @property {String} mountPath Mount path for the server, defaults to /parse - * @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production - * @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10 - * @property {Any} passwordPolicy Password policy for enforcing password related rules - * @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground - * @property {Number} port The port to run the ParseServer, defaults to 1337. - * @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names - * @property {Boolean} preventLoginWithUnverifiedEmail Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false - * @property {ProtectedFields} protectedFields Protected fields that should be treated with extra security when fetching details. - * @property {String} publicServerURL Public URL to your parse server with http:// or https://. - * @property {Any} push Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications - * @property {String} readOnlyMasterKey Read-only key, which has the same capabilities as MasterKey without writes - * @property {String} restAPIKey Key for REST calls - * @property {Boolean} revokeSessionOnPasswordReset When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions. - * @property {Boolean} scheduledPush Configuration for push scheduling, defaults to false. - * @property {Number} schemaCacheTTL The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable. - * @property {Function} serverCloseComplete Callback when server has closed - * @property {Function} serverStartComplete Callback when server has started - * @property {String} serverURL URL to your parse server with http:// or https://. - * @property {Number} sessionLength Session duration, in seconds, defaults to 1 year - * @property {Boolean} silent Disables console output - * @property {Boolean} startLiveQueryServer Starts the liveQuery server - * @property {String[]} userSensitiveFields Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields - * @property {Boolean} verbose Set the logging to verbose - * @property {Boolean} verifyUserEmails Enable (or disable) user email validation, defaults to false - * @property {String} webhookKey Key sent with outgoing webhook calls - */ - -/** - * @interface CustomPagesOptions - * @property {String} choosePassword choose password page path - * @property {String} invalidLink invalid link page path - * @property {String} invalidVerificationLink invalid verification link page path - * @property {String} linkSendFail verification link send fail page path - * @property {String} linkSendSuccess verification link send success page path - * @property {String} parseFrameURL for masking user-facing pages - * @property {String} passwordResetSuccess password reset success page path - * @property {String} verifyEmailSuccess verify email success page path - */ - -/** - * @interface LiveQueryOptions - * @property {String[]} classNames parse-server's LiveQuery classNames - * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter - * @property {Any} redisOptions parse-server's LiveQuery redisOptions - * @property {String} redisURL parse-server's LiveQuery redisURL - * @property {Adapter} wssAdapter Adapter module for the WebSocketServer - */ - -/** - * @interface LiveQueryServerOptions - * @property {String} appId This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId. - * @property {Number} cacheTimeout Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds). - * @property {Any} keyPairs A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details. - * @property {String} logLevel This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO. - * @property {String} masterKey This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey. - * @property {Number} port The port to run the LiveQuery server, defaults to 1337. - * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter - * @property {Any} redisOptions parse-server's LiveQuery redisOptions - * @property {String} redisURL parse-server's LiveQuery redisURL - * @property {String} serverURL This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL. - * @property {Number} websocketTimeout Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s). - * @property {Adapter} wssAdapter Adapter module for the WebSocketServer - */ - -/** - * @interface IdempotencyOptions - * @property {String[]} paths An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths. - * @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s. - */ -"use strict"; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2RvY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQThFQTs7Ozs7Ozs7Ozs7O0FBWUE7Ozs7Ozs7OztBQVNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlU2VydmVyT3B0aW9uc1xuICogQHByb3BlcnR5IHtBbnl9IGFjY291bnRMb2Nrb3V0IGFjY291bnQgbG9ja291dCBwb2xpY3kgZm9yIGZhaWxlZCBsb2dpbiBhdHRlbXB0c1xuICogQHByb3BlcnR5IHtCb29sZWFufSBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gRW5hYmxlIChvciBkaXNhYmxlKSBjbGllbnQgY2xhc3MgY3JlYXRpb24sIGRlZmF1bHRzIHRvIHRydWVcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gYWxsb3dDdXN0b21PYmplY3RJZCBFbmFibGUgKG9yIGRpc2FibGUpIGN1c3RvbSBvYmplY3RJZFxuICogQHByb3BlcnR5IHtTdHJpbmdbXX0gYWxsb3dIZWFkZXJzIEFkZCBoZWFkZXJzIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBhbGxvd09yaWdpbiBTZXRzIHRoZSBvcmlnaW4gdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8QW5hbHl0aWNzQWRhcHRlcj59IGFuYWx5dGljc0FkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBhbmFseXRpY3NcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBhcHBJZCBZb3VyIFBhcnNlIEFwcGxpY2F0aW9uIElEXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYXBwTmFtZSBTZXRzIHRoZSBhcHAgbmFtZVxuICogQHByb3BlcnR5IHtBbnl9IGF1dGggQ29uZmlndXJhdGlvbiBmb3IgeW91ciBhdXRoZW50aWNhdGlvbiBwcm92aWRlcnMsIGFzIHN0cmluZ2lmaWVkIEpTT04uIFNlZSBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvI29hdXRoLWFuZC0zcmQtcGFydHktYXV0aGVudGljYXRpb25cbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxDYWNoZUFkYXB0ZXI+fSBjYWNoZUFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBjYWNoZVxuICogQHByb3BlcnR5IHtOdW1iZXJ9IGNhY2hlTWF4U2l6ZSBTZXRzIHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBpbiBtZW1vcnkgY2FjaGUsIGRlZmF1bHRzIHRvIDEwMDAwXG4gKiBAcHJvcGVydHkge051bWJlcn0gY2FjaGVUVEwgU2V0cyB0aGUgVFRMIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlIChpbiBtcyksIGRlZmF1bHRzIHRvIDUwMDAgKDUgc2Vjb25kcylcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBjbGllbnRLZXkgS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBjbG91ZCBGdWxsIHBhdGggdG8geW91ciBjbG91ZCBjb2RlIG1haW4uanNcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfEJvb2xlYW59IGNsdXN0ZXIgUnVuIHdpdGggY2x1c3Rlciwgb3B0aW9uYWxseSBzZXQgdGhlIG51bWJlciBvZiBwcm9jZXNzZXMgZGVmYXVsdCB0byBvcy5jcHVzKCkubGVuZ3RoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gY29sbGVjdGlvblByZWZpeCBBIGNvbGxlY3Rpb24gcHJlZml4IGZvciB0aGUgY2xhc3Nlc1xuICogQHByb3BlcnR5IHtDdXN0b21QYWdlc09wdGlvbnN9IGN1c3RvbVBhZ2VzIGN1c3RvbSBwYWdlcyBmb3IgcGFzc3dvcmQgdmFsaWRhdGlvbiBhbmQgcmVzZXRcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxTdG9yYWdlQWRhcHRlcj59IGRhdGFiYXNlQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGRhdGFiYXNlXG4gKiBAcHJvcGVydHkge0FueX0gZGF0YWJhc2VPcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgbW9uZ29kYiBjbGllbnRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBkYXRhYmFzZVVSSSBUaGUgZnVsbCBVUkkgdG8geW91ciBkYXRhYmFzZS4gU3VwcG9ydGVkIGRhdGFiYXNlcyBhcmUgbW9uZ29kYiBvciBwb3N0Z3Jlcy5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZGlyZWN0QWNjZXNzIFJlcGxhY2UgSFRUUCBJbnRlcmZhY2Ugd2hlbiB1c2luZyBKUyBTREsgaW4gY3VycmVudCBub2RlIHJ1bnRpbWUsIGRlZmF1bHRzIHRvIGZhbHNlLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBkb3ROZXRLZXkgS2V5IGZvciBVbml0eSBhbmQgLk5ldCBTREtcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxNYWlsQWRhcHRlcj59IGVtYWlsQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZ1xuICogQHByb3BlcnR5IHtOdW1iZXJ9IGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIEVtYWlsIHZlcmlmaWNhdGlvbiB0b2tlbiB2YWxpZGl0eSBkdXJhdGlvbiwgaW4gc2Vjb25kc1xuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVBbm9ueW1vdXNVc2VycyBFbmFibGUgKG9yIGRpc2FibGUpIGFub255bW91cyB1c2VycywgZGVmYXVsdHMgdG8gdHJ1ZVxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyIEVuYWJsZXMgdGhlIGRlZmF1bHQgZXhwcmVzcyBlcnJvciBoYW5kbGVyIGZvciBhbGwgZXJyb3JzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIFVzZSBhIHNpbmdsZSBzY2hlbWEgY2FjaGUgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cy4gUmVkdWNlcyBudW1iZXIgb2YgcXVlcmllcyBtYWRlIHRvIF9TQ0hFTUEsIGRlZmF1bHRzIHRvIGZhbHNlLCBpLmUuIHVuaXF1ZSBzY2hlbWEgY2FjaGUgcGVyIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMgU2V0cyB3ZXRoZXIgd2Ugc2hvdWxkIGV4cGlyZSB0aGUgaW5hY3RpdmUgc2Vzc2lvbnMsIGRlZmF1bHRzIHRvIHRydWVcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWxlS2V5IEtleSBmb3IgeW91ciBmaWxlc1xuICogQHByb3BlcnR5IHtBZGFwdGVyPEZpbGVzQWRhcHRlcj59IGZpbGVzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGZpbGVzIHN1Yi1zeXN0ZW1cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBncmFwaFFMUGF0aCBNb3VudCBwYXRoIGZvciB0aGUgR3JhcGhRTCBlbmRwb2ludCwgZGVmYXVsdHMgdG8gL2dyYXBocWxcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBncmFwaFFMU2NoZW1hIEZ1bGwgcGF0aCB0byB5b3VyIEdyYXBoUUwgY3VzdG9tIHNjaGVtYS5ncmFwaHFsIGZpbGVcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBob3N0IFRoZSBob3N0IHRvIHNlcnZlIFBhcnNlU2VydmVyIG9uLCBkZWZhdWx0cyB0byAwLjAuMC4wXG4gKiBAcHJvcGVydHkge0lkZW1wb3RlbmN5T3B0aW9uc30gaWRlbXBvdGVuY3lPcHRpb25zIE9wdGlvbnMgZm9yIHJlcXVlc3QgaWRlbXBvdGVuY3kgdG8gZGVkdXBsaWNhdGUgaWRlbnRpY2FsIHJlcXVlc3RzIHRoYXQgbWF5IGJlIGNhdXNlZCBieSBuZXR3b3JrIGlzc3Vlcy4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gKiBAcHJvcGVydHkge1N0cmluZ30gamF2YXNjcmlwdEtleSBLZXkgZm9yIHRoZSBKYXZhc2NyaXB0IFNES1xuICogQHByb3BlcnR5IHtCb29sZWFufSBqc29uTG9ncyBMb2cgYXMgc3RydWN0dXJlZCBKU09OIG9iamVjdHNcbiAqIEBwcm9wZXJ0eSB7TGl2ZVF1ZXJ5T3B0aW9uc30gbGl2ZVF1ZXJ5IHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjb25maWd1cmF0aW9uIG9iamVjdFxuICogQHByb3BlcnR5IHtMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zfSBsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIExpdmUgcXVlcnkgc2VydmVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyAod2lsbCBzdGFydCB0aGUgbGl2ZVF1ZXJ5IHNlcnZlcilcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxMb2dnZXJBZGFwdGVyPn0gbG9nZ2VyQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGxvZ2dpbmcgc3ViLXN5c3RlbVxuICogQHByb3BlcnR5IHtTdHJpbmd9IGxvZ0xldmVsIFNldHMgdGhlIGxldmVsIGZvciBsb2dzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbG9nc0ZvbGRlciBGb2xkZXIgZm9yIHRoZSBsb2dzIChkZWZhdWx0cyB0byAnLi9sb2dzJyk7IHNldCB0byBudWxsIHRvIGRpc2FibGUgZmlsZSBiYXNlZCBsb2dnaW5nXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWFzdGVyS2V5IFlvdXIgUGFyc2UgTWFzdGVyIEtleVxuICogQHByb3BlcnR5IHtTdHJpbmdbXX0gbWFzdGVyS2V5SXBzIFJlc3RyaWN0IG1hc3RlcktleSB0byBiZSB1c2VkIGJ5IG9ubHkgdGhlc2UgaXBzLCBkZWZhdWx0cyB0byBbXSAoYWxsb3cgYWxsIGlwcylcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBtYXhMaW1pdCBNYXggdmFsdWUgZm9yIGxpbWl0IG9wdGlvbiBvbiBxdWVyaWVzLCBkZWZhdWx0cyB0byB1bmxpbWl0ZWRcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfFN0cmluZ30gbWF4TG9nRmlsZXMgTWF4aW11bSBudW1iZXIgb2YgbG9ncyB0byBrZWVwLiBJZiBub3Qgc2V0LCBubyBsb2dzIHdpbGwgYmUgcmVtb3ZlZC4gVGhpcyBjYW4gYmUgYSBudW1iZXIgb2YgZmlsZXMgb3IgbnVtYmVyIG9mIGRheXMuIElmIHVzaW5nIGRheXMsIGFkZCAnZCcgYXMgdGhlIHN1ZmZpeC4gKGRlZmF1bHQ6IG51bGwpXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWF4VXBsb2FkU2l6ZSBNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iXG4gKiBAcHJvcGVydHkge1VuaW9ufSBtaWRkbGV3YXJlIG1pZGRsZXdhcmUgZm9yIGV4cHJlc3Mgc2VydmVyLCBjYW4gYmUgc3RyaW5nIG9yIGZ1bmN0aW9uXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1vdW50R3JhcGhRTCBNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBtb3VudFBhdGggTW91bnQgcGF0aCBmb3IgdGhlIHNlcnZlciwgZGVmYXVsdHMgdG8gL3BhcnNlXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1vdW50UGxheWdyb3VuZCBNb3VudHMgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCAtIG5ldmVyIHVzZSB0aGlzIG9wdGlvbiBpbiBwcm9kdWN0aW9uXG4gKiBAcHJvcGVydHkge051bWJlcn0gb2JqZWN0SWRTaXplIFNldHMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIGdlbmVyYXRlZCBvYmplY3QgaWQncywgZGVmYXVsdCAxMFxuICogQHByb3BlcnR5IHtBbnl9IHBhc3N3b3JkUG9saWN5IFBhc3N3b3JkIHBvbGljeSBmb3IgZW5mb3JjaW5nIHBhc3N3b3JkIHJlbGF0ZWQgcnVsZXNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwbGF5Z3JvdW5kUGF0aCBNb3VudCBwYXRoIGZvciB0aGUgR3JhcGhRTCBQbGF5Z3JvdW5kLCBkZWZhdWx0cyB0byAvcGxheWdyb3VuZFxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHBvcnQgVGhlIHBvcnQgdG8gcnVuIHRoZSBQYXJzZVNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gcHJlc2VydmVGaWxlTmFtZSBFbmFibGUgKG9yIGRpc2FibGUpIHRoZSBhZGRpdGlvbiBvZiBhIHVuaXF1ZSBoYXNoIHRvIHRoZSBmaWxlIG5hbWVzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwgUHJldmVudCB1c2VyIGZyb20gbG9naW4gaWYgZW1haWwgaXMgbm90IHZlcmlmaWVkIGFuZCBQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTIGlzIHRydWUsIGRlZmF1bHRzIHRvIGZhbHNlXG4gKiBAcHJvcGVydHkge1Byb3RlY3RlZEZpZWxkc30gcHJvdGVjdGVkRmllbGRzIFByb3RlY3RlZCBmaWVsZHMgdGhhdCBzaG91bGQgYmUgdHJlYXRlZCB3aXRoIGV4dHJhIHNlY3VyaXR5IHdoZW4gZmV0Y2hpbmcgZGV0YWlscy5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwdWJsaWNTZXJ2ZXJVUkwgUHVibGljIFVSTCB0byB5b3VyIHBhcnNlIHNlcnZlciB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8uXG4gKiBAcHJvcGVydHkge0FueX0gcHVzaCBDb25maWd1cmF0aW9uIGZvciBwdXNoLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNwdXNoLW5vdGlmaWNhdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWFkT25seU1hc3RlcktleSBSZWFkLW9ubHkga2V5LCB3aGljaCBoYXMgdGhlIHNhbWUgY2FwYWJpbGl0aWVzIGFzIE1hc3RlcktleSB3aXRob3V0IHdyaXRlc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlc3RBUElLZXkgS2V5IGZvciBSRVNUIGNhbGxzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQgV2hlbiBhIHVzZXIgY2hhbmdlcyB0aGVpciBwYXNzd29yZCwgZWl0aGVyIHRocm91Z2ggdGhlIHJlc2V0IHBhc3N3b3JkIGVtYWlsIG9yIHdoaWxlIGxvZ2dlZCBpbiwgYWxsIHNlc3Npb25zIGFyZSByZXZva2VkIGlmIHRoaXMgaXMgdHJ1ZS4gU2V0IHRvIGZhbHNlIGlmIHlvdSBkb24ndCB3YW50IHRvIHJldm9rZSBzZXNzaW9ucy5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2NoZWR1bGVkUHVzaCBDb25maWd1cmF0aW9uIGZvciBwdXNoIHNjaGVkdWxpbmcsIGRlZmF1bHRzIHRvIGZhbHNlLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHNjaGVtYUNhY2hlVFRMIFRoZSBUVEwgZm9yIGNhY2hpbmcgdGhlIHNjaGVtYSBmb3Igb3B0aW1pemluZyByZWFkL3dyaXRlIG9wZXJhdGlvbnMuIFlvdSBzaG91bGQgcHV0IGEgbG9uZyBUVEwgd2hlbiB5b3VyIERCIGlzIGluIHByb2R1Y3Rpb24uIGRlZmF1bHQgdG8gNTAwMDsgc2V0IDAgdG8gZGlzYWJsZS5cbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IHNlcnZlckNsb3NlQ29tcGxldGUgQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZFxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gc2VydmVyU3RhcnRDb21wbGV0ZSBDYWxsYmFjayB3aGVuIHNlcnZlciBoYXMgc3RhcnRlZFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHNlcnZlclVSTCBVUkwgdG8geW91ciBwYXJzZSBzZXJ2ZXIgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHNlc3Npb25MZW5ndGggU2Vzc2lvbiBkdXJhdGlvbiwgaW4gc2Vjb25kcywgZGVmYXVsdHMgdG8gMSB5ZWFyXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNpbGVudCBEaXNhYmxlcyBjb25zb2xlIG91dHB1dFxuICogQHByb3BlcnR5IHtCb29sZWFufSBzdGFydExpdmVRdWVyeVNlcnZlciBTdGFydHMgdGhlIGxpdmVRdWVyeSBzZXJ2ZXJcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IHVzZXJTZW5zaXRpdmVGaWVsZHMgUGVyc29uYWxseSBpZGVudGlmaWFibGUgaW5mb3JtYXRpb24gZmllbGRzIGluIHRoZSB1c2VyIHRhYmxlIHRoZSBzaG91bGQgYmUgcmVtb3ZlZCBmb3Igbm9uLWF1dGhvcml6ZWQgdXNlcnMuIERlcHJlY2F0ZWQgQHNlZSBwcm90ZWN0ZWRGaWVsZHNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdmVyYm9zZSBTZXQgdGhlIGxvZ2dpbmcgdG8gdmVyYm9zZVxuICogQHByb3BlcnR5IHtCb29sZWFufSB2ZXJpZnlVc2VyRW1haWxzIEVuYWJsZSAob3IgZGlzYWJsZSkgdXNlciBlbWFpbCB2YWxpZGF0aW9uLCBkZWZhdWx0cyB0byBmYWxzZVxuICogQHByb3BlcnR5IHtTdHJpbmd9IHdlYmhvb2tLZXkgS2V5IHNlbnQgd2l0aCBvdXRnb2luZyB3ZWJob29rIGNhbGxzXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIEN1c3RvbVBhZ2VzT3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGNob29zZVBhc3N3b3JkIGNob29zZSBwYXNzd29yZCBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnZhbGlkTGluayBpbnZhbGlkIGxpbmsgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsgaW52YWxpZCB2ZXJpZmljYXRpb24gbGluayBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsaW5rU2VuZEZhaWwgdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBmYWlsIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGxpbmtTZW5kU3VjY2VzcyB2ZXJpZmljYXRpb24gbGluayBzZW5kIHN1Y2Nlc3MgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFyc2VGcmFtZVVSTCBmb3IgbWFza2luZyB1c2VyLWZhY2luZyBwYWdlc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IHBhc3N3b3JkUmVzZXRTdWNjZXNzIHBhc3N3b3JkIHJlc2V0IHN1Y2Nlc3MgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdmVyaWZ5RW1haWxTdWNjZXNzIHZlcmlmeSBlbWFpbCBzdWNjZXNzIHBhZ2UgcGF0aFxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBMaXZlUXVlcnlPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ1tdfSBjbGFzc05hbWVzIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjbGFzc05hbWVzXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8UHViU3ViQWRhcHRlcj59IHB1YlN1YkFkYXB0ZXIgTGl2ZVF1ZXJ5IHB1YnN1YiBhZGFwdGVyXG4gKiBAcHJvcGVydHkge0FueX0gcmVkaXNPcHRpb25zIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWRpc1VSTCBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkxcbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxXU1NBZGFwdGVyPn0gd3NzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIFdlYlNvY2tldFNlcnZlclxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYXBwSWQgVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBhcHBJZCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIGFwcElkLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IGNhY2hlVGltZW91dCBOdW1iZXIgaW4gbWlsbGlzZWNvbmRzLiBXaGVuIGNsaWVudHMgcHJvdmlkZSB0aGUgc2Vzc2lvblRva2VuIHRvIHRoZSBMaXZlUXVlcnkgc2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byBmZXRjaCBpdHMgUGFyc2VVc2VyJ3Mgb2JqZWN0SWQgZnJvbSBwYXJzZSBzZXJ2ZXIgYW5kIHN0b3JlIGl0IGluIHRoZSBjYWNoZS4gVGhlIHZhbHVlIGRlZmluZXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBjYWNoZS4gQ2hlY2sgdGhlIGZvbGxvd2luZyBTZWN1cml0eSBzZWN0aW9uIGFuZCBvdXIgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscywgZGVmYXVsdHMgdG8gNSAqIDEwMDAgbXMgKDUgc2Vjb25kcykuXG4gKiBAcHJvcGVydHkge0FueX0ga2V5UGFpcnMgQSBKU09OIG9iamVjdCB0aGF0IHNlcnZlcyBhcyBhIHdoaXRlbGlzdCBvZiBrZXlzLiBJdCBpcyB1c2VkIGZvciB2YWxpZGF0aW5nIGNsaWVudHMgd2hlbiB0aGV5IHRyeSB0byBjb25uZWN0IHRvIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGxvZ0xldmVsIFRoaXMgc3RyaW5nIGRlZmluZXMgdGhlIGxvZyBsZXZlbCBvZiB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gV2Ugc3VwcG9ydCBWRVJCT1NFLCBJTkZPLCBFUlJPUiwgTk9ORSwgZGVmYXVsdHMgdG8gSU5GTy5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBtYXN0ZXJLZXkgVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBtYXN0ZXJLZXkgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBtYXN0ZXJLZXkuXG4gKiBAcHJvcGVydHkge051bWJlcn0gcG9ydCBUaGUgcG9ydCB0byBydW4gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8UHViU3ViQWRhcHRlcj59IHB1YlN1YkFkYXB0ZXIgTGl2ZVF1ZXJ5IHB1YnN1YiBhZGFwdGVyXG4gKiBAcHJvcGVydHkge0FueX0gcmVkaXNPcHRpb25zIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZWRpc1VSTCBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkxcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBzZXJ2ZXJVUkwgVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBzZXJ2ZXJVUkwgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBzZXJ2ZXJVUkwuXG4gKiBAcHJvcGVydHkge051bWJlcn0gd2Vic29ja2V0VGltZW91dCBOdW1iZXIgb2YgbWlsbGlzZWNvbmRzIGJldHdlZW4gcGluZy9wb25nIGZyYW1lcy4gVGhlIFdlYlNvY2tldCBzZXJ2ZXIgc2VuZHMgcGluZy9wb25nIGZyYW1lcyB0byB0aGUgY2xpZW50cyB0byBrZWVwIHRoZSBXZWJTb2NrZXQgYWxpdmUuIFRoaXMgdmFsdWUgZGVmaW5lcyB0aGUgaW50ZXJ2YWwgb2YgdGhlIHBpbmcvcG9uZyBmcmFtZSBmcm9tIHRoZSBzZXJ2ZXIgdG8gY2xpZW50cywgZGVmYXVsdHMgdG8gMTAgKiAxMDAwIG1zICgxMCBzKS5cbiAqIEBwcm9wZXJ0eSB7QWRhcHRlcjxXU1NBZGFwdGVyPn0gd3NzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIFdlYlNvY2tldFNlcnZlclxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBJZGVtcG90ZW5jeU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IHBhdGhzIEFuIGFycmF5IG9mIHBhdGhzIGZvciB3aGljaCB0aGUgZmVhdHVyZSBzaG91bGQgYmUgZW5hYmxlZC4gVGhlIG1vdW50IHBhdGggbXVzdCBub3QgYmUgaW5jbHVkZWQsIGZvciBleGFtcGxlIGluc3RlYWQgb2YgYC9wYXJzZS9mdW5jdGlvbnMvbXlGdW5jdGlvbmAgc3BlY2lmaXkgYGZ1bmN0aW9ucy9teUZ1bmN0aW9uYC4gVGhlIGVudHJpZXMgYXJlIGludGVycHJldGVkIGFzIHJlZ3VsYXIgZXhwcmVzc2lvbiwgZm9yIGV4YW1wbGUgYGZ1bmN0aW9ucy8uKmAgbWF0Y2hlcyBhbGwgZnVuY3Rpb25zLCBgam9icy8uKmAgbWF0Y2hlcyBhbGwgam9icywgYGNsYXNzZXMvLipgIG1hdGNoZXMgYWxsIGNsYXNzZXMsIGAuKmAgbWF0Y2hlcyBhbGwgcGF0aHMuXG4gKiBAcHJvcGVydHkge051bWJlcn0gdHRsIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFmdGVyIHdoaWNoIGEgcmVxdWVzdCByZWNvcmQgaXMgZGlzY2FyZGVkIGZyb20gdGhlIGRhdGFiYXNlLCBkZWZhdWx0cyB0byAzMDBzLlxuICovXG4iXX0= \ No newline at end of file diff --git a/lib/Options/index.js b/lib/Options/index.js deleted file mode 100644 index 75d7985142..0000000000 --- a/lib/Options/index.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; - -var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); - -var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); - -var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); - -var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); - -var _CacheAdapter = require("../Adapters/Cache/CacheAdapter"); - -var _MailAdapter = require("../Adapters/Email/MailAdapter"); - -var _PubSubAdapter = require("../Adapters/PubSub/PubSubAdapter"); - -var _WSSAdapter = require("../Adapters/WebSocketServer/WSSAdapter"); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IHsgRmlsZXNBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRmlsZXMvRmlsZXNBZGFwdGVyJztcbmltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlcic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHsgQ2FjaGVBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQ2FjaGUvQ2FjaGVBZGFwdGVyJztcbmltcG9ydCB7IE1haWxBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRW1haWwvTWFpbEFkYXB0ZXInO1xuaW1wb3J0IHsgUHViU3ViQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9QdWJTdWJBZGFwdGVyJztcbmltcG9ydCB7IFdTU0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlcic7XG5cbi8vIEBmbG93XG50eXBlIEFkYXB0ZXI8VD4gPSBzdHJpbmcgfCBhbnkgfCBUO1xudHlwZSBOdW1iZXJPckJvb2xlYW4gPSBudW1iZXIgfCBib29sZWFuO1xudHlwZSBOdW1iZXJPclN0cmluZyA9IG51bWJlciB8IHN0cmluZztcbnR5cGUgUHJvdGVjdGVkRmllbGRzID0gYW55O1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlU2VydmVyT3B0aW9ucyB7XG4gIC8qIFlvdXIgUGFyc2UgQXBwbGljYXRpb24gSURcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FQUExJQ0FUSU9OX0lEICovXG4gIGFwcElkOiBzdHJpbmc7XG4gIC8qIFlvdXIgUGFyc2UgTWFzdGVyIEtleSAqL1xuICBtYXN0ZXJLZXk6IHN0cmluZztcbiAgLyogVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAgOkVOVjogUEFSU0VfU0VSVkVSX1VSTCAqL1xuICBzZXJ2ZXJVUkw6IHN0cmluZztcbiAgLyogUmVzdHJpY3QgbWFzdGVyS2V5IHRvIGJlIHVzZWQgYnkgb25seSB0aGVzZSBpcHMsIGRlZmF1bHRzIHRvIFtdIChhbGxvdyBhbGwgaXBzKVxuICA6REVGQVVMVDogW10gKi9cbiAgbWFzdGVyS2V5SXBzOiA/KHN0cmluZ1tdKTtcbiAgLyogU2V0cyB0aGUgYXBwIG5hbWUgKi9cbiAgYXBwTmFtZTogP3N0cmluZztcbiAgLyogQWRkIGhlYWRlcnMgdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyAqL1xuICBhbGxvd0hlYWRlcnM6ID8oc3RyaW5nW10pO1xuICAvKiBTZXRzIHRoZSBvcmlnaW4gdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luICovXG4gIGFsbG93T3JpZ2luOiA/c3RyaW5nO1xuICAvKiBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcyAqL1xuICBhbmFseXRpY3NBZGFwdGVyOiA/QWRhcHRlcjxBbmFseXRpY3NBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBmaWxlcyBzdWItc3lzdGVtICovXG4gIGZpbGVzQWRhcHRlcjogP0FkYXB0ZXI8RmlsZXNBZGFwdGVyPjtcbiAgLyogQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zICovXG4gIHB1c2g6ID9hbnk7XG4gIC8qIENvbmZpZ3VyYXRpb24gZm9yIHB1c2ggc2NoZWR1bGluZywgZGVmYXVsdHMgdG8gZmFsc2UuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBzY2hlZHVsZWRQdXNoOiA/Ym9vbGVhbjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0gKi9cbiAgbG9nZ2VyQWRhcHRlcjogP0FkYXB0ZXI8TG9nZ2VyQWRhcHRlcj47XG4gIC8qIExvZyBhcyBzdHJ1Y3R1cmVkIEpTT04gb2JqZWN0c1xuICA6RU5WOiBKU09OX0xPR1MgKi9cbiAganNvbkxvZ3M6ID9ib29sZWFuO1xuICAvKiBGb2xkZXIgZm9yIHRoZSBsb2dzIChkZWZhdWx0cyB0byAnLi9sb2dzJyk7IHNldCB0byBudWxsIHRvIGRpc2FibGUgZmlsZSBiYXNlZCBsb2dnaW5nXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9MT0dTX0ZPTERFUlxuICA6REVGQVVMVDogLi9sb2dzICovXG4gIGxvZ3NGb2xkZXI6ID9zdHJpbmc7XG4gIC8qIFNldCB0aGUgbG9nZ2luZyB0byB2ZXJib3NlXG4gIDpFTlY6IFZFUkJPU0UgKi9cbiAgdmVyYm9zZTogP2Jvb2xlYW47XG4gIC8qIFNldHMgdGhlIGxldmVsIGZvciBsb2dzICovXG4gIGxvZ0xldmVsOiA/c3RyaW5nO1xuICAvKiBNYXhpbXVtIG51bWJlciBvZiBsb2dzIHRvIGtlZXAuIElmIG5vdCBzZXQsIG5vIGxvZ3Mgd2lsbCBiZSByZW1vdmVkLiBUaGlzIGNhbiBiZSBhIG51bWJlciBvZiBmaWxlcyBvciBudW1iZXIgb2YgZGF5cy4gSWYgdXNpbmcgZGF5cywgYWRkICdkJyBhcyB0aGUgc3VmZml4LiAoZGVmYXVsdDogbnVsbCkgKi9cbiAgbWF4TG9nRmlsZXM6ID9OdW1iZXJPclN0cmluZztcbiAgLyogRGlzYWJsZXMgY29uc29sZSBvdXRwdXRcbiAgOkVOVjogU0lMRU5UICovXG4gIHNpbGVudDogP2Jvb2xlYW47XG4gIC8qIFRoZSBmdWxsIFVSSSB0byB5b3VyIGRhdGFiYXNlLiBTdXBwb3J0ZWQgZGF0YWJhc2VzIGFyZSBtb25nb2RiIG9yIHBvc3RncmVzLlxuICA6REVGQVVMVDogbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZSAqL1xuICBkYXRhYmFzZVVSSTogc3RyaW5nO1xuICAvKiBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIG1vbmdvZGIgY2xpZW50ICovXG4gIGRhdGFiYXNlT3B0aW9uczogP2FueTtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBkYXRhYmFzZSAqL1xuICBkYXRhYmFzZUFkYXB0ZXI6ID9BZGFwdGVyPFN0b3JhZ2VBZGFwdGVyPjtcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgY2xvdWQgY29kZSBtYWluLmpzICovXG4gIGNsb3VkOiA/c3RyaW5nO1xuICAvKiBBIGNvbGxlY3Rpb24gcHJlZml4IGZvciB0aGUgY2xhc3Nlc1xuICA6REVGQVVMVDogJycgKi9cbiAgY29sbGVjdGlvblByZWZpeDogP3N0cmluZztcbiAgLyogS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMgKi9cbiAgY2xpZW50S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIHRoZSBKYXZhc2NyaXB0IFNESyAqL1xuICBqYXZhc2NyaXB0S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIFVuaXR5IGFuZCAuTmV0IFNESyAqL1xuICBkb3ROZXRLZXk6ID9zdHJpbmc7XG4gIC8qIEtleSBmb3IgUkVTVCBjYWxsc1xuICA6RU5WOiBQQVJTRV9TRVJWRVJfUkVTVF9BUElfS0VZICovXG4gIHJlc3RBUElLZXk6ID9zdHJpbmc7XG4gIC8qIFJlYWQtb25seSBrZXksIHdoaWNoIGhhcyB0aGUgc2FtZSBjYXBhYmlsaXRpZXMgYXMgTWFzdGVyS2V5IHdpdGhvdXQgd3JpdGVzICovXG4gIHJlYWRPbmx5TWFzdGVyS2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgc2VudCB3aXRoIG91dGdvaW5nIHdlYmhvb2sgY2FsbHMgKi9cbiAgd2ViaG9va0tleTogP3N0cmluZztcbiAgLyogS2V5IGZvciB5b3VyIGZpbGVzICovXG4gIGZpbGVLZXk6ID9zdHJpbmc7XG4gIC8qIEVuYWJsZSAob3IgZGlzYWJsZSkgdGhlIGFkZGl0aW9uIG9mIGEgdW5pcXVlIGhhc2ggdG8gdGhlIGZpbGUgbmFtZXNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1BSRVNFUlZFX0ZJTEVfTkFNRVxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgcHJlc2VydmVGaWxlTmFtZTogP2Jvb2xlYW47XG4gIC8qIFBlcnNvbmFsbHkgaWRlbnRpZmlhYmxlIGluZm9ybWF0aW9uIGZpZWxkcyBpbiB0aGUgdXNlciB0YWJsZSB0aGUgc2hvdWxkIGJlIHJlbW92ZWQgZm9yIG5vbi1hdXRob3JpemVkIHVzZXJzLiBEZXByZWNhdGVkIEBzZWUgcHJvdGVjdGVkRmllbGRzICovXG4gIHVzZXJTZW5zaXRpdmVGaWVsZHM6ID8oc3RyaW5nW10pO1xuICAvKiBQcm90ZWN0ZWQgZmllbGRzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgd2l0aCBleHRyYSBzZWN1cml0eSB3aGVuIGZldGNoaW5nIGRldGFpbHMuXG4gIDpERUZBVUxUOiB7XCJfVXNlclwiOiB7XCIqXCI6IFtcImVtYWlsXCJdfX0gKi9cbiAgcHJvdGVjdGVkRmllbGRzOiA/UHJvdGVjdGVkRmllbGRzO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIGFub255bW91cyB1c2VycywgZGVmYXVsdHMgdG8gdHJ1ZVxuICA6RU5WOiBQQVJTRV9TRVJWRVJfRU5BQkxFX0FOT05fVVNFUlNcbiAgOkRFRkFVTFQ6IHRydWUgKi9cbiAgZW5hYmxlQW5vbnltb3VzVXNlcnM6ID9ib29sZWFuO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIGNsaWVudCBjbGFzcyBjcmVhdGlvbiwgZGVmYXVsdHMgdG8gdHJ1ZVxuICA6RU5WOiBQQVJTRV9TRVJWRVJfQUxMT1dfQ0xJRU5UX0NMQVNTX0NSRUFUSU9OXG4gIDpERUZBVUxUOiB0cnVlICovXG4gIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbjogP2Jvb2xlYW47XG4gIC8qIEVuYWJsZSAob3IgZGlzYWJsZSkgY3VzdG9tIG9iamVjdElkXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9BTExPV19DVVNUT01fT0JKRUNUX0lEXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBhbGxvd0N1c3RvbU9iamVjdElkOiA/Ym9vbGVhbjtcbiAgLyogQ29uZmlndXJhdGlvbiBmb3IgeW91ciBhdXRoZW50aWNhdGlvbiBwcm92aWRlcnMsIGFzIHN0cmluZ2lmaWVkIEpTT04uIFNlZSBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvI29hdXRoLWFuZC0zcmQtcGFydHktYXV0aGVudGljYXRpb25cbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FVVEhfUFJPVklERVJTICovXG4gIGF1dGg6ID9hbnk7XG4gIC8qIE1heCBmaWxlIHNpemUgZm9yIHVwbG9hZHMsIGRlZmF1bHRzIHRvIDIwbWJcbiAgOkRFRkFVTFQ6IDIwbWIgKi9cbiAgbWF4VXBsb2FkU2l6ZTogP3N0cmluZztcbiAgLyogRW5hYmxlIChvciBkaXNhYmxlKSB1c2VyIGVtYWlsIHZhbGlkYXRpb24sIGRlZmF1bHRzIHRvIGZhbHNlXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICB2ZXJpZnlVc2VyRW1haWxzOiA/Ym9vbGVhbjtcbiAgLyogUHJldmVudCB1c2VyIGZyb20gbG9naW4gaWYgZW1haWwgaXMgbm90IHZlcmlmaWVkIGFuZCBQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTIGlzIHRydWUsIGRlZmF1bHRzIHRvIGZhbHNlXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsOiA/Ym9vbGVhbjtcbiAgLyogRW1haWwgdmVyaWZpY2F0aW9uIHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uLCBpbiBzZWNvbmRzICovXG4gIGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uOiA/bnVtYmVyO1xuICAvKiBhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHMgKi9cbiAgYWNjb3VudExvY2tvdXQ6ID9hbnk7XG4gIC8qIFBhc3N3b3JkIHBvbGljeSBmb3IgZW5mb3JjaW5nIHBhc3N3b3JkIHJlbGF0ZWQgcnVsZXMgKi9cbiAgcGFzc3dvcmRQb2xpY3k6ID9hbnk7XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGUgKi9cbiAgY2FjaGVBZGFwdGVyOiA/QWRhcHRlcjxDYWNoZUFkYXB0ZXI+O1xuICAvKiBBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZyAqL1xuICBlbWFpbEFkYXB0ZXI6ID9BZGFwdGVyPE1haWxBZGFwdGVyPjtcbiAgLyogUHVibGljIFVSTCB0byB5b3VyIHBhcnNlIHNlcnZlciB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8uXG4gIDpFTlY6IFBBUlNFX1BVQkxJQ19TRVJWRVJfVVJMICovXG4gIHB1YmxpY1NlcnZlclVSTDogP3N0cmluZztcbiAgLyogY3VzdG9tIHBhZ2VzIGZvciBwYXNzd29yZCB2YWxpZGF0aW9uIGFuZCByZXNldFxuICA6REVGQVVMVDoge30gKi9cbiAgY3VzdG9tUGFnZXM6ID9DdXN0b21QYWdlc09wdGlvbnM7XG4gIC8qIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSBjb25maWd1cmF0aW9uIG9iamVjdCAqL1xuICBsaXZlUXVlcnk6ID9MaXZlUXVlcnlPcHRpb25zO1xuICAvKiBTZXNzaW9uIGR1cmF0aW9uLCBpbiBzZWNvbmRzLCBkZWZhdWx0cyB0byAxIHllYXJcbiAgOkRFRkFVTFQ6IDMxNTM2MDAwICovXG4gIHNlc3Npb25MZW5ndGg6ID9udW1iZXI7XG4gIC8qIE1heCB2YWx1ZSBmb3IgbGltaXQgb3B0aW9uIG9uIHF1ZXJpZXMsIGRlZmF1bHRzIHRvIHVubGltaXRlZCAqL1xuICBtYXhMaW1pdDogP251bWJlcjtcbiAgLyogU2V0cyB3ZXRoZXIgd2Ugc2hvdWxkIGV4cGlyZSB0aGUgaW5hY3RpdmUgc2Vzc2lvbnMsIGRlZmF1bHRzIHRvIHRydWVcbiAgOkRFRkFVTFQ6IHRydWUgKi9cbiAgZXhwaXJlSW5hY3RpdmVTZXNzaW9uczogP2Jvb2xlYW47XG4gIC8qIFdoZW4gYSB1c2VyIGNoYW5nZXMgdGhlaXIgcGFzc3dvcmQsIGVpdGhlciB0aHJvdWdoIHRoZSByZXNldCBwYXNzd29yZCBlbWFpbCBvciB3aGlsZSBsb2dnZWQgaW4sIGFsbCBzZXNzaW9ucyBhcmUgcmV2b2tlZCBpZiB0aGlzIGlzIHRydWUuIFNldCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudCB0byByZXZva2Ugc2Vzc2lvbnMuXG4gIDpERUZBVUxUOiB0cnVlICovXG4gIHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQ6ID9ib29sZWFuO1xuICAvKiBUaGUgVFRMIGZvciBjYWNoaW5nIHRoZSBzY2hlbWEgZm9yIG9wdGltaXppbmcgcmVhZC93cml0ZSBvcGVyYXRpb25zLiBZb3Ugc2hvdWxkIHB1dCBhIGxvbmcgVFRMIHdoZW4geW91ciBEQiBpcyBpbiBwcm9kdWN0aW9uLiBkZWZhdWx0IHRvIDUwMDA7IHNldCAwIHRvIGRpc2FibGUuXG4gIDpERUZBVUxUOiA1MDAwICovXG4gIHNjaGVtYUNhY2hlVFRMOiA/bnVtYmVyO1xuICAvKiBTZXRzIHRoZSBUVEwgZm9yIHRoZSBpbiBtZW1vcnkgY2FjaGUgKGluIG1zKSwgZGVmYXVsdHMgdG8gNTAwMCAoNSBzZWNvbmRzKVxuICA6REVGQVVMVDogNTAwMCAqL1xuICBjYWNoZVRUTDogP251bWJlcjtcbiAgLyogU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMFxuICA6REVGQVVMVDogMTAwMDAgKi9cbiAgY2FjaGVNYXhTaXplOiA/bnVtYmVyO1xuICAvKiBSZXBsYWNlIEhUVFAgSW50ZXJmYWNlIHdoZW4gdXNpbmcgSlMgU0RLIGluIGN1cnJlbnQgbm9kZSBydW50aW1lLCBkZWZhdWx0cyB0byBmYWxzZS4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1NcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGRpcmVjdEFjY2VzczogP2Jvb2xlYW47XG4gIC8qIFVzZSBhIHNpbmdsZSBzY2hlbWEgY2FjaGUgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cy4gUmVkdWNlcyBudW1iZXIgb2YgcXVlcmllcyBtYWRlIHRvIF9TQ0hFTUEsIGRlZmF1bHRzIHRvIGZhbHNlLCBpLmUuIHVuaXF1ZSBzY2hlbWEgY2FjaGUgcGVyIHJlcXVlc3QuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZTogP2Jvb2xlYW47XG4gIC8qIEVuYWJsZXMgdGhlIGRlZmF1bHQgZXhwcmVzcyBlcnJvciBoYW5kbGVyIGZvciBhbGwgZXJyb3JzXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyOiA/Ym9vbGVhbjtcbiAgLyogU2V0cyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gZ2VuZXJhdGVkIG9iamVjdCBpZCdzLCBkZWZhdWx0IDEwXG4gIDpERUZBVUxUOiAxMCAqL1xuICBvYmplY3RJZFNpemU6ID9udW1iZXI7XG4gIC8qIFRoZSBwb3J0IHRvIHJ1biB0aGUgUGFyc2VTZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gIDpFTlY6IFBPUlRcbiAgOkRFRkFVTFQ6IDEzMzcgKi9cbiAgcG9ydDogP251bWJlcjtcbiAgLyogVGhlIGhvc3QgdG8gc2VydmUgUGFyc2VTZXJ2ZXIgb24sIGRlZmF1bHRzIHRvIDAuMC4wLjBcbiAgOkRFRkFVTFQ6IDAuMC4wLjAgKi9cbiAgaG9zdDogP3N0cmluZztcbiAgLyogTW91bnQgcGF0aCBmb3IgdGhlIHNlcnZlciwgZGVmYXVsdHMgdG8gL3BhcnNlXG4gIDpERUZBVUxUOiAvcGFyc2UgKi9cbiAgbW91bnRQYXRoOiA/c3RyaW5nO1xuICAvKiBSdW4gd2l0aCBjbHVzdGVyLCBvcHRpb25hbGx5IHNldCB0aGUgbnVtYmVyIG9mIHByb2Nlc3NlcyBkZWZhdWx0IHRvIG9zLmNwdXMoKS5sZW5ndGggKi9cbiAgY2x1c3RlcjogP051bWJlck9yQm9vbGVhbjtcbiAgLyogbWlkZGxld2FyZSBmb3IgZXhwcmVzcyBzZXJ2ZXIsIGNhbiBiZSBzdHJpbmcgb3IgZnVuY3Rpb24gKi9cbiAgbWlkZGxld2FyZTogPygoKCkgPT4gdm9pZCkgfCBzdHJpbmcpO1xuICAvKiBTdGFydHMgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIgKi9cbiAgc3RhcnRMaXZlUXVlcnlTZXJ2ZXI6ID9ib29sZWFuO1xuICAvKiBMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpICovXG4gIGxpdmVRdWVyeVNlcnZlck9wdGlvbnM6ID9MaXZlUXVlcnlTZXJ2ZXJPcHRpb25zO1xuICAvKiBPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLlxuICA6RU5WOiBQQVJTRV9TRVJWRVJfRVhQRVJJTUVOVEFMX0lERU1QT1RFTkNZX09QVElPTlNcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGlkZW1wb3RlbmN5T3B0aW9uczogP0lkZW1wb3RlbmN5T3B0aW9ucztcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZSAqL1xuICBncmFwaFFMU2NoZW1hOiA/c3RyaW5nO1xuICAvKiBNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUxcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIG1vdW50R3JhcGhRTDogP2Jvb2xlYW47XG4gIC8qIE1vdW50IHBhdGggZm9yIHRoZSBHcmFwaFFMIGVuZHBvaW50LCBkZWZhdWx0cyB0byAvZ3JhcGhxbFxuICA6RU5WOiBQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIXG4gIDpERUZBVUxUOiAvZ3JhcGhxbCAqL1xuICBncmFwaFFMUGF0aDogP3N0cmluZztcbiAgLyogTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvblxuICA6RU5WOiBQQVJTRV9TRVJWRVJfTU9VTlRfUExBWUdST1VORFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgbW91bnRQbGF5Z3JvdW5kOiA/Ym9vbGVhbjtcbiAgLyogTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1BMQVlHUk9VTkRfUEFUSFxuICA6REVGQVVMVDogL3BsYXlncm91bmQgKi9cbiAgcGxheWdyb3VuZFBhdGg6ID9zdHJpbmc7XG4gIC8qIENhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBzdGFydGVkICovXG4gIHNlcnZlclN0YXJ0Q29tcGxldGU6ID8oZXJyb3I6ID9FcnJvcikgPT4gdm9pZDtcbiAgLyogQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZCAqL1xuICBzZXJ2ZXJDbG9zZUNvbXBsZXRlOiA/KCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21QYWdlc09wdGlvbnMge1xuICAvKiBpbnZhbGlkIGxpbmsgcGFnZSBwYXRoICovXG4gIGludmFsaWRMaW5rOiA/c3RyaW5nO1xuICAvKiB2ZXJpZnkgZW1haWwgc3VjY2VzcyBwYWdlIHBhdGggKi9cbiAgdmVyaWZ5RW1haWxTdWNjZXNzOiA/c3RyaW5nO1xuICAvKiBpbnZhbGlkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aCAqL1xuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluazogP3N0cmluZztcbiAgLyogdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICBsaW5rU2VuZFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIHZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgZmFpbCBwYWdlIHBhdGggKi9cbiAgbGlua1NlbmRGYWlsOiA/c3RyaW5nO1xuICAvKiBjaG9vc2UgcGFzc3dvcmQgcGFnZSBwYXRoICovXG4gIGNob29zZVBhc3N3b3JkOiA/c3RyaW5nO1xuICAvKiBwYXNzd29yZCByZXNldCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICBwYXNzd29yZFJlc2V0U3VjY2VzczogP3N0cmluZztcbiAgLyogZm9yIG1hc2tpbmcgdXNlci1mYWNpbmcgcGFnZXMgKi9cbiAgcGFyc2VGcmFtZVVSTDogP3N0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXZlUXVlcnlPcHRpb25zIHtcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IGNsYXNzTmFtZXNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9DTEFTU05BTUVTICovXG4gIGNsYXNzTmFtZXM6ID8oc3RyaW5nW10pO1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zICovXG4gIHJlZGlzT3B0aW9uczogP2FueTtcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMICovXG4gIHJlZGlzVVJMOiA/c3RyaW5nO1xuICAvKiBMaXZlUXVlcnkgcHVic3ViIGFkYXB0ZXIgKi9cbiAgcHViU3ViQWRhcHRlcjogP0FkYXB0ZXI8UHViU3ViQWRhcHRlcj47XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyICovXG4gIHdzc0FkYXB0ZXI6ID9BZGFwdGVyPFdTU0FkYXB0ZXI+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpdmVRdWVyeVNlcnZlck9wdGlvbnMge1xuICAvKiBUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIGFwcElkIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgYXBwSWQuKi9cbiAgYXBwSWQ6ID9zdHJpbmc7XG4gIC8qIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgbWFzdGVyS2V5IGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgbWFzdGVyS2V5LiovXG4gIG1hc3RlcktleTogP3N0cmluZztcbiAgLyogVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBzZXJ2ZXJVUkwgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBzZXJ2ZXJVUkwuKi9cbiAgc2VydmVyVVJMOiA/c3RyaW5nO1xuICAvKiBBIEpTT04gb2JqZWN0IHRoYXQgc2VydmVzIGFzIGEgd2hpdGVsaXN0IG9mIGtleXMuIEl0IGlzIHVzZWQgZm9yIHZhbGlkYXRpbmcgY2xpZW50cyB3aGVuIHRoZXkgdHJ5IHRvIGNvbm5lY3QgdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMuKi9cbiAga2V5UGFpcnM6ID9hbnk7XG4gIC8qIE51bWJlciBvZiBtaWxsaXNlY29uZHMgYmV0d2VlbiBwaW5nL3BvbmcgZnJhbWVzLiBUaGUgV2ViU29ja2V0IHNlcnZlciBzZW5kcyBwaW5nL3BvbmcgZnJhbWVzIHRvIHRoZSBjbGllbnRzIHRvIGtlZXAgdGhlIFdlYlNvY2tldCBhbGl2ZS4gVGhpcyB2YWx1ZSBkZWZpbmVzIHRoZSBpbnRlcnZhbCBvZiB0aGUgcGluZy9wb25nIGZyYW1lIGZyb20gdGhlIHNlcnZlciB0byBjbGllbnRzLCBkZWZhdWx0cyB0byAxMCAqIDEwMDAgbXMgKDEwIHMpLiovXG4gIHdlYnNvY2tldFRpbWVvdXQ6ID9udW1iZXI7XG4gIC8qIE51bWJlciBpbiBtaWxsaXNlY29uZHMuIFdoZW4gY2xpZW50cyBwcm92aWRlIHRoZSBzZXNzaW9uVG9rZW4gdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIGZldGNoIGl0cyBQYXJzZVVzZXIncyBvYmplY3RJZCBmcm9tIHBhcnNlIHNlcnZlciBhbmQgc3RvcmUgaXQgaW4gdGhlIGNhY2hlLiBUaGUgdmFsdWUgZGVmaW5lcyB0aGUgZHVyYXRpb24gb2YgdGhlIGNhY2hlLiBDaGVjayB0aGUgZm9sbG93aW5nIFNlY3VyaXR5IHNlY3Rpb24gYW5kIG91ciBwcm90b2NvbCBzcGVjaWZpY2F0aW9uIGZvciBkZXRhaWxzLCBkZWZhdWx0cyB0byA1ICogMTAwMCBtcyAoNSBzZWNvbmRzKS4qL1xuICBjYWNoZVRpbWVvdXQ6ID9udW1iZXI7XG4gIC8qIFRoaXMgc3RyaW5nIGRlZmluZXMgdGhlIGxvZyBsZXZlbCBvZiB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gV2Ugc3VwcG9ydCBWRVJCT1NFLCBJTkZPLCBFUlJPUiwgTk9ORSwgZGVmYXVsdHMgdG8gSU5GTy4qL1xuICBsb2dMZXZlbDogP3N0cmluZztcbiAgLyogVGhlIHBvcnQgdG8gcnVuIHRoZSBMaXZlUXVlcnkgc2VydmVyLCBkZWZhdWx0cyB0byAxMzM3LlxuICA6REVGQVVMVDogMTMzNyAqL1xuICBwb3J0OiA/bnVtYmVyO1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zICovXG4gIHJlZGlzT3B0aW9uczogP2FueTtcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMICovXG4gIHJlZGlzVVJMOiA/c3RyaW5nO1xuICAvKiBMaXZlUXVlcnkgcHVic3ViIGFkYXB0ZXIgKi9cbiAgcHViU3ViQWRhcHRlcjogP0FkYXB0ZXI8UHViU3ViQWRhcHRlcj47XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgV2ViU29ja2V0U2VydmVyICovXG4gIHdzc0FkYXB0ZXI6ID9BZGFwdGVyPFdTU0FkYXB0ZXI+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElkZW1wb3RlbmN5T3B0aW9ucyB7XG4gIC8qIEFuIGFycmF5IG9mIHBhdGhzIGZvciB3aGljaCB0aGUgZmVhdHVyZSBzaG91bGQgYmUgZW5hYmxlZC4gVGhlIG1vdW50IHBhdGggbXVzdCBub3QgYmUgaW5jbHVkZWQsIGZvciBleGFtcGxlIGluc3RlYWQgb2YgYC9wYXJzZS9mdW5jdGlvbnMvbXlGdW5jdGlvbmAgc3BlY2lmaXkgYGZ1bmN0aW9ucy9teUZ1bmN0aW9uYC4gVGhlIGVudHJpZXMgYXJlIGludGVycHJldGVkIGFzIHJlZ3VsYXIgZXhwcmVzc2lvbiwgZm9yIGV4YW1wbGUgYGZ1bmN0aW9ucy8uKmAgbWF0Y2hlcyBhbGwgZnVuY3Rpb25zLCBgam9icy8uKmAgbWF0Y2hlcyBhbGwgam9icywgYGNsYXNzZXMvLipgIG1hdGNoZXMgYWxsIGNsYXNzZXMsIGAuKmAgbWF0Y2hlcyBhbGwgcGF0aHMuXG4gIDpERUZBVUxUOiBbXSAqL1xuICBwYXRoczogPyhzdHJpbmdbXSk7XG4gIC8qIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFmdGVyIHdoaWNoIGEgcmVxdWVzdCByZWNvcmQgaXMgZGlzY2FyZGVkIGZyb20gdGhlIGRhdGFiYXNlLCBkZWZhdWx0cyB0byAzMDBzLlxuICA6REVGQVVMVDogMzAwICovXG4gIHR0bDogP251bWJlcjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Options/parsers.js b/lib/Options/parsers.js deleted file mode 100644 index d5bc65c7d4..0000000000 --- a/lib/Options/parsers.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; - -function numberParser(key) { - return function (opt) { - const intOpt = parseInt(opt); - - if (!Number.isInteger(intOpt)) { - throw new Error(`Key ${key} has invalid value ${opt}`); - } - - return intOpt; - }; -} - -function numberOrBoolParser(key) { - return function (opt) { - if (typeof opt === 'boolean') { - return opt; - } - - if (opt === 'true') { - return true; - } - - if (opt === 'false') { - return false; - } - - return numberParser(key)(opt); - }; -} - -function objectParser(opt) { - if (typeof opt == 'object') { - return opt; - } - - return JSON.parse(opt); -} - -function arrayParser(opt) { - if (Array.isArray(opt)) { - return opt; - } else if (typeof opt === 'string') { - return opt.split(','); - } else { - throw new Error(`${opt} should be a comma separated string or an array`); - } -} - -function moduleOrObjectParser(opt) { - if (typeof opt == 'object') { - return opt; - } - - try { - return JSON.parse(opt); - } catch (e) { - /* */ - } - - return opt; -} - -function booleanParser(opt) { - if (opt == true || opt == 'true' || opt == '1') { - return true; - } - - return false; -} - -function nullParser(opt) { - if (opt == 'null') { - return null; - } - - return opt; -} - -module.exports = { - numberParser, - numberOrBoolParser, - nullParser, - booleanParser, - moduleOrObjectParser, - arrayParser, - objectParser -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL3BhcnNlcnMuanMiXSwibmFtZXMiOlsibnVtYmVyUGFyc2VyIiwia2V5Iiwib3B0IiwiaW50T3B0IiwicGFyc2VJbnQiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJFcnJvciIsIm51bWJlck9yQm9vbFBhcnNlciIsIm9iamVjdFBhcnNlciIsIkpTT04iLCJwYXJzZSIsImFycmF5UGFyc2VyIiwiQXJyYXkiLCJpc0FycmF5Iiwic3BsaXQiLCJtb2R1bGVPck9iamVjdFBhcnNlciIsImUiLCJib29sZWFuUGFyc2VyIiwibnVsbFBhcnNlciIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkI7QUFDekIsU0FBTyxVQUFVQyxHQUFWLEVBQWU7QUFDcEIsVUFBTUMsTUFBTSxHQUFHQyxRQUFRLENBQUNGLEdBQUQsQ0FBdkI7O0FBQ0EsUUFBSSxDQUFDRyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJILE1BQWpCLENBQUwsRUFBK0I7QUFDN0IsWUFBTSxJQUFJSSxLQUFKLENBQVcsT0FBTU4sR0FBSSxzQkFBcUJDLEdBQUksRUFBOUMsQ0FBTjtBQUNEOztBQUNELFdBQU9DLE1BQVA7QUFDRCxHQU5EO0FBT0Q7O0FBRUQsU0FBU0ssa0JBQVQsQ0FBNEJQLEdBQTVCLEVBQWlDO0FBQy9CLFNBQU8sVUFBVUMsR0FBVixFQUFlO0FBQ3BCLFFBQUksT0FBT0EsR0FBUCxLQUFlLFNBQW5CLEVBQThCO0FBQzVCLGFBQU9BLEdBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssTUFBWixFQUFvQjtBQUNsQixhQUFPLElBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssT0FBWixFQUFxQjtBQUNuQixhQUFPLEtBQVA7QUFDRDs7QUFDRCxXQUFPRixZQUFZLENBQUNDLEdBQUQsQ0FBWixDQUFrQkMsR0FBbEIsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTTyxZQUFULENBQXNCUCxHQUF0QixFQUEyQjtBQUN6QixNQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFPQSxHQUFQO0FBQ0Q7O0FBQ0QsU0FBT1EsSUFBSSxDQUFDQyxLQUFMLENBQVdULEdBQVgsQ0FBUDtBQUNEOztBQUVELFNBQVNVLFdBQVQsQ0FBcUJWLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlXLEtBQUssQ0FBQ0MsT0FBTixDQUFjWixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBUDtBQUNELEdBRkQsTUFFTyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUNsQyxXQUFPQSxHQUFHLENBQUNhLEtBQUosQ0FBVSxHQUFWLENBQVA7QUFDRCxHQUZNLE1BRUE7QUFDTCxVQUFNLElBQUlSLEtBQUosQ0FBVyxHQUFFTCxHQUFJLGlEQUFqQixDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTYyxvQkFBVCxDQUE4QmQsR0FBOUIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxHQUFQLElBQWMsUUFBbEIsRUFBNEI7QUFDMUIsV0FBT0EsR0FBUDtBQUNEOztBQUNELE1BQUk7QUFDRixXQUFPUSxJQUFJLENBQUNDLEtBQUwsQ0FBV1QsR0FBWCxDQUFQO0FBQ0QsR0FGRCxDQUVFLE9BQU9lLENBQVAsRUFBVTtBQUNWO0FBQ0Q7O0FBQ0QsU0FBT2YsR0FBUDtBQUNEOztBQUVELFNBQVNnQixhQUFULENBQXVCaEIsR0FBdkIsRUFBNEI7QUFDMUIsTUFBSUEsR0FBRyxJQUFJLElBQVAsSUFBZUEsR0FBRyxJQUFJLE1BQXRCLElBQWdDQSxHQUFHLElBQUksR0FBM0MsRUFBZ0Q7QUFDOUMsV0FBTyxJQUFQO0FBQ0Q7O0FBQ0QsU0FBTyxLQUFQO0FBQ0Q7O0FBRUQsU0FBU2lCLFVBQVQsQ0FBb0JqQixHQUFwQixFQUF5QjtBQUN2QixNQUFJQSxHQUFHLElBQUksTUFBWCxFQUFtQjtBQUNqQixXQUFPLElBQVA7QUFDRDs7QUFDRCxTQUFPQSxHQUFQO0FBQ0Q7O0FBRURrQixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZnJCLEVBQUFBLFlBRGU7QUFFZlEsRUFBQUEsa0JBRmU7QUFHZlcsRUFBQUEsVUFIZTtBQUlmRCxFQUFBQSxhQUplO0FBS2ZGLEVBQUFBLG9CQUxlO0FBTWZKLEVBQUFBLFdBTmU7QUFPZkgsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIG51bWJlclBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBjb25zdCBpbnRPcHQgPSBwYXJzZUludChvcHQpO1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbnRPcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEtleSAke2tleX0gaGFzIGludmFsaWQgdmFsdWUgJHtvcHR9YCk7XG4gICAgfVxuICAgIHJldHVybiBpbnRPcHQ7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG51bWJlck9yQm9vbFBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gb3B0O1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAnZmFsc2UnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBudW1iZXJQYXJzZXIoa2V5KShvcHQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvYmplY3RQYXJzZXIob3B0KSB7XG4gIGlmICh0eXBlb2Ygb3B0ID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9wdDtcbiAgfVxuICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xufVxuXG5mdW5jdGlvbiBhcnJheVBhcnNlcihvcHQpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0KSkge1xuICAgIHJldHVybiBvcHQ7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gb3B0LnNwbGl0KCcsJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke29wdH0gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGVkIHN0cmluZyBvciBhbiBhcnJheWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vZHVsZU9yT2JqZWN0UGFyc2VyKG9wdCkge1xuICBpZiAodHlwZW9mIG9wdCA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvcHQ7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICByZXR1cm4gb3B0O1xufVxuXG5mdW5jdGlvbiBib29sZWFuUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09IHRydWUgfHwgb3B0ID09ICd0cnVlJyB8fCBvcHQgPT0gJzEnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBudWxsUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09ICdudWxsJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBvcHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBudW1iZXJQYXJzZXIsXG4gIG51bWJlck9yQm9vbFBhcnNlcixcbiAgbnVsbFBhcnNlcixcbiAgYm9vbGVhblBhcnNlcixcbiAgbW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIGFycmF5UGFyc2VyLFxuICBvYmplY3RQYXJzZXIsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/ParseMessageQueue.js b/lib/ParseMessageQueue.js deleted file mode 100644 index 3bf0e42236..0000000000 --- a/lib/ParseMessageQueue.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseMessageQueue = void 0; - -var _AdapterLoader = require("./Adapters/AdapterLoader"); - -var _EventEmitterMQ = require("./Adapters/MessageQueue/EventEmitterMQ"); - -const ParseMessageQueue = {}; -exports.ParseMessageQueue = ParseMessageQueue; - -ParseMessageQueue.createPublisher = function (config) { - const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); - - if (typeof adapter.createPublisher !== 'function') { - throw 'pubSubAdapter should have createPublisher()'; - } - - return adapter.createPublisher(config); -}; - -ParseMessageQueue.createSubscriber = function (config) { - const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); - - if (typeof adapter.createSubscriber !== 'function') { - throw 'messageQueueAdapter should have createSubscriber()'; - } - - return adapter.createSubscriber(config); -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZU1lc3NhZ2VRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQYXJzZU1lc3NhZ2VRdWV1ZSIsImNyZWF0ZVB1Ymxpc2hlciIsImNvbmZpZyIsImFkYXB0ZXIiLCJtZXNzYWdlUXVldWVBZGFwdGVyIiwiRXZlbnRFbWl0dGVyTVEiLCJjcmVhdGVTdWJzY3JpYmVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBRUEsTUFBTUEsaUJBQWlCLEdBQUcsRUFBMUI7OztBQUVBQSxpQkFBaUIsQ0FBQ0MsZUFBbEIsR0FBb0MsVUFBVUMsTUFBVixFQUE0QjtBQUM5RCxRQUFNQyxPQUFPLEdBQUcsZ0NBQVlELE1BQU0sQ0FBQ0UsbUJBQW5CLEVBQXdDQyw4QkFBeEMsRUFBd0RILE1BQXhELENBQWhCOztBQUNBLE1BQUksT0FBT0MsT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFVBQU0sNkNBQU47QUFDRDs7QUFDRCxTQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JDLE1BQXhCLENBQVA7QUFDRCxDQU5EOztBQVFBRixpQkFBaUIsQ0FBQ00sZ0JBQWxCLEdBQXFDLFVBQVVKLE1BQVYsRUFBNkI7QUFDaEUsUUFBTUMsT0FBTyxHQUFHLGdDQUFZRCxNQUFNLENBQUNFLG1CQUFuQixFQUF3Q0MsOEJBQXhDLEVBQXdESCxNQUF4RCxDQUFoQjs7QUFDQSxNQUFJLE9BQU9DLE9BQU8sQ0FBQ0csZ0JBQWYsS0FBb0MsVUFBeEMsRUFBb0Q7QUFDbEQsVUFBTSxvREFBTjtBQUNEOztBQUNELFNBQU9ILE9BQU8sQ0FBQ0csZ0JBQVIsQ0FBeUJKLE1BQXpCLENBQVA7QUFDRCxDQU5EIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyTVEgfSBmcm9tICcuL0FkYXB0ZXJzL01lc3NhZ2VRdWV1ZS9FdmVudEVtaXR0ZXJNUSc7XG5cbmNvbnN0IFBhcnNlTWVzc2FnZVF1ZXVlID0ge307XG5cblBhcnNlTWVzc2FnZVF1ZXVlLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVQdWJsaXNoZXIoKSc7XG4gIH1cbiAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG59O1xuXG5QYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVTdWJzY3JpYmVyID0gZnVuY3Rpb24gKGNvbmZpZzogYW55KTogdm9pZCB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgJ21lc3NhZ2VRdWV1ZUFkYXB0ZXIgc2hvdWxkIGhhdmUgY3JlYXRlU3Vic2NyaWJlcigpJztcbiAgfVxuICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG59O1xuXG5leHBvcnQgeyBQYXJzZU1lc3NhZ2VRdWV1ZSB9O1xuIl19 \ No newline at end of file diff --git a/lib/ParseServer.js b/lib/ParseServer.js deleted file mode 100644 index 59d9a823a6..0000000000 --- a/lib/ParseServer.js +++ /dev/null @@ -1,495 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _Options = require("./Options"); - -var _defaults = _interopRequireDefault(require("./defaults")); - -var logging = _interopRequireWildcard(require("./logger")); - -var _Config = _interopRequireDefault(require("./Config")); - -var _PromiseRouter = _interopRequireDefault(require("./PromiseRouter")); - -var _requiredParameter = _interopRequireDefault(require("./requiredParameter")); - -var _AnalyticsRouter = require("./Routers/AnalyticsRouter"); - -var _ClassesRouter = require("./Routers/ClassesRouter"); - -var _FeaturesRouter = require("./Routers/FeaturesRouter"); - -var _FilesRouter = require("./Routers/FilesRouter"); - -var _FunctionsRouter = require("./Routers/FunctionsRouter"); - -var _GlobalConfigRouter = require("./Routers/GlobalConfigRouter"); - -var _GraphQLRouter = require("./Routers/GraphQLRouter"); - -var _HooksRouter = require("./Routers/HooksRouter"); - -var _IAPValidationRouter = require("./Routers/IAPValidationRouter"); - -var _InstallationsRouter = require("./Routers/InstallationsRouter"); - -var _LogsRouter = require("./Routers/LogsRouter"); - -var _ParseLiveQueryServer = require("./LiveQuery/ParseLiveQueryServer"); - -var _PublicAPIRouter = require("./Routers/PublicAPIRouter"); - -var _PushRouter = require("./Routers/PushRouter"); - -var _CloudCodeRouter = require("./Routers/CloudCodeRouter"); - -var _RolesRouter = require("./Routers/RolesRouter"); - -var _SchemasRouter = require("./Routers/SchemasRouter"); - -var _SessionsRouter = require("./Routers/SessionsRouter"); - -var _UsersRouter = require("./Routers/UsersRouter"); - -var _PurgeRouter = require("./Routers/PurgeRouter"); - -var _AudiencesRouter = require("./Routers/AudiencesRouter"); - -var _AggregateRouter = require("./Routers/AggregateRouter"); - -var _ParseServerRESTController = require("./ParseServerRESTController"); - -var controllers = _interopRequireWildcard(require("./Controllers")); - -var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// ParseServer - open-source compatible API Server for Parse apps -var batch = require('./batch'), - bodyParser = require('body-parser'), - express = require('express'), - middlewares = require('./middlewares'), - Parse = require('parse/node').Parse, - { - parse -} = require('graphql'), - path = require('path'), - fs = require('fs'); - -// Mutate the Parse object to add the Cloud Code handlers -addParseCloud(); // ParseServer works like a constructor of an express app. -// https://parseplatform.org/parse-server/api/master/ParseServerOptions.html - -class ParseServer { - /** - * @constructor - * @param {ParseServerOptions} options the parse server initialization options - */ - constructor(options) { - injectDefaults(options); - const { - appId = (0, _requiredParameter.default)('You must provide an appId!'), - masterKey = (0, _requiredParameter.default)('You must provide a masterKey!'), - cloud, - javascriptKey, - serverURL = (0, _requiredParameter.default)('You must provide a serverURL!'), - serverStartComplete - } = options; // Initialize the node client SDK automatically - - Parse.initialize(appId, javascriptKey || 'unused', masterKey); - Parse.serverURL = serverURL; - const allControllers = controllers.getControllers(options); - const { - loggerController, - databaseController, - hooksController - } = allControllers; - this.config = _Config.default.put(Object.assign({}, options, allControllers)); - logging.setLogger(loggerController); - const dbInitPromise = databaseController.performInitialization(); - const hooksLoadPromise = hooksController.load(); // Note: Tests will start to fail if any validation happens after this is called. - - Promise.all([dbInitPromise, hooksLoadPromise]).then(() => { - if (serverStartComplete) { - serverStartComplete(); - } - }).catch(error => { - if (serverStartComplete) { - serverStartComplete(error); - } else { - console.error(error); - process.exit(1); - } - }); - - if (cloud) { - addParseCloud(); - - if (typeof cloud === 'function') { - cloud(Parse); - } else if (typeof cloud === 'string') { - require(path.resolve(process.cwd(), cloud)); - } else { - throw "argument 'cloud' must either be a string or a function"; - } - } - } - - get app() { - if (!this._app) { - this._app = ParseServer.app(this.config); - } - - return this._app; - } - - handleShutdown() { - const promises = []; - const { - adapter: databaseAdapter - } = this.config.databaseController; - - if (databaseAdapter && typeof databaseAdapter.handleShutdown === 'function') { - promises.push(databaseAdapter.handleShutdown()); - } - - const { - adapter: fileAdapter - } = this.config.filesController; - - if (fileAdapter && typeof fileAdapter.handleShutdown === 'function') { - promises.push(fileAdapter.handleShutdown()); - } - - const { - adapter: cacheAdapter - } = this.config.cacheController; - - if (cacheAdapter && typeof cacheAdapter.handleShutdown === 'function') { - promises.push(cacheAdapter.handleShutdown()); - } - - return (promises.length > 0 ? Promise.all(promises) : Promise.resolve()).then(() => { - if (this.config.serverCloseComplete) { - this.config.serverCloseComplete(); - } - }); - } - /** - * @static - * Create an express app for the parse server - * @param {Object} options let you specify the maxUploadSize when creating the express app */ - - - static app({ - maxUploadSize = '20mb', - appId, - directAccess - }) { - // This app serves the Parse API directly. - // It's the equivalent of https://api.parse.com/1 in the hosted Parse API. - var api = express(); //api.use("/apps", express.static(__dirname + "/public")); - - api.use(middlewares.allowCrossDomain(appId)); // File handling needs to be before default middlewares are applied - - api.use('/', new _FilesRouter.FilesRouter().expressRouter({ - maxUploadSize: maxUploadSize - })); - api.use('/health', function (req, res) { - res.json({ - status: 'ok' - }); - }); - api.use('/', bodyParser.urlencoded({ - extended: false - }), new _PublicAPIRouter.PublicAPIRouter().expressRouter()); - api.use(bodyParser.json({ - type: '*/*', - limit: maxUploadSize - })); - api.use(middlewares.allowMethodOverride); - api.use(middlewares.handleParseHeaders); - const appRouter = ParseServer.promiseRouter({ - appId - }); - api.use(appRouter.expressRouter()); - api.use(middlewares.handleParseErrors); // run the following when not testing - - if (!process.env.TESTING) { - //This causes tests to spew some useless warnings, so disable in test - - /* istanbul ignore next */ - process.on('uncaughtException', err => { - if (err.code === 'EADDRINUSE') { - // user-friendly message for this common error - process.stderr.write(`Unable to listen on port ${err.port}. The port is already in use.`); - process.exit(0); - } else { - throw err; - } - }); // verify the server url after a 'mount' event is received - - /* istanbul ignore next */ - - api.on('mount', function () { - ParseServer.verifyServerUrl(); - }); - } - - if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1' || directAccess) { - Parse.CoreManager.setRESTController((0, _ParseServerRESTController.ParseServerRESTController)(appId, appRouter)); - } - - return api; - } - - static promiseRouter({ - appId - }) { - const routers = [new _ClassesRouter.ClassesRouter(), new _UsersRouter.UsersRouter(), new _SessionsRouter.SessionsRouter(), new _RolesRouter.RolesRouter(), new _AnalyticsRouter.AnalyticsRouter(), new _InstallationsRouter.InstallationsRouter(), new _FunctionsRouter.FunctionsRouter(), new _SchemasRouter.SchemasRouter(), new _PushRouter.PushRouter(), new _LogsRouter.LogsRouter(), new _IAPValidationRouter.IAPValidationRouter(), new _FeaturesRouter.FeaturesRouter(), new _GlobalConfigRouter.GlobalConfigRouter(), new _GraphQLRouter.GraphQLRouter(), new _PurgeRouter.PurgeRouter(), new _HooksRouter.HooksRouter(), new _CloudCodeRouter.CloudCodeRouter(), new _AudiencesRouter.AudiencesRouter(), new _AggregateRouter.AggregateRouter()]; - const routes = routers.reduce((memo, router) => { - return memo.concat(router.routes); - }, []); - const appRouter = new _PromiseRouter.default(routes, appId); - batch.mountOnto(appRouter); - return appRouter; - } - /** - * starts the parse server's express app - * @param {ParseServerOptions} options to use to start the server - * @param {Function} callback called when the server has started - * @returns {ParseServer} the parse server instance - */ - - - start(options, callback) { - const app = express(); - - if (options.middleware) { - let middleware; - - if (typeof options.middleware == 'string') { - middleware = require(path.resolve(process.cwd(), options.middleware)); - } else { - middleware = options.middleware; // use as-is let express fail - } - - app.use(middleware); - } - - app.use(options.mountPath, this.app); - - if (options.mountGraphQL === true || options.mountPlayground === true) { - let graphQLCustomTypeDefs = undefined; - - if (typeof options.graphQLSchema === 'string') { - graphQLCustomTypeDefs = parse(fs.readFileSync(options.graphQLSchema, 'utf8')); - } else if (typeof options.graphQLSchema === 'object' || typeof options.graphQLSchema === 'function') { - graphQLCustomTypeDefs = options.graphQLSchema; - } - - const parseGraphQLServer = new _ParseGraphQLServer.ParseGraphQLServer(this, { - graphQLPath: options.graphQLPath, - playgroundPath: options.playgroundPath, - graphQLCustomTypeDefs - }); - - if (options.mountGraphQL) { - parseGraphQLServer.applyGraphQL(app); - } - - if (options.mountPlayground) { - parseGraphQLServer.applyPlayground(app); - } - } - - const server = app.listen(options.port, options.host, callback); - this.server = server; - - if (options.startLiveQueryServer || options.liveQueryServerOptions) { - this.liveQueryServer = ParseServer.createLiveQueryServer(server, options.liveQueryServerOptions, options); - } - /* istanbul ignore next */ - - - if (!process.env.TESTING) { - configureListeners(this); - } - - this.expressApp = app; - return this; - } - /** - * Creates a new ParseServer and starts it. - * @param {ParseServerOptions} options used to start the server - * @param {Function} callback called when the server has started - * @returns {ParseServer} the parse server instance - */ - - - static start(options, callback) { - const parseServer = new ParseServer(options); - return parseServer.start(options, callback); - } - /** - * Helper method to create a liveQuery server - * @static - * @param {Server} httpServer an optional http server to pass - * @param {LiveQueryServerOptions} config options for the liveQueryServer - * @param {ParseServerOptions} options options for the ParseServer - * @returns {ParseLiveQueryServer} the live query server instance - */ - - - static createLiveQueryServer(httpServer, config, options) { - if (!httpServer || config && config.port) { - var app = express(); - httpServer = require('http').createServer(app); - httpServer.listen(config.port); - } - - return new _ParseLiveQueryServer.ParseLiveQueryServer(httpServer, config, options); - } - - static verifyServerUrl(callback) { - // perform a health check on the serverURL value - if (Parse.serverURL) { - const request = require('./request'); - - request({ - url: Parse.serverURL.replace(/\/$/, '') + '/health' - }).catch(response => response).then(response => { - const json = response.data || null; - - if (response.status !== 200 || !json || json && json.status !== 'ok') { - /* eslint-disable no-console */ - console.warn(`\nWARNING, Unable to connect to '${Parse.serverURL}'.` + ` Cloud code and push notifications may be unavailable!\n`); - /* eslint-enable no-console */ - - if (callback) { - callback(false); - } - } else { - if (callback) { - callback(true); - } - } - }); - } - } - -} - -function addParseCloud() { - const ParseCloud = require('./cloud-code/Parse.Cloud'); - - Object.assign(Parse.Cloud, ParseCloud); - global.Parse = Parse; -} - -function injectDefaults(options) { - Object.keys(_defaults.default).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(options, key)) { - options[key] = _defaults.default[key]; - } - }); - - if (!Object.prototype.hasOwnProperty.call(options, 'serverURL')) { - options.serverURL = `http://localhost:${options.port}${options.mountPath}`; - } // Reserved Characters - - - if (options.appId) { - const regex = /[!#$%'()*+&/:;=?@[\]{}^,|<>]/g; - - if (options.appId.match(regex)) { - console.warn(`\nWARNING, appId that contains special characters can cause issues while using with urls.\n`); - } - } // Backwards compatibility - - - if (options.userSensitiveFields) { - /* eslint-disable no-console */ - !process.env.TESTING && console.warn(`\nDEPRECATED: userSensitiveFields has been replaced by protectedFields allowing the ability to protect fields in all classes with CLP. \n`); - /* eslint-enable no-console */ - - const userSensitiveFields = Array.from(new Set([...(_defaults.default.userSensitiveFields || []), ...(options.userSensitiveFields || [])])); // If the options.protectedFields is unset, - // it'll be assigned the default above. - // Here, protect against the case where protectedFields - // is set, but doesn't have _User. - - if (!('_User' in options.protectedFields)) { - options.protectedFields = Object.assign({ - _User: [] - }, options.protectedFields); - } - - options.protectedFields['_User']['*'] = Array.from(new Set([...(options.protectedFields['_User']['*'] || []), ...userSensitiveFields])); - } // Merge protectedFields options with defaults. - - - Object.keys(_defaults.default.protectedFields).forEach(c => { - const cur = options.protectedFields[c]; - - if (!cur) { - options.protectedFields[c] = _defaults.default.protectedFields[c]; - } else { - Object.keys(_defaults.default.protectedFields[c]).forEach(r => { - const unq = new Set([...(options.protectedFields[c][r] || []), ..._defaults.default.protectedFields[c][r]]); - options.protectedFields[c][r] = Array.from(unq); - }); - } - }); - options.masterKeyIps = Array.from(new Set(options.masterKeyIps.concat(_defaults.default.masterKeyIps, options.masterKeyIps))); -} // Those can't be tested as it requires a subprocess - -/* istanbul ignore next */ - - -function configureListeners(parseServer) { - const server = parseServer.server; - const sockets = {}; - /* Currently, express doesn't shut down immediately after receiving SIGINT/SIGTERM if it has client connections that haven't timed out. (This is a known issue with node - https://github.com/nodejs/node/issues/2642) - This function, along with `destroyAliveConnections()`, intend to fix this behavior such that parse server will close all open connections and initiate the shutdown process as soon as it receives a SIGINT/SIGTERM signal. */ - - server.on('connection', socket => { - const socketId = socket.remoteAddress + ':' + socket.remotePort; - sockets[socketId] = socket; - socket.on('close', () => { - delete sockets[socketId]; - }); - }); - - const destroyAliveConnections = function () { - for (const socketId in sockets) { - try { - sockets[socketId].destroy(); - } catch (e) { - /* */ - } - } - }; - - const handleShutdown = function () { - process.stdout.write('Termination signal received. Shutting down.'); - destroyAliveConnections(); - server.close(); - parseServer.handleShutdown(); - }; - - process.on('SIGTERM', handleShutdown); - process.on('SIGINT', handleShutdown); -} - -var _default = ParseServer; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlci5qcyJdLCJuYW1lcyI6WyJiYXRjaCIsInJlcXVpcmUiLCJib2R5UGFyc2VyIiwiZXhwcmVzcyIsIm1pZGRsZXdhcmVzIiwiUGFyc2UiLCJwYXJzZSIsInBhdGgiLCJmcyIsImFkZFBhcnNlQ2xvdWQiLCJQYXJzZVNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImluamVjdERlZmF1bHRzIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJjbG91ZCIsImphdmFzY3JpcHRLZXkiLCJzZXJ2ZXJVUkwiLCJzZXJ2ZXJTdGFydENvbXBsZXRlIiwiaW5pdGlhbGl6ZSIsImFsbENvbnRyb2xsZXJzIiwiY29udHJvbGxlcnMiLCJnZXRDb250cm9sbGVycyIsImxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJob29rc0NvbnRyb2xsZXIiLCJjb25maWciLCJDb25maWciLCJwdXQiLCJPYmplY3QiLCJhc3NpZ24iLCJsb2dnaW5nIiwic2V0TG9nZ2VyIiwiZGJJbml0UHJvbWlzZSIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsImhvb2tzTG9hZFByb21pc2UiLCJsb2FkIiwiUHJvbWlzZSIsImFsbCIsInRoZW4iLCJjYXRjaCIsImVycm9yIiwiY29uc29sZSIsInByb2Nlc3MiLCJleGl0IiwicmVzb2x2ZSIsImN3ZCIsImFwcCIsIl9hcHAiLCJoYW5kbGVTaHV0ZG93biIsInByb21pc2VzIiwiYWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInB1c2giLCJmaWxlQWRhcHRlciIsImZpbGVzQ29udHJvbGxlciIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsImxlbmd0aCIsInNlcnZlckNsb3NlQ29tcGxldGUiLCJtYXhVcGxvYWRTaXplIiwiZGlyZWN0QWNjZXNzIiwiYXBpIiwidXNlIiwiYWxsb3dDcm9zc0RvbWFpbiIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsInJlcSIsInJlcyIsImpzb24iLCJzdGF0dXMiLCJ1cmxlbmNvZGVkIiwiZXh0ZW5kZWQiLCJQdWJsaWNBUElSb3V0ZXIiLCJ0eXBlIiwibGltaXQiLCJhbGxvd01ldGhvZE92ZXJyaWRlIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiYXBwUm91dGVyIiwicHJvbWlzZVJvdXRlciIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZW52IiwiVEVTVElORyIsIm9uIiwiZXJyIiwiY29kZSIsInN0ZGVyciIsIndyaXRlIiwicG9ydCIsInZlcmlmeVNlcnZlclVybCIsIlBBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MiLCJDb3JlTWFuYWdlciIsInNldFJFU1RDb250cm9sbGVyIiwicm91dGVycyIsIkNsYXNzZXNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsIlNlc3Npb25zUm91dGVyIiwiUm9sZXNSb3V0ZXIiLCJBbmFseXRpY3NSb3V0ZXIiLCJJbnN0YWxsYXRpb25zUm91dGVyIiwiRnVuY3Rpb25zUm91dGVyIiwiU2NoZW1hc1JvdXRlciIsIlB1c2hSb3V0ZXIiLCJMb2dzUm91dGVyIiwiSUFQVmFsaWRhdGlvblJvdXRlciIsIkZlYXR1cmVzUm91dGVyIiwiR2xvYmFsQ29uZmlnUm91dGVyIiwiR3JhcGhRTFJvdXRlciIsIlB1cmdlUm91dGVyIiwiSG9va3NSb3V0ZXIiLCJDbG91ZENvZGVSb3V0ZXIiLCJBdWRpZW5jZXNSb3V0ZXIiLCJBZ2dyZWdhdGVSb3V0ZXIiLCJyb3V0ZXMiLCJyZWR1Y2UiLCJtZW1vIiwicm91dGVyIiwiY29uY2F0IiwiUHJvbWlzZVJvdXRlciIsIm1vdW50T250byIsInN0YXJ0IiwiY2FsbGJhY2siLCJtaWRkbGV3YXJlIiwibW91bnRQYXRoIiwibW91bnRHcmFwaFFMIiwibW91bnRQbGF5Z3JvdW5kIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWZzIiwidW5kZWZpbmVkIiwiZ3JhcGhRTFNjaGVtYSIsInJlYWRGaWxlU3luYyIsInBhcnNlR3JhcGhRTFNlcnZlciIsIlBhcnNlR3JhcGhRTFNlcnZlciIsImdyYXBoUUxQYXRoIiwicGxheWdyb3VuZFBhdGgiLCJhcHBseUdyYXBoUUwiLCJhcHBseVBsYXlncm91bmQiLCJzZXJ2ZXIiLCJsaXN0ZW4iLCJob3N0Iiwic3RhcnRMaXZlUXVlcnlTZXJ2ZXIiLCJsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIiwibGl2ZVF1ZXJ5U2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwiY29uZmlndXJlTGlzdGVuZXJzIiwiZXhwcmVzc0FwcCIsInBhcnNlU2VydmVyIiwiaHR0cFNlcnZlciIsImNyZWF0ZVNlcnZlciIsIlBhcnNlTGl2ZVF1ZXJ5U2VydmVyIiwicmVxdWVzdCIsInVybCIsInJlcGxhY2UiLCJyZXNwb25zZSIsImRhdGEiLCJ3YXJuIiwiUGFyc2VDbG91ZCIsIkNsb3VkIiwiZ2xvYmFsIiwia2V5cyIsImRlZmF1bHRzIiwiZm9yRWFjaCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlZ2V4IiwibWF0Y2giLCJ1c2VyU2Vuc2l0aXZlRmllbGRzIiwiQXJyYXkiLCJmcm9tIiwiU2V0IiwicHJvdGVjdGVkRmllbGRzIiwiX1VzZXIiLCJjIiwiY3VyIiwiciIsInVucSIsIm1hc3RlcktleUlwcyIsInNvY2tldHMiLCJzb2NrZXQiLCJzb2NrZXRJZCIsInJlbW90ZUFkZHJlc3MiLCJyZW1vdGVQb3J0IiwiZGVzdHJveUFsaXZlQ29ubmVjdGlvbnMiLCJkZXN0cm95IiwiZSIsInN0ZG91dCIsImNsb3NlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBV0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBekNBO0FBRUEsSUFBSUEs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QmxDLGNBQXRCO0FBQ0FOLEVBQUFBLE9BQU8sQ0FBQ3dDLEVBQVIsQ0FBVyxRQUFYLEVBQXFCbEMsY0FBckI7QUFDRDs7ZUFFY3hDLFciLCJzb3VyY2VzQ29udGVudCI6WyIvLyBQYXJzZVNlcnZlciAtIG9wZW4tc291cmNlIGNvbXBhdGlibGUgQVBJIFNlcnZlciBmb3IgUGFyc2UgYXBwc1xuXG52YXIgYmF0Y2ggPSByZXF1aXJlKCcuL2JhdGNoJyksXG4gIGJvZHlQYXJzZXIgPSByZXF1aXJlKCdib2R5LXBhcnNlcicpLFxuICBleHByZXNzID0gcmVxdWlyZSgnZXhwcmVzcycpLFxuICBtaWRkbGV3YXJlcyA9IHJlcXVpcmUoJy4vbWlkZGxld2FyZXMnKSxcbiAgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2UsXG4gIHsgcGFyc2UgfSA9IHJlcXVpcmUoJ2dyYXBocWwnKSxcbiAgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKSxcbiAgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5pbXBvcnQgeyBQYXJzZVNlcnZlck9wdGlvbnMsIExpdmVRdWVyeVNlcnZlck9wdGlvbnMgfSBmcm9tICcuL09wdGlvbnMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4vZGVmYXVsdHMnO1xuaW1wb3J0ICogYXMgbG9nZ2luZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vQ29uZmlnJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi9yZXF1aXJlZFBhcmFtZXRlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQW5hbHl0aWNzUm91dGVyJztcbmltcG9ydCB7IENsYXNzZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgeyBGZWF0dXJlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9GZWF0dXJlc1JvdXRlcic7XG5pbXBvcnQgeyBGaWxlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9GaWxlc1JvdXRlcic7XG5pbXBvcnQgeyBGdW5jdGlvbnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRnVuY3Rpb25zUm91dGVyJztcbmltcG9ydCB7IEdsb2JhbENvbmZpZ1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9HbG9iYWxDb25maWdSb3V0ZXInO1xuaW1wb3J0IHsgR3JhcGhRTFJvdXRlciB9IGZyb20gJy4vUm91dGVycy9HcmFwaFFMUm91dGVyJztcbmltcG9ydCB7IEhvb2tzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0hvb2tzUm91dGVyJztcbmltcG9ydCB7IElBUFZhbGlkYXRpb25Sb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvSUFQVmFsaWRhdGlvblJvdXRlcic7XG5pbXBvcnQgeyBJbnN0YWxsYXRpb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0luc3RhbGxhdGlvbnNSb3V0ZXInO1xuaW1wb3J0IHsgTG9nc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Mb2dzUm91dGVyJztcbmltcG9ydCB7IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIH0gZnJvbSAnLi9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXInO1xuaW1wb3J0IHsgUHVibGljQVBJUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1YmxpY0FQSVJvdXRlcic7XG5pbXBvcnQgeyBQdXNoUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1c2hSb3V0ZXInO1xuaW1wb3J0IHsgQ2xvdWRDb2RlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0Nsb3VkQ29kZVJvdXRlcic7XG5pbXBvcnQgeyBSb2xlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Sb2xlc1JvdXRlcic7XG5pbXBvcnQgeyBTY2hlbWFzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1NjaGVtYXNSb3V0ZXInO1xuaW1wb3J0IHsgU2Vzc2lvbnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvU2Vzc2lvbnNSb3V0ZXInO1xuaW1wb3J0IHsgVXNlcnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvVXNlcnNSb3V0ZXInO1xuaW1wb3J0IHsgUHVyZ2VSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUHVyZ2VSb3V0ZXInO1xuaW1wb3J0IHsgQXVkaWVuY2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0F1ZGllbmNlc1JvdXRlcic7XG5pbXBvcnQgeyBBZ2dyZWdhdGVSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQWdncmVnYXRlUm91dGVyJztcbmltcG9ydCB7IFBhcnNlU2VydmVyUkVTVENvbnRyb2xsZXIgfSBmcm9tICcuL1BhcnNlU2VydmVyUkVTVENvbnRyb2xsZXInO1xuaW1wb3J0ICogYXMgY29udHJvbGxlcnMgZnJvbSAnLi9Db250cm9sbGVycyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxTZXJ2ZXIgfSBmcm9tICcuL0dyYXBoUUwvUGFyc2VHcmFwaFFMU2VydmVyJztcblxuLy8gTXV0YXRlIHRoZSBQYXJzZSBvYmplY3QgdG8gYWRkIHRoZSBDbG91ZCBDb2RlIGhhbmRsZXJzXG5hZGRQYXJzZUNsb3VkKCk7XG5cbi8vIFBhcnNlU2VydmVyIHdvcmtzIGxpa2UgYSBjb25zdHJ1Y3RvciBvZiBhbiBleHByZXNzIGFwcC5cbi8vIGh0dHBzOi8vcGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2FwaS9tYXN0ZXIvUGFyc2VTZXJ2ZXJPcHRpb25zLmh0bWxcbmNsYXNzIFBhcnNlU2VydmVyIHtcbiAgLyoqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1BhcnNlU2VydmVyT3B0aW9uc30gb3B0aW9ucyB0aGUgcGFyc2Ugc2VydmVyIGluaXRpYWxpemF0aW9uIG9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICAgIGluamVjdERlZmF1bHRzKG9wdGlvbnMpO1xuICAgIGNvbnN0IHtcbiAgICAgIGFwcElkID0gcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYW4gYXBwSWQhJyksXG4gICAgICBtYXN0ZXJLZXkgPSByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIG1hc3RlcktleSEnKSxcbiAgICAgIGNsb3VkLFxuICAgICAgamF2YXNjcmlwdEtleSxcbiAgICAgIHNlcnZlclVSTCA9IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgc2VydmVyVVJMIScpLFxuICAgICAgc2VydmVyU3RhcnRDb21wbGV0ZSxcbiAgICB9ID0gb3B0aW9ucztcbiAgICAvLyBJbml0aWFsaXplIHRoZSBub2RlIGNsaWVudCBTREsgYXV0b21hdGljYWxseVxuICAgIFBhcnNlLmluaXRpYWxpemUoYXBwSWQsIGphdmFzY3JpcHRLZXkgfHwgJ3VudXNlZCcsIG1hc3RlcktleSk7XG4gICAgUGFyc2Uuc2VydmVyVVJMID0gc2VydmVyVVJMO1xuXG4gICAgY29uc3QgYWxsQ29udHJvbGxlcnMgPSBjb250cm9sbGVycy5nZXRDb250cm9sbGVycyhvcHRpb25zKTtcblxuICAgIGNvbnN0IHsgbG9nZ2VyQ29udHJvbGxlciwgZGF0YWJhc2VDb250cm9sbGVyLCBob29rc0NvbnRyb2xsZXIgfSA9IGFsbENvbnRyb2xsZXJzO1xuICAgIHRoaXMuY29uZmlnID0gQ29uZmlnLnB1dChPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCBhbGxDb250cm9sbGVycykpO1xuXG4gICAgbG9nZ2luZy5zZXRMb2dnZXIobG9nZ2VyQ29udHJvbGxlcik7XG4gICAgY29uc3QgZGJJbml0UHJvbWlzZSA9IGRhdGFiYXNlQ29udHJvbGxlci5wZXJmb3JtSW5pdGlhbGl6YXRpb24oKTtcbiAgICBjb25zdCBob29rc0xvYWRQcm9taXNlID0gaG9va3NDb250cm9sbGVyLmxvYWQoKTtcblxuICAgIC8vIE5vdGU6IFRlc3RzIHdpbGwgc3RhcnQgdG8gZmFpbCBpZiBhbnkgdmFsaWRhdGlvbiBoYXBwZW5zIGFmdGVyIHRoaXMgaXMgY2FsbGVkLlxuICAgIFByb21pc2UuYWxsKFtkYkluaXRQcm9taXNlLCBob29rc0xvYWRQcm9taXNlXSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHNlcnZlclN0YXJ0Q29tcGxldGUpIHtcbiAgICAgICAgICBzZXJ2ZXJTdGFydENvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoc2VydmVyU3RhcnRDb21wbGV0ZSkge1xuICAgICAgICAgIHNlcnZlclN0YXJ0Q29tcGxldGUoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZiAoY2xvdWQpIHtcbiAgICAgIGFkZFBhcnNlQ2xvdWQoKTtcbiAgICAgIGlmICh0eXBlb2YgY2xvdWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY2xvdWQoUGFyc2UpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY2xvdWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlcXVpcmUocGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGNsb3VkKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBcImFyZ3VtZW50ICdjbG91ZCcgbXVzdCBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvblwiO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBhcHAoKSB7XG4gICAgaWYgKCF0aGlzLl9hcHApIHtcbiAgICAgIHRoaXMuX2FwcCA9IFBhcnNlU2VydmVyLmFwcCh0aGlzLmNvbmZpZyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hcHA7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgIGNvbnN0IHsgYWRhcHRlcjogZGF0YWJhc2VBZGFwdGVyIH0gPSB0aGlzLmNvbmZpZy5kYXRhYmFzZUNvbnRyb2xsZXI7XG4gICAgaWYgKGRhdGFiYXNlQWRhcHRlciAmJiB0eXBlb2YgZGF0YWJhc2VBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGRhdGFiYXNlQWRhcHRlci5oYW5kbGVTaHV0ZG93bigpKTtcbiAgICB9XG4gICAgY29uc3QgeyBhZGFwdGVyOiBmaWxlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuZmlsZXNDb250cm9sbGVyO1xuICAgIGlmIChmaWxlQWRhcHRlciAmJiB0eXBlb2YgZmlsZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHByb21pc2VzLnB1c2goZmlsZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgYWRhcHRlcjogY2FjaGVBZGFwdGVyIH0gPSB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXI7XG4gICAgaWYgKGNhY2hlQWRhcHRlciAmJiB0eXBlb2YgY2FjaGVBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGNhY2hlQWRhcHRlci5oYW5kbGVTaHV0ZG93bigpKTtcbiAgICB9XG4gICAgcmV0dXJuIChwcm9taXNlcy5sZW5ndGggPiAwID8gUHJvbWlzZS5hbGwocHJvbWlzZXMpIDogUHJvbWlzZS5yZXNvbHZlKCkpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY29uZmlnLnNlcnZlckNsb3NlQ29tcGxldGUpIHtcbiAgICAgICAgdGhpcy5jb25maWcuc2VydmVyQ2xvc2VDb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQ3JlYXRlIGFuIGV4cHJlc3MgYXBwIGZvciB0aGUgcGFyc2Ugc2VydmVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGxldCB5b3Ugc3BlY2lmeSB0aGUgbWF4VXBsb2FkU2l6ZSB3aGVuIGNyZWF0aW5nIHRoZSBleHByZXNzIGFwcCAgKi9cbiAgc3RhdGljIGFwcCh7IG1heFVwbG9hZFNpemUgPSAnMjBtYicsIGFwcElkLCBkaXJlY3RBY2Nlc3MgfSkge1xuICAgIC8vIFRoaXMgYXBwIHNlcnZlcyB0aGUgUGFyc2UgQVBJIGRpcmVjdGx5LlxuICAgIC8vIEl0J3MgdGhlIGVxdWl2YWxlbnQgb2YgaHR0cHM6Ly9hcGkucGFyc2UuY29tLzEgaW4gdGhlIGhvc3RlZCBQYXJzZSBBUEkuXG4gICAgdmFyIGFwaSA9IGV4cHJlc3MoKTtcbiAgICAvL2FwaS51c2UoXCIvYXBwc1wiLCBleHByZXNzLnN0YXRpYyhfX2Rpcm5hbWUgKyBcIi9wdWJsaWNcIikpO1xuICAgIGFwaS51c2UobWlkZGxld2FyZXMuYWxsb3dDcm9zc0RvbWFpbihhcHBJZCkpO1xuICAgIC8vIEZpbGUgaGFuZGxpbmcgbmVlZHMgdG8gYmUgYmVmb3JlIGRlZmF1bHQgbWlkZGxld2FyZXMgYXJlIGFwcGxpZWRcbiAgICBhcGkudXNlKFxuICAgICAgJy8nLFxuICAgICAgbmV3IEZpbGVzUm91dGVyKCkuZXhwcmVzc1JvdXRlcih7XG4gICAgICAgIG1heFVwbG9hZFNpemU6IG1heFVwbG9hZFNpemUsXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBhcGkudXNlKCcvaGVhbHRoJywgZnVuY3Rpb24gKHJlcSwgcmVzKSB7XG4gICAgICByZXMuanNvbih7XG4gICAgICAgIHN0YXR1czogJ29rJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYXBpLnVzZSgnLycsIGJvZHlQYXJzZXIudXJsZW5jb2RlZCh7IGV4dGVuZGVkOiBmYWxzZSB9KSwgbmV3IFB1YmxpY0FQSVJvdXRlcigpLmV4cHJlc3NSb3V0ZXIoKSk7XG5cbiAgICBhcGkudXNlKGJvZHlQYXJzZXIuanNvbih7IHR5cGU6ICcqLyonLCBsaW1pdDogbWF4VXBsb2FkU2l6ZSB9KSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5hbGxvd01ldGhvZE92ZXJyaWRlKTtcbiAgICBhcGkudXNlKG1pZGRsZXdhcmVzLmhhbmRsZVBhcnNlSGVhZGVycyk7XG5cbiAgICBjb25zdCBhcHBSb3V0ZXIgPSBQYXJzZVNlcnZlci5wcm9taXNlUm91dGVyKHsgYXBwSWQgfSk7XG4gICAgYXBpLnVzZShhcHBSb3V0ZXIuZXhwcmVzc1JvdXRlcigpKTtcblxuICAgIGFwaS51c2UobWlkZGxld2FyZXMuaGFuZGxlUGFyc2VFcnJvcnMpO1xuXG4gICAgLy8gcnVuIHRoZSBmb2xsb3dpbmcgd2hlbiBub3QgdGVzdGluZ1xuICAgIGlmICghcHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgICAgLy9UaGlzIGNhdXNlcyB0ZXN0cyB0byBzcGV3IHNvbWUgdXNlbGVzcyB3YXJuaW5ncywgc28gZGlzYWJsZSBpbiB0ZXN0XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09ICdFQUREUklOVVNFJykge1xuICAgICAgICAgIC8vIHVzZXItZnJpZW5kbHkgbWVzc2FnZSBmb3IgdGhpcyBjb21tb24gZXJyb3JcbiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgVW5hYmxlIHRvIGxpc3RlbiBvbiBwb3J0ICR7ZXJyLnBvcnR9LiBUaGUgcG9ydCBpcyBhbHJlYWR5IGluIHVzZS5gKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIHZlcmlmeSB0aGUgc2VydmVyIHVybCBhZnRlciBhICdtb3VudCcgZXZlbnQgaXMgcmVjZWl2ZWRcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBhcGkub24oJ21vdW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBQYXJzZVNlcnZlci52ZXJpZnlTZXJ2ZXJVcmwoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBFUklNRU5UQUxfRElSRUNUX0FDQ0VTUyA9PT0gJzEnIHx8IGRpcmVjdEFjY2Vzcykge1xuICAgICAgUGFyc2UuQ29yZU1hbmFnZXIuc2V0UkVTVENvbnRyb2xsZXIoUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcihhcHBJZCwgYXBwUm91dGVyKSk7XG4gICAgfVxuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBzdGF0aWMgcHJvbWlzZVJvdXRlcih7IGFwcElkIH0pIHtcbiAgICBjb25zdCByb3V0ZXJzID0gW1xuICAgICAgbmV3IENsYXNzZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBVc2Vyc1JvdXRlcigpLFxuICAgICAgbmV3IFNlc3Npb25zUm91dGVyKCksXG4gICAgICBuZXcgUm9sZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBBbmFseXRpY3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBJbnN0YWxsYXRpb25zUm91dGVyKCksXG4gICAgICBuZXcgRnVuY3Rpb25zUm91dGVyKCksXG4gICAgICBuZXcgU2NoZW1hc1JvdXRlcigpLFxuICAgICAgbmV3IFB1c2hSb3V0ZXIoKSxcbiAgICAgIG5ldyBMb2dzUm91dGVyKCksXG4gICAgICBuZXcgSUFQVmFsaWRhdGlvblJvdXRlcigpLFxuICAgICAgbmV3IEZlYXR1cmVzUm91dGVyKCksXG4gICAgICBuZXcgR2xvYmFsQ29uZmlnUm91dGVyKCksXG4gICAgICBuZXcgR3JhcGhRTFJvdXRlcigpLFxuICAgICAgbmV3IFB1cmdlUm91dGVyKCksXG4gICAgICBuZXcgSG9va3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBDbG91ZENvZGVSb3V0ZXIoKSxcbiAgICAgIG5ldyBBdWRpZW5jZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBBZ2dyZWdhdGVSb3V0ZXIoKSxcbiAgICBdO1xuXG4gICAgY29uc3Qgcm91dGVzID0gcm91dGVycy5yZWR1Y2UoKG1lbW8sIHJvdXRlcikgPT4ge1xuICAgICAgcmV0dXJuIG1lbW8uY29uY2F0KHJvdXRlci5yb3V0ZXMpO1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IGFwcFJvdXRlciA9IG5ldyBQcm9taXNlUm91dGVyKHJvdXRlcywgYXBwSWQpO1xuXG4gICAgYmF0Y2gubW91bnRPbnRvKGFwcFJvdXRlcik7XG4gICAgcmV0dXJuIGFwcFJvdXRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBzdGFydHMgdGhlIHBhcnNlIHNlcnZlcidzIGV4cHJlc3MgYXBwXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIHRvIHVzZSB0byBzdGFydCB0aGUgc2VydmVyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGNhbGxlZCB3aGVuIHRoZSBzZXJ2ZXIgaGFzIHN0YXJ0ZWRcbiAgICogQHJldHVybnMge1BhcnNlU2VydmVyfSB0aGUgcGFyc2Ugc2VydmVyIGluc3RhbmNlXG4gICAqL1xuICBzdGFydChvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsIGNhbGxiYWNrOiA/KCkgPT4gdm9pZCkge1xuICAgIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcbiAgICBpZiAob3B0aW9ucy5taWRkbGV3YXJlKSB7XG4gICAgICBsZXQgbWlkZGxld2FyZTtcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5taWRkbGV3YXJlID09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1pZGRsZXdhcmUgPSByZXF1aXJlKHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBvcHRpb25zLm1pZGRsZXdhcmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pZGRsZXdhcmUgPSBvcHRpb25zLm1pZGRsZXdhcmU7IC8vIHVzZSBhcy1pcyBsZXQgZXhwcmVzcyBmYWlsXG4gICAgICB9XG4gICAgICBhcHAudXNlKG1pZGRsZXdhcmUpO1xuICAgIH1cblxuICAgIGFwcC51c2Uob3B0aW9ucy5tb3VudFBhdGgsIHRoaXMuYXBwKTtcblxuICAgIGlmIChvcHRpb25zLm1vdW50R3JhcGhRTCA9PT0gdHJ1ZSB8fCBvcHRpb25zLm1vdW50UGxheWdyb3VuZCA9PT0gdHJ1ZSkge1xuICAgICAgbGV0IGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5ncmFwaFFMU2NoZW1hID09PSAnc3RyaW5nJykge1xuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSBwYXJzZShmcy5yZWFkRmlsZVN5bmMob3B0aW9ucy5ncmFwaFFMU2NoZW1hLCAndXRmOCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdvYmplY3QnIHx8XG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSBvcHRpb25zLmdyYXBoUUxTY2hlbWE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcnNlR3JhcGhRTFNlcnZlciA9IG5ldyBQYXJzZUdyYXBoUUxTZXJ2ZXIodGhpcywge1xuICAgICAgICBncmFwaFFMUGF0aDogb3B0aW9ucy5ncmFwaFFMUGF0aCxcbiAgICAgICAgcGxheWdyb3VuZFBhdGg6IG9wdGlvbnMucGxheWdyb3VuZFBhdGgsXG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2VydmVyLmFwcGx5R3JhcGhRTChhcHApO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5tb3VudFBsYXlncm91bmQpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2VydmVyLmFwcGx5UGxheWdyb3VuZChhcHApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNlcnZlciA9IGFwcC5saXN0ZW4ob3B0aW9ucy5wb3J0LCBvcHRpb25zLmhvc3QsIGNhbGxiYWNrKTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcblxuICAgIGlmIChvcHRpb25zLnN0YXJ0TGl2ZVF1ZXJ5U2VydmVyIHx8IG9wdGlvbnMubGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucykge1xuICAgICAgdGhpcy5saXZlUXVlcnlTZXJ2ZXIgPSBQYXJzZVNlcnZlci5jcmVhdGVMaXZlUXVlcnlTZXJ2ZXIoXG4gICAgICAgIHNlcnZlcixcbiAgICAgICAgb3B0aW9ucy5saXZlUXVlcnlTZXJ2ZXJPcHRpb25zLFxuICAgICAgICBvcHRpb25zXG4gICAgICApO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmICghcHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgICAgY29uZmlndXJlTGlzdGVuZXJzKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLmV4cHJlc3NBcHAgPSBhcHA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBQYXJzZVNlcnZlciBhbmQgc3RhcnRzIGl0LlxuICAgKiBAcGFyYW0ge1BhcnNlU2VydmVyT3B0aW9uc30gb3B0aW9ucyB1c2VkIHRvIHN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHNlcnZlciBoYXMgc3RhcnRlZFxuICAgKiBAcmV0dXJucyB7UGFyc2VTZXJ2ZXJ9IHRoZSBwYXJzZSBzZXJ2ZXIgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBzdGFydChvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsIGNhbGxiYWNrOiA/KCkgPT4gdm9pZCkge1xuICAgIGNvbnN0IHBhcnNlU2VydmVyID0gbmV3IFBhcnNlU2VydmVyKG9wdGlvbnMpO1xuICAgIHJldHVybiBwYXJzZVNlcnZlci5zdGFydChvcHRpb25zLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIG1ldGhvZCB0byBjcmVhdGUgYSBsaXZlUXVlcnkgc2VydmVyXG4gICAqIEBzdGF0aWNcbiAgICogQHBhcmFtIHtTZXJ2ZXJ9IGh0dHBTZXJ2ZXIgYW4gb3B0aW9uYWwgaHR0cCBzZXJ2ZXIgdG8gcGFzc1xuICAgKiBAcGFyYW0ge0xpdmVRdWVyeVNlcnZlck9wdGlvbnN9IGNvbmZpZyBvcHRpb25zIGZvciB0aGUgbGl2ZVF1ZXJ5U2VydmVyXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIG9wdGlvbnMgZm9yIHRoZSBQYXJzZVNlcnZlclxuICAgKiBAcmV0dXJucyB7UGFyc2VMaXZlUXVlcnlTZXJ2ZXJ9IHRoZSBsaXZlIHF1ZXJ5IHNlcnZlciBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZUxpdmVRdWVyeVNlcnZlcihcbiAgICBodHRwU2VydmVyLFxuICAgIGNvbmZpZzogTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyxcbiAgICBvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnNcbiAgKSB7XG4gICAgaWYgKCFodHRwU2VydmVyIHx8IChjb25maWcgJiYgY29uZmlnLnBvcnQpKSB7XG4gICAgICB2YXIgYXBwID0gZXhwcmVzcygpO1xuICAgICAgaHR0cFNlcnZlciA9IHJlcXVpcmUoJ2h0dHAnKS5jcmVhdGVTZXJ2ZXIoYXBwKTtcbiAgICAgIGh0dHBTZXJ2ZXIubGlzdGVuKGNvbmZpZy5wb3J0KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQYXJzZUxpdmVRdWVyeVNlcnZlcihodHRwU2VydmVyLCBjb25maWcsIG9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIHZlcmlmeVNlcnZlclVybChjYWxsYmFjaykge1xuICAgIC8vIHBlcmZvcm0gYSBoZWFsdGggY2hlY2sgb24gdGhlIHNlcnZlclVSTCB2YWx1ZVxuICAgIGlmIChQYXJzZS5zZXJ2ZXJVUkwpIHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSByZXF1aXJlKCcuL3JlcXVlc3QnKTtcbiAgICAgIHJlcXVlc3QoeyB1cmw6IFBhcnNlLnNlcnZlclVSTC5yZXBsYWNlKC9cXC8kLywgJycpICsgJy9oZWFsdGgnIH0pXG4gICAgICAgIC5jYXRjaChyZXNwb25zZSA9PiByZXNwb25zZSlcbiAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgIGNvbnN0IGpzb24gPSByZXNwb25zZS5kYXRhIHx8IG51bGw7XG4gICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwIHx8ICFqc29uIHx8IChqc29uICYmIGpzb24uc3RhdHVzICE9PSAnb2snKSkge1xuICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgXFxuV0FSTklORywgVW5hYmxlIHRvIGNvbm5lY3QgdG8gJyR7UGFyc2Uuc2VydmVyVVJMfScuYCArXG4gICAgICAgICAgICAgICAgYCBDbG91ZCBjb2RlIGFuZCBwdXNoIG5vdGlmaWNhdGlvbnMgbWF5IGJlIHVuYXZhaWxhYmxlIVxcbmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICBjYWxsYmFjayhmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICBjYWxsYmFjayh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRQYXJzZUNsb3VkKCkge1xuICBjb25zdCBQYXJzZUNsb3VkID0gcmVxdWlyZSgnLi9jbG91ZC1jb2RlL1BhcnNlLkNsb3VkJyk7XG4gIE9iamVjdC5hc3NpZ24oUGFyc2UuQ2xvdWQsIFBhcnNlQ2xvdWQpO1xuICBnbG9iYWwuUGFyc2UgPSBQYXJzZTtcbn1cblxuZnVuY3Rpb24gaW5qZWN0RGVmYXVsdHMob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKSB7XG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywga2V5KSkge1xuICAgICAgb3B0aW9uc1trZXldID0gZGVmYXVsdHNba2V5XTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMsICdzZXJ2ZXJVUkwnKSkge1xuICAgIG9wdGlvbnMuc2VydmVyVVJMID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRpb25zLnBvcnR9JHtvcHRpb25zLm1vdW50UGF0aH1gO1xuICB9XG5cbiAgLy8gUmVzZXJ2ZWQgQ2hhcmFjdGVyc1xuICBpZiAob3B0aW9ucy5hcHBJZCkge1xuICAgIGNvbnN0IHJlZ2V4ID0gL1shIyQlJygpKismLzo7PT9AW1xcXXt9Xix8PD5dL2c7XG4gICAgaWYgKG9wdGlvbnMuYXBwSWQubWF0Y2gocmVnZXgpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBcXG5XQVJOSU5HLCBhcHBJZCB0aGF0IGNvbnRhaW5zIHNwZWNpYWwgY2hhcmFjdGVycyBjYW4gY2F1c2UgaXNzdWVzIHdoaWxlIHVzaW5nIHdpdGggdXJscy5cXG5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gIGlmIChvcHRpb25zLnVzZXJTZW5zaXRpdmVGaWVsZHMpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgIXByb2Nlc3MuZW52LlRFU1RJTkcgJiZcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFxcbkRFUFJFQ0FURUQ6IHVzZXJTZW5zaXRpdmVGaWVsZHMgaGFzIGJlZW4gcmVwbGFjZWQgYnkgcHJvdGVjdGVkRmllbGRzIGFsbG93aW5nIHRoZSBhYmlsaXR5IHRvIHByb3RlY3QgZmllbGRzIGluIGFsbCBjbGFzc2VzIHdpdGggQ0xQLiBcXG5gXG4gICAgICApO1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuXG4gICAgY29uc3QgdXNlclNlbnNpdGl2ZUZpZWxkcyA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4oZGVmYXVsdHMudXNlclNlbnNpdGl2ZUZpZWxkcyB8fCBbXSksIC4uLihvcHRpb25zLnVzZXJTZW5zaXRpdmVGaWVsZHMgfHwgW10pXSlcbiAgICApO1xuXG4gICAgLy8gSWYgdGhlIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzIGlzIHVuc2V0LFxuICAgIC8vIGl0J2xsIGJlIGFzc2lnbmVkIHRoZSBkZWZhdWx0IGFib3ZlLlxuICAgIC8vIEhlcmUsIHByb3RlY3QgYWdhaW5zdCB0aGUgY2FzZSB3aGVyZSBwcm90ZWN0ZWRGaWVsZHNcbiAgICAvLyBpcyBzZXQsIGJ1dCBkb2Vzbid0IGhhdmUgX1VzZXIuXG4gICAgaWYgKCEoJ19Vc2VyJyBpbiBvcHRpb25zLnByb3RlY3RlZEZpZWxkcykpIHtcbiAgICAgIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzID0gT2JqZWN0LmFzc2lnbih7IF9Vc2VyOiBbXSB9LCBvcHRpb25zLnByb3RlY3RlZEZpZWxkcyk7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbJ19Vc2VyJ11bJyonXSA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4ob3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbJ19Vc2VyJ11bJyonXSB8fCBbXSksIC4uLnVzZXJTZW5zaXRpdmVGaWVsZHNdKVxuICAgICk7XG4gIH1cblxuICAvLyBNZXJnZSBwcm90ZWN0ZWRGaWVsZHMgb3B0aW9ucyB3aXRoIGRlZmF1bHRzLlxuICBPYmplY3Qua2V5cyhkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHMpLmZvckVhY2goYyA9PiB7XG4gICAgY29uc3QgY3VyID0gb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY107XG4gICAgaWYgKCFjdXIpIHtcbiAgICAgIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzW2NdID0gZGVmYXVsdHMucHJvdGVjdGVkRmllbGRzW2NdO1xuICAgIH0gZWxzZSB7XG4gICAgICBPYmplY3Qua2V5cyhkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY10pLmZvckVhY2gociA9PiB7XG4gICAgICAgIGNvbnN0IHVucSA9IG5ldyBTZXQoW1xuICAgICAgICAgIC4uLihvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXVtyXSB8fCBbXSksXG4gICAgICAgICAgLi4uZGVmYXVsdHMucHJvdGVjdGVkRmllbGRzW2NdW3JdLFxuICAgICAgICBdKTtcbiAgICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY11bcl0gPSBBcnJheS5mcm9tKHVucSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIG9wdGlvbnMubWFzdGVyS2V5SXBzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KG9wdGlvbnMubWFzdGVyS2V5SXBzLmNvbmNhdChkZWZhdWx0cy5tYXN0ZXJLZXlJcHMsIG9wdGlvbnMubWFzdGVyS2V5SXBzKSlcbiAgKTtcbn1cblxuLy8gVGhvc2UgY2FuJ3QgYmUgdGVzdGVkIGFzIGl0IHJlcXVpcmVzIGEgc3VicHJvY2Vzc1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGNvbmZpZ3VyZUxpc3RlbmVycyhwYXJzZVNlcnZlcikge1xuICBjb25zdCBzZXJ2ZXIgPSBwYXJzZVNlcnZlci5zZXJ2ZXI7XG4gIGNvbnN0IHNvY2tldHMgPSB7fTtcbiAgLyogQ3VycmVudGx5LCBleHByZXNzIGRvZXNuJ3Qgc2h1dCBkb3duIGltbWVkaWF0ZWx5IGFmdGVyIHJlY2VpdmluZyBTSUdJTlQvU0lHVEVSTSBpZiBpdCBoYXMgY2xpZW50IGNvbm5lY3Rpb25zIHRoYXQgaGF2ZW4ndCB0aW1lZCBvdXQuIChUaGlzIGlzIGEga25vd24gaXNzdWUgd2l0aCBub2RlIC0gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2lzc3Vlcy8yNjQyKVxuICAgIFRoaXMgZnVuY3Rpb24sIGFsb25nIHdpdGggYGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zKClgLCBpbnRlbmQgdG8gZml4IHRoaXMgYmVoYXZpb3Igc3VjaCB0aGF0IHBhcnNlIHNlcnZlciB3aWxsIGNsb3NlIGFsbCBvcGVuIGNvbm5lY3Rpb25zIGFuZCBpbml0aWF0ZSB0aGUgc2h1dGRvd24gcHJvY2VzcyBhcyBzb29uIGFzIGl0IHJlY2VpdmVzIGEgU0lHSU5UL1NJR1RFUk0gc2lnbmFsLiAqL1xuICBzZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCBzb2NrZXQgPT4ge1xuICAgIGNvbnN0IHNvY2tldElkID0gc29ja2V0LnJlbW90ZUFkZHJlc3MgKyAnOicgKyBzb2NrZXQucmVtb3RlUG9ydDtcbiAgICBzb2NrZXRzW3NvY2tldElkXSA9IHNvY2tldDtcbiAgICBzb2NrZXQub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgZGVsZXRlIHNvY2tldHNbc29ja2V0SWRdO1xuICAgIH0pO1xuICB9KTtcblxuICBjb25zdCBkZXN0cm95QWxpdmVDb25uZWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKGNvbnN0IHNvY2tldElkIGluIHNvY2tldHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNvY2tldHNbc29ja2V0SWRdLmRlc3Ryb3koKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogKi9cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlU2h1dGRvd24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoJ1Rlcm1pbmF0aW9uIHNpZ25hbCByZWNlaXZlZC4gU2h1dHRpbmcgZG93bi4nKTtcbiAgICBkZXN0cm95QWxpdmVDb25uZWN0aW9ucygpO1xuICAgIHNlcnZlci5jbG9zZSgpO1xuICAgIHBhcnNlU2VydmVyLmhhbmRsZVNodXRkb3duKCk7XG4gIH07XG4gIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBoYW5kbGVTaHV0ZG93bik7XG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsIGhhbmRsZVNodXRkb3duKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/ParseServerRESTController.js b/lib/ParseServerRESTController.js deleted file mode 100644 index 9602de13a6..0000000000 --- a/lib/ParseServerRESTController.js +++ /dev/null @@ -1,184 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseServerRESTController = ParseServerRESTController; -exports.default = void 0; - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const Config = require('./Config'); - -const Auth = require('./Auth'); - -const RESTController = require('parse/lib/node/RESTController'); - -const URL = require('url'); - -const Parse = require('parse/node'); - -function getSessionToken(options) { - if (options && typeof options.sessionToken === 'string') { - return Promise.resolve(options.sessionToken); - } - - return Promise.resolve(null); -} - -function getAuth(options = {}, config) { - const installationId = options.installationId || 'cloud'; - - if (options.useMasterKey) { - return Promise.resolve(new Auth.Auth({ - config, - isMaster: true, - installationId - })); - } - - return getSessionToken(options).then(sessionToken => { - if (sessionToken) { - options.sessionToken = sessionToken; - return Auth.getAuthForSessionToken({ - config, - sessionToken: sessionToken, - installationId - }); - } else { - return Promise.resolve(new Auth.Auth({ - config, - installationId - })); - } - }); -} - -function ParseServerRESTController(applicationId, router) { - function handleRequest(method, path, data = {}, options = {}, config) { - // Store the arguments, for later use if internal fails - const args = arguments; - - if (!config) { - config = Config.get(applicationId); - } - - const serverURL = URL.parse(config.serverURL); - - if (path.indexOf(serverURL.path) === 0) { - path = path.slice(serverURL.path.length, path.length); - } - - if (path[0] !== '/') { - path = '/' + path; - } - - if (path === '/batch') { - let initialPromise = Promise.resolve(); - - if (data.transaction === true) { - initialPromise = config.database.createTransactionalSession(); - } - - return initialPromise.then(() => { - const promises = data.requests.map(request => { - return handleRequest(request.method, request.path, request.body, options, config).then(response => { - if (options.returnStatus) { - const status = response._status; - delete response._status; - return { - success: response, - _status: status - }; - } - - return { - success: response - }; - }, error => { - return { - error: { - code: error.code, - error: error.message - } - }; - }); - }); - return Promise.all(promises).then(result => { - if (data.transaction === true) { - if (result.find(resultItem => typeof resultItem.error === 'object')) { - return config.database.abortTransactionalSession().then(() => { - return Promise.reject(result); - }); - } else { - return config.database.commitTransactionalSession().then(() => { - return result; - }); - } - } else { - return result; - } - }); - }); - } - - let query; - - if (method === 'GET') { - query = data; - } - - return new Promise((resolve, reject) => { - getAuth(options, config).then(auth => { - const request = { - body: data, - config, - auth, - info: { - applicationId: applicationId, - sessionToken: options.sessionToken, - installationId: options.installationId, - context: options.context || {} // Add context - - }, - query - }; - return Promise.resolve().then(() => { - return router.tryRouteRequest(method, path, request); - }).then(resp => { - const { - response, - status - } = resp; - - if (options.returnStatus) { - resolve(_objectSpread(_objectSpread({}, response), {}, { - _status: status - })); - } else { - resolve(response); - } - }, err => { - if (err instanceof Parse.Error && err.code == Parse.Error.INVALID_JSON && err.message == `cannot route ${method} ${path}`) { - RESTController.request.apply(null, args).then(resolve, reject); - } else { - reject(err); - } - }); - }, reject); - }); - } - - return { - request: handleRequest, - ajax: RESTController.ajax - }; -} - -var _default = ParseServerRESTController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkNvbmZpZyIsInJlcXVpcmUiLCJBdXRoIiwiUkVTVENvbnRyb2xsZXIiLCJVUkwiLCJQYXJzZSIsImdldFNlc3Npb25Ub2tlbiIsIm9wdGlvbnMiLCJzZXNzaW9uVG9rZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldEF1dGgiLCJjb25maWciLCJpbnN0YWxsYXRpb25JZCIsInVzZU1hc3RlcktleSIsImlzTWFzdGVyIiwidGhlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIiwiYXBwbGljYXRpb25JZCIsInJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJtZXRob2QiLCJwYXRoIiwiZGF0YSIsImFyZ3MiLCJhcmd1bWVudHMiLCJnZXQiLCJzZXJ2ZXJVUkwiLCJwYXJzZSIsImluZGV4T2YiLCJzbGljZSIsImxlbmd0aCIsImluaXRpYWxQcm9taXNlIiwidHJhbnNhY3Rpb24iLCJkYXRhYmFzZSIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwicHJvbWlzZXMiLCJyZXF1ZXN0cyIsIm1hcCIsInJlcXVlc3QiLCJib2R5IiwicmVzcG9uc2UiLCJyZXR1cm5TdGF0dXMiLCJzdGF0dXMiLCJfc3RhdHVzIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHQiLCJmaW5kIiwicmVzdWx0SXRlbSIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInF1ZXJ5IiwiYXV0aCIsImluZm8iLCJjb250ZXh0IiwidHJ5Um91dGVSZXF1ZXN0IiwicmVzcCIsImVyciIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiYXBwbHkiLCJhamF4Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FB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SUFBSSxFQUFFaEUsY0FBYyxDQUFDZ0U7QUFGaEIsR0FBUDtBQUlEOztlQUVjakQseUIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBDb25maWcgPSByZXF1aXJlKCcuL0NvbmZpZycpO1xuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xuY29uc3QgUkVTVENvbnRyb2xsZXIgPSByZXF1aXJlKCdwYXJzZS9saWIvbm9kZS9SRVNUQ29udHJvbGxlcicpO1xuY29uc3QgVVJMID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcblxuZnVuY3Rpb24gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuc2Vzc2lvblRva2VuID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUob3B0aW9ucy5zZXNzaW9uVG9rZW4pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG59XG5cbmZ1bmN0aW9uIGdldEF1dGgob3B0aW9ucyA9IHt9LCBjb25maWcpIHtcbiAgY29uc3QgaW5zdGFsbGF0aW9uSWQgPSBvcHRpb25zLmluc3RhbGxhdGlvbklkIHx8ICdjbG91ZCc7XG4gIGlmIChvcHRpb25zLnVzZU1hc3RlcktleSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEF1dGguQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgfVxuICByZXR1cm4gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpLnRoZW4oc2Vzc2lvblRva2VuID0+IHtcbiAgICBpZiAoc2Vzc2lvblRva2VuKSB7XG4gICAgICBvcHRpb25zLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICAgIHJldHVybiBBdXRoLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgICBjb25maWcsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBBdXRoLkF1dGgoeyBjb25maWcsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcGxpY2F0aW9uSWQsIHJvdXRlcikge1xuICBmdW5jdGlvbiBoYW5kbGVSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgZGF0YSA9IHt9LCBvcHRpb25zID0ge30sIGNvbmZpZykge1xuICAgIC8vIFN0b3JlIHRoZSBhcmd1bWVudHMsIGZvciBsYXRlciB1c2UgaWYgaW50ZXJuYWwgZmFpbHNcbiAgICBjb25zdCBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgfVxuICAgIGNvbnN0IHNlcnZlclVSTCA9IFVSTC5wYXJzZShjb25maWcuc2VydmVyVVJMKTtcbiAgICBpZiAocGF0aC5pbmRleE9mKHNlcnZlclVSTC5wYXRoKSA9PT0gMCkge1xuICAgICAgcGF0aCA9IHBhdGguc2xpY2Uoc2VydmVyVVJMLnBhdGgubGVuZ3RoLCBwYXRoLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKHBhdGhbMF0gIT09ICcvJykge1xuICAgICAgcGF0aCA9ICcvJyArIHBhdGg7XG4gICAgfVxuXG4gICAgaWYgKHBhdGggPT09ICcvYmF0Y2gnKSB7XG4gICAgICBsZXQgaW5pdGlhbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgIGluaXRpYWxQcm9taXNlID0gY29uZmlnLmRhdGFiYXNlLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW5pdGlhbFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gZGF0YS5yZXF1ZXN0cy5tYXAocmVxdWVzdCA9PiB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZVJlcXVlc3QocmVxdWVzdC5tZXRob2QsIHJlcXVlc3QucGF0aCwgcmVxdWVzdC5ib2R5LCBvcHRpb25zLCBjb25maWcpLnRoZW4oXG4gICAgICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLnJldHVyblN0YXR1cykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogcmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHJlc3BvbnNlIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVycm9yOiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0sXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmZpbmQocmVzdWx0SXRlbSA9PiB0eXBlb2YgcmVzdWx0SXRlbS5lcnJvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHF1ZXJ5O1xuICAgIGlmIChtZXRob2QgPT09ICdHRVQnKSB7XG4gICAgICBxdWVyeSA9IGRhdGE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGdldEF1dGgob3B0aW9ucywgY29uZmlnKS50aGVuKGF1dGggPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgaW5mbzoge1xuICAgICAgICAgICAgYXBwbGljYXRpb25JZDogYXBwbGljYXRpb25JZCxcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogb3B0aW9ucy5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICBpbnN0YWxsYXRpb25JZDogb3B0aW9ucy5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIGNvbnRleHQ6IG9wdGlvbnMuY29udGV4dCB8fCB7fSwgLy8gQWRkIGNvbnRleHRcbiAgICAgICAgICB9LFxuICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcm91dGVyLnRyeVJvdXRlUmVxdWVzdChtZXRob2QsIHBhdGgsIHJlcXVlc3QpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICByZXNwID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgeyByZXNwb25zZSwgc3RhdHVzIH0gPSByZXNwO1xuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5yZXR1cm5TdGF0dXMpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHsgLi4ucmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBQYXJzZS5FcnJvciAmJlxuICAgICAgICAgICAgICAgIGVyci5jb2RlID09IFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiAmJlxuICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IGBjYW5ub3Qgcm91dGUgJHttZXRob2R9ICR7cGF0aH1gXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIFJFU1RDb250cm9sbGVyLnJlcXVlc3QuYXBwbHkobnVsbCwgYXJncykudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgIH0sIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHJlcXVlc3Q6IGhhbmRsZVJlcXVlc3QsXG4gICAgYWpheDogUkVTVENvbnRyb2xsZXIuYWpheCxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcjtcbmV4cG9ydCB7IFBhcnNlU2VydmVyUkVTVENvbnRyb2xsZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/PromiseRouter.js b/lib/PromiseRouter.js deleted file mode 100644 index 71f2d5ea39..0000000000 --- a/lib/PromiseRouter.js +++ /dev/null @@ -1,255 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _express = _interopRequireDefault(require("express")); - -var _logger = _interopRequireDefault(require("./logger")); - -var _util = require("util"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// A router that is based on promises rather than req/res/next. -// This is intended to replace the use of express.Router to handle -// subsections of the API surface. -// This will make it easier to have methods like 'batch' that -// themselves use our routing information, without disturbing express -// components that external developers may be modifying. -const Layer = require('express/lib/router/layer'); - -function validateParameter(key, value) { - if (key == 'className') { - if (value.match(/_?[A-Za-z][A-Za-z_0-9]*/)) { - return value; - } - } else if (key == 'objectId') { - if (value.match(/[A-Za-z0-9]+/)) { - return value; - } - } else { - return value; - } -} - -class PromiseRouter { - // Each entry should be an object with: - // path: the path to route, in express format - // method: the HTTP method that this route handles. - // Must be one of: POST, GET, PUT, DELETE - // handler: a function that takes request, and returns a promise. - // Successful handlers should resolve to an object with fields: - // status: optional. the http status code. defaults to 200 - // response: a json object with the content of the response - // location: optional. a location header - constructor(routes = [], appId) { - this.routes = routes; - this.appId = appId; - this.mountRoutes(); - } // Leave the opportunity to - // subclasses to mount their routes by overriding - - - mountRoutes() {} // Merge the routes into this one - - - merge(router) { - for (var route of router.routes) { - this.routes.push(route); - } - } - - route(method, path, ...handlers) { - switch (method) { - case 'POST': - case 'GET': - case 'PUT': - case 'DELETE': - break; - - default: - throw 'cannot route method: ' + method; - } - - let handler = handlers[0]; - - if (handlers.length > 1) { - handler = function (req) { - return handlers.reduce((promise, handler) => { - return promise.then(() => { - return handler(req); - }); - }, Promise.resolve()); - }; - } - - this.routes.push({ - path: path, - method: method, - handler: handler, - layer: new Layer(path, null, handler) - }); - } // Returns an object with: - // handler: the handler that should deal with this request - // params: any :-params that got parsed from the path - // Returns undefined if there is no match. - - - match(method, path) { - for (var route of this.routes) { - if (route.method != method) { - continue; - } - - const layer = route.layer || new Layer(route.path, null, route.handler); - const match = layer.match(path); - - if (match) { - const params = layer.params; - Object.keys(params).forEach(key => { - params[key] = validateParameter(key, params[key]); - }); - return { - params: params, - handler: route.handler - }; - } - } - } // Mount the routes on this router onto an express app (or express router) - - - mountOnto(expressApp) { - this.routes.forEach(route => { - const method = route.method.toLowerCase(); - const handler = makeExpressHandler(this.appId, route.handler); - expressApp[method].call(expressApp, route.path, handler); - }); - return expressApp; - } - - expressRouter() { - return this.mountOnto(_express.default.Router()); - } - - tryRouteRequest(method, path, request) { - var match = this.match(method, path); - - if (!match) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'cannot route ' + method + ' ' + path); - } - - request.params = match.params; - return new Promise((resolve, reject) => { - match.handler(request).then(resolve, reject); - }); - } - -} // A helper function to make an express handler out of a a promise -// handler. -// Express handlers should never throw; if a promise handler throws we -// just treat it like it resolved to an error. - - -exports.default = PromiseRouter; - -function makeExpressHandler(appId, promiseHandler) { - return function (req, res, next) { - try { - const url = maskSensitiveUrl(req); - const body = Object.assign({}, req.body); - const method = req.method; - const headers = req.headers; - - _logger.default.logRequest({ - method, - url, - headers, - body - }); - - promiseHandler(req).then(result => { - clearSchemaCache(req); - - if (!result.response && !result.location && !result.text) { - _logger.default.error('the handler did not include a "response" or a "location" field'); - - throw 'control should not get here'; - } - - _logger.default.logResponse({ - method, - url, - result - }); - - var status = result.status || 200; - res.status(status); - - if (result.text) { - res.send(result.text); - return; - } - - if (result.location) { - res.set('Location', result.location); // Override the default expressjs response - // as it double encodes %encoded chars in URL - - if (!result.response) { - res.send('Found. Redirecting to ' + result.location); - return; - } - } - - if (result.headers) { - Object.keys(result.headers).forEach(header => { - res.set(header, result.headers[header]); - }); - } - - res.json(result.response); - }, error => { - clearSchemaCache(req); - next(error); - }).catch(e => { - clearSchemaCache(req); - - _logger.default.error(`Error generating response. ${(0, _util.inspect)(e)}`, { - error: e - }); - - next(e); - }); - } catch (e) { - clearSchemaCache(req); - - _logger.default.error(`Error handling request: ${(0, _util.inspect)(e)}`, { - error: e - }); - - next(e); - } - }; -} - -function maskSensitiveUrl(req) { - let maskUrl = req.originalUrl.toString(); - const shouldMaskUrl = req.method === 'GET' && req.originalUrl.includes('/login') && !req.originalUrl.includes('classes'); - - if (shouldMaskUrl) { - maskUrl = _logger.default.maskSensitiveUrl(maskUrl); - } - - return maskUrl; -} - -function clearSchemaCache(req) { - if (req.config && !req.config.enableSingleSchemaCache) { - req.config.database.schemaCache.clear(); - } -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Qcm9taXNlUm91dGVyLmpzIl0sIm5hbWVzIjpbIkxheWVyIiwicmVxdWlyZSIsInZhbGlkYXRlUGFyYW1ldGVyIiwia2V5IiwidmFsdWUiLCJtYXRjaCIsIlByb21pc2VSb3V0ZXIiLCJjb25zdHJ1Y3RvciIsInJvdXRlcyIsImFwcElkIiwibW91bnRSb3V0ZXMiLCJtZXJnZSIsInJvdXRlciIsInJvdXRlIiwicHVzaCIsIm1ldGhvZCIsInBhdGgiLCJoYW5kbGVycyIsImhhbmRsZXIiLCJsZW5ndGgiLCJyZXEiLCJyZWR1Y2UiLCJwcm9taXNlIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwibGF5ZXIiLCJwYXJhbXMiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsIm1vdW50T250byIsImV4cHJlc3NBcHAiLCJ0b0xvd2VyQ2FzZSIsIm1ha2VFeHByZXNzSGFuZGxlciIsImNhbGwiLCJleHByZXNzUm91dGVyIiwiZXhwcmVzcyIsIlJvdXRlciIsInRyeVJvdXRlUmVxdWVzdCIsInJlcXVlc3QiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicmVqZWN0IiwicHJvbWlzZUhhbmRsZXIiLCJyZXMiLCJuZXh0IiwidXJsIiwibWFza1NlbnNpdGl2ZVVybCIsImJvZHkiLCJhc3NpZ24iLCJoZWFkZXJzIiwibG9nIiwibG9nUmVxdWVzdCIsInJlc3VsdCIsImNsZWFyU2NoZW1hQ2FjaGUiLCJyZXNwb25zZSIsImxvY2F0aW9uIiwidGV4dCIsImVycm9yIiwibG9nUmVzcG9uc2UiLCJzdGF0dXMiLCJzZW5kIiwic2V0IiwiaGVhZGVyIiwianNvbiIsImNhdGNoIiwiZSIsIm1hc2tVcmwiLCJvcmlnaW5hbFVybCIsInRvU3RyaW5nIiwic2hvdWxkTWFza1VybCIsImluY2x1ZGVzIiwiY29uZmlnIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkYXRhYmFzZSIsInNjaGVtYUNhY2hlIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7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Z0JHLFFBQWhCLENBQXlCLFNBQXpCLENBSEg7O0FBSUEsTUFBSUQsYUFBSixFQUFtQjtBQUNqQkgsSUFBQUEsT0FBTyxHQUFHaEIsZ0JBQUlKLGdCQUFKLENBQXFCb0IsT0FBckIsQ0FBVjtBQUNEOztBQUNELFNBQU9BLE9BQVA7QUFDRDs7QUFFRCxTQUFTYixnQkFBVCxDQUEwQnBDLEdBQTFCLEVBQStCO0FBQzdCLE1BQUlBLEdBQUcsQ0FBQ3NELE1BQUosSUFBYyxDQUFDdEQsR0FBRyxDQUFDc0QsTUFBSixDQUFXQyx1QkFBOUIsRUFBdUQ7QUFDckR2RCxJQUFBQSxHQUFHLENBQUNzRCxNQUFKLENBQVdFLFFBQVgsQ0FBb0JDLFdBQXBCLENBQWdDQyxLQUFoQztBQUNEO0FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIHJvdXRlciB0aGF0IGlzIGJhc2VkIG9uIHByb21pc2VzIHJhdGhlciB0aGFuIHJlcS9yZXMvbmV4dC5cbi8vIFRoaXMgaXMgaW50ZW5kZWQgdG8gcmVwbGFjZSB0aGUgdXNlIG9mIGV4cHJlc3MuUm91dGVyIHRvIGhhbmRsZVxuLy8gc3Vic2VjdGlvbnMgb2YgdGhlIEFQSSBzdXJmYWNlLlxuLy8gVGhpcyB3aWxsIG1ha2UgaXQgZWFzaWVyIHRvIGhhdmUgbWV0aG9kcyBsaWtlICdiYXRjaCcgdGhhdFxuLy8gdGhlbXNlbHZlcyB1c2Ugb3VyIHJvdXRpbmcgaW5mb3JtYXRpb24sIHdpdGhvdXQgZGlzdHVyYmluZyBleHByZXNzXG4vLyBjb21wb25lbnRzIHRoYXQgZXh0ZXJuYWwgZGV2ZWxvcGVycyBtYXkgYmUgbW9kaWZ5aW5nLlxuXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgaW5zcGVjdCB9IGZyb20gJ3V0aWwnO1xuY29uc3QgTGF5ZXIgPSByZXF1aXJlKCdleHByZXNzL2xpYi9yb3V0ZXIvbGF5ZXInKTtcblxuZnVuY3Rpb24gdmFsaWRhdGVQYXJhbWV0ZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5ID09ICdjbGFzc05hbWUnKSB7XG4gICAgaWYgKHZhbHVlLm1hdGNoKC9fP1tBLVphLXpdW0EtWmEtel8wLTldKi8pKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9IGVsc2UgaWYgKGtleSA9PSAnb2JqZWN0SWQnKSB7XG4gICAgaWYgKHZhbHVlLm1hdGNoKC9bQS1aYS16MC05XSsvKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvbWlzZVJvdXRlciB7XG4gIC8vIEVhY2ggZW50cnkgc2hvdWxkIGJlIGFuIG9iamVjdCB3aXRoOlxuICAvLyBwYXRoOiB0aGUgcGF0aCB0byByb3V0ZSwgaW4gZXhwcmVzcyBmb3JtYXRcbiAgLy8gbWV0aG9kOiB0aGUgSFRUUCBtZXRob2QgdGhhdCB0aGlzIHJvdXRlIGhhbmRsZXMuXG4gIC8vICAgTXVzdCBiZSBvbmUgb2Y6IFBPU1QsIEdFVCwgUFVULCBERUxFVEVcbiAgLy8gaGFuZGxlcjogYSBmdW5jdGlvbiB0aGF0IHRha2VzIHJlcXVlc3QsIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAgLy8gICBTdWNjZXNzZnVsIGhhbmRsZXJzIHNob3VsZCByZXNvbHZlIHRvIGFuIG9iamVjdCB3aXRoIGZpZWxkczpcbiAgLy8gICAgIHN0YXR1czogb3B0aW9uYWwuIHRoZSBodHRwIHN0YXR1cyBjb2RlLiBkZWZhdWx0cyB0byAyMDBcbiAgLy8gICAgIHJlc3BvbnNlOiBhIGpzb24gb2JqZWN0IHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIHJlc3BvbnNlXG4gIC8vICAgICBsb2NhdGlvbjogb3B0aW9uYWwuIGEgbG9jYXRpb24gaGVhZGVyXG4gIGNvbnN0cnVjdG9yKHJvdXRlcyA9IFtdLCBhcHBJZCkge1xuICAgIHRoaXMucm91dGVzID0gcm91dGVzO1xuICAgIHRoaXMuYXBwSWQgPSBhcHBJZDtcbiAgICB0aGlzLm1vdW50Um91dGVzKCk7XG4gIH1cblxuICAvLyBMZWF2ZSB0aGUgb3Bwb3J0dW5pdHkgdG9cbiAgLy8gc3ViY2xhc3NlcyB0byBtb3VudCB0aGVpciByb3V0ZXMgYnkgb3ZlcnJpZGluZ1xuICBtb3VudFJvdXRlcygpIHt9XG5cbiAgLy8gTWVyZ2UgdGhlIHJvdXRlcyBpbnRvIHRoaXMgb25lXG4gIG1lcmdlKHJvdXRlcikge1xuICAgIGZvciAodmFyIHJvdXRlIG9mIHJvdXRlci5yb3V0ZXMpIHtcbiAgICAgIHRoaXMucm91dGVzLnB1c2gocm91dGUpO1xuICAgIH1cbiAgfVxuXG4gIHJvdXRlKG1ldGhvZCwgcGF0aCwgLi4uaGFuZGxlcnMpIHtcbiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgY2FzZSAnUE9TVCc6XG4gICAgICBjYXNlICdHRVQnOlxuICAgICAgY2FzZSAnUFVUJzpcbiAgICAgIGNhc2UgJ0RFTEVURSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgJ2Nhbm5vdCByb3V0ZSBtZXRob2Q6ICcgKyBtZXRob2Q7XG4gICAgfVxuXG4gICAgbGV0IGhhbmRsZXIgPSBoYW5kbGVyc1swXTtcblxuICAgIGlmIChoYW5kbGVycy5sZW5ndGggPiAxKSB7XG4gICAgICBoYW5kbGVyID0gZnVuY3Rpb24gKHJlcSkge1xuICAgICAgICByZXR1cm4gaGFuZGxlcnMucmVkdWNlKChwcm9taXNlLCBoYW5kbGVyKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXEpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9LCBQcm9taXNlLnJlc29sdmUoKSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucm91dGVzLnB1c2goe1xuICAgICAgcGF0aDogcGF0aCxcbiAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgaGFuZGxlcjogaGFuZGxlcixcbiAgICAgIGxheWVyOiBuZXcgTGF5ZXIocGF0aCwgbnVsbCwgaGFuZGxlciksXG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGFuIG9iamVjdCB3aXRoOlxuICAvLyAgIGhhbmRsZXI6IHRoZSBoYW5kbGVyIHRoYXQgc2hvdWxkIGRlYWwgd2l0aCB0aGlzIHJlcXVlc3RcbiAgLy8gICBwYXJhbXM6IGFueSA6LXBhcmFtcyB0aGF0IGdvdCBwYXJzZWQgZnJvbSB0aGUgcGF0aFxuICAvLyBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBubyBtYXRjaC5cbiAgbWF0Y2gobWV0aG9kLCBwYXRoKSB7XG4gICAgZm9yICh2YXIgcm91dGUgb2YgdGhpcy5yb3V0ZXMpIHtcbiAgICAgIGlmIChyb3V0ZS5tZXRob2QgIT0gbWV0aG9kKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbGF5ZXIgPSByb3V0ZS5sYXllciB8fCBuZXcgTGF5ZXIocm91dGUucGF0aCwgbnVsbCwgcm91dGUuaGFuZGxlcik7XG4gICAgICBjb25zdCBtYXRjaCA9IGxheWVyLm1hdGNoKHBhdGgpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IGxheWVyLnBhcmFtcztcbiAgICAgICAgT2JqZWN0LmtleXMocGFyYW1zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWxpZGF0ZVBhcmFtZXRlcihrZXksIHBhcmFtc1trZXldKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IHBhcmFtczogcGFyYW1zLCBoYW5kbGVyOiByb3V0ZS5oYW5kbGVyIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTW91bnQgdGhlIHJvdXRlcyBvbiB0aGlzIHJvdXRlciBvbnRvIGFuIGV4cHJlc3MgYXBwIChvciBleHByZXNzIHJvdXRlcilcbiAgbW91bnRPbnRvKGV4cHJlc3NBcHApIHtcbiAgICB0aGlzLnJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IHtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IHJvdXRlLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgaGFuZGxlciA9IG1ha2VFeHByZXNzSGFuZGxlcih0aGlzLmFwcElkLCByb3V0ZS5oYW5kbGVyKTtcbiAgICAgIGV4cHJlc3NBcHBbbWV0aG9kXS5jYWxsKGV4cHJlc3NBcHAsIHJvdXRlLnBhdGgsIGhhbmRsZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiBleHByZXNzQXBwO1xuICB9XG5cbiAgZXhwcmVzc1JvdXRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5tb3VudE9udG8oZXhwcmVzcy5Sb3V0ZXIoKSk7XG4gIH1cblxuICB0cnlSb3V0ZVJlcXVlc3QobWV0aG9kLCBwYXRoLCByZXF1ZXN0KSB7XG4gICAgdmFyIG1hdGNoID0gdGhpcy5tYXRjaChtZXRob2QsIHBhdGgpO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdjYW5ub3Qgcm91dGUgJyArIG1ldGhvZCArICcgJyArIHBhdGgpO1xuICAgIH1cbiAgICByZXF1ZXN0LnBhcmFtcyA9IG1hdGNoLnBhcmFtcztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgbWF0Y2guaGFuZGxlcihyZXF1ZXN0KS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLy8gQSBoZWxwZXIgZnVuY3Rpb24gdG8gbWFrZSBhbiBleHByZXNzIGhhbmRsZXIgb3V0IG9mIGEgYSBwcm9taXNlXG4vLyBoYW5kbGVyLlxuLy8gRXhwcmVzcyBoYW5kbGVycyBzaG91bGQgbmV2ZXIgdGhyb3c7IGlmIGEgcHJvbWlzZSBoYW5kbGVyIHRocm93cyB3ZVxuLy8ganVzdCB0cmVhdCBpdCBsaWtlIGl0IHJlc29sdmVkIHRvIGFuIGVycm9yLlxuZnVuY3Rpb24gbWFrZUV4cHJlc3NIYW5kbGVyKGFwcElkLCBwcm9taXNlSGFuZGxlcikge1xuICByZXR1cm4gZnVuY3Rpb24gKHJlcSwgcmVzLCBuZXh0KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVybCA9IG1hc2tTZW5zaXRpdmVVcmwocmVxKTtcbiAgICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHt9LCByZXEuYm9keSk7XG4gICAgICBjb25zdCBtZXRob2QgPSByZXEubWV0aG9kO1xuICAgICAgY29uc3QgaGVhZGVycyA9IHJlcS5oZWFkZXJzO1xuICAgICAgbG9nLmxvZ1JlcXVlc3Qoe1xuICAgICAgICBtZXRob2QsXG4gICAgICAgIHVybCxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYm9keSxcbiAgICAgIH0pO1xuICAgICAgcHJvbWlzZUhhbmRsZXIocmVxKVxuICAgICAgICAudGhlbihcbiAgICAgICAgICByZXN1bHQgPT4ge1xuICAgICAgICAgICAgY2xlYXJTY2hlbWFDYWNoZShyZXEpO1xuICAgICAgICAgICAgaWYgKCFyZXN1bHQucmVzcG9uc2UgJiYgIXJlc3VsdC5sb2NhdGlvbiAmJiAhcmVzdWx0LnRleHQpIHtcbiAgICAgICAgICAgICAgbG9nLmVycm9yKCd0aGUgaGFuZGxlciBkaWQgbm90IGluY2x1ZGUgYSBcInJlc3BvbnNlXCIgb3IgYSBcImxvY2F0aW9uXCIgZmllbGQnKTtcbiAgICAgICAgICAgICAgdGhyb3cgJ2NvbnRyb2wgc2hvdWxkIG5vdCBnZXQgaGVyZSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvZy5sb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSk7XG5cbiAgICAgICAgICAgIHZhciBzdGF0dXMgPSByZXN1bHQuc3RhdHVzIHx8IDIwMDtcbiAgICAgICAgICAgIHJlcy5zdGF0dXMoc3RhdHVzKTtcblxuICAgICAgICAgICAgaWYgKHJlc3VsdC50ZXh0KSB7XG4gICAgICAgICAgICAgIHJlcy5zZW5kKHJlc3VsdC50ZXh0KTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzdWx0LmxvY2F0aW9uKSB7XG4gICAgICAgICAgICAgIHJlcy5zZXQoJ0xvY2F0aW9uJywgcmVzdWx0LmxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgLy8gT3ZlcnJpZGUgdGhlIGRlZmF1bHQgZXhwcmVzc2pzIHJlc3BvbnNlXG4gICAgICAgICAgICAgIC8vIGFzIGl0IGRvdWJsZSBlbmNvZGVzICVlbmNvZGVkIGNoYXJzIGluIFVSTFxuICAgICAgICAgICAgICBpZiAoIXJlc3VsdC5yZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIHJlcy5zZW5kKCdGb3VuZC4gUmVkaXJlY3RpbmcgdG8gJyArIHJlc3VsdC5sb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0LmhlYWRlcnMpLmZvckVhY2goaGVhZGVyID0+IHtcbiAgICAgICAgICAgICAgICByZXMuc2V0KGhlYWRlciwgcmVzdWx0LmhlYWRlcnNbaGVhZGVyXSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLmpzb24ocmVzdWx0LnJlc3BvbnNlKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAgIGNsZWFyU2NoZW1hQ2FjaGUocmVxKTtcbiAgICAgICAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgY2xlYXJTY2hlbWFDYWNoZShyZXEpO1xuICAgICAgICAgIGxvZy5lcnJvcihgRXJyb3IgZ2VuZXJhdGluZyByZXNwb25zZS4gJHtpbnNwZWN0KGUpfWAsIHsgZXJyb3I6IGUgfSk7XG4gICAgICAgICAgbmV4dChlKTtcbiAgICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY2xlYXJTY2hlbWFDYWNoZShyZXEpO1xuICAgICAgbG9nLmVycm9yKGBFcnJvciBoYW5kbGluZyByZXF1ZXN0OiAke2luc3BlY3QoZSl9YCwgeyBlcnJvcjogZSB9KTtcbiAgICAgIG5leHQoZSk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBtYXNrU2Vuc2l0aXZlVXJsKHJlcSkge1xuICBsZXQgbWFza1VybCA9IHJlcS5vcmlnaW5hbFVybC50b1N0cmluZygpO1xuICBjb25zdCBzaG91bGRNYXNrVXJsID1cbiAgICByZXEubWV0aG9kID09PSAnR0VUJyAmJlxuICAgIHJlcS5vcmlnaW5hbFVybC5pbmNsdWRlcygnL2xvZ2luJykgJiZcbiAgICAhcmVxLm9yaWdpbmFsVXJsLmluY2x1ZGVzKCdjbGFzc2VzJyk7XG4gIGlmIChzaG91bGRNYXNrVXJsKSB7XG4gICAgbWFza1VybCA9IGxvZy5tYXNrU2Vuc2l0aXZlVXJsKG1hc2tVcmwpO1xuICB9XG4gIHJldHVybiBtYXNrVXJsO1xufVxuXG5mdW5jdGlvbiBjbGVhclNjaGVtYUNhY2hlKHJlcSkge1xuICBpZiAocmVxLmNvbmZpZyAmJiAhcmVxLmNvbmZpZy5lbmFibGVTaW5nbGVTY2hlbWFDYWNoZSkge1xuICAgIHJlcS5jb25maWcuZGF0YWJhc2Uuc2NoZW1hQ2FjaGUuY2xlYXIoKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Push/PushQueue.js b/lib/Push/PushQueue.js deleted file mode 100644 index f3e2d1d755..0000000000 --- a/lib/Push/PushQueue.js +++ /dev/null @@ -1,79 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.PushQueue = void 0; - -var _ParseMessageQueue = require("../ParseMessageQueue"); - -var _rest = _interopRequireDefault(require("../rest")); - -var _utils = require("./utils"); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const PUSH_CHANNEL = 'parse-server-push'; -const DEFAULT_BATCH_SIZE = 100; - -class PushQueue { - // config object of the publisher, right now it only contains the redisURL, - // but we may extend it later. - constructor(config = {}) { - this.channel = config.channel || PushQueue.defaultPushChannel(); - this.batchSize = config.batchSize || DEFAULT_BATCH_SIZE; - this.parsePublisher = _ParseMessageQueue.ParseMessageQueue.createPublisher(config); - } - - static defaultPushChannel() { - return `${_node.default.applicationId}-${PUSH_CHANNEL}`; - } - - enqueue(body, where, config, auth, pushStatus) { - const limit = this.batchSize; - where = (0, _utils.applyDeviceTokenExists)(where); // Order by objectId so no impact on the DB - - const order = 'objectId'; - return Promise.resolve().then(() => { - return _rest.default.find(config, auth, '_Installation', where, { - limit: 0, - count: true - }); - }).then(({ - results, - count - }) => { - if (!results || count == 0) { - return pushStatus.complete(); - } - - pushStatus.setRunning(Math.ceil(count / limit)); - let skip = 0; - - while (skip < count) { - const query = { - where, - limit, - skip, - order - }; - const pushWorkItem = { - body, - query, - pushStatus: { - objectId: pushStatus.objectId - }, - applicationId: config.applicationId - }; - this.parsePublisher.publish(this.channel, JSON.stringify(pushWorkItem)); - skip += limit; - } - }); - } - -} - -exports.PushQueue = PushQueue; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQVVNIX0NIQU5ORUwiLCJERUZBVUxUX0JBVENIX1NJWkUiLCJQdXNoUXVldWUiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNoYW5uZWwiLCJkZWZhdWx0UHVzaENoYW5uZWwiLCJiYXRjaFNpemUiLCJwYXJzZVB1Ymxpc2hlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlUHVibGlzaGVyIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwiZW5xdWV1ZSIsImJvZHkiLCJ3aGVyZSIsImF1dGgiLCJwdXNoU3RhdHVzIiwibGltaXQiLCJvcmRlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsInJlc3QiLCJmaW5kIiwiY291bnQiLCJyZXN1bHRzIiwiY29tcGxldGUiLCJzZXRSdW5uaW5nIiwiTWF0aCIsImNlaWwiLCJza2lwIiwicXVlcnkiLCJwdXNoV29ya0l0ZW0iLCJvYmplY3RJZCIsInB1Ymxpc2giLCJKU09OIiwic3RyaW5naWZ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxZQUFZLEdBQUcsbUJBQXJCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRU8sTUFBTUMsU0FBTixDQUFnQjtBQUtyQjtBQUNBO0FBQ0FDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBVyxHQUFHLEVBQWYsRUFBbUI7QUFDNUIsU0FBS0MsT0FBTCxHQUFlRCxNQUFNLENBQUNDLE9BQVAsSUFBa0JILFNBQVMsQ0FBQ0ksa0JBQVYsRUFBakM7QUFDQSxTQUFLQyxTQUFMLEdBQWlCSCxNQUFNLENBQUNHLFNBQVAsSUFBb0JOLGtCQUFyQztBQUNBLFNBQUtPLGNBQUwsR0FBc0JDLHFDQUFrQkMsZUFBbEIsQ0FBa0NOLE1BQWxDLENBQXRCO0FBQ0Q7O0FBRUQsU0FBT0Usa0JBQVAsR0FBNEI7QUFDMUIsV0FBUSxHQUFFSyxjQUFNQyxhQUFjLElBQUdaLFlBQWEsRUFBOUM7QUFDRDs7QUFFRGEsRUFBQUEsT0FBTyxDQUFDQyxJQUFELEVBQU9DLEtBQVAsRUFBY1gsTUFBZCxFQUFzQlksSUFBdEIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDLFVBQU1DLEtBQUssR0FBRyxLQUFLWCxTQUFuQjtBQUVBUSxJQUFBQSxLQUFLLEdBQUcsbUNBQXVCQSxLQUF2QixDQUFSLENBSDZDLENBSzdDOztBQUNBLFVBQU1JLEtBQUssR0FBRyxVQUFkO0FBQ0EsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBT0MsY0FBS0MsSUFBTCxDQUFVcEIsTUFBVixFQUFrQlksSUFBbEIsRUFBd0IsZUFBeEIsRUFBeUNELEtBQXpDLEVBQWdEO0FBQ3JERyxRQUFBQSxLQUFLLEVBQUUsQ0FEOEM7QUFFckRPLFFBQUFBLEtBQUssRUFBRTtBQUY4QyxPQUFoRCxDQUFQO0FBSUQsS0FOSSxFQU9KSCxJQVBJLENBT0MsQ0FBQztBQUFFSSxNQUFBQSxPQUFGO0FBQVdELE1BQUFBO0FBQVgsS0FBRCxLQUF3QjtBQUM1QixVQUFJLENBQUNDLE9BQUQsSUFBWUQsS0FBSyxJQUFJLENBQXpCLEVBQTRCO0FBQzFCLGVBQU9SLFVBQVUsQ0FBQ1UsUUFBWCxFQUFQO0FBQ0Q7O0FBQ0RWLE1BQUFBLFVBQVUsQ0FBQ1csVUFBWCxDQUFzQkMsSUFBSSxDQUFDQyxJQUFMLENBQVVMLEtBQUssR0FBR1AsS0FBbEIsQ0FBdEI7QUFDQSxVQUFJYSxJQUFJLEdBQUcsQ0FBWDs7QUFDQSxhQUFPQSxJQUFJLEdBQUdOLEtBQWQsRUFBcUI7QUFDbkIsY0FBTU8sS0FBSyxHQUFHO0FBQ1pqQixVQUFBQSxLQURZO0FBRVpHLFVBQUFBLEtBRlk7QUFHWmEsVUFBQUEsSUFIWTtBQUlaWixVQUFBQTtBQUpZLFNBQWQ7QUFPQSxjQUFNYyxZQUFZLEdBQUc7QUFDbkJuQixVQUFBQSxJQURtQjtBQUVuQmtCLFVBQUFBLEtBRm1CO0FBR25CZixVQUFBQSxVQUFVLEVBQUU7QUFBRWlCLFlBQUFBLFFBQVEsRUFBRWpCLFVBQVUsQ0FBQ2lCO0FBQXZCLFdBSE87QUFJbkJ0QixVQUFBQSxhQUFhLEVBQUVSLE1BQU0sQ0FBQ1E7QUFKSCxTQUFyQjtBQU1BLGFBQUtKLGNBQUwsQ0FBb0IyQixPQUFwQixDQUE0QixLQUFLOUIsT0FBakMsRUFBMEMrQixJQUFJLENBQUNDLFNBQUwsQ0FBZUosWUFBZixDQUExQztBQUNBRixRQUFBQSxJQUFJLElBQUliLEtBQVI7QUFDRDtBQUNGLEtBOUJJLENBQVA7QUErQkQ7O0FBdkRvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlTWVzc2FnZVF1ZXVlIH0gZnJvbSAnLi4vUGFyc2VNZXNzYWdlUXVldWUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgeyBhcHBseURldmljZVRva2VuRXhpc3RzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmNvbnN0IFBVU0hfQ0hBTk5FTCA9ICdwYXJzZS1zZXJ2ZXItcHVzaCc7XG5jb25zdCBERUZBVUxUX0JBVENIX1NJWkUgPSAxMDA7XG5cbmV4cG9ydCBjbGFzcyBQdXNoUXVldWUge1xuICBwYXJzZVB1Ymxpc2hlcjogT2JqZWN0O1xuICBjaGFubmVsOiBTdHJpbmc7XG4gIGJhdGNoU2l6ZTogTnVtYmVyO1xuXG4gIC8vIGNvbmZpZyBvYmplY3Qgb2YgdGhlIHB1Ymxpc2hlciwgcmlnaHQgbm93IGl0IG9ubHkgY29udGFpbnMgdGhlIHJlZGlzVVJMLFxuICAvLyBidXQgd2UgbWF5IGV4dGVuZCBpdCBsYXRlci5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBhbnkgPSB7fSkge1xuICAgIHRoaXMuY2hhbm5lbCA9IGNvbmZpZy5jaGFubmVsIHx8IFB1c2hRdWV1ZS5kZWZhdWx0UHVzaENoYW5uZWwoKTtcbiAgICB0aGlzLmJhdGNoU2l6ZSA9IGNvbmZpZy5iYXRjaFNpemUgfHwgREVGQVVMVF9CQVRDSF9TSVpFO1xuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIgPSBQYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVQdWJsaXNoZXIoY29uZmlnKTtcbiAgfVxuXG4gIHN0YXRpYyBkZWZhdWx0UHVzaENoYW5uZWwoKSB7XG4gICAgcmV0dXJuIGAke1BhcnNlLmFwcGxpY2F0aW9uSWR9LSR7UFVTSF9DSEFOTkVMfWA7XG4gIH1cblxuICBlbnF1ZXVlKGJvZHksIHdoZXJlLCBjb25maWcsIGF1dGgsIHB1c2hTdGF0dXMpIHtcbiAgICBjb25zdCBsaW1pdCA9IHRoaXMuYmF0Y2hTaXplO1xuXG4gICAgd2hlcmUgPSBhcHBseURldmljZVRva2VuRXhpc3RzKHdoZXJlKTtcblxuICAgIC8vIE9yZGVyIGJ5IG9iamVjdElkIHNvIG5vIGltcGFjdCBvbiB0aGUgREJcbiAgICBjb25zdCBvcmRlciA9ICdvYmplY3RJZCc7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiByZXN0LmZpbmQoY29uZmlnLCBhdXRoLCAnX0luc3RhbGxhdGlvbicsIHdoZXJlLCB7XG4gICAgICAgICAgbGltaXQ6IDAsXG4gICAgICAgICAgY291bnQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCh7IHJlc3VsdHMsIGNvdW50IH0pID0+IHtcbiAgICAgICAgaWYgKCFyZXN1bHRzIHx8IGNvdW50ID09IDApIHtcbiAgICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hTdGF0dXMuc2V0UnVubmluZyhNYXRoLmNlaWwoY291bnQgLyBsaW1pdCkpO1xuICAgICAgICBsZXQgc2tpcCA9IDA7XG4gICAgICAgIHdoaWxlIChza2lwIDwgY291bnQpIHtcbiAgICAgICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgICAgIHdoZXJlLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgb3JkZXIsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHB1c2hXb3JrSXRlbSA9IHtcbiAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgIHB1c2hTdGF0dXM6IHsgb2JqZWN0SWQ6IHB1c2hTdGF0dXMub2JqZWN0SWQgfSxcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uSWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5wYXJzZVB1Ymxpc2hlci5wdWJsaXNoKHRoaXMuY2hhbm5lbCwgSlNPTi5zdHJpbmdpZnkocHVzaFdvcmtJdGVtKSk7XG4gICAgICAgICAgc2tpcCArPSBsaW1pdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Push/PushWorker.js b/lib/Push/PushWorker.js deleted file mode 100644 index d845117b7b..0000000000 --- a/lib/Push/PushWorker.js +++ /dev/null @@ -1,130 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushWorker = void 0; - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -var _AdaptableController = _interopRequireDefault(require("../Controllers/AdaptableController")); - -var _Auth = require("../Auth"); - -var _Config = _interopRequireDefault(require("../Config")); - -var _PushAdapter = require("../Adapters/Push/PushAdapter"); - -var _rest = _interopRequireDefault(require("../rest")); - -var _StatusHandler = require("../StatusHandler"); - -var utils = _interopRequireWildcard(require("./utils")); - -var _ParseMessageQueue = require("../ParseMessageQueue"); - -var _PushQueue = require("./PushQueue"); - -var _logger = _interopRequireDefault(require("../logger")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// -disable-next -function groupByBadge(installations) { - return installations.reduce((map, installation) => { - const badge = installation.badge + ''; - map[badge] = map[badge] || []; - map[badge].push(installation); - return map; - }, {}); -} - -class PushWorker { - constructor(pushAdapter, subscriberConfig = {}) { - _AdaptableController.default.validateAdapter(pushAdapter, this, _PushAdapter.PushAdapter); - - this.adapter = pushAdapter; - this.channel = subscriberConfig.channel || _PushQueue.PushQueue.defaultPushChannel(); - this.subscriber = _ParseMessageQueue.ParseMessageQueue.createSubscriber(subscriberConfig); - - if (this.subscriber) { - const subscriber = this.subscriber; - subscriber.subscribe(this.channel); - subscriber.on('message', (channel, messageStr) => { - const workItem = JSON.parse(messageStr); - this.run(workItem); - }); - } - } - - run({ - body, - query, - pushStatus, - applicationId, - UTCOffset - }) { - const config = _Config.default.get(applicationId); - - const auth = (0, _Auth.master)(config); - const where = utils.applyDeviceTokenExists(query.where); - delete query.where; - pushStatus = (0, _StatusHandler.pushStatusHandler)(config, pushStatus.objectId); - return _rest.default.find(config, auth, '_Installation', where, query).then(({ - results - }) => { - if (results.length == 0) { - return; - } - - return this.sendToAdapter(body, results, pushStatus, config, UTCOffset); - }); - } - - sendToAdapter(body, installations, pushStatus, config, UTCOffset) { - // Check if we have locales in the push body - const locales = utils.getLocalesFromPush(body); - - if (locales.length > 0) { - // Get all tranformed bodies for each locale - const bodiesPerLocales = utils.bodiesPerLocales(body, locales); // Group installations on the specified locales (en, fr, default etc...) - - const grouppedInstallations = utils.groupByLocaleIdentifier(installations, locales); - const promises = Object.keys(grouppedInstallations).map(locale => { - const installations = grouppedInstallations[locale]; - const body = bodiesPerLocales[locale]; - return this.sendToAdapter(body, installations, pushStatus, config, UTCOffset); - }); - return Promise.all(promises); - } - - if (!utils.isPushIncrementing(body)) { - _logger.default.verbose(`Sending push to ${installations.length}`); - - return this.adapter.send(body, installations, pushStatus.objectId).then(results => { - return pushStatus.trackSent(results, UTCOffset).then(() => results); - }); - } // Collect the badges to reduce the # of calls - - - const badgeInstallationsMap = groupByBadge(installations); // Map the on the badges count and return the send result - - const promises = Object.keys(badgeInstallationsMap).map(badge => { - const payload = (0, _deepcopy.default)(body); - payload.data.badge = parseInt(badge); - const installations = badgeInstallationsMap[badge]; - return this.sendToAdapter(payload, installations, pushStatus, config, UTCOffset); - }); - return Promise.all(promises); - } - -} - -exports.PushWorker = PushWorker; -var _default = PushWorker; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hXb3JrZXIuanMiXSwibmFtZXMiOlsiZ3JvdXBCeUJhZGdlIiwiaW5zdGFsbGF0aW9ucyIsInJlZHVjZSIsIm1hcCIsImluc3RhbGxhdGlvbiIsImJhZGdlIiwicHVzaCIsIlB1c2hXb3JrZXIiLCJjb25zdHJ1Y3RvciIsInB1c2hBZGFwdGVyIiwic3Vic2NyaWJlckNvbmZpZyIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJ2YWxpZGF0ZUFkYXB0ZXIiLCJQdXNoQWRhcHRlciIsImFkYXB0ZXIiLCJjaGFubmVsIiwiUHVzaFF1ZXVlIiwiZGVmYXVsdFB1c2hDaGFubmVsIiwic3Vic2NyaWJlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlU3Vic2NyaWJlciIsInN1YnNjcmliZSIsIm9uIiwibWVzc2FnZVN0ciIsIndvcmtJdGVtIiwiSlNPTiIsInBhcnNlIiwicnVuIiwiYm9keSIsInF1ZXJ5IiwicHVzaFN0YXR1cyIsImFwcGxpY2F0aW9uSWQiLCJVVENPZmZzZXQiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJhdXRoIiwid2hlcmUiLCJ1dGlscyIsImFwcGx5RGV2aWNlVG9rZW5FeGlzdHMiLCJvYmplY3RJZCIsInJlc3QiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJzZW5kVG9BZGFwdGVyIiwibG9jYWxlcyIsImdldExvY2FsZXNGcm9tUHVzaCIsImJvZGllc1BlckxvY2FsZXMiLCJncm91cHBlZEluc3RhbGxhdGlvbnMiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsInByb21pc2VzIiwiT2JqZWN0Iiwia2V5cyIsImxvY2FsZSIsIlByb21pc2UiLCJhbGwiLCJpc1B1c2hJbmNyZW1lbnRpbmciLCJsb2dnZXIiLCJ2ZXJib3NlIiwic2VuZCIsInRyYWNrU2VudCIsImJhZGdlSW5zdGFsbGF0aW9uc01hcCIsInBheWxvYWQiLCJkYXRhIiwicGFyc2VJbnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFYQTtBQWFBLFNBQVNBLFlBQVQsQ0FBc0JDLGFBQXRCLEVBQXFDO0FBQ25DLFNBQU9BLGFBQWEsQ0FBQ0MsTUFBZCxDQUFxQixDQUFDQyxHQUFELEVBQU1DLFlBQU4sS0FBdUI7QUFDakQsVUFBTUMsS0FBSyxHQUFHRCxZQUFZLENBQUNDLEtBQWIsR0FBcUIsRUFBbkM7QUFDQUYsSUFBQUEsR0FBRyxDQUFDRSxLQUFELENBQUgsR0FBYUYsR0FBRyxDQUFDRSxLQUFELENBQUgsSUFBYyxFQUEzQjtBQUNBRixJQUFBQSxHQUFHLENBQUNFLEtBQUQsQ0FBSCxDQUFXQyxJQUFYLENBQWdCRixZQUFoQjtBQUNBLFdBQU9ELEdBQVA7QUFDRCxHQUxNLEVBS0osRUFMSSxDQUFQO0FBTUQ7O0FBRU0sTUFBTUksVUFBTixDQUFpQjtBQUt0QkMsRUFBQUEsV0FBVyxDQUFDQyxXQUFELEVBQTJCQyxnQkFBcUIsR0FBRyxFQUFuRCxFQUF1RDtBQUNoRUMsaUNBQW9CQyxlQUFwQixDQUFvQ0gsV0FBcEMsRUFBaUQsSUFBakQsRUFBdURJLHdCQUF2RDs7QUFDQSxTQUFLQyxPQUFMLEdBQWVMLFdBQWY7QUFFQSxTQUFLTSxPQUFMLEdBQWVMLGdCQUFnQixDQUFDSyxPQUFqQixJQUE0QkMscUJBQVVDLGtCQUFWLEVBQTNDO0FBQ0EsU0FBS0MsVUFBTCxHQUFrQkMscUNBQWtCQyxnQkFBbEIsQ0FBbUNWLGdCQUFuQyxDQUFsQjs7QUFDQSxRQUFJLEtBQUtRLFVBQVQsRUFBcUI7QUFDbkIsWUFBTUEsVUFBVSxHQUFHLEtBQUtBLFVBQXhCO0FBQ0FBLE1BQUFBLFVBQVUsQ0FBQ0csU0FBWCxDQUFxQixLQUFLTixPQUExQjtBQUNBRyxNQUFBQSxVQUFVLENBQUNJLEVBQVgsQ0FBYyxTQUFkLEVBQXlCLENBQUNQLE9BQUQsRUFBVVEsVUFBVixLQUF5QjtBQUNoRCxjQUFNQyxRQUFRLEdBQUdDLElBQUksQ0FBQ0MsS0FBTCxDQUFXSCxVQUFYLENBQWpCO0FBQ0EsYUFBS0ksR0FBTCxDQUFTSCxRQUFUO0FBQ0QsT0FIRDtBQUlEO0FBQ0Y7O0FBRURHLEVBQUFBLEdBQUcsQ0FBQztBQUFFQyxJQUFBQSxJQUFGO0FBQVFDLElBQUFBLEtBQVI7QUFBZUMsSUFBQUEsVUFBZjtBQUEyQkMsSUFBQUEsYUFBM0I7QUFBMENDLElBQUFBO0FBQTFDLEdBQUQsRUFBeUU7QUFDMUUsVUFBTUMsTUFBTSxHQUFHQyxnQkFBT0MsR0FBUCxDQUFXSixhQUFYLENBQWY7O0FBQ0EsVUFBTUssSUFBSSxHQUFHLGtCQUFPSCxNQUFQLENBQWI7QUFDQSxVQUFNSSxLQUFLLEdBQUdDLEtBQUssQ0FBQ0Msc0JBQU4sQ0FBNkJWLEtBQUssQ0FBQ1EsS0FBbkMsQ0FBZDtBQUNBLFdBQU9SLEtBQUssQ0FBQ1EsS0FBYjtBQUNBUCxJQUFBQSxVQUFVLEdBQUcsc0NBQWtCRyxNQUFsQixFQUEwQkgsVUFBVSxDQUFDVSxRQUFyQyxDQUFiO0FBQ0EsV0FBT0MsY0FBS0MsSUFBTCxDQUFVVCxNQUFWLEVBQWtCRyxJQUFsQixFQUF3QixlQUF4QixFQUF5Q0MsS0FBekMsRUFBZ0RSLEtBQWhELEVBQXVEYyxJQUF2RCxDQUE0RCxDQUFDO0FBQUVDLE1BQUFBO0FBQUYsS0FBRCxLQUFpQjtBQUNsRixVQUFJQSxPQUFPLENBQUNDLE1BQVIsSUFBa0IsQ0FBdEIsRUFBeUI7QUFDdkI7QUFDRDs7QUFDRCxhQUFPLEtBQUtDLGFBQUwsQ0FBbUJsQixJQUFuQixFQUF5QmdCLE9BQXpCLEVBQWtDZCxVQUFsQyxFQUE4Q0csTUFBOUMsRUFBc0RELFNBQXRELENBQVA7QUFDRCxLQUxNLENBQVA7QUFNRDs7QUFFRGMsRUFBQUEsYUFBYSxDQUNYbEIsSUFEVyxFQUVYM0IsYUFGVyxFQUdYNkIsVUFIVyxFQUlYRyxNQUpXLEVBS1hELFNBTFcsRUFNQztBQUNaO0FBQ0EsVUFBTWUsT0FBTyxHQUFHVCxLQUFLLENBQUNVLGtCQUFOLENBQXlCcEIsSUFBekIsQ0FBaEI7O0FBQ0EsUUFBSW1CLE9BQU8sQ0FBQ0YsTUFBUixHQUFpQixDQUFyQixFQUF3QjtBQUN0QjtBQUNBLFlBQU1JLGdCQUFnQixHQUFHWCxLQUFLLENBQUNXLGdCQUFOLENBQXVCckIsSUFBdkIsRUFBNkJtQixPQUE3QixDQUF6QixDQUZzQixDQUl0Qjs7QUFDQSxZQUFNRyxxQkFBcUIsR0FBR1osS0FBSyxDQUFDYSx1QkFBTixDQUE4QmxELGFBQTlCLEVBQTZDOEMsT0FBN0MsQ0FBOUI7QUFDQSxZQUFNSyxRQUFRLEdBQUdDLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZSixxQkFBWixFQUFtQy9DLEdBQW5DLENBQXVDb0QsTUFBTSxJQUFJO0FBQ2hFLGNBQU10RCxhQUFhLEdBQUdpRCxxQkFBcUIsQ0FBQ0ssTUFBRCxDQUEzQztBQUNBLGNBQU0zQixJQUFJLEdBQUdxQixnQkFBZ0IsQ0FBQ00sTUFBRCxDQUE3QjtBQUNBLGVBQU8sS0FBS1QsYUFBTCxDQUFtQmxCLElBQW5CLEVBQXlCM0IsYUFBekIsRUFBd0M2QixVQUF4QyxFQUFvREcsTUFBcEQsRUFBNERELFNBQTVELENBQVA7QUFDRCxPQUpnQixDQUFqQjtBQUtBLGFBQU93QixPQUFPLENBQUNDLEdBQVIsQ0FBWUwsUUFBWixDQUFQO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDZCxLQUFLLENBQUNvQixrQkFBTixDQUF5QjlCLElBQXpCLENBQUwsRUFBcUM7QUFDbkMrQixzQkFBT0MsT0FBUCxDQUFnQixtQkFBa0IzRCxhQUFhLENBQUM0QyxNQUFPLEVBQXZEOztBQUNBLGFBQU8sS0FBSy9CLE9BQUwsQ0FBYStDLElBQWIsQ0FBa0JqQyxJQUFsQixFQUF3QjNCLGFBQXhCLEVBQXVDNkIsVUFBVSxDQUFDVSxRQUFsRCxFQUE0REcsSUFBNUQsQ0FBaUVDLE9BQU8sSUFBSTtBQUNqRixlQUFPZCxVQUFVLENBQUNnQyxTQUFYLENBQXFCbEIsT0FBckIsRUFBOEJaLFNBQTlCLEVBQXlDVyxJQUF6QyxDQUE4QyxNQUFNQyxPQUFwRCxDQUFQO0FBQ0QsT0FGTSxDQUFQO0FBR0QsS0F0QlcsQ0F3Qlo7OztBQUNBLFVBQU1tQixxQkFBcUIsR0FBRy9ELFlBQVksQ0FBQ0MsYUFBRCxDQUExQyxDQXpCWSxDQTJCWjs7QUFDQSxVQUFNbUQsUUFBUSxHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWVMscUJBQVosRUFBbUM1RCxHQUFuQyxDQUF1Q0UsS0FBSyxJQUFJO0FBQy9ELFlBQU0yRCxPQUFPLEdBQUcsdUJBQVNwQyxJQUFULENBQWhCO0FBQ0FvQyxNQUFBQSxPQUFPLENBQUNDLElBQVIsQ0FBYTVELEtBQWIsR0FBcUI2RCxRQUFRLENBQUM3RCxLQUFELENBQTdCO0FBQ0EsWUFBTUosYUFBYSxHQUFHOEQscUJBQXFCLENBQUMxRCxLQUFELENBQTNDO0FBQ0EsYUFBTyxLQUFLeUMsYUFBTCxDQUFtQmtCLE9BQW5CLEVBQTRCL0QsYUFBNUIsRUFBMkM2QixVQUEzQyxFQUF1REcsTUFBdkQsRUFBK0RELFNBQS9ELENBQVA7QUFDRCxLQUxnQixDQUFqQjtBQU1BLFdBQU93QixPQUFPLENBQUNDLEdBQVIsQ0FBWUwsUUFBWixDQUFQO0FBQ0Q7O0FBNUVxQjs7O2VBK0VUN0MsVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBkZWVwY29weSBmcm9tICdkZWVwY29weSc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuLi9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IG1hc3RlciB9IGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IHsgUHVzaEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHVzaFN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUGFyc2VNZXNzYWdlUXVldWUgfSBmcm9tICcuLi9QYXJzZU1lc3NhZ2VRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuL1B1c2hRdWV1ZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKSB7XG4gIHJldHVybiBpbnN0YWxsYXRpb25zLnJlZHVjZSgobWFwLCBpbnN0YWxsYXRpb24pID0+IHtcbiAgICBjb25zdCBiYWRnZSA9IGluc3RhbGxhdGlvbi5iYWRnZSArICcnO1xuICAgIG1hcFtiYWRnZV0gPSBtYXBbYmFkZ2VdIHx8IFtdO1xuICAgIG1hcFtiYWRnZV0ucHVzaChpbnN0YWxsYXRpb24pO1xuICAgIHJldHVybiBtYXA7XG4gIH0sIHt9KTtcbn1cblxuZXhwb3J0IGNsYXNzIFB1c2hXb3JrZXIge1xuICBzdWJzY3JpYmVyOiA/YW55O1xuICBhZGFwdGVyOiBhbnk7XG4gIGNoYW5uZWw6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdXNoQWRhcHRlcjogUHVzaEFkYXB0ZXIsIHN1YnNjcmliZXJDb25maWc6IGFueSA9IHt9KSB7XG4gICAgQWRhcHRhYmxlQ29udHJvbGxlci52YWxpZGF0ZUFkYXB0ZXIocHVzaEFkYXB0ZXIsIHRoaXMsIFB1c2hBZGFwdGVyKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBwdXNoQWRhcHRlcjtcblxuICAgIHRoaXMuY2hhbm5lbCA9IHN1YnNjcmliZXJDb25maWcuY2hhbm5lbCB8fCBQdXNoUXVldWUuZGVmYXVsdFB1c2hDaGFubmVsKCk7XG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VNZXNzYWdlUXVldWUuY3JlYXRlU3Vic2NyaWJlcihzdWJzY3JpYmVyQ29uZmlnKTtcbiAgICBpZiAodGhpcy5zdWJzY3JpYmVyKSB7XG4gICAgICBjb25zdCBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmVyO1xuICAgICAgc3Vic2NyaWJlci5zdWJzY3JpYmUodGhpcy5jaGFubmVsKTtcbiAgICAgIHN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgICBjb25zdCB3b3JrSXRlbSA9IEpTT04ucGFyc2UobWVzc2FnZVN0cik7XG4gICAgICAgIHRoaXMucnVuKHdvcmtJdGVtKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJ1bih7IGJvZHksIHF1ZXJ5LCBwdXNoU3RhdHVzLCBhcHBsaWNhdGlvbklkLCBVVENPZmZzZXQgfTogYW55KTogUHJvbWlzZTwqPiB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBsaWNhdGlvbklkKTtcbiAgICBjb25zdCBhdXRoID0gbWFzdGVyKGNvbmZpZyk7XG4gICAgY29uc3Qgd2hlcmUgPSB1dGlscy5hcHBseURldmljZVRva2VuRXhpc3RzKHF1ZXJ5LndoZXJlKTtcbiAgICBkZWxldGUgcXVlcnkud2hlcmU7XG4gICAgcHVzaFN0YXR1cyA9IHB1c2hTdGF0dXNIYW5kbGVyKGNvbmZpZywgcHVzaFN0YXR1cy5vYmplY3RJZCk7XG4gICAgcmV0dXJuIHJlc3QuZmluZChjb25maWcsIGF1dGgsICdfSW5zdGFsbGF0aW9uJywgd2hlcmUsIHF1ZXJ5KS50aGVuKCh7IHJlc3VsdHMgfSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCByZXN1bHRzLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgfSk7XG4gIH1cblxuICBzZW5kVG9BZGFwdGVyKFxuICAgIGJvZHk6IGFueSxcbiAgICBpbnN0YWxsYXRpb25zOiBhbnlbXSxcbiAgICBwdXNoU3RhdHVzOiBhbnksXG4gICAgY29uZmlnOiBDb25maWcsXG4gICAgVVRDT2Zmc2V0OiA/YW55XG4gICk6IFByb21pc2U8Kj4ge1xuICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgbG9jYWxlcyBpbiB0aGUgcHVzaCBib2R5XG4gICAgY29uc3QgbG9jYWxlcyA9IHV0aWxzLmdldExvY2FsZXNGcm9tUHVzaChib2R5KTtcbiAgICBpZiAobG9jYWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBHZXQgYWxsIHRyYW5mb3JtZWQgYm9kaWVzIGZvciBlYWNoIGxvY2FsZVxuICAgICAgY29uc3QgYm9kaWVzUGVyTG9jYWxlcyA9IHV0aWxzLmJvZGllc1BlckxvY2FsZXMoYm9keSwgbG9jYWxlcyk7XG5cbiAgICAgIC8vIEdyb3VwIGluc3RhbGxhdGlvbnMgb24gdGhlIHNwZWNpZmllZCBsb2NhbGVzIChlbiwgZnIsIGRlZmF1bHQgZXRjLi4uKVxuICAgICAgY29uc3QgZ3JvdXBwZWRJbnN0YWxsYXRpb25zID0gdXRpbHMuZ3JvdXBCeUxvY2FsZUlkZW50aWZpZXIoaW5zdGFsbGF0aW9ucywgbG9jYWxlcyk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKGdyb3VwcGVkSW5zdGFsbGF0aW9ucykubWFwKGxvY2FsZSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbnMgPSBncm91cHBlZEluc3RhbGxhdGlvbnNbbG9jYWxlXTtcbiAgICAgICAgY29uc3QgYm9keSA9IGJvZGllc1BlckxvY2FsZXNbbG9jYWxlXTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlscy5pc1B1c2hJbmNyZW1lbnRpbmcoYm9keSkpIHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBTZW5kaW5nIHB1c2ggdG8gJHtpbnN0YWxsYXRpb25zLmxlbmd0aH1gKTtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuc2VuZChib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLm9iamVjdElkKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy50cmFja1NlbnQocmVzdWx0cywgVVRDT2Zmc2V0KS50aGVuKCgpID0+IHJlc3VsdHMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29sbGVjdCB0aGUgYmFkZ2VzIHRvIHJlZHVjZSB0aGUgIyBvZiBjYWxsc1xuICAgIGNvbnN0IGJhZGdlSW5zdGFsbGF0aW9uc01hcCA9IGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKTtcblxuICAgIC8vIE1hcCB0aGUgb24gdGhlIGJhZGdlcyBjb3VudCBhbmQgcmV0dXJuIHRoZSBzZW5kIHJlc3VsdFxuICAgIGNvbnN0IHByb21pc2VzID0gT2JqZWN0LmtleXMoYmFkZ2VJbnN0YWxsYXRpb25zTWFwKS5tYXAoYmFkZ2UgPT4ge1xuICAgICAgY29uc3QgcGF5bG9hZCA9IGRlZXBjb3B5KGJvZHkpO1xuICAgICAgcGF5bG9hZC5kYXRhLmJhZGdlID0gcGFyc2VJbnQoYmFkZ2UpO1xuICAgICAgY29uc3QgaW5zdGFsbGF0aW9ucyA9IGJhZGdlSW5zdGFsbGF0aW9uc01hcFtiYWRnZV07XG4gICAgICByZXR1cm4gdGhpcy5zZW5kVG9BZGFwdGVyKHBheWxvYWQsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMsIGNvbmZpZywgVVRDT2Zmc2V0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1c2hXb3JrZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Push/utils.js b/lib/Push/utils.js deleted file mode 100644 index a35a716a15..0000000000 --- a/lib/Push/utils.js +++ /dev/null @@ -1,159 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isPushIncrementing = isPushIncrementing; -exports.getLocalesFromPush = getLocalesFromPush; -exports.transformPushBodyForLocale = transformPushBodyForLocale; -exports.stripLocalesFromBody = stripLocalesFromBody; -exports.bodiesPerLocales = bodiesPerLocales; -exports.groupByLocaleIdentifier = groupByLocaleIdentifier; -exports.validatePushType = validatePushType; -exports.applyDeviceTokenExists = applyDeviceTokenExists; - -var _node = _interopRequireDefault(require("parse/node")); - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function isPushIncrementing(body) { - if (!body.data || !body.data.badge) { - return false; - } - - const badge = body.data.badge; - - if (typeof badge == 'string' && badge.toLowerCase() == 'increment') { - return true; - } - - return typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount); -} - -const localizableKeys = ['alert', 'title']; - -function getLocalesFromPush(body) { - const data = body.data; - - if (!data) { - return []; - } - - return [...new Set(Object.keys(data).reduce((memo, key) => { - localizableKeys.forEach(localizableKey => { - if (key.indexOf(`${localizableKey}-`) == 0) { - memo.push(key.slice(localizableKey.length + 1)); - } - }); - return memo; - }, []))]; -} - -function transformPushBodyForLocale(body, locale) { - const data = body.data; - - if (!data) { - return body; - } - - body = (0, _deepcopy.default)(body); - localizableKeys.forEach(key => { - const localeValue = body.data[`${key}-${locale}`]; - - if (localeValue) { - body.data[key] = localeValue; - } - }); - return stripLocalesFromBody(body); -} - -function stripLocalesFromBody(body) { - if (!body.data) { - return body; - } - - Object.keys(body.data).forEach(key => { - localizableKeys.forEach(localizableKey => { - if (key.indexOf(`${localizableKey}-`) == 0) { - delete body.data[key]; - } - }); - }); - return body; -} - -function bodiesPerLocales(body, locales = []) { - // Get all tranformed bodies for each locale - const result = locales.reduce((memo, locale) => { - memo[locale] = transformPushBodyForLocale(body, locale); - return memo; - }, {}); // Set the default locale, with the stripped body - - result.default = stripLocalesFromBody(body); - return result; -} - -function groupByLocaleIdentifier(installations, locales = []) { - return installations.reduce((map, installation) => { - let added = false; - locales.forEach(locale => { - if (added) { - return; - } - - if (installation.localeIdentifier && installation.localeIdentifier.indexOf(locale) === 0) { - added = true; - map[locale] = map[locale] || []; - map[locale].push(installation); - } - }); - - if (!added) { - map.default.push(installation); - } - - return map; - }, { - default: [] - }); -} -/** - * Check whether the deviceType parameter in qury condition is valid or not. - * @param {Object} where A query condition - * @param {Array} validPushTypes An array of valid push types(string) - */ - - -function validatePushType(where = {}, validPushTypes = []) { - var deviceTypeField = where.deviceType || {}; - var deviceTypes = []; - - if (typeof deviceTypeField === 'string') { - deviceTypes.push(deviceTypeField); - } else if (Array.isArray(deviceTypeField['$in'])) { - deviceTypes.concat(deviceTypeField['$in']); - } - - for (var i = 0; i < deviceTypes.length; i++) { - var deviceType = deviceTypes[i]; - - if (validPushTypes.indexOf(deviceType) < 0) { - throw new _node.default.Error(_node.default.Error.PUSH_MISCONFIGURED, deviceType + ' is not supported push type.'); - } - } -} - -function applyDeviceTokenExists(where) { - where = (0, _deepcopy.default)(where); - - if (!Object.prototype.hasOwnProperty.call(where, 'deviceToken')) { - where['deviceToken'] = { - $exists: true - }; - } - - return where; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL3V0aWxzLmpzIl0sIm5hbWVzIjpbImlzUHVzaEluY3JlbWVudGluZyIsImJvZHkiLCJkYXRhIiwiYmFkZ2UiLCJ0b0xvd2VyQ2FzZSIsIl9fb3AiLCJOdW1iZXIiLCJhbW91bnQiLCJsb2NhbGl6YWJsZUtleXMiLCJnZXRMb2NhbGVzRnJvbVB1c2giLCJTZXQiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwibWVtbyIsImtleSIsImZvckVhY2giLCJsb2NhbGl6YWJsZUtleSIsImluZGV4T2YiLCJwdXNoIiwic2xpY2UiLCJsZW5ndGgiLCJ0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZSIsImxvY2FsZSIsImxvY2FsZVZhbHVlIiwic3RyaXBMb2NhbGVzRnJvbUJvZHkiLCJib2RpZXNQZXJMb2NhbGVzIiwibG9jYWxlcyIsInJlc3VsdCIsImRlZmF1bHQiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsImluc3RhbGxhdGlvbnMiLCJtYXAiLCJpbnN0YWxsYXRpb24iLCJhZGRlZCIsImxvY2FsZUlkZW50aWZpZXIiLCJ2YWxpZGF0ZVB1c2hUeXBlIiwid2hlcmUiLCJ2YWxpZFB1c2hUeXBlcyIsImRldmljZVR5cGVGaWVsZCIsImRldmljZVR5cGUiLCJkZXZpY2VUeXBlcyIsIkFycmF5IiwiaXNBcnJheSIsImNvbmNhdCIsImkiLCJQYXJzZSIsIkVycm9yIiwiUFVTSF9NSVNDT05GSUdVUkVEIiwiYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIiRleGlzdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxTQUFTQSxrQkFBVCxDQUE0QkMsSUFBNUIsRUFBa0M7QUFDdkMsTUFBSSxDQUFDQSxJQUFJLENBQUNDLElBQU4sSUFBYyxDQUFDRCxJQUFJLENBQUNDLElBQUwsQ0FBVUMsS0FBN0IsRUFBb0M7QUFDbEMsV0FBTyxLQUFQO0FB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Z0IsTUFBQUEsT0FBTyxFQUFFO0FBQVgsS0FBdkI7QUFDRDs7QUFDRCxTQUFPaEIsS0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGRlZXBjb3B5IGZyb20gJ2RlZXBjb3B5JztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHVzaEluY3JlbWVudGluZyhib2R5KSB7XG4gIGlmICghYm9keS5kYXRhIHx8ICFib2R5LmRhdGEuYmFkZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBiYWRnZSA9IGJvZHkuZGF0YS5iYWRnZTtcbiAgaWYgKHR5cGVvZiBiYWRnZSA9PSAnc3RyaW5nJyAmJiBiYWRnZS50b0xvd2VyQ2FzZSgpID09ICdpbmNyZW1lbnQnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIHR5cGVvZiBiYWRnZSA9PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBiYWRnZS5fX29wID09ICdzdHJpbmcnICYmXG4gICAgYmFkZ2UuX19vcC50b0xvd2VyQ2FzZSgpID09ICdpbmNyZW1lbnQnICYmXG4gICAgTnVtYmVyKGJhZGdlLmFtb3VudClcbiAgKTtcbn1cblxuY29uc3QgbG9jYWxpemFibGVLZXlzID0gWydhbGVydCcsICd0aXRsZSddO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9jYWxlc0Zyb21QdXNoKGJvZHkpIHtcbiAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YTtcbiAgaWYgKCFkYXRhKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBbXG4gICAgLi4ubmV3IFNldChcbiAgICAgIE9iamVjdC5rZXlzKGRhdGEpLnJlZHVjZSgobWVtbywga2V5KSA9PiB7XG4gICAgICAgIGxvY2FsaXphYmxlS2V5cy5mb3JFYWNoKGxvY2FsaXphYmxlS2V5ID0+IHtcbiAgICAgICAgICBpZiAoa2V5LmluZGV4T2YoYCR7bG9jYWxpemFibGVLZXl9LWApID09IDApIHtcbiAgICAgICAgICAgIG1lbW8ucHVzaChrZXkuc2xpY2UobG9jYWxpemFibGVLZXkubGVuZ3RoICsgMSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgfSwgW10pXG4gICAgKSxcbiAgXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVB1c2hCb2R5Rm9yTG9jYWxlKGJvZHksIGxvY2FsZSkge1xuICBjb25zdCBkYXRhID0gYm9keS5kYXRhO1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm4gYm9keTtcbiAgfVxuICBib2R5ID0gZGVlcGNvcHkoYm9keSk7XG4gIGxvY2FsaXphYmxlS2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgY29uc3QgbG9jYWxlVmFsdWUgPSBib2R5LmRhdGFbYCR7a2V5fS0ke2xvY2FsZX1gXTtcbiAgICBpZiAobG9jYWxlVmFsdWUpIHtcbiAgICAgIGJvZHkuZGF0YVtrZXldID0gbG9jYWxlVmFsdWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHN0cmlwTG9jYWxlc0Zyb21Cb2R5KGJvZHkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RyaXBMb2NhbGVzRnJvbUJvZHkoYm9keSkge1xuICBpZiAoIWJvZHkuZGF0YSkge1xuICAgIHJldHVybiBib2R5O1xuICB9XG4gIE9iamVjdC5rZXlzKGJvZHkuZGF0YSkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGxvY2FsaXphYmxlS2V5cy5mb3JFYWNoKGxvY2FsaXphYmxlS2V5ID0+IHtcbiAgICAgIGlmIChrZXkuaW5kZXhPZihgJHtsb2NhbGl6YWJsZUtleX0tYCkgPT0gMCkge1xuICAgICAgICBkZWxldGUgYm9keS5kYXRhW2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gYm9keTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJvZGllc1BlckxvY2FsZXMoYm9keSwgbG9jYWxlcyA9IFtdKSB7XG4gIC8vIEdldCBhbGwgdHJhbmZvcm1lZCBib2RpZXMgZm9yIGVhY2ggbG9jYWxlXG4gIGNvbnN0IHJlc3VsdCA9IGxvY2FsZXMucmVkdWNlKChtZW1vLCBsb2NhbGUpID0+IHtcbiAgICBtZW1vW2xvY2FsZV0gPSB0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZShib2R5LCBsb2NhbGUpO1xuICAgIHJldHVybiBtZW1vO1xuICB9LCB7fSk7XG4gIC8vIFNldCB0aGUgZGVmYXVsdCBsb2NhbGUsIHdpdGggdGhlIHN0cmlwcGVkIGJvZHlcbiAgcmVzdWx0LmRlZmF1bHQgPSBzdHJpcExvY2FsZXNGcm9tQm9keShib2R5KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwQnlMb2NhbGVJZGVudGlmaWVyKGluc3RhbGxhdGlvbnMsIGxvY2FsZXMgPSBbXSkge1xuICByZXR1cm4gaW5zdGFsbGF0aW9ucy5yZWR1Y2UoXG4gICAgKG1hcCwgaW5zdGFsbGF0aW9uKSA9PiB7XG4gICAgICBsZXQgYWRkZWQgPSBmYWxzZTtcbiAgICAgIGxvY2FsZXMuZm9yRWFjaChsb2NhbGUgPT4ge1xuICAgICAgICBpZiAoYWRkZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5sb2NhbGVJZGVudGlmaWVyICYmIGluc3RhbGxhdGlvbi5sb2NhbGVJZGVudGlmaWVyLmluZGV4T2YobG9jYWxlKSA9PT0gMCkge1xuICAgICAgICAgIGFkZGVkID0gdHJ1ZTtcbiAgICAgICAgICBtYXBbbG9jYWxlXSA9IG1hcFtsb2NhbGVdIHx8IFtdO1xuICAgICAgICAgIG1hcFtsb2NhbGVdLnB1c2goaW5zdGFsbGF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoIWFkZGVkKSB7XG4gICAgICAgIG1hcC5kZWZhdWx0LnB1c2goaW5zdGFsbGF0aW9uKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYXA7XG4gICAgfSxcbiAgICB7IGRlZmF1bHQ6IFtdIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIHRoZSBkZXZpY2VUeXBlIHBhcmFtZXRlciBpbiBxdXJ5IGNvbmRpdGlvbiBpcyB2YWxpZCBvciBub3QuXG4gKiBAcGFyYW0ge09iamVjdH0gd2hlcmUgQSBxdWVyeSBjb25kaXRpb25cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbGlkUHVzaFR5cGVzIEFuIGFycmF5IG9mIHZhbGlkIHB1c2ggdHlwZXMoc3RyaW5nKVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQdXNoVHlwZSh3aGVyZSA9IHt9LCB2YWxpZFB1c2hUeXBlcyA9IFtdKSB7XG4gIHZhciBkZXZpY2VUeXBlRmllbGQgPSB3aGVyZS5kZXZpY2VUeXBlIHx8IHt9O1xuICB2YXIgZGV2aWNlVHlwZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBkZXZpY2VUeXBlRmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgZGV2aWNlVHlwZXMucHVzaChkZXZpY2VUeXBlRmllbGQpO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZGV2aWNlVHlwZUZpZWxkWyckaW4nXSkpIHtcbiAgICBkZXZpY2VUeXBlcy5jb25jYXQoZGV2aWNlVHlwZUZpZWxkWyckaW4nXSk7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXZpY2VUeXBlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXZpY2VUeXBlID0gZGV2aWNlVHlwZXNbaV07XG4gICAgaWYgKHZhbGlkUHVzaFR5cGVzLmluZGV4T2YoZGV2aWNlVHlwZSkgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgZGV2aWNlVHlwZSArICcgaXMgbm90IHN1cHBvcnRlZCBwdXNoIHR5cGUuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5RGV2aWNlVG9rZW5FeGlzdHMod2hlcmUpIHtcbiAgd2hlcmUgPSBkZWVwY29weSh3aGVyZSk7XG4gIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHdoZXJlLCAnZGV2aWNlVG9rZW4nKSkge1xuICAgIHdoZXJlWydkZXZpY2VUb2tlbiddID0geyAkZXhpc3RzOiB0cnVlIH07XG4gIH1cbiAgcmV0dXJuIHdoZXJlO1xufVxuIl19 \ No newline at end of file diff --git a/lib/RestQuery.js b/lib/RestQuery.js deleted file mode 100644 index 02d7d0f9d3..0000000000 --- a/lib/RestQuery.js +++ /dev/null @@ -1,978 +0,0 @@ -"use strict"; - -// An object that encapsulates everything we need to run a 'find' -// operation, encoded in the REST API format. -var SchemaController = require('./Controllers/SchemaController'); - -var Parse = require('parse/node').Parse; - -const triggers = require('./triggers'); - -const { - continueWhile -} = require('parse/lib/node/promiseUtils'); - -const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL']; // restOptions can include: -// skip -// limit -// order -// count -// include -// keys -// excludeKeys -// redirectClassNameForKey -// readPreference -// includeReadPreference -// subqueryReadPreference - -function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, clientSDK, runAfterFind = true) { - this.config = config; - this.auth = auth; - this.className = className; - this.restWhere = restWhere; - this.restOptions = restOptions; - this.clientSDK = clientSDK; - this.runAfterFind = runAfterFind; - this.response = null; - this.findOptions = {}; - - if (!this.auth.isMaster) { - if (this.className == '_Session') { - if (!this.auth.user) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - this.restWhere = { - $and: [this.restWhere, { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.auth.user.id - } - }] - }; - } - } - - this.doCount = false; - this.includeAll = false; // The format for this.include is not the same as the format for the - // include option - it's the paths we should include, in order, - // stored as arrays, taking into account that we need to include foo - // before including foo.bar. Also it should dedupe. - // For example, passing an arg of include=foo.bar,foo.baz could lead to - // this.include = [['foo'], ['foo', 'baz'], ['foo', 'bar']] - - this.include = []; // If we have keys, we probably want to force some includes (n-1 level) - // See issue: https://github.com/parse-community/parse-server/issues/3185 - - if (Object.prototype.hasOwnProperty.call(restOptions, 'keys')) { - const keysForInclude = restOptions.keys.split(',').filter(key => { - // At least 2 components - return key.split('.').length > 1; - }).map(key => { - // Slice the last component (a.b.c -> a.b) - // Otherwise we'll include one level too much. - return key.slice(0, key.lastIndexOf('.')); - }).join(','); // Concat the possibly present include string with the one from the keys - // Dedup / sorting is handle in 'include' case. - - if (keysForInclude.length > 0) { - if (!restOptions.include || restOptions.include.length == 0) { - restOptions.include = keysForInclude; - } else { - restOptions.include += ',' + keysForInclude; - } - } - } - - for (var option in restOptions) { - switch (option) { - case 'keys': - { - const keys = restOptions.keys.split(',').concat(AlwaysSelectedKeys); - this.keys = Array.from(new Set(keys)); - break; - } - - case 'excludeKeys': - { - const exclude = restOptions.excludeKeys.split(',').filter(k => AlwaysSelectedKeys.indexOf(k) < 0); - this.excludeKeys = Array.from(new Set(exclude)); - break; - } - - case 'count': - this.doCount = true; - break; - - case 'includeAll': - this.includeAll = true; - break; - - case 'explain': - case 'hint': - case 'distinct': - case 'pipeline': - case 'skip': - case 'limit': - case 'readPreference': - this.findOptions[option] = restOptions[option]; - break; - - case 'order': - var fields = restOptions.order.split(','); - this.findOptions.sort = fields.reduce((sortMap, field) => { - field = field.trim(); - - if (field === '$score') { - sortMap.score = { - $meta: 'textScore' - }; - } else if (field[0] == '-') { - sortMap[field.slice(1)] = -1; - } else { - sortMap[field] = 1; - } - - return sortMap; - }, {}); - break; - - case 'include': - { - const paths = restOptions.include.split(','); - - if (paths.includes('*')) { - this.includeAll = true; - break; - } // Load the existing includes (from keys) - - - const pathSet = paths.reduce((memo, path) => { - // Split each paths on . (a.b.c -> [a,b,c]) - // reduce to create all paths - // ([a,b,c] -> {a: true, 'a.b': true, 'a.b.c': true}) - return path.split('.').reduce((memo, path, index, parts) => { - memo[parts.slice(0, index + 1).join('.')] = true; - return memo; - }, memo); - }, {}); - this.include = Object.keys(pathSet).map(s => { - return s.split('.'); - }).sort((a, b) => { - return a.length - b.length; // Sort by number of components - }); - break; - } - - case 'redirectClassNameForKey': - this.redirectKey = restOptions.redirectClassNameForKey; - this.redirectClassName = null; - break; - - case 'includeReadPreference': - case 'subqueryReadPreference': - break; - - default: - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad option: ' + option); - } - } -} // A convenient method to perform all the steps of processing a query -// in order. -// Returns a promise for the response - an object with optional keys -// 'results' and 'count'. -// TODO: consolidate the replaceX functions - - -RestQuery.prototype.execute = function (executeOptions) { - return Promise.resolve().then(() => { - return this.buildRestWhere(); - }).then(() => { - return this.handleIncludeAll(); - }).then(() => { - return this.handleExcludeKeys(); - }).then(() => { - return this.runFind(executeOptions); - }).then(() => { - return this.runCount(); - }).then(() => { - return this.handleInclude(); - }).then(() => { - return this.runAfterFindTrigger(); - }).then(() => { - return this.response; - }); -}; - -RestQuery.prototype.each = function (callback) { - const { - config, - auth, - className, - restWhere, - restOptions, - clientSDK - } = this; // if the limit is set, use it - - restOptions.limit = restOptions.limit || 100; - restOptions.order = 'objectId'; - let finished = false; - return continueWhile(() => { - return !finished; - }, async () => { - const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); - const { - results - } = await query.execute(); - results.forEach(callback); - finished = results.length < restOptions.limit; - - if (!finished) { - restWhere.objectId = Object.assign({}, restWhere.objectId, { - $gt: results[results.length - 1].objectId - }); - } - }); -}; - -RestQuery.prototype.buildRestWhere = function () { - return Promise.resolve().then(() => { - return this.getUserAndRoleACL(); - }).then(() => { - return this.redirectClassNameForKey(); - }).then(() => { - return this.validateClientClassCreation(); - }).then(() => { - return this.replaceSelect(); - }).then(() => { - return this.replaceDontSelect(); - }).then(() => { - return this.replaceInQuery(); - }).then(() => { - return this.replaceNotInQuery(); - }).then(() => { - return this.replaceEquality(); - }); -}; // Uses the Auth object to get the list of roles, adds the user id - - -RestQuery.prototype.getUserAndRoleACL = function () { - if (this.auth.isMaster) { - return Promise.resolve(); - } - - this.findOptions.acl = ['*']; - - if (this.auth.user) { - return this.auth.getUserRoles().then(roles => { - this.findOptions.acl = this.findOptions.acl.concat(roles, [this.auth.user.id]); - return; - }); - } else { - return Promise.resolve(); - } -}; // Changes the className if redirectClassNameForKey is set. -// Returns a promise. - - -RestQuery.prototype.redirectClassNameForKey = function () { - if (!this.redirectKey) { - return Promise.resolve(); - } // We need to change the class name based on the schema - - - return this.config.database.redirectClassNameForKey(this.className, this.redirectKey).then(newClassName => { - this.className = newClassName; - this.redirectClassName = newClassName; - }); -}; // Validates this operation against the allowClientClassCreation config. - - -RestQuery.prototype.validateClientClassCreation = function () { - if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { - return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { - if (hasClass !== true) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); - } - }); - } else { - return Promise.resolve(); - } -}; - -function transformInQuery(inQueryObject, className, results) { - var values = []; - - for (var result of results) { - values.push({ - __type: 'Pointer', - className: className, - objectId: result.objectId - }); - } - - delete inQueryObject['$inQuery']; - - if (Array.isArray(inQueryObject['$in'])) { - inQueryObject['$in'] = inQueryObject['$in'].concat(values); - } else { - inQueryObject['$in'] = values; - } -} // Replaces a $inQuery clause by running the subquery, if there is an -// $inQuery clause. -// The $inQuery clause turns into an $in with values that are just -// pointers to the objects returned in the subquery. - - -RestQuery.prototype.replaceInQuery = function () { - var inQueryObject = findObjectWithKey(this.restWhere, '$inQuery'); - - if (!inQueryObject) { - return; - } // The inQuery value must have precisely two keys - where and className - - - var inQueryValue = inQueryObject['$inQuery']; - - if (!inQueryValue.where || !inQueryValue.className) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $inQuery'); - } - - const additionalOptions = { - redirectClassNameForKey: inQueryValue.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, inQueryValue.className, inQueryValue.where, additionalOptions); - return subquery.execute().then(response => { - transformInQuery(inQueryObject, subquery.className, response.results); // Recurse to repeat - - return this.replaceInQuery(); - }); -}; - -function transformNotInQuery(notInQueryObject, className, results) { - var values = []; - - for (var result of results) { - values.push({ - __type: 'Pointer', - className: className, - objectId: result.objectId - }); - } - - delete notInQueryObject['$notInQuery']; - - if (Array.isArray(notInQueryObject['$nin'])) { - notInQueryObject['$nin'] = notInQueryObject['$nin'].concat(values); - } else { - notInQueryObject['$nin'] = values; - } -} // Replaces a $notInQuery clause by running the subquery, if there is an -// $notInQuery clause. -// The $notInQuery clause turns into a $nin with values that are just -// pointers to the objects returned in the subquery. - - -RestQuery.prototype.replaceNotInQuery = function () { - var notInQueryObject = findObjectWithKey(this.restWhere, '$notInQuery'); - - if (!notInQueryObject) { - return; - } // The notInQuery value must have precisely two keys - where and className - - - var notInQueryValue = notInQueryObject['$notInQuery']; - - if (!notInQueryValue.where || !notInQueryValue.className) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $notInQuery'); - } - - const additionalOptions = { - redirectClassNameForKey: notInQueryValue.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, notInQueryValue.className, notInQueryValue.where, additionalOptions); - return subquery.execute().then(response => { - transformNotInQuery(notInQueryObject, subquery.className, response.results); // Recurse to repeat - - return this.replaceNotInQuery(); - }); -}; // Used to get the deepest object from json using dot notation. - - -const getDeepestObjectFromKey = (json, key, idx, src) => { - if (key in json) { - return json[key]; - } - - src.splice(1); // Exit Early -}; - -const transformSelect = (selectObject, key, objects) => { - var values = []; - - for (var result of objects) { - values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); - } - - delete selectObject['$select']; - - if (Array.isArray(selectObject['$in'])) { - selectObject['$in'] = selectObject['$in'].concat(values); - } else { - selectObject['$in'] = values; - } -}; // Replaces a $select clause by running the subquery, if there is a -// $select clause. -// The $select clause turns into an $in with values selected out of -// the subquery. -// Returns a possible-promise. - - -RestQuery.prototype.replaceSelect = function () { - var selectObject = findObjectWithKey(this.restWhere, '$select'); - - if (!selectObject) { - return; - } // The select value must have precisely two keys - query and key - - - var selectValue = selectObject['$select']; // iOS SDK don't send where if not set, let it pass - - if (!selectValue.query || !selectValue.key || typeof selectValue.query !== 'object' || !selectValue.query.className || Object.keys(selectValue).length !== 2) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $select'); - } - - const additionalOptions = { - redirectClassNameForKey: selectValue.query.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, selectValue.query.className, selectValue.query.where, additionalOptions); - return subquery.execute().then(response => { - transformSelect(selectObject, selectValue.key, response.results); // Keep replacing $select clauses - - return this.replaceSelect(); - }); -}; - -const transformDontSelect = (dontSelectObject, key, objects) => { - var values = []; - - for (var result of objects) { - values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); - } - - delete dontSelectObject['$dontSelect']; - - if (Array.isArray(dontSelectObject['$nin'])) { - dontSelectObject['$nin'] = dontSelectObject['$nin'].concat(values); - } else { - dontSelectObject['$nin'] = values; - } -}; // Replaces a $dontSelect clause by running the subquery, if there is a -// $dontSelect clause. -// The $dontSelect clause turns into an $nin with values selected out of -// the subquery. -// Returns a possible-promise. - - -RestQuery.prototype.replaceDontSelect = function () { - var dontSelectObject = findObjectWithKey(this.restWhere, '$dontSelect'); - - if (!dontSelectObject) { - return; - } // The dontSelect value must have precisely two keys - query and key - - - var dontSelectValue = dontSelectObject['$dontSelect']; - - if (!dontSelectValue.query || !dontSelectValue.key || typeof dontSelectValue.query !== 'object' || !dontSelectValue.query.className || Object.keys(dontSelectValue).length !== 2) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $dontSelect'); - } - - const additionalOptions = { - redirectClassNameForKey: dontSelectValue.query.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, dontSelectValue.query.className, dontSelectValue.query.where, additionalOptions); - return subquery.execute().then(response => { - transformDontSelect(dontSelectObject, dontSelectValue.key, response.results); // Keep replacing $dontSelect clauses - - return this.replaceDontSelect(); - }); -}; - -const cleanResultAuthData = function (result) { - delete result.password; - - if (result.authData) { - Object.keys(result.authData).forEach(provider => { - if (result.authData[provider] === null) { - delete result.authData[provider]; - } - }); - - if (Object.keys(result.authData).length == 0) { - delete result.authData; - } - } -}; - -const replaceEqualityConstraint = constraint => { - if (typeof constraint !== 'object') { - return constraint; - } - - const equalToObject = {}; - let hasDirectConstraint = false; - let hasOperatorConstraint = false; - - for (const key in constraint) { - if (key.indexOf('$') !== 0) { - hasDirectConstraint = true; - equalToObject[key] = constraint[key]; - } else { - hasOperatorConstraint = true; - } - } - - if (hasDirectConstraint && hasOperatorConstraint) { - constraint['$eq'] = equalToObject; - Object.keys(equalToObject).forEach(key => { - delete constraint[key]; - }); - } - - return constraint; -}; - -RestQuery.prototype.replaceEquality = function () { - if (typeof this.restWhere !== 'object') { - return; - } - - for (const key in this.restWhere) { - this.restWhere[key] = replaceEqualityConstraint(this.restWhere[key]); - } -}; // Returns a promise for whether it was successful. -// Populates this.response with an object that only has 'results'. - - -RestQuery.prototype.runFind = function (options = {}) { - if (this.findOptions.limit === 0) { - this.response = { - results: [] - }; - return Promise.resolve(); - } - - const findOptions = Object.assign({}, this.findOptions); - - if (this.keys) { - findOptions.keys = this.keys.map(key => { - return key.split('.')[0]; - }); - } - - if (options.op) { - findOptions.op = options.op; - } - - return this.config.database.find(this.className, this.restWhere, findOptions, this.auth).then(results => { - if (this.className === '_User' && findOptions.explain !== true) { - for (var result of results) { - cleanResultAuthData(result); - } - } - - this.config.filesController.expandFilesInObject(this.config, results); - - if (this.redirectClassName) { - for (var r of results) { - r.className = this.redirectClassName; - } - } - - this.response = { - results: results - }; - }); -}; // Returns a promise for whether it was successful. -// Populates this.response.count with the count - - -RestQuery.prototype.runCount = function () { - if (!this.doCount) { - return; - } - - this.findOptions.count = true; - delete this.findOptions.skip; - delete this.findOptions.limit; - return this.config.database.find(this.className, this.restWhere, this.findOptions).then(c => { - this.response.count = c; - }); -}; // Augments this.response with all pointers on an object - - -RestQuery.prototype.handleIncludeAll = function () { - if (!this.includeAll) { - return; - } - - return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { - const includeFields = []; - const keyFields = []; - - for (const field in schema.fields) { - if (schema.fields[field].type && schema.fields[field].type === 'Pointer') { - includeFields.push([field]); - keyFields.push(field); - } - } // Add fields to include, keys, remove dups - - - this.include = [...new Set([...this.include, ...includeFields])]; // if this.keys not set, then all keys are already included - - if (this.keys) { - this.keys = [...new Set([...this.keys, ...keyFields])]; - } - }); -}; // Updates property `this.keys` to contain all keys but the ones unselected. - - -RestQuery.prototype.handleExcludeKeys = function () { - if (!this.excludeKeys) { - return; - } - - if (this.keys) { - this.keys = this.keys.filter(k => !this.excludeKeys.includes(k)); - return; - } - - return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { - const fields = Object.keys(schema.fields); - this.keys = fields.filter(k => !this.excludeKeys.includes(k)); - }); -}; // Augments this.response with data at the paths provided in this.include. - - -RestQuery.prototype.handleInclude = function () { - if (this.include.length == 0) { - return; - } - - var pathResponse = includePath(this.config, this.auth, this.response, this.include[0], this.restOptions); - - if (pathResponse.then) { - return pathResponse.then(newResponse => { - this.response = newResponse; - this.include = this.include.slice(1); - return this.handleInclude(); - }); - } else if (this.include.length > 0) { - this.include = this.include.slice(1); - return this.handleInclude(); - } - - return pathResponse; -}; //Returns a promise of a processed set of results - - -RestQuery.prototype.runAfterFindTrigger = function () { - if (!this.response) { - return; - } - - if (!this.runAfterFind) { - return; - } // Avoid doing any setup for triggers if there is no 'afterFind' trigger for this class. - - - const hasAfterFindHook = triggers.triggerExists(this.className, triggers.Types.afterFind, this.config.applicationId); - - if (!hasAfterFindHook) { - return Promise.resolve(); - } // Skip Aggregate and Distinct Queries - - - if (this.findOptions.pipeline || this.findOptions.distinct) { - return Promise.resolve(); - } - - const json = Object.assign({}, this.restOptions); - json.where = this.restWhere; - const parseQuery = new Parse.Query(this.className); - parseQuery.withJSON(json); // Run afterFind trigger and set the new results - - return triggers.maybeRunAfterFindTrigger(triggers.Types.afterFind, this.auth, this.className, this.response.results, this.config, parseQuery).then(results => { - // Ensure we properly set the className back - if (this.redirectClassName) { - this.response.results = results.map(object => { - if (object instanceof Parse.Object) { - object = object.toJSON(); - } - - object.className = this.redirectClassName; - return object; - }); - } else { - this.response.results = results; - } - }); -}; // Adds included values to the response. -// Path is a list of field names. -// Returns a promise for an augmented response. - - -function includePath(config, auth, response, path, restOptions = {}) { - var pointers = findPointers(response.results, path); - - if (pointers.length == 0) { - return response; - } - - const pointersHash = {}; - - for (var pointer of pointers) { - if (!pointer) { - continue; - } - - const className = pointer.className; // only include the good pointers - - if (className) { - pointersHash[className] = pointersHash[className] || new Set(); - pointersHash[className].add(pointer.objectId); - } - } - - const includeRestOptions = {}; - - if (restOptions.keys) { - const keys = new Set(restOptions.keys.split(',')); - const keySet = Array.from(keys).reduce((set, key) => { - const keyPath = key.split('.'); - let i = 0; - - for (i; i < path.length; i++) { - if (path[i] != keyPath[i]) { - return set; - } - } - - if (i < keyPath.length) { - set.add(keyPath[i]); - } - - return set; - }, new Set()); - - if (keySet.size > 0) { - includeRestOptions.keys = Array.from(keySet).join(','); - } - } - - if (restOptions.includeReadPreference) { - includeRestOptions.readPreference = restOptions.includeReadPreference; - includeRestOptions.includeReadPreference = restOptions.includeReadPreference; - } else if (restOptions.readPreference) { - includeRestOptions.readPreference = restOptions.readPreference; - } - - const queryPromises = Object.keys(pointersHash).map(className => { - const objectIds = Array.from(pointersHash[className]); - let where; - - if (objectIds.length === 1) { - where = { - objectId: objectIds[0] - }; - } else { - where = { - objectId: { - $in: objectIds - } - }; - } - - var query = new RestQuery(config, auth, className, where, includeRestOptions); - return query.execute({ - op: 'get' - }).then(results => { - results.className = className; - return Promise.resolve(results); - }); - }); // Get the objects for all these object ids - - return Promise.all(queryPromises).then(responses => { - var replace = responses.reduce((replace, includeResponse) => { - for (var obj of includeResponse.results) { - obj.__type = 'Object'; - obj.className = includeResponse.className; - - if (obj.className == '_User' && !auth.isMaster) { - delete obj.sessionToken; - delete obj.authData; - } - - replace[obj.objectId] = obj; - } - - return replace; - }, {}); - var resp = { - results: replacePointers(response.results, path, replace) - }; - - if (response.count) { - resp.count = response.count; - } - - return resp; - }); -} // Object may be a list of REST-format object to find pointers in, or -// it may be a single object. -// If the path yields things that aren't pointers, this throws an error. -// Path is a list of fields to search into. -// Returns a list of pointers in REST format. - - -function findPointers(object, path) { - if (object instanceof Array) { - var answer = []; - - for (var x of object) { - answer = answer.concat(findPointers(x, path)); - } - - return answer; - } - - if (typeof object !== 'object' || !object) { - return []; - } - - if (path.length == 0) { - if (object === null || object.__type == 'Pointer') { - return [object]; - } - - return []; - } - - var subobject = object[path[0]]; - - if (!subobject) { - return []; - } - - return findPointers(subobject, path.slice(1)); -} // Object may be a list of REST-format objects to replace pointers -// in, or it may be a single object. -// Path is a list of fields to search into. -// replace is a map from object id -> object. -// Returns something analogous to object, but with the appropriate -// pointers inflated. - - -function replacePointers(object, path, replace) { - if (object instanceof Array) { - return object.map(obj => replacePointers(obj, path, replace)).filter(obj => typeof obj !== 'undefined'); - } - - if (typeof object !== 'object' || !object) { - return object; - } - - if (path.length === 0) { - if (object && object.__type === 'Pointer') { - return replace[object.objectId]; - } - - return object; - } - - var subobject = object[path[0]]; - - if (!subobject) { - return object; - } - - var newsub = replacePointers(subobject, path.slice(1), replace); - var answer = {}; - - for (var key in object) { - if (key == path[0]) { - answer[key] = newsub; - } else { - answer[key] = object[key]; - } - } - - return answer; -} // Finds a subobject that has the given key, if there is one. -// Returns undefined otherwise. - - -function findObjectWithKey(root, key) { - if (typeof root !== 'object') { - return; - } - - if (root instanceof Array) { - for (var item of root) { - const answer = findObjectWithKey(item, key); - - if (answer) { - return answer; - } - } - } - - if (root && root[key]) { - return root; - } - - for (var subkey in root) { - const answer = findObjectWithKey(root[subkey], key); - - if (answer) { - return answer; - } - } -} - -module.exports = RestQuery; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0UXVlcnkuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJQYXJzZSIsInRyaWdnZXJzIiwiY29udGludWVXaGlsZSIsIkFsd2F5c1NlbGVjdGVkS2V5cyIsIlJlc3RRdWVyeSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsImNsaWVudFNESyIsInJ1bkFmdGVyRmluZCIsInJlc3BvbnNlIiwiZmluZE9wdGlvbnMiLCJpc01hc3RlciIsInVzZXIiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIiRhbmQiLCJfX3R5cGUiLCJvYmplY3RJZCIsImlkIiwiZG9Db3VudCIsImluY2x1ZGVBbGwiLCJpbmNsdWRlIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwia2V5c0ZvckluY2x1ZGUiLCJrZXlzIiwic3BsaXQiLCJmaWx0ZXIiLCJrZXkiLCJsZW5ndGgiLCJtYXAiLCJzbGljZSIsImxhc3RJbmRleE9mIiwiam9pbiIsIm9wdGlvbiIsImNvbmNhdCIsIkFycmF5IiwiZnJvbSIsIlNldCIsImV4Y2x1ZGUiLCJleGNsdWRlS2V5cyIsImsiLCJpbmRleE9mIiwiZmllbGRzIiwib3JkZXIiLCJzb3J0IiwicmVkdWNlIiwic29ydE1hcCIsImZpZWxkIiwidHJpbSIsInNjb3JlIiwiJG1ldGEiLCJwYXRocyIsImluY2x1ZGVzIiwicGF0aFNldCIsIm1lbW8iLCJwYXRoIiwiaW5kZXgiLCJwYXJ0cyIsInMiLCJhIiwiYiIsInJlZGlyZWN0S2V5IiwicmVkaXJlY3RDbGFzc05hbWVGb3JLZXkiLCJyZWRpcmVjdENsYXNzTmFtZSIsIklOVkFMSURfSlNPTiIsImV4ZWN1dGUiLCJleGVjdXRlT3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImJ1aWxkUmVzdFdoZXJlIiwiaGFuZGxlSW5jbHVkZUFsbCIsImhhbmRsZUV4Y2x1ZGVLZXlzIiwicnVuRmluZCIsInJ1bkNvdW50IiwiaGFuZGxlSW5jbHVkZSIsInJ1bkFmdGVyRmluZFRyaWdnZXIiLCJlYWNoIiwiY2FsbGJhY2siLCJsaW1pdCIsImZpbmlzaGVkIiwicXVlcnkiLCJyZXN1bHRzIiwiZm9yRWFjaCIsImFzc2lnbiIsIiRndCIsImdldFVzZXJBbmRSb2xlQUNMIiwidmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uIiwicmVwbGFjZVNlbGVjdCIsInJlcGxhY2VEb250U2VsZWN0IiwicmVwbGFjZUluUXVlcnkiLCJyZXBsYWNlTm90SW5RdWVyeSIsInJlcGxhY2VFcXVhbGl0eSIsImFjbCIsImdldFVzZXJSb2xlcyIsInJvbGVzIiwiZGF0YWJhc2UiLCJuZXdDbGFzc05hbWUiLCJhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24iLCJzeXN0ZW1DbGFzc2VzIiwibG9hZFNjaGVtYSIsInNjaGVtYUNvbnRyb2xsZXIiLCJoYXNDbGFzcyIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJ0cmFuc2Zvcm1JblF1ZXJ5IiwiaW5RdWVyeU9iamVjdCIsInZhbHVlcyIsInJlc3VsdCIsInB1c2giLCJpc0FycmF5IiwiZmluZE9iamVjdFdpdGhLZXkiLCJpblF1ZXJ5VmFsdWUiLCJ3aGVyZSIsIklOVkFMSURfUVVFUlkiLCJhZGRpdGlvbmFsT3B0aW9ucyIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJyZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5IiwidHJhbnNmb3JtTm90SW5RdWVyeSIsIm5vdEluUXVlcnlPYmplY3QiLCJub3RJblF1ZXJ5VmFsdWUiLCJnZXREZWVwZXN0T2JqZWN0RnJvbUtleSIsImpzb24iLCJpZHgiLCJzcmMiLCJzcGxpY2UiLCJ0cmFuc2Zvcm1TZWxlY3QiLCJzZWxlY3RPYmplY3QiLCJvYmplY3RzIiwic2VsZWN0VmFsdWUiLCJ0cmFuc2Zvcm1Eb250U2VsZWN0IiwiZG9udFNlbGVjdE9iamVjdCIsImRvbnRTZWxlY3RWYWx1ZSIsImNsZWFuUmVzdWx0QXV0aERhdGEiLCJwYXNzd29yZCIsImF1dGhEYXRhIiwicHJvdmlkZXIiLCJyZXBsYWNlRXF1YWxpdHlDb25zdHJhaW50IiwiY29uc3RyYWludCIsImVxdWFsVG9PYmplY3QiLCJoYXNEaXJlY3RDb25zdHJhaW50IiwiaGFzT3BlcmF0b3JDb25zdHJhaW50Iiwib3B0aW9ucyIsIm9wIiwiZmluZCIsImV4cGxhaW4iLCJmaWxlc0NvbnRyb2xsZXIiLCJleHBhbmRGaWxlc0luT2JqZWN0IiwiciIsImNvdW50Iiwic2tpcCIsImMiLCJnZXRPbmVTY2hlbWEiLCJzY2hlbWEiLCJpbmNsdWRlRmllbGRzIiwia2V5RmllbGRzIiwidHlwZSIsInBhdGhSZXNwb25zZSIsImluY2x1ZGVQYXRoIiwibmV3UmVzcG9uc2UiLCJoYXNBZnRlckZpbmRIb29rIiwidHJpZ2dlckV4aXN0cyIsIlR5cGVzIiwiYWZ0ZXJGaW5kIiwiYXBwbGljYXRpb25JZCIsInBpcGVsaW5lIiwiZGlzdGluY3QiLCJwYXJzZVF1ZXJ5IiwiUXVlcnkiLCJ3aXRoSlNPTiIsIm1heWJlUnVuQWZ0ZXJGaW5kVHJpZ2dlciIsIm9iamVjdCIsInRvSlNPTiIsInBvaW50ZXJzIiwiZmluZFBvaW50ZXJzIiwicG9pbnRlcnNIYXNoIiwicG9pbnRlciIsImFkZCIsImluY2x1ZGVSZXN0T3B0aW9ucyIsImtleVNldCIsInNldCIsImtleVBhdGgiLCJpIiwic2l6ZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInF1ZXJ5UHJvbWlzZXMiLCJvYmplY3RJZHMiLCIkaW4iLCJhbGwiLCJyZXNwb25zZXMiLCJyZXBsYWNlIiwiaW5jbHVkZVJlc3BvbnNlIiwib2JqIiwic2Vzc2lvblRva2VuIiwicmVzcCIsInJlcGxhY2VQb2ludGVycyIsImFuc3dlciIsIngiLCJzdWJvYmplY3QiLCJuZXdzdWIiLCJyb290IiwiaXRlbSIsInN1YmtleSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUVBLElBQUlBLGdCQUFnQixHQUFHQyxPQUFPLENBQUMsZ0NBQUQsQ0FBOUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQzs7QUFDQSxNQUFNQyxRQUFRLEdBQUdGLE9BQU8sQ0FBQyxZQUFELENBQXhCOztBQUNBLE1BQU07QUFBRUcsRUFBQUE7QUFBRixJQUFvQkgsT0FBTyxDQUFDLDZCQUFELENBQWpDOztBQUNBLE1BQU1JLGtCQUFrQixHQUFHLENBQUMsVUFBRCxFQUFhLFdBQWIsRUFBMEIsV0FBMUIsRUFBdUMsS0FBdkMsQ0FBM0IsQyxDQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxTQUFTQyxTQUFULENBQ0VDLE1BREYsRUFFRUMsSUFGRixFQUdFQyxTQUhGLEVBSUVDLFNBQVMsR0FBRyxFQUpkLEVBS0VDLFdBQVcsR0FBRyxFQUxoQixFQU1FQyxTQU5GLEVBT0VDLFlBQVksR0FBRyxJQVBqQixFQVFFO0FBQ0EsT0FBS04sTUFBTCxHQUFjQSxNQUFkO0FBQ0EsT0FBS0MsSUFBTCxHQUFZQSxJQUFaO0FBQ0EsT0FBS0MsU0FBTCxHQUFpQkEsU0FBakI7QUFDQSxPQUFLQyxTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLE9BQUtDLFdBQUwsR0FBbUJBLFdBQW5CO0FBQ0EsT0FBS0MsU0FBTCxHQUFpQkEsU0FBakI7QUFDQSxPQUFLQyxZQUFMLEdBQW9CQSxZQUFwQjtBQUNBLE9BQUtDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQSxPQUFLQyxXQUFMLEdBQW1CLEVBQW5COztBQUVBLE1BQUksQ0FBQyxLQUFLUCxJQUFMLENBQVVRLFFBQWYsRUFBeUI7QUFDdkIsUUFBSSxLQUFLUCxTQUFMLElBQWtCLFVBQXRCLEVBQWtDO0FBQ2hDLFVBQUksQ0FBQyxLQUFLRCxJQUFMLENBQVVTLElBQWYsRUFBcUI7QUFDbkIsY0FBTSxJQUFJZixLQUFLLENBQUNnQixLQUFWLENBQWdCaEIsS0FBSyxDQUFDZ0IsS0FBTixDQUFZQyxxQkFBNUIsRUFBbUQsdUJBQW5ELENBQU47QUFDRDs7QUFDRCxXQUFLVCxTQUFMLEdBQWlCO0FBQ2ZVLFFBQUFBLElBQUksRUFBRSxDQUNKLEtBQUtWLFNBREQsRUFFSjtBQUNFTyxVQUFBQSxJQUFJLEVBQUU7QUFDSkksWUFBQUEsTUFBTSxFQUFFLFNBREo7QUFFSlosWUFBQUEsU0FBUyxFQUFFLE9BRlA7QUFHSmEsWUFBQUEsUUFBUSxFQUFFLEtBQUtkLElBQUwsQ0FBVVMsSUFBVixDQUFlTTtBQUhyQjtBQURSLFNBRkk7QUFEUyxPQUFqQjtBQVlEO0FBQ0Y7O0FBRUQsT0FBS0MsT0FBTCxHQUFlLEtBQWY7QUFDQSxPQUFLQyxVQUFMLEdBQWtCLEtBQWxCLENBaENBLENBa0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxPQUFLQyxPQUFMLEdBQWUsRUFBZixDQXhDQSxDQTBDQTtBQUNBOztBQUNBLE1BQUlDLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDbkIsV0FBckMsRUFBa0QsTUFBbEQsQ0FBSixFQUErRDtBQUM3RCxVQUFNb0IsY0FBYyxHQUFHcEIsV0FBVyxDQUFDcUIsSUFBWixDQUNwQkMsS0FEb0IsQ0FDZCxHQURjLEVBRXBCQyxNQUZvQixDQUViQyxHQUFHLElBQUk7QUFDYjtBQUNBLGFBQU9BLEdBQUcsQ0FBQ0YsS0FBSixDQUFVLEdBQVYsRUFBZUcsTUFBZixHQUF3QixDQUEvQjtBQUNELEtBTG9CLEVBTXBCQyxHQU5vQixDQU1oQkYsR0FBRyxJQUFJO0FBQ1Y7QUFDQTtBQUNBLGFBQU9BLEdBQUcsQ0FBQ0csS0FBSixDQUFVLENBQVYsRUFBYUgsR0FBRyxDQUFDSSxXQUFKLENBQWdCLEdBQWhCLENBQWIsQ0FBUDtBQUNELEtBVm9CLEVBV3BCQyxJQVhvQixDQVdmLEdBWGUsQ0FBdkIsQ0FENkQsQ0FjN0Q7QUFDQTs7QUFDQSxRQUFJVCxjQUFjLENBQUNLLE1BQWYsR0FBd0IsQ0FBNUIsRUFBK0I7QUFDN0IsVUFBSSxDQUFDekIsV0FBVyxDQUFDZSxPQUFiLElBQXdCZixXQUFXLENBQUNlLE9BQVosQ0FBb0JVLE1BQXBCLElBQThCLENBQTFELEVBQTZEO0FBQzNEekIsUUFBQUEsV0FBVyxDQUFDZSxPQUFaLEdBQXNCSyxjQUF0QjtBQUNELE9BRkQsTUFFTztBQUNMcEIsUUFBQUEsV0FBVyxDQUFDZSxPQUFaLElBQXVCLE1BQU1LLGNBQTdCO0FBQ0Q7QUFDRjtBQUNGOztBQUVELE9BQUssSUFBSVUsTUFBVCxJQUFtQjlCLFdBQW5CLEVBQWdDO0FBQzlCLFlBQVE4QixNQUFSO0FBQ0UsV0FBSyxNQUFMO0FBQWE7QUFDWCxnQkFBTVQsSUFBSSxHQUFHckIsV0FBVyxDQUFDcUIsSUFBWixDQUFpQkMsS0FBakIsQ0FBdUIsR0FBdkIsRUFBNEJTLE1BQTVCLENBQW1DckMsa0JBQW5DLENBQWI7QUFDQSxlQUFLMkIsSUFBTCxHQUFZVyxLQUFLLENBQUNDLElBQU4sQ0FBVyxJQUFJQyxHQUFKLENBQVFiLElBQVIsQ0FBWCxDQUFaO0FBQ0E7QUFDRDs7QUFDRCxXQUFLLGFBQUw7QUFBb0I7QUFDbEIsZ0JBQU1jLE9BQU8sR0FBR25DLFdBQVcsQ0FBQ29DLFdBQVosQ0FDYmQsS0FEYSxDQUNQLEdBRE8sRUFFYkMsTUFGYSxDQUVOYyxDQUFDLElBQUkzQyxrQkFBa0IsQ0FBQzRDLE9BQW5CLENBQTJCRCxDQUEzQixJQUFnQyxDQUYvQixDQUFoQjtBQUdBLGVBQUtELFdBQUwsR0FBbUJKLEtBQUssQ0FBQ0MsSUFBTixDQUFXLElBQUlDLEdBQUosQ0FBUUMsT0FBUixDQUFYLENBQW5CO0FBQ0E7QUFDRDs7QUFDRCxXQUFLLE9BQUw7QUFDRSxhQUFLdEIsT0FBTCxHQUFlLElBQWY7QUFDQTs7QUFDRixXQUFLLFlBQUw7QUFDRSxhQUFLQyxVQUFMLEdBQWtCLElBQWxCO0FBQ0E7O0FBQ0YsV0FBSyxTQUFMO0FBQ0EsV0FBSyxNQUFMO0FBQ0EsV0FBSyxVQUFMO0FBQ0EsV0FBSyxVQUFMO0FBQ0EsV0FBSyxNQUFMO0FBQ0EsV0FBSyxPQUFMO0FBQ0EsV0FBSyxnQkFBTDtBQUNFLGFBQUtWLFdBQUwsQ0FBaUIwQixNQUFqQixJQUEyQjlCLFdBQVcsQ0FBQzhCLE1BQUQsQ0FBdEM7QUFDQTs7QUFDRixXQUFLLE9BQUw7QUFDRSxZQUFJUyxNQUFNLEdBQUd2QyxXQUFXLENBQUN3QyxLQUFaLENBQWtCbEIsS0FBbEIsQ0FBd0IsR0FBeEIsQ0FBYjtBQUNBLGFBQUtsQixXQUFMLENBQWlCcUMsSUFBakIsR0FBd0JGLE1BQU0sQ0FBQ0csTUFBUCxDQUFjLENBQUNDLE9BQUQsRUFBVUMsS0FBVixLQUFvQjtBQUN4REEsVUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNDLElBQU4sRUFBUjs7QUFDQSxjQUFJRCxLQUFLLEtBQUssUUFBZCxFQUF3QjtBQUN0QkQsWUFBQUEsT0FBTyxDQUFDRyxLQUFSLEdBQWdCO0FBQUVDLGNBQUFBLEtBQUssRUFBRTtBQUFULGFBQWhCO0FBQ0QsV0FGRCxNQUVPLElBQUlILEtBQUssQ0FBQyxDQUFELENBQUwsSUFBWSxHQUFoQixFQUFxQjtBQUMxQkQsWUFBQUEsT0FBTyxDQUFDQyxLQUFLLENBQUNqQixLQUFOLENBQVksQ0FBWixDQUFELENBQVAsR0FBMEIsQ0FBQyxDQUEzQjtBQUNELFdBRk0sTUFFQTtBQUNMZ0IsWUFBQUEsT0FBTyxDQUFDQyxLQUFELENBQVAsR0FBaUIsQ0FBakI7QUFDRDs7QUFDRCxpQkFBT0QsT0FBUDtBQUNELFNBVnVCLEVBVXJCLEVBVnFCLENBQXhCO0FBV0E7O0FBQ0YsV0FBSyxTQUFMO0FBQWdCO0FBQ2QsZ0JBQU1LLEtBQUssR0FBR2hELFdBQVcsQ0FBQ2UsT0FBWixDQUFvQk8sS0FBcEIsQ0FBMEIsR0FBMUIsQ0FBZDs7QUFDQSxjQUFJMEIsS0FBSyxDQUFDQyxRQUFOLENBQWUsR0FBZixDQUFKLEVBQXlCO0FBQ3ZCLGlCQUFLbkMsVUFBTCxHQUFrQixJQUFsQjtBQUNBO0FBQ0QsV0FMYSxDQU1kOzs7QUFDQSxnQkFBTW9DLE9BQU8sR0FBR0YsS0FBSyxDQUFDTixNQUFOLENBQWEsQ0FBQ1MsSUFBRCxFQUFPQyxJQUFQLEtBQWdCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBLG1CQUFPQSxJQUFJLENBQUM5QixLQUFMLENBQVcsR0FBWCxFQUFnQm9CLE1BQWhCLENBQXVCLENBQUNTLElBQUQsRUFBT0MsSUFBUCxFQUFhQyxLQUFiLEVBQW9CQyxLQUFwQixLQUE4QjtBQUMxREgsY0FBQUEsSUFBSSxDQUFDRyxLQUFLLENBQUMzQixLQUFOLENBQVksQ0FBWixFQUFlMEIsS0FBSyxHQUFHLENBQXZCLEVBQTBCeEIsSUFBMUIsQ0FBK0IsR0FBL0IsQ0FBRCxDQUFKLEdBQTRDLElBQTVDO0FBQ0EscUJBQU9zQixJQUFQO0FBQ0QsYUFITSxFQUdKQSxJQUhJLENBQVA7QUFJRCxXQVJlLEVBUWIsRUFSYSxDQUFoQjtBQVVBLGVBQUtwQyxPQUFMLEdBQWVDLE1BQU0sQ0FBQ0ssSUFBUCxDQUFZNkIsT0FBWixFQUNaeEIsR0FEWSxDQUNSNkIsQ0FBQyxJQUFJO0FBQ1IsbUJBQU9BLENBQUMsQ0FBQ2pDLEtBQUYsQ0FBUSxHQUFSLENBQVA7QUFDRCxXQUhZLEVBSVptQixJQUpZLENBSVAsQ0FBQ2UsQ0FBRCxFQUFJQyxDQUFKLEtBQVU7QUFDZCxtQkFBT0QsQ0FBQyxDQUFDL0IsTUFBRixHQUFXZ0MsQ0FBQyxDQUFDaEMsTUFBcEIsQ0FEYyxDQUNjO0FBQzdCLFdBTlksQ0FBZjtBQU9BO0FBQ0Q7O0FBQ0QsV0FBSyx5QkFBTDtBQUNFLGFBQUtpQyxXQUFMLEdBQW1CMUQsV0FBVyxDQUFDMkQsdUJBQS9CO0FBQ0EsYUFBS0MsaUJBQUwsR0FBeUIsSUFBekI7QUFDQTs7QUFDRixXQUFLLHVCQUFMO0FBQ0EsV0FBSyx3QkFBTDtBQUNFOztBQUNGO0FBQ0UsY0FBTSxJQUFJckUsS0FBSyxDQUFDZ0IsS0FBVixDQUFnQmhCLEtBQUssQ0FBQ2dCLEtBQU4sQ0FBWXNELFlBQTVCLEVBQTBDLGlCQUFpQi9CLE1BQTNELENBQU47QUE1RUo7QUE4RUQ7QUFDRixDLENBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0FuQyxTQUFTLENBQUNzQixTQUFWLENBQW9CNkMsT0FBcEIsR0FBOEIsVUFBVUMsY0FBVixFQUEwQjtBQUN0RCxTQUFPQyxPQUFPLENBQUNDLE9BQVIsR0FDSkMsSUFESSxDQUNDLE1BQU07QUFDVixXQUFPLEtBQUtDLGNBQUwsRUFBUDtBQUNELEdBSEksRUFJSkQsSUFKSSxDQUlDLE1BQU07QUFDVixXQUFPLEtBQUtFLGdCQUFMLEVBQVA7QUFDRCxHQU5JLEVBT0pGLElBUEksQ0FPQyxNQUFNO0FBQ1YsV0FBTyxLQUFLRyxpQkFBTCxFQUFQO0FBQ0QsR0FUSSxFQVVKSCxJQVZJLENBVUMsTUFBTTtBQUNWLFdBQU8sS0FBS0ksT0FBTCxDQUFhUCxjQUFiLENBQVA7QUFDRCxHQVpJLEVBYUpHLElBYkksQ0FhQyxNQUFNO0FBQ1YsV0FBTyxLQUFLSyxRQUFMLEVBQVA7QUFDRCxHQWZJLEVBZ0JKTCxJQWhCSSxDQWdCQyxNQUFNO0FBQ1YsV0FBTyxLQUFLTSxhQUFMLEVBQVA7QUFDRCxHQWxCSSxFQW1CSk4sSUFuQkksQ0FtQkMsTUFBTTtBQUNWLFdBQU8sS0FBS08sbUJBQUwsRUFBUDtBQUNELEdBckJJLEVBc0JKUCxJQXRCSSxDQXNCQyxNQUFNO0FBQ1YsV0FBTyxLQUFLL0QsUUFBWjtBQUNELEdBeEJJLENBQVA7QUF5QkQsQ0ExQkQ7O0FBNEJBUixTQUFTLENBQUNzQixTQUFWLENBQW9CeUQsSUFBcEIsR0FBMkIsVUFBVUMsUUFBVixFQUFvQjtBQUM3QyxRQUFNO0FBQUUvRSxJQUFBQSxNQUFGO0FBQVVDLElBQUFBLElBQVY7QUFBZ0JDLElBQUFBLFNBQWhCO0FBQTJCQyxJQUFBQSxTQUEzQjtBQUFzQ0MsSUFBQUEsV0FBdEM7QUFBbURDLElBQUFBO0FBQW5ELE1BQWlFLElBQXZFLENBRDZDLENBRTdDOztBQUNBRCxFQUFBQSxXQUFXLENBQUM0RSxLQUFaLEdBQW9CNUUsV0FBVyxDQUFDNEUsS0FBWixJQUFxQixHQUF6QztBQUNBNUUsRUFBQUEsV0FBVyxDQUFDd0MsS0FBWixHQUFvQixVQUFwQjtBQUNBLE1BQUlxQyxRQUFRLEdBQUcsS0FBZjtBQUVBLFNBQU9wRixhQUFhLENBQ2xCLE1BQU07QUFDSixXQUFPLENBQUNvRixRQUFSO0FBQ0QsR0FIaUIsRUFJbEIsWUFBWTtBQUNWLFVBQU1DLEtBQUssR0FBRyxJQUFJbkYsU0FBSixDQUFjQyxNQUFkLEVBQXNCQyxJQUF0QixFQUE0QkMsU0FBNUIsRUFBdUNDLFNBQXZDLEVBQWtEQyxXQUFsRCxFQUErREMsU0FBL0QsQ0FBZDtBQUNBLFVBQU07QUFBRThFLE1BQUFBO0FBQUYsUUFBYyxNQUFNRCxLQUFLLENBQUNoQixPQUFOLEVBQTFCO0FBQ0FpQixJQUFBQSxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JMLFFBQWhCO0FBQ0FFLElBQUFBLFFBQVEsR0FBR0UsT0FBTyxDQUFDdEQsTUFBUixHQUFpQnpCLFdBQVcsQ0FBQzRFLEtBQXhDOztBQUNBLFFBQUksQ0FBQ0MsUUFBTCxFQUFlO0FBQ2I5RSxNQUFBQSxTQUFTLENBQUNZLFFBQVYsR0FBcUJLLE1BQU0sQ0FBQ2lFLE1BQVAsQ0FBYyxFQUFkLEVBQWtCbEYsU0FBUyxDQUFDWSxRQUE1QixFQUFzQztBQUN6RHVFLFFBQUFBLEdBQUcsRUFBRUgsT0FBTyxDQUFDQSxPQUFPLENBQUN0RCxNQUFSLEdBQWlCLENBQWxCLENBQVAsQ0FBNEJkO0FBRHdCLE9BQXRDLENBQXJCO0FBR0Q7QUFDRixHQWRpQixDQUFwQjtBQWdCRCxDQXZCRDs7QUF5QkFoQixTQUFTLENBQUNzQixTQUFWLENBQW9Ca0QsY0FBcEIsR0FBcUMsWUFBWTtBQUMvQyxTQUFPSCxPQUFPLENBQUNDLE9BQVIsR0FDSkMsSUFESSxDQUNDLE1BQU07QUFDVixXQUFPLEtBQUtpQixpQkFBTCxFQUFQO0FBQ0QsR0FISSxFQUlKakIsSUFKSSxDQUlDLE1BQU07QUFDVixXQUFPLEtBQUtQLHVCQUFMLEVBQVA7QUFDRCxHQU5JLEVBT0pPLElBUEksQ0FPQyxNQUFNO0FBQ1YsV0FBTyxLQUFLa0IsMkJBQUwsRUFBUDtBQUNELEdBVEksRUFVSmxCLElBVkksQ0FVQyxNQUFNO0FBQ1YsV0FBTyxLQUFLbUIsYUFBTCxFQUFQO0FBQ0QsR0FaSSxFQWFKbkIsSUFiSSxDQWFDLE1BQU07QUFDVixXQUFPLEtBQUtvQixpQkFBTCxFQUFQO0FBQ0QsR0FmSSxFQWdCSnBCLElBaEJJLENBZ0JDLE1BQU07QUFDVixXQUFPLEtBQUtxQixjQUFMLEVBQVA7QUFDRCxHQWxCSSxFQW1CSnJCLElBbkJJLENBbUJDLE1BQU07QUFDVixXQUFPLEtBQUtzQixpQkFBTCxFQUFQO0FBQ0QsR0FyQkksRUFzQkp0QixJQXRCSSxDQXNCQyxNQUFNO0FBQ1YsV0FBTyxLQUFLdUIsZUFBTCxFQUFQO0FBQ0QsR0F4QkksQ0FBUDtBQXlCRCxDQTFCRCxDLENBNEJBOzs7QUFDQTlGLFNBQVMsQ0FBQ3NCLFNBQVYsQ0FBb0JrRSxpQkFBcEIsR0FBd0MsWUFBWTtBQUNsRCxNQUFJLEtBQUt0RixJQUFMLENBQVVRLFFBQWQsRUFBd0I7QUFDdEIsV0FBTzJELE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsT0FBSzdELFdBQUwsQ0FBaUJzRixHQUFqQixHQUF1QixDQUFDLEdBQUQsQ0FBdkI7O0FBRUEsTUFBSSxLQUFLN0YsSUFBTCxDQUFVUyxJQUFkLEVBQW9CO0FBQ2xCLFdBQU8sS0FBS1QsSUFBTCxDQUFVOEYsWUFBVixHQUF5QnpCLElBQXpCLENBQThCMEIsS0FBSyxJQUFJO0FBQzVDLFdBQUt4RixXQUFMLENBQWlCc0YsR0FBakIsR0FBdUIsS0FBS3RGLFdBQUwsQ0FBaUJzRixHQUFqQixDQUFxQjNELE1BQXJCLENBQTRCNkQsS0FBNUIsRUFBbUMsQ0FBQyxLQUFLL0YsSUFBTCxDQUFVUyxJQUFWLENBQWVNLEVBQWhCLENBQW5DLENBQXZCO0FBQ0E7QUFDRCxLQUhNLENBQVA7QUFJRCxHQUxELE1BS087QUFDTCxXQUFPb0QsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDtBQUNGLENBZkQsQyxDQWlCQTtBQUNBOzs7QUFDQXRFLFNBQVMsQ0FBQ3NCLFNBQVYsQ0FBb0IwQyx1QkFBcEIsR0FBOEMsWUFBWTtBQUN4RCxNQUFJLENBQUMsS0FBS0QsV0FBVixFQUF1QjtBQUNyQixXQUFPTSxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEdBSHVELENBS3hEOzs7QUFDQSxTQUFPLEtBQUtyRSxNQUFMLENBQVlpRyxRQUFaLENBQ0psQyx1QkFESSxDQUNvQixLQUFLN0QsU0FEekIsRUFDb0MsS0FBSzRELFdBRHpDLEVBRUpRLElBRkksQ0FFQzRCLFlBQVksSUFBSTtBQUNwQixTQUFLaEcsU0FBTCxHQUFpQmdHLFlBQWpCO0FBQ0EsU0FBS2xDLGlCQUFMLEdBQXlCa0MsWUFBekI7QUFDRCxHQUxJLENBQVA7QUFNRCxDQVpELEMsQ0FjQTs7O0FBQ0FuRyxTQUFTLENBQUNzQixTQUFWLENBQW9CbUUsMkJBQXBCLEdBQWtELFlBQVk7QUFDNUQsTUFDRSxLQUFLeEYsTUFBTCxDQUFZbUcsd0JBQVosS0FBeUMsS0FBekMsSUFDQSxDQUFDLEtBQUtsRyxJQUFMLENBQVVRLFFBRFgsSUFFQWhCLGdCQUFnQixDQUFDMkcsYUFBakIsQ0FBK0IxRCxPQUEvQixDQUF1QyxLQUFLeEMsU0FBNUMsTUFBMkQsQ0FBQyxDQUg5RCxFQUlFO0FBQ0EsV0FBTyxLQUFLRixNQUFMLENBQVlpRyxRQUFaLENBQ0pJLFVBREksR0FFSi9CLElBRkksQ0FFQ2dDLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ0MsUUFBakIsQ0FBMEIsS0FBS3JHLFNBQS9CLENBRnJCLEVBR0pvRSxJQUhJLENBR0NpQyxRQUFRLElBQUk7QUFDaEIsVUFBSUEsUUFBUSxLQUFLLElBQWpCLEVBQXVCO0FBQ3JCLGNBQU0sSUFBSTVHLEtBQUssQ0FBQ2dCLEtBQVYsQ0FDSmhCLEtBQUssQ0FBQ2dCLEtBQU4sQ0FBWTZGLG1CQURSLEVBRUosd0NBQXdDLHNCQUF4QyxHQUFpRSxLQUFLdEcsU0FGbEUsQ0FBTjtBQUlEO0FBQ0YsS0FWSSxDQUFQO0FBV0QsR0FoQkQsTUFnQk87QUFDTCxXQUFPa0UsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDtBQUNGLENBcEJEOztBQXNCQSxTQUFTb0MsZ0JBQVQsQ0FBMEJDLGFBQTFCLEVBQXlDeEcsU0FBekMsRUFBb0RpRixPQUFwRCxFQUE2RDtBQUMzRCxNQUFJd0IsTUFBTSxHQUFHLEVBQWI7O0FBQ0EsT0FBSyxJQUFJQyxNQUFULElBQW1CekIsT0FBbkIsRUFBNEI7QUFDMUJ3QixJQUFBQSxNQUFNLENBQUNFLElBQVAsQ0FBWTtBQUNWL0YsTUFBQUEsTUFBTSxFQUFFLFNBREU7QUFFVlosTUFBQUEsU0FBUyxFQUFFQSxTQUZEO0FBR1ZhLE1BQUFBLFFBQVEsRUFBRTZGLE1BQU0sQ0FBQzdGO0FBSFAsS0FBWjtBQUtEOztBQUNELFNBQU8yRixhQUFhLENBQUMsVUFBRCxDQUFwQjs7QUFDQSxNQUFJdEUsS0FBSyxDQUFDMEUsT0FBTixDQUFjSixhQUFhLENBQUMsS0FBRCxDQUEzQixDQUFKLEVBQXlDO0FBQ3ZDQSxJQUFBQSxhQUFhLENBQUMsS0FBRCxDQUFiLEdBQXVCQSxhQUFhLENBQUMsS0FBRCxDQUFiLENBQXFCdkUsTUFBckIsQ0FBNEJ3RSxNQUE1QixDQUF2QjtBQUNELEdBRkQsTUFFTztBQUNMRCxJQUFBQSxhQUFhLENBQUMsS0FBRCxDQUFiLEdBQXVCQyxNQUF2QjtBQUNEO0FBQ0YsQyxDQUVEO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTVHLFNBQVMsQ0FBQ3NCLFNBQVYsQ0FBb0JzRSxjQUFwQixHQUFxQyxZQUFZO0FBQy9DLE1BQUllLGFBQWEsR0FBR0ssaUJBQWlCLENBQUMsS0FBSzVHLFNBQU4sRUFBaUIsVUFBakIsQ0FBckM7O0FBQ0EsTUFBSSxDQUFDdUcsYUFBTCxFQUFvQjtBQUNsQjtBQUNELEdBSjhDLENBTS9DOzs7QUFDQSxNQUFJTSxZQUFZLEdBQUdOLGFBQWEsQ0FBQyxVQUFELENBQWhDOztBQUNBLE1BQUksQ0FBQ00sWUFBWSxDQUFDQyxLQUFkLElBQXVCLENBQUNELFlBQVksQ0FBQzlHLFNBQXpDLEVBQW9EO0FBQ2xELFVBQU0sSUFBSVAsS0FBSyxDQUFDZ0IsS0FBVixDQUFnQmhCLEtBQUssQ0FBQ2dCLEtBQU4sQ0FBWXVHLGFBQTVCLEVBQTJDLDRCQUEzQyxDQUFOO0FBQ0Q7O0FBRUQsUUFBTUMsaUJBQWlCLEdBQUc7QUFDeEJwRCxJQUFBQSx1QkFBdUIsRUFBRWlELFlBQVksQ0FBQ2pEO0FBRGQsR0FBMUI7O0FBSUEsTUFBSSxLQUFLM0QsV0FBTCxDQUFpQmdILHNCQUFyQixFQUE2QztBQUMzQ0QsSUFBQUEsaUJBQWlCLENBQUNFLGNBQWxCLEdBQW1DLEtBQUtqSCxXQUFMLENBQWlCZ0gsc0JBQXBEO0FBQ0FELElBQUFBLGlCQUFpQixDQUFDQyxzQkFBbEIsR0FBMkMsS0FBS2hILFdBQUwsQ0FBaUJnSCxzQkFBNUQ7QUFDRCxHQUhELE1BR08sSUFBSSxLQUFLaEgsV0FBTCxDQUFpQmlILGNBQXJCLEVBQXFDO0FBQzFDRixJQUFBQSxpQkFBaUIsQ0FBQ0UsY0FBbEIsR0FBbUMsS0FBS2pILFdBQUwsQ0FBaUJpSCxjQUFwRDtBQUNEOztBQUVELE1BQUlDLFFBQVEsR0FBRyxJQUFJdkgsU0FBSixDQUNiLEtBQUtDLE1BRFEsRUFFYixLQUFLQyxJQUZRLEVBR2IrRyxZQUFZLENBQUM5RyxTQUhBLEVBSWI4RyxZQUFZLENBQUNDLEtBSkEsRUFLYkUsaUJBTGEsQ0FBZjtBQU9BLFNBQU9HLFFBQVEsQ0FBQ3BELE9BQVQsR0FBbUJJLElBQW5CLENBQXdCL0QsUUFBUSxJQUFJO0FBQ3pDa0csSUFBQUEsZ0JBQWdCLENBQUNDLGFBQUQsRUFBZ0JZLFFBQVEsQ0FBQ3BILFNBQXpCLEVBQW9DSyxRQUFRLENBQUM0RSxPQUE3QyxDQUFoQixDQUR5QyxDQUV6Qzs7QUFDQSxXQUFPLEtBQUtRLGNBQUwsRUFBUDtBQUNELEdBSk0sQ0FBUDtBQUtELENBbkNEOztBQXFDQSxTQUFTNEIsbUJBQVQsQ0FBNkJDLGdCQUE3QixFQUErQ3RILFNBQS9DLEVBQTBEaUYsT0FBMUQsRUFBbUU7QUFDakUsTUFBSXdCLE1BQU0sR0FBRyxFQUFiOztBQUNBLE9BQUssSUFBSUMsTUFBVCxJQUFtQnpCLE9BQW5CLEVBQTRCO0FBQzFCd0IsSUFBQUEsTUFBTSxDQUFDRSxJQUFQLENBQVk7QUFDVi9GLE1BQUFBLE1BQU0sRUFBRSxTQURFO0FBRVZaLE1BQUFBLFNBQVMsRUFBRUEsU0FGRDtBQUdWYSxNQUFBQSxRQUFRLEVBQUU2RixNQUFNLENBQUM3RjtBQUhQLEtBQVo7QUFLRDs7QUFDRCxTQUFPeUcsZ0JBQWdCLENBQUMsYUFBRCxDQUF2Qjs7QUFDQSxNQUFJcEYsS0FBSyxDQUFDMEUsT0FBTixDQUFjVSxnQkFBZ0IsQ0FBQyxNQUFELENBQTlCLENBQUosRUFBNkM7QUFDM0NBLElBQUFBLGdCQUFnQixDQUFDLE1BQUQsQ0FBaEIsR0FBMkJBLGdCQUFnQixDQUFDLE1BQUQsQ0FBaEIsQ0FBeUJyRixNQUF6QixDQUFnQ3dFLE1BQWhDLENBQTNCO0FBQ0QsR0FGRCxNQUVPO0FBQ0xhLElBQUFBLGdCQUFnQixDQUFDLE1BQUQsQ0FBaEIsR0FBMkJiLE1BQTNCO0FBQ0Q7QUFDRixDLENBRUQ7QUFDQTtBQUNBO0FBQ0E7OztBQUNBNUcsU0FBUyxDQUFDc0IsU0FBVixDQUFvQnVFLGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUk0QixnQkFBZ0IsR0FBR1QsaUJBQWlCLENBQUMsS0FBSzVHLFNBQU4sRUFBaUIsYUFBakIsQ0FBeEM7O0FBQ0EsTUFBSSxDQUFDcUgsZ0JBQUwsRUFBdUI7QUFDckI7QUFDRCxHQUppRCxDQU1sRDs7O0FBQ0EsTUFBSUMsZUFBZSxHQUFHRCxnQkFBZ0IsQ0FBQyxhQUFELENBQXRDOztBQUNBLE1BQUksQ0FBQ0MsZUFBZSxDQUFDUixLQUFqQixJQUEwQixDQUFDUSxlQUFlLENBQUN2SCxTQUEvQyxFQUEwRDtBQUN4RCxVQUFNLElBQUlQLEtBQUssQ0FBQ2dCLEtBQVYsQ0FBZ0JoQixLQUFLLENBQUNnQixLQUFOLENBQVl1RyxhQUE1QixFQUEyQywrQkFBM0MsQ0FBTjtBQUNEOztBQUVELFFBQU1DLGlCQUFpQixHQUFHO0FBQ3hCcEQsSUFBQUEsdUJBQXVCLEVBQUUwRCxlQUFlLENBQUMxRDtBQURqQixHQUExQjs7QUFJQSxNQUFJLEtBQUszRCxXQUFMLENBQWlCZ0gsc0JBQXJCLEVBQTZDO0FBQzNDRCxJQUFBQSxpQkFBaUIsQ0FBQ0UsY0FBbEIsR0FBbUMsS0FBS2pILFdBQUwsQ0FBaUJnSCxzQkFBcEQ7QUFDQUQsSUFBQUEsaUJBQWlCLENBQUNDLHNCQUFsQixHQUEyQyxLQUFLaEgsV0FBTCxDQUFpQmdILHNCQUE1RDtBQUNELEdBSEQsTUFHTyxJQUFJLEtBQUtoSCxXQUFMLENBQWlCaUgsY0FBckIsRUFBcUM7QUFDMUNGLElBQUFBLGlCQUFpQixDQUFDRSxjQUFsQixHQUFtQyxLQUFLakgsV0FBTCxDQUFpQmlILGNBQXBEO0FBQ0Q7O0FBRUQsTUFBSUMsUUFBUSxHQUFHLElBQUl2SCxTQUFKLENBQ2IsS0FBS0MsTUFEUSxFQUViLEtBQUtDLElBRlEsRUFHYndILGVBQWUsQ0FBQ3ZILFNBSEgsRUFJYnVILGVBQWUsQ0FBQ1IsS0FKSCxFQUtiRSxpQkFMYSxDQUFmO0FBT0EsU0FBT0csUUFBUSxDQUFDcEQsT0FBVCxHQUFtQkksSUFBbkIsQ0FBd0IvRCxRQUFRLElBQUk7QUFDekNnSCxJQUFBQSxtQkFBbUIsQ0FBQ0MsZ0JBQUQsRUFBbUJGLFFBQVEsQ0FBQ3BILFNBQTVCLEVBQXVDSyxRQUFRLENBQUM0RSxPQUFoRCxDQUFuQixDQUR5QyxDQUV6Qzs7QUFDQSxXQUFPLEtBQUtTLGlCQUFMLEVBQVA7QUFDRCxHQUpNLENBQVA7QUFLRCxDQW5DRCxDLENBcUNBOzs7QUFDQSxNQUFNOEIsdUJBQXVCLEdBQUcsQ0FBQ0MsSUFBRCxFQUFPL0YsR0FBUCxFQUFZZ0csR0FBWixFQUFpQkMsR0FBakIsS0FBeUI7QUFDdkQsTUFBSWpHLEdBQUcsSUFBSStGLElBQVgsRUFBaUI7QUFDZixXQUFPQSxJQUFJLENBQUMvRixHQUFELENBQVg7QUFDRDs7QUFDRGlHLEVBQUFBLEdBQUcsQ0FBQ0MsTUFBSixDQUFXLENBQVgsRUFKdUQsQ0FJeEM7QUFDaEIsQ0FMRDs7QUFPQSxNQUFNQyxlQUFlLEdBQUcsQ0FBQ0MsWUFBRCxFQUFlcEcsR0FBZixFQUFvQnFHLE9BQXBCLEtBQWdDO0FBQ3RELE1BQUl0QixNQUFNLEdBQUcsRUFBYjs7QUFDQSxPQUFLLElBQUlDLE1BQVQsSUFBbUJxQixPQUFuQixFQUE0QjtBQUMxQnRCLElBQUFBLE1BQU0sQ0FBQ0UsSUFBUCxDQUFZakYsR0FBRyxDQUFDRixLQUFKLENBQVUsR0FBVixFQUFlb0IsTUFBZixDQUFzQjRFLHVCQUF0QixFQUErQ2QsTUFBL0MsQ0FBWjtBQUNEOztBQUNELFNBQU9vQixZQUFZLENBQUMsU0FBRCxDQUFuQjs7QUFDQSxNQUFJNUYsS0FBSyxDQUFDMEUsT0FBTixDQUFja0IsWUFBWSxDQUFDLEtBQUQsQ0FBMUIsQ0FBSixFQUF3QztBQUN0Q0EsSUFBQUEsWUFBWSxDQUFDLEtBQUQsQ0FBWixHQUFzQkEsWUFBWSxDQUFDLEtBQUQsQ0FBWixDQUFvQjdGLE1BQXBCLENBQTJCd0UsTUFBM0IsQ0FBdEI7QUFDRCxHQUZELE1BRU87QUFDTHFCLElBQUFBLFlBQVksQ0FBQyxLQUFELENBQVosR0FBc0JyQixNQUF0QjtBQUNEO0FBQ0YsQ0FYRCxDLENBYUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0E1RyxTQUFTLENBQUNzQixTQUFWLENBQW9Cb0UsYUFBcEIsR0FBb0MsWUFBWTtBQUM5QyxNQUFJdUMsWUFBWSxHQUFHakIsaUJBQWlCLENBQUMsS0FBSzVHLFNBQU4sRUFBaUIsU0FBakIsQ0FBcEM7O0FBQ0EsTUFBSSxDQUFDNkgsWUFBTCxFQUFtQjtBQUNqQjtBQUNELEdBSjZDLENBTTlDOzs7QUFDQSxNQUFJRSxXQUFXLEdBQUdGLFlBQVksQ0FBQyxTQUFELENBQTlCLENBUDhDLENBUTlDOztBQUNBLE1BQ0UsQ0FBQ0UsV0FBVyxDQUFDaEQsS0FBYixJQUNBLENBQUNnRCxXQUFXLENBQUN0RyxHQURiLElBRUEsT0FBT3NHLFdBQVcsQ0FBQ2hELEtBQW5CLEtBQTZCLFFBRjdCLElBR0EsQ0FBQ2dELFdBQVcsQ0FBQ2hELEtBQVosQ0FBa0JoRixTQUhuQixJQUlBa0IsTUFBTSxDQUFDSyxJQUFQLENBQVl5RyxXQUFaLEVBQXlCckcsTUFBekIsS0FBb0MsQ0FMdEMsRUFNRTtBQUNBLFVBQU0sSUFBSWxDLEtBQUssQ0FBQ2dCLEtBQVYsQ0FBZ0JoQixLQUFLLENBQUNnQixLQUFOLENBQVl1RyxhQUE1QixFQUEyQywyQkFBM0MsQ0FBTjtBQUNEOztBQUVELFFBQU1DLGlCQUFpQixHQUFHO0FBQ3hCcEQsSUFBQUEsdUJBQXVCLEVBQUVtRSxXQUFXLENBQUNoRCxLQUFaLENBQWtCbkI7QUFEbkIsR0FBMUI7O0FBSUEsTUFBSSxLQUFLM0QsV0FBTCxDQUFpQmdILHNCQUFyQixFQUE2QztBQUMzQ0QsSUFBQUEsaUJBQWlCLENBQUNFLGNBQWxCLEdBQW1DLEtBQUtqSCxXQUFMLENBQWlCZ0gsc0JBQXBEO0FBQ0FELElBQUFBLGlCQUFpQixDQUFDQyxzQkFBbEIsR0FBMkMsS0FBS2hILFdBQUwsQ0FBaUJnSCxzQkFBNUQ7QUFDRCxHQUhELE1BR08sSUFBSSxLQUFLaEgsV0FBTCxDQUFpQmlILGNBQXJCLEVBQXFDO0FBQzFDRixJQUFBQSxpQkFBaUIsQ0FBQ0UsY0FBbEIsR0FBbUMsS0FBS2pILFdBQUwsQ0FBaUJpSCxjQUFwRDtBQUNEOztBQUVELE1BQUlDLFFBQVEsR0FBRyxJQUFJdkgsU0FBSixDQUNiLEtBQUtDLE1BRFEsRUFFYixLQUFLQyxJQUZRLEVBR2JpSSxXQUFXLENBQUNoRCxLQUFaLENBQWtCaEYsU0FITCxFQUliZ0ksV0FBVyxDQUFDaEQsS0FBWixDQUFrQitCLEtBSkwsRUFLYkUsaUJBTGEsQ0FBZjtBQU9BLFNBQU9HLFFBQVEsQ0FBQ3BELE9BQVQsR0FBbUJJLElBQW5CLENBQXdCL0QsUUFBUSxJQUFJO0FBQ3pDd0gsSUFBQUEsZUFBZSxDQUFDQyxZQUFELEVBQWVFLFdBQVcsQ0FBQ3RHLEdBQTNCLEVBQWdDckIsUUFBUSxDQUFDNEUsT0FBekMsQ0FBZixDQUR5QyxDQUV6Qzs7QUFDQSxXQUFPLEtBQUtNLGFBQUwsRUFBUDtBQUNELEdBSk0sQ0FBUDtBQUtELENBMUNEOztBQTRDQSxNQUFNMEMsbUJBQW1CLEdBQUcsQ0FBQ0MsZ0JBQUQsRUFBbUJ4RyxHQUFuQixFQUF3QnFHLE9BQXhCLEtBQW9DO0FBQzlELE1BQUl0QixNQUFNLEdBQUcsRUFBYjs7QUFDQSxPQUFLLElBQUlDLE1BQVQsSUFBbUJxQixPQUFuQixFQUE0QjtBQUMxQnRCLElBQUFBLE1BQU0sQ0FBQ0UsSUFBUCxDQUFZakYsR0FBRyxDQUFDRixLQUFKLENBQVUsR0FBVixFQUFlb0IsTUFBZixDQUFzQjRFLHVCQUF0QixFQUErQ2QsTUFBL0MsQ0FBWjtBQUNEOztBQUNELFNBQU93QixnQkFBZ0IsQ0FBQyxhQUFELENBQXZCOztBQUNBLE1BQUloRyxLQUFLLENBQUMwRSxPQUFOLENBQWNzQixnQkFBZ0IsQ0FBQyxNQUFELENBQTlCLENBQUosRUFBNkM7QUFDM0NBLElBQUFBLGdCQUFnQixDQUFDLE1BQUQsQ0FBaEIsR0FBMkJBLGdCQUFnQixDQUFDLE1BQUQsQ0FBaEIsQ0FBeUJqRyxNQUF6QixDQUFnQ3dFLE1BQWhDLENBQTNCO0FBQ0QsR0FGRCxNQUVPO0FBQ0x5QixJQUFBQSxnQkFBZ0IsQ0FBQyxNQUFELENBQWhCLEdBQTJCekIsTUFBM0I7QUFDRDtBQUNGLENBWEQsQyxDQWFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBNUcsU0FBUyxDQUFDc0IsU0FBVixDQUFvQnFFLGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUkwQyxnQkFBZ0IsR0FBR3JCLGlCQUFpQixDQUFDLEtBQUs1RyxTQUFOLEVBQWlCLGFBQWpCLENBQXhDOztBQUNBLE1BQUksQ0FBQ2lJLGdCQUFMLEVBQXVCO0FBQ3JCO0FBQ0QsR0FKaUQsQ0FNbEQ7OztBQUNBLE1BQUlDLGVBQWUsR0FBR0QsZ0JBQWdCLENBQUMsYUFBRCxDQUF0Qzs7QUFDQSxNQUNFLENBQUNDLGVBQWUsQ0FBQ25ELEtBQWpCLElBQ0EsQ0FBQ21ELGVBQWUsQ0FBQ3pHLEdBRGpCLElBRUEsT0FBT3lHLGVBQWUsQ0FBQ25ELEtBQXZCLEtBQWlDLFFBRmpDLElBR0EsQ0FBQ21ELGVBQWUsQ0FBQ25ELEtBQWhCLENBQXNCaEYsU0FIdkIsSUFJQWtCLE1BQU0sQ0FBQ0ssSUFBUCxDQUFZNEcsZUFBWixFQUE2QnhHLE1BQTdCLEtBQXdDLENBTDFDLEVBTUU7QUFDQSxVQUFNLElBQUlsQyxLQUFLLENBQUNnQixLQUFWLENBQWdCaEIsS0FBSyxDQUFDZ0IsS0FBTixDQUFZdUcsYUFBNUIsRUFBMkMsK0JBQTNDLENBQU47QUFDRDs7QUFDRCxRQUFNQyxpQkFBaUIsR0FBRztBQUN4QnBELElBQUFBLHVCQUF1QixFQUFFc0UsZUFBZSxDQUFDbkQsS0FBaEIsQ0FBc0JuQjtBQUR2QixHQUExQjs7QUFJQSxNQUFJLEtBQUszRCxXQUFMLENBQWlCZ0gsc0JBQXJCLEVBQTZDO0FBQzNDRCxJQUFBQSxpQkFBaUIsQ0FBQ0UsY0FBbEIsR0FBbUMsS0FBS2pILFdBQUwsQ0FBaUJnSCxzQkFBcEQ7QUFDQUQsSUFBQUEsaUJBQWlCLENBQUNDLHNCQUFsQixHQUEyQyxLQUFLaEgsV0FBTCxDQUFpQmdILHNCQUE1RDtBQUNELEdBSEQsTUFHTyxJQUFJLEtBQUtoSCxXQUFMLENBQWlCaUgsY0FBckIsRUFBcUM7QUFDMUNGLElBQUFBLGlCQUFpQixDQUFDRSxjQUFsQixHQUFtQyxLQUFLakgsV0FBTCxDQUFpQmlILGNBQXBEO0FBQ0Q7O0FBRUQsTUFBSUMsUUFBUSxHQUFHLElBQUl2SCxTQUFKLENBQ2IsS0FBS0MsTUFEUSxFQUViLEtBQUtDLElBRlEsRUFHYm9JLGVBQWUsQ0FBQ25ELEtBQWhCLENBQXNCaEYsU0FIVCxFQUlibUksZUFBZSxDQUFDbkQsS0FBaEIsQ0FBc0IrQixLQUpULEVBS2JFLGlCQUxhLENBQWY7QUFPQSxTQUFPRyxRQUFRLENBQUNwRCxPQUFULEdBQW1CSSxJQUFuQixDQUF3Qi9ELFFBQVEsSUFBSTtBQUN6QzRILElBQUFBLG1CQUFtQixDQUFDQyxnQkFBRCxFQUFtQkMsZUFBZSxDQUFDekcsR0FBbkMsRUFBd0NyQixRQUFRLENBQUM0RSxPQUFqRCxDQUFuQixDQUR5QyxDQUV6Qzs7QUFDQSxXQUFPLEtBQUtPLGlCQUFMLEVBQVA7QUFDRCxHQUpNLENBQVA7QUFLRCxDQXhDRDs7QUEwQ0EsTUFBTTRDLG1CQUFtQixHQUFHLFVBQVUxQixNQUFWLEVBQWtCO0FBQzVDLFNBQU9BLE1BQU0sQ0FBQzJCLFFBQWQ7O0FBQ0EsTUFBSTNCLE1BQU0sQ0FBQzRCLFFBQVgsRUFBcUI7QUFDbkJwSCxJQUFBQSxNQUFNLENBQUNLLElBQVAsQ0FBWW1GLE1BQU0sQ0FBQzRCLFFBQW5CLEVBQTZCcEQsT0FBN0IsQ0FBcUNxRCxRQUFRLElBQUk7QUFDL0MsVUFBSTdCLE1BQU0sQ0FBQzRCLFFBQVAsQ0FBZ0JDLFFBQWhCLE1BQThCLElBQWxDLEVBQXdDO0FBQ3RDLGVBQU83QixNQUFNLENBQUM0QixRQUFQLENBQWdCQyxRQUFoQixDQUFQO0FBQ0Q7QUFDRixLQUpEOztBQU1BLFFBQUlySCxNQUFNLENBQUNLLElBQVAsQ0FBWW1GLE1BQU0sQ0FBQzRCLFFBQW5CLEVBQTZCM0csTUFBN0IsSUFBdUMsQ0FBM0MsRUFBOEM7QUFDNUMsYUFBTytFLE1BQU0sQ0FBQzRCLFFBQWQ7QUFDRDtBQUNGO0FBQ0YsQ0FiRDs7QUFlQSxNQUFNRSx5QkFBeUIsR0FBR0MsVUFBVSxJQUFJO0FBQzlDLE1BQUksT0FBT0EsVUFBUCxLQUFzQixRQUExQixFQUFvQztBQUNsQyxXQUFPQSxVQUFQO0FBQ0Q7O0FBQ0QsUUFBTUMsYUFBYSxHQUFHLEVBQXRCO0FBQ0EsTUFBSUMsbUJBQW1CLEdBQUcsS0FBMUI7QUFDQSxNQUFJQyxxQkFBcUIsR0FBRyxLQUE1Qjs7QUFDQSxPQUFLLE1BQU1sSCxHQUFYLElBQWtCK0csVUFBbEIsRUFBOEI7QUFDNUIsUUFBSS9HLEdBQUcsQ0FBQ2MsT0FBSixDQUFZLEdBQVosTUFBcUIsQ0FBekIsRUFBNEI7QUFDMUJtRyxNQUFBQSxtQkFBbUIsR0FBRyxJQUF0QjtBQUNBRCxNQUFBQSxhQUFhLENBQUNoSCxHQUFELENBQWIsR0FBcUIrRyxVQUFVLENBQUMvRyxHQUFELENBQS9CO0FBQ0QsS0FIRCxNQUdPO0FBQ0xrSCxNQUFBQSxxQkFBcUIsR0FBRyxJQUF4QjtBQUNEO0FBQ0Y7O0FBQ0QsTUFBSUQsbUJBQW1CLElBQUlDLHFCQUEzQixFQUFrRDtBQUNoREgsSUFBQUEsVUFBVSxDQUFDLEtBQUQsQ0FBVixHQUFvQkMsYUFBcEI7QUFDQXhILElBQUFBLE1BQU0sQ0FBQ0ssSUFBUCxDQUFZbUgsYUFBWixFQUEyQnhELE9BQTNCLENBQW1DeEQsR0FBRyxJQUFJO0FBQ3hDLGFBQU8rRyxVQUFVLENBQUMvRyxHQUFELENBQWpCO0FBQ0QsS0FGRDtBQUdEOztBQUNELFNBQU8rRyxVQUFQO0FBQ0QsQ0F0QkQ7O0FBd0JBNUksU0FBUyxDQUFDc0IsU0FBVixDQUFvQndFLGVBQXBCLEdBQXNDLFlBQVk7QUFDaEQsTUFBSSxPQUFPLEtBQUsxRixTQUFaLEtBQTBCLFFBQTlCLEVBQXdDO0FBQ3RDO0FBQ0Q7O0FBQ0QsT0FBSyxNQUFNeUIsR0FBWCxJQUFrQixLQUFLekIsU0FBdkIsRUFBa0M7QUFDaEMsU0FBS0EsU0FBTCxDQUFleUIsR0FBZixJQUFzQjhHLHlCQUF5QixDQUFDLEtBQUt2SSxTQUFMLENBQWV5QixHQUFmLENBQUQsQ0FBL0M7QUFDRDtBQUNGLENBUEQsQyxDQVNBO0FBQ0E7OztBQUNBN0IsU0FBUyxDQUFDc0IsU0FBVixDQUFvQnFELE9BQXBCLEdBQThCLFVBQVVxRSxPQUFPLEdBQUcsRUFBcEIsRUFBd0I7QUFDcEQsTUFBSSxLQUFLdkksV0FBTCxDQUFpQndFLEtBQWpCLEtBQTJCLENBQS9CLEVBQWtDO0FBQ2hDLFNBQUt6RSxRQUFMLEdBQWdCO0FBQUU0RSxNQUFBQSxPQUFPLEVBQUU7QUFBWCxLQUFoQjtBQUNBLFdBQU9mLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBQ0QsUUFBTTdELFdBQVcsR0FBR1ksTUFBTSxDQUFDaUUsTUFBUCxDQUFjLEVBQWQsRUFBa0IsS0FBSzdFLFdBQXZCLENBQXBCOztBQUNBLE1BQUksS0FBS2lCLElBQVQsRUFBZTtBQUNiakIsSUFBQUEsV0FBVyxDQUFDaUIsSUFBWixHQUFtQixLQUFLQSxJQUFMLENBQVVLLEdBQVYsQ0FBY0YsR0FBRyxJQUFJO0FBQ3RDLGFBQU9BLEdBQUcsQ0FBQ0YsS0FBSixDQUFVLEdBQVYsRUFBZSxDQUFmLENBQVA7QUFDRCxLQUZrQixDQUFuQjtBQUdEOztBQUNELE1BQUlxSCxPQUFPLENBQUNDLEVBQVosRUFBZ0I7QUFDZHhJLElBQUFBLFdBQVcsQ0FBQ3dJLEVBQVosR0FBaUJELE9BQU8sQ0FBQ0MsRUFBekI7QUFDRDs7QUFDRCxTQUFPLEtBQUtoSixNQUFMLENBQVlpRyxRQUFaLENBQ0pnRCxJQURJLENBQ0MsS0FBSy9JLFNBRE4sRUFDaUIsS0FBS0MsU0FEdEIsRUFDaUNLLFdBRGpDLEVBQzhDLEtBQUtQLElBRG5ELEVBRUpxRSxJQUZJLENBRUNhLE9BQU8sSUFBSTtBQUNmLFFBQUksS0FBS2pGLFNBQUwsS0FBbUIsT0FBbkIsSUFBOEJNLFdBQVcsQ0FBQzBJLE9BQVosS0FBd0IsSUFBMUQsRUFBZ0U7QUFDOUQsV0FBSyxJQUFJdEMsTUFBVCxJQUFtQnpCLE9BQW5CLEVBQTRCO0FBQzFCbUQsUUFBQUEsbUJBQW1CLENBQUMxQixNQUFELENBQW5CO0FBQ0Q7QUFDRjs7QUFFRCxTQUFLNUcsTUFBTCxDQUFZbUosZUFBWixDQUE0QkMsbUJBQTVCLENBQWdELEtBQUtwSixNQUFyRCxFQUE2RG1GLE9BQTdEOztBQUVBLFFBQUksS0FBS25CLGlCQUFULEVBQTRCO0FBQzFCLFdBQUssSUFBSXFGLENBQVQsSUFBY2xFLE9BQWQsRUFBdUI7QUFDckJrRSxRQUFBQSxDQUFDLENBQUNuSixTQUFGLEdBQWMsS0FBSzhELGlCQUFuQjtBQUNEO0FBQ0Y7O0FBQ0QsU0FBS3pELFFBQUwsR0FBZ0I7QUFBRTRFLE1BQUFBLE9BQU8sRUFBRUE7QUFBWCxLQUFoQjtBQUNELEdBakJJLENBQVA7QUFrQkQsQ0FoQ0QsQyxDQWtDQTtBQUNBOzs7QUFDQXBGLFNBQVMsQ0FBQ3NCLFNBQVYsQ0FBb0JzRCxRQUFwQixHQUErQixZQUFZO0FBQ3pDLE1BQUksQ0FBQyxLQUFLMUQsT0FBVixFQUFtQjtBQUNqQjtBQUNEOztBQUNELE9BQUtULFdBQUwsQ0FBaUI4SSxLQUFqQixHQUF5QixJQUF6QjtBQUNBLFNBQU8sS0FBSzlJLFdBQUwsQ0FBaUIrSSxJQUF4QjtBQUNBLFNBQU8sS0FBSy9JLFdBQUwsQ0FBaUJ3RSxLQUF4QjtBQUNBLFNBQU8sS0FBS2hGLE1BQUwsQ0FBWWlHLFFBQVosQ0FBcUJnRCxJQUFyQixDQUEwQixLQUFLL0ksU0FBL0IsRUFBMEMsS0FBS0MsU0FBL0MsRUFBMEQsS0FBS0ssV0FBL0QsRUFBNEU4RCxJQUE1RSxDQUFpRmtGLENBQUMsSUFBSTtBQUMzRixTQUFLakosUUFBTCxDQUFjK0ksS0FBZCxHQUFzQkUsQ0FBdEI7QUFDRCxHQUZNLENBQVA7QUFHRCxDQVZELEMsQ0FZQTs7O0FBQ0F6SixTQUFTLENBQUNzQixTQUFWLENBQW9CbUQsZ0JBQXBCLEdBQXVDLFlBQVk7QUFDakQsTUFBSSxDQUFDLEtBQUt0RCxVQUFWLEVBQXNCO0FBQ3BCO0FBQ0Q7O0FBQ0QsU0FBTyxLQUFLbEIsTUFBTCxDQUFZaUcsUUFBWixDQUNKSSxVQURJLEdBRUovQixJQUZJLENBRUNnQyxnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNtRCxZQUFqQixDQUE4QixLQUFLdkosU0FBbkMsQ0FGckIsRUFHSm9FLElBSEksQ0FHQ29GLE1BQU0sSUFBSTtBQUNkLFVBQU1DLGFBQWEsR0FBRyxFQUF0QjtBQUNBLFVBQU1DLFNBQVMsR0FBRyxFQUFsQjs7QUFDQSxTQUFLLE1BQU01RyxLQUFYLElBQW9CMEcsTUFBTSxDQUFDL0csTUFBM0IsRUFBbUM7QUFDakMsVUFBSStHLE1BQU0sQ0FBQy9HLE1BQVAsQ0FBY0ssS0FBZCxFQUFxQjZHLElBQXJCLElBQTZCSCxNQUFNLENBQUMvRyxNQUFQLENBQWNLLEtBQWQsRUFBcUI2RyxJQUFyQixLQUE4QixTQUEvRCxFQUEwRTtBQUN4RUYsUUFBQUEsYUFBYSxDQUFDOUMsSUFBZCxDQUFtQixDQUFDN0QsS0FBRCxDQUFuQjtBQUNBNEcsUUFBQUEsU0FBUyxDQUFDL0MsSUFBVixDQUFlN0QsS0FBZjtBQUNEO0FBQ0YsS0FSYSxDQVNkOzs7QUFDQSxTQUFLN0IsT0FBTCxHQUFlLENBQUMsR0FBRyxJQUFJbUIsR0FBSixDQUFRLENBQUMsR0FBRyxLQUFLbkIsT0FBVCxFQUFrQixHQUFHd0ksYUFBckIsQ0FBUixDQUFKLENBQWYsQ0FWYyxDQVdkOztBQUNBLFFBQUksS0FBS2xJLElBQVQsRUFBZTtBQUNiLFdBQUtBLElBQUwsR0FBWSxDQUFDLEdBQUcsSUFBSWEsR0FBSixDQUFRLENBQUMsR0FBRyxLQUFLYixJQUFULEVBQWUsR0FBR21JLFNBQWxCLENBQVIsQ0FBSixDQUFaO0FBQ0Q7QUFDRixHQWxCSSxDQUFQO0FBbUJELENBdkJELEMsQ0F5QkE7OztBQUNBN0osU0FBUyxDQUFDc0IsU0FBVixDQUFvQm9ELGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUksQ0FBQyxLQUFLakMsV0FBVixFQUF1QjtBQUNyQjtBQUNEOztBQUNELE1BQUksS0FBS2YsSUFBVCxFQUFlO0FBQ2IsU0FBS0EsSUFBTCxHQUFZLEtBQUtBLElBQUwsQ0FBVUUsTUFBVixDQUFpQmMsQ0FBQyxJQUFJLENBQUMsS0FBS0QsV0FBTCxDQUFpQmEsUUFBakIsQ0FBMEJaLENBQTFCLENBQXZCLENBQVo7QUFDQTtBQUNEOztBQUNELFNBQU8sS0FBS3pDLE1BQUwsQ0FBWWlHLFFBQVosQ0FDSkksVUFESSxHQUVKL0IsSUFGSSxDQUVDZ0MsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDbUQsWUFBakIsQ0FBOEIsS0FBS3ZKLFNBQW5DLENBRnJCLEVBR0pvRSxJQUhJLENBR0NvRixNQUFNLElBQUk7QUFDZCxVQUFNL0csTUFBTSxHQUFHdkIsTUFBTSxDQUFDSyxJQUFQLENBQVlpSSxNQUFNLENBQUMvRyxNQUFuQixDQUFmO0FBQ0EsU0FBS2xCLElBQUwsR0FBWWtCLE1BQU0sQ0FBQ2hCLE1BQVAsQ0FBY2MsQ0FBQyxJQUFJLENBQUMsS0FBS0QsV0FBTCxDQUFpQmEsUUFBakIsQ0FBMEJaLENBQTFCLENBQXBCLENBQVo7QUFDRCxHQU5JLENBQVA7QUFPRCxDQWZELEMsQ0FpQkE7OztBQUNBMUMsU0FBUyxDQUFDc0IsU0FBVixDQUFvQnVELGFBQXBCLEdBQW9DLFlBQVk7QUFDOUMsTUFBSSxLQUFLekQsT0FBTCxDQUFhVSxNQUFiLElBQXVCLENBQTNCLEVBQThCO0FBQzVCO0FBQ0Q7O0FBRUQsTUFBSWlJLFlBQVksR0FBR0MsV0FBVyxDQUM1QixLQUFLL0osTUFEdUIsRUFFNUIsS0FBS0MsSUFGdUIsRUFHNUIsS0FBS00sUUFIdUIsRUFJNUIsS0FBS1ksT0FBTCxDQUFhLENBQWIsQ0FKNEIsRUFLNUIsS0FBS2YsV0FMdUIsQ0FBOUI7O0FBT0EsTUFBSTBKLFlBQVksQ0FBQ3hGLElBQWpCLEVBQXVCO0FBQ3JCLFdBQU93RixZQUFZLENBQUN4RixJQUFiLENBQWtCMEYsV0FBVyxJQUFJO0FBQ3RDLFdBQUt6SixRQUFMLEdBQWdCeUosV0FBaEI7QUFDQSxXQUFLN0ksT0FBTCxHQUFlLEtBQUtBLE9BQUwsQ0FBYVksS0FBYixDQUFtQixDQUFuQixDQUFmO0FBQ0EsYUFBTyxLQUFLNkMsYUFBTCxFQUFQO0FBQ0QsS0FKTSxDQUFQO0FBS0QsR0FORCxNQU1PLElBQUksS0FBS3pELE9BQUwsQ0FBYVUsTUFBYixHQUFzQixDQUExQixFQUE2QjtBQUNsQyxTQUFLVixPQUFMLEdBQWUsS0FBS0EsT0FBTCxDQUFhWSxLQUFiLENBQW1CLENBQW5CLENBQWY7QUFDQSxXQUFPLEtBQUs2QyxhQUFMLEVBQVA7QUFDRDs7QUFFRCxTQUFPa0YsWUFBUDtBQUNELENBeEJELEMsQ0EwQkE7OztBQUNBL0osU0FBUyxDQUFDc0IsU0FBVixDQUFvQndELG1CQUFwQixHQUEwQyxZQUFZO0FBQ3BELE1BQUksQ0FBQyxLQUFLdEUsUUFBVixFQUFvQjtBQUNsQjtBQUNEOztBQUNELE1BQUksQ0FBQyxLQUFLRCxZQUFWLEVBQXdCO0FBQ3RCO0FBQ0QsR0FObUQsQ0FPcEQ7OztBQUNBLFFBQU0ySixnQkFBZ0IsR0FBR3JLLFFBQVEsQ0FBQ3NLLGFBQVQsQ0FDdkIsS0FBS2hLLFNBRGtCLEVBRXZCTixRQUFRLENBQUN1SyxLQUFULENBQWVDLFNBRlEsRUFHdkIsS0FBS3BLLE1BQUwsQ0FBWXFLLGFBSFcsQ0FBekI7O0FBS0EsTUFBSSxDQUFDSixnQkFBTCxFQUF1QjtBQUNyQixXQUFPN0YsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxHQWZtRCxDQWdCcEQ7OztBQUNBLE1BQUksS0FBSzdELFdBQUwsQ0FBaUI4SixRQUFqQixJQUE2QixLQUFLOUosV0FBTCxDQUFpQitKLFFBQWxELEVBQTREO0FBQzFELFdBQU9uRyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVELFFBQU1zRCxJQUFJLEdBQUd2RyxNQUFNLENBQUNpRSxNQUFQLENBQWMsRUFBZCxFQUFrQixLQUFLakYsV0FBdkIsQ0FBYjtBQUNBdUgsRUFBQUEsSUFBSSxDQUFDVixLQUFMLEdBQWEsS0FBSzlHLFNBQWxCO0FBQ0EsUUFBTXFLLFVBQVUsR0FBRyxJQUFJN0ssS0FBSyxDQUFDOEssS0FBVixDQUFnQixLQUFLdkssU0FBckIsQ0FBbkI7QUFDQXNLLEVBQUFBLFVBQVUsQ0FBQ0UsUUFBWCxDQUFvQi9DLElBQXBCLEVBeEJvRCxDQXlCcEQ7O0FBQ0EsU0FBTy9ILFFBQVEsQ0FDWitLLHdCQURJLENBRUgvSyxRQUFRLENBQUN1SyxLQUFULENBQWVDLFNBRlosRUFHSCxLQUFLbkssSUFIRixFQUlILEtBQUtDLFNBSkYsRUFLSCxLQUFLSyxRQUFMLENBQWM0RSxPQUxYLEVBTUgsS0FBS25GLE1BTkYsRUFPSHdLLFVBUEcsRUFTSmxHLElBVEksQ0FTQ2EsT0FBTyxJQUFJO0FBQ2Y7QUFDQSxRQUFJLEtBQUtuQixpQkFBVCxFQUE0QjtBQUMxQixXQUFLekQsUUFBTCxDQUFjNEUsT0FBZCxHQUF3QkEsT0FBTyxDQUFDckQsR0FBUixDQUFZOEksTUFBTSxJQUFJO0FBQzVDLFlBQUlBLE1BQU0sWUFBWWpMLEtBQUssQ0FBQ3lCLE1BQTVCLEVBQW9DO0FBQ2xDd0osVUFBQUEsTUFBTSxHQUFHQSxNQUFNLENBQUNDLE1BQVAsRUFBVDtBQUNEOztBQUNERCxRQUFBQSxNQUFNLENBQUMxSyxTQUFQLEdBQW1CLEtBQUs4RCxpQkFBeEI7QUFDQSxlQUFPNEcsTUFBUDtBQUNELE9BTnVCLENBQXhCO0FBT0QsS0FSRCxNQVFPO0FBQ0wsV0FBS3JLLFFBQUwsQ0FBYzRFLE9BQWQsR0FBd0JBLE9BQXhCO0FBQ0Q7QUFDRixHQXRCSSxDQUFQO0FBdUJELENBakRELEMsQ0FtREE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTNEUsV0FBVCxDQUFxQi9KLE1BQXJCLEVBQTZCQyxJQUE3QixFQUFtQ00sUUFBbkMsRUFBNkNpRCxJQUE3QyxFQUFtRHBELFdBQVcsR0FBRyxFQUFqRSxFQUFxRTtBQUNuRSxNQUFJMEssUUFBUSxHQUFHQyxZQUFZLENBQUN4SyxRQUFRLENBQUM0RSxPQUFWLEVBQW1CM0IsSUFBbkIsQ0FBM0I7O0FBQ0EsTUFBSXNILFFBQVEsQ0FBQ2pKLE1BQVQsSUFBbUIsQ0FBdkIsRUFBMEI7QUFDeEIsV0FBT3RCLFFBQVA7QUFDRDs7QUFDRCxRQUFNeUssWUFBWSxHQUFHLEVBQXJCOztBQUNBLE9BQUssSUFBSUMsT0FBVCxJQUFvQkgsUUFBcEIsRUFBOEI7QUFDNUIsUUFBSSxDQUFDRyxPQUFMLEVBQWM7QUFDWjtBQUNEOztBQUNELFVBQU0vSyxTQUFTLEdBQUcrSyxPQUFPLENBQUMvSyxTQUExQixDQUo0QixDQUs1Qjs7QUFDQSxRQUFJQSxTQUFKLEVBQWU7QUFDYjhLLE1BQUFBLFlBQVksQ0FBQzlLLFNBQUQsQ0FBWixHQUEwQjhLLFlBQVksQ0FBQzlLLFNBQUQsQ0FBWixJQUEyQixJQUFJb0MsR0FBSixFQUFyRDtBQUNBMEksTUFBQUEsWUFBWSxDQUFDOUssU0FBRCxDQUFaLENBQXdCZ0wsR0FBeEIsQ0FBNEJELE9BQU8sQ0FBQ2xLLFFBQXBDO0FBQ0Q7QUFDRjs7QUFDRCxRQUFNb0ssa0JBQWtCLEdBQUcsRUFBM0I7O0FBQ0EsTUFBSS9LLFdBQVcsQ0FBQ3FCLElBQWhCLEVBQXNCO0FBQ3BCLFVBQU1BLElBQUksR0FBRyxJQUFJYSxHQUFKLENBQVFsQyxXQUFXLENBQUNxQixJQUFaLENBQWlCQyxLQUFqQixDQUF1QixHQUF2QixDQUFSLENBQWI7QUFDQSxVQUFNMEosTUFBTSxHQUFHaEosS0FBSyxDQUFDQyxJQUFOLENBQVdaLElBQVgsRUFBaUJxQixNQUFqQixDQUF3QixDQUFDdUksR0FBRCxFQUFNekosR0FBTixLQUFjO0FBQ25ELFlBQU0wSixPQUFPLEdBQUcxSixHQUFHLENBQUNGLEtBQUosQ0FBVSxHQUFWLENBQWhCO0FBQ0EsVUFBSTZKLENBQUMsR0FBRyxDQUFSOztBQUNBLFdBQUtBLENBQUwsRUFBUUEsQ0FBQyxHQUFHL0gsSUFBSSxDQUFDM0IsTUFBakIsRUFBeUIwSixDQUFDLEVBQTFCLEVBQThCO0FBQzVCLFlBQUkvSCxJQUFJLENBQUMrSCxDQUFELENBQUosSUFBV0QsT0FBTyxDQUFDQyxDQUFELENBQXRCLEVBQTJCO0FBQ3pCLGlCQUFPRixHQUFQO0FBQ0Q7QUFDRjs7QUFDRCxVQUFJRSxDQUFDLEdBQUdELE9BQU8sQ0FBQ3pKLE1BQWhCLEVBQXdCO0FBQ3RCd0osUUFBQUEsR0FBRyxDQUFDSCxHQUFKLENBQVFJLE9BQU8sQ0FBQ0MsQ0FBRCxDQUFmO0FBQ0Q7O0FBQ0QsYUFBT0YsR0FBUDtBQUNELEtBWmMsRUFZWixJQUFJL0ksR0FBSixFQVpZLENBQWY7O0FBYUEsUUFBSThJLE1BQU0sQ0FBQ0ksSUFBUCxHQUFjLENBQWxCLEVBQXFCO0FBQ25CTCxNQUFBQSxrQkFBa0IsQ0FBQzFKLElBQW5CLEdBQTBCVyxLQUFLLENBQUNDLElBQU4sQ0FBVytJLE1BQVgsRUFBbUJuSixJQUFuQixDQUF3QixHQUF4QixDQUExQjtBQUNEO0FBQ0Y7O0FBRUQsTUFBSTdCLFdBQVcsQ0FBQ3FMLHFCQUFoQixFQUF1QztBQUNyQ04sSUFBQUEsa0JBQWtCLENBQUM5RCxjQUFuQixHQUFvQ2pILFdBQVcsQ0FBQ3FMLHFCQUFoRDtBQUNBTixJQUFBQSxrQkFBa0IsQ0FBQ00scUJBQW5CLEdBQTJDckwsV0FBVyxDQUFDcUwscUJBQXZEO0FBQ0QsR0FIRCxNQUdPLElBQUlyTCxXQUFXLENBQUNpSCxjQUFoQixFQUFnQztBQUNyQzhELElBQUFBLGtCQUFrQixDQUFDOUQsY0FBbkIsR0FBb0NqSCxXQUFXLENBQUNpSCxjQUFoRDtBQUNEOztBQUVELFFBQU1xRSxhQUFhLEdBQUd0SyxNQUFNLENBQUNLLElBQVAsQ0FBWXVKLFlBQVosRUFBMEJsSixHQUExQixDQUE4QjVCLFNBQVMsSUFBSTtBQUMvRCxVQUFNeUwsU0FBUyxHQUFHdkosS0FBSyxDQUFDQyxJQUFOLENBQVcySSxZQUFZLENBQUM5SyxTQUFELENBQXZCLENBQWxCO0FBQ0EsUUFBSStHLEtBQUo7O0FBQ0EsUUFBSTBFLFNBQVMsQ0FBQzlKLE1BQVYsS0FBcUIsQ0FBekIsRUFBNEI7QUFDMUJvRixNQUFBQSxLQUFLLEdBQUc7QUFBRWxHLFFBQUFBLFFBQVEsRUFBRTRLLFNBQVMsQ0FBQyxDQUFEO0FBQXJCLE9BQVI7QUFDRCxLQUZELE1BRU87QUFDTDFFLE1BQUFBLEtBQUssR0FBRztBQUFFbEcsUUFBQUEsUUFBUSxFQUFFO0FBQUU2SyxVQUFBQSxHQUFHLEVBQUVEO0FBQVA7QUFBWixPQUFSO0FBQ0Q7O0FBQ0QsUUFBSXpHLEtBQUssR0FBRyxJQUFJbkYsU0FBSixDQUFjQyxNQUFkLEVBQXNCQyxJQUF0QixFQUE0QkMsU0FBNUIsRUFBdUMrRyxLQUF2QyxFQUE4Q2tFLGtCQUE5QyxDQUFaO0FBQ0EsV0FBT2pHLEtBQUssQ0FBQ2hCLE9BQU4sQ0FBYztBQUFFOEUsTUFBQUEsRUFBRSxFQUFFO0FBQU4sS0FBZCxFQUE2QjFFLElBQTdCLENBQWtDYSxPQUFPLElBQUk7QUFDbERBLE1BQUFBLE9BQU8sQ0FBQ2pGLFNBQVIsR0FBb0JBLFNBQXBCO0FBQ0EsYUFBT2tFLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQmMsT0FBaEIsQ0FBUDtBQUNELEtBSE0sQ0FBUDtBQUlELEdBYnFCLENBQXRCLENBN0NtRSxDQTREbkU7O0FBQ0EsU0FBT2YsT0FBTyxDQUFDeUgsR0FBUixDQUFZSCxhQUFaLEVBQTJCcEgsSUFBM0IsQ0FBZ0N3SCxTQUFTLElBQUk7QUFDbEQsUUFBSUMsT0FBTyxHQUFHRCxTQUFTLENBQUNoSixNQUFWLENBQWlCLENBQUNpSixPQUFELEVBQVVDLGVBQVYsS0FBOEI7QUFDM0QsV0FBSyxJQUFJQyxHQUFULElBQWdCRCxlQUFlLENBQUM3RyxPQUFoQyxFQUF5QztBQUN2QzhHLFFBQUFBLEdBQUcsQ0FBQ25MLE1BQUosR0FBYSxRQUFiO0FBQ0FtTCxRQUFBQSxHQUFHLENBQUMvTCxTQUFKLEdBQWdCOEwsZUFBZSxDQUFDOUwsU0FBaEM7O0FBRUEsWUFBSStMLEdBQUcsQ0FBQy9MLFNBQUosSUFBaUIsT0FBakIsSUFBNEIsQ0FBQ0QsSUFBSSxDQUFDUSxRQUF0QyxFQUFnRDtBQUM5QyxpQkFBT3dMLEdBQUcsQ0FBQ0MsWUFBWDtBQUNBLGlCQUFPRCxHQUFHLENBQUN6RCxRQUFYO0FBQ0Q7O0FBQ0R1RCxRQUFBQSxPQUFPLENBQUNFLEdBQUcsQ0FBQ2xMLFFBQUwsQ0FBUCxHQUF3QmtMLEdBQXhCO0FBQ0Q7O0FBQ0QsYUFBT0YsT0FBUDtBQUNELEtBWmEsRUFZWCxFQVpXLENBQWQ7QUFjQSxRQUFJSSxJQUFJLEdBQUc7QUFDVGhILE1BQUFBLE9BQU8sRUFBRWlILGVBQWUsQ0FBQzdMLFFBQVEsQ0FBQzRFLE9BQVYsRUFBbUIzQixJQUFuQixFQUF5QnVJLE9BQXpCO0FBRGYsS0FBWDs7QUFHQSxRQUFJeEwsUUFBUSxDQUFDK0ksS0FBYixFQUFvQjtBQUNsQjZDLE1BQUFBLElBQUksQ0FBQzdDLEtBQUwsR0FBYS9JLFFBQVEsQ0FBQytJLEtBQXRCO0FBQ0Q7O0FBQ0QsV0FBTzZDLElBQVA7QUFDRCxHQXRCTSxDQUFQO0FBdUJELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQSxTQUFTcEIsWUFBVCxDQUFzQkgsTUFBdEIsRUFBOEJwSCxJQUE5QixFQUFvQztBQUNsQyxNQUFJb0gsTUFBTSxZQUFZeEksS0FBdEIsRUFBNkI7QUFDM0IsUUFBSWlLLE1BQU0sR0FBRyxFQUFiOztBQUNBLFNBQUssSUFBSUMsQ0FBVCxJQUFjMUIsTUFBZCxFQUFzQjtBQUNwQnlCLE1BQUFBLE1BQU0sR0FBR0EsTUFBTSxDQUFDbEssTUFBUCxDQUFjNEksWUFBWSxDQUFDdUIsQ0FBRCxFQUFJOUksSUFBSixDQUExQixDQUFUO0FBQ0Q7O0FBQ0QsV0FBTzZJLE1BQVA7QUFDRDs7QUFFRCxNQUFJLE9BQU96QixNQUFQLEtBQWtCLFFBQWxCLElBQThCLENBQUNBLE1BQW5DLEVBQTJDO0FBQ3pDLFdBQU8sRUFBUDtBQUNEOztBQUVELE1BQUlwSCxJQUFJLENBQUMzQixNQUFMLElBQWUsQ0FBbkIsRUFBc0I7QUFDcEIsUUFBSStJLE1BQU0sS0FBSyxJQUFYLElBQW1CQSxNQUFNLENBQUM5SixNQUFQLElBQWlCLFNBQXhDLEVBQW1EO0FBQ2pELGFBQU8sQ0FBQzhKLE1BQUQsQ0FBUDtBQUNEOztBQUNELFdBQU8sRUFBUDtBQUNEOztBQUVELE1BQUkyQixTQUFTLEdBQUczQixNQUFNLENBQUNwSCxJQUFJLENBQUMsQ0FBRCxDQUFMLENBQXRCOztBQUNBLE1BQUksQ0FBQytJLFNBQUwsRUFBZ0I7QUFDZCxXQUFPLEVBQVA7QUFDRDs7QUFDRCxTQUFPeEIsWUFBWSxDQUFDd0IsU0FBRCxFQUFZL0ksSUFBSSxDQUFDekIsS0FBTCxDQUFXLENBQVgsQ0FBWixDQUFuQjtBQUNELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLFNBQVNxSyxlQUFULENBQXlCeEIsTUFBekIsRUFBaUNwSCxJQUFqQyxFQUF1Q3VJLE9BQXZDLEVBQWdEO0FBQzlDLE1BQUluQixNQUFNLFlBQVl4SSxLQUF0QixFQUE2QjtBQUMzQixXQUFPd0ksTUFBTSxDQUNWOUksR0FESSxDQUNBbUssR0FBRyxJQUFJRyxlQUFlLENBQUNILEdBQUQsRUFBTXpJLElBQU4sRUFBWXVJLE9BQVosQ0FEdEIsRUFFSnBLLE1BRkksQ0FFR3NLLEdBQUcsSUFBSSxPQUFPQSxHQUFQLEtBQWUsV0FGekIsQ0FBUDtBQUdEOztBQUVELE1BQUksT0FBT3JCLE1BQVAsS0FBa0IsUUFBbEIsSUFBOEIsQ0FBQ0EsTUFBbkMsRUFBMkM7QUFDekMsV0FBT0EsTUFBUDtBQUNEOztBQUVELE1BQUlwSCxJQUFJLENBQUMzQixNQUFMLEtBQWdCLENBQXBCLEVBQXVCO0FBQ3JCLFFBQUkrSSxNQUFNLElBQUlBLE1BQU0sQ0FBQzlKLE1BQVAsS0FBa0IsU0FBaEMsRUFBMkM7QUFDekMsYUFBT2lMLE9BQU8sQ0FBQ25CLE1BQU0sQ0FBQzdKLFFBQVIsQ0FBZDtBQUNEOztBQUNELFdBQU82SixNQUFQO0FBQ0Q7O0FBRUQsTUFBSTJCLFNBQVMsR0FBRzNCLE1BQU0sQ0FBQ3BILElBQUksQ0FBQyxDQUFELENBQUwsQ0FBdEI7O0FBQ0EsTUFBSSxDQUFDK0ksU0FBTCxFQUFnQjtBQUNkLFdBQU8zQixNQUFQO0FBQ0Q7O0FBQ0QsTUFBSTRCLE1BQU0sR0FBR0osZUFBZSxDQUFDRyxTQUFELEVBQVkvSSxJQUFJLENBQUN6QixLQUFMLENBQVcsQ0FBWCxDQUFaLEVBQTJCZ0ssT0FBM0IsQ0FBNUI7QUFDQSxNQUFJTSxNQUFNLEdBQUcsRUFBYjs7QUFDQSxPQUFLLElBQUl6SyxHQUFULElBQWdCZ0osTUFBaEIsRUFBd0I7QUFDdEIsUUFBSWhKLEdBQUcsSUFBSTRCLElBQUksQ0FBQyxDQUFELENBQWYsRUFBb0I7QUFDbEI2SSxNQUFBQSxNQUFNLENBQUN6SyxHQUFELENBQU4sR0FBYzRLLE1BQWQ7QUFDRCxLQUZELE1BRU87QUFDTEgsTUFBQUEsTUFBTSxDQUFDekssR0FBRCxDQUFOLEdBQWNnSixNQUFNLENBQUNoSixHQUFELENBQXBCO0FBQ0Q7QUFDRjs7QUFDRCxTQUFPeUssTUFBUDtBQUNELEMsQ0FFRDtBQUNBOzs7QUFDQSxTQUFTdEYsaUJBQVQsQ0FBMkIwRixJQUEzQixFQUFpQzdLLEdBQWpDLEVBQXNDO0FBQ3BDLE1BQUksT0FBTzZLLElBQVAsS0FBZ0IsUUFBcEIsRUFBOEI7QUFDNUI7QUFDRDs7QUFDRCxNQUFJQSxJQUFJLFlBQVlySyxLQUFwQixFQUEyQjtBQUN6QixTQUFLLElBQUlzSyxJQUFULElBQWlCRCxJQUFqQixFQUF1QjtBQUNyQixZQUFNSixNQUFNLEdBQUd0RixpQkFBaUIsQ0FBQzJGLElBQUQsRUFBTzlLLEdBQVAsQ0FBaEM7O0FBQ0EsVUFBSXlLLE1BQUosRUFBWTtBQUNWLGVBQU9BLE1BQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsTUFBSUksSUFBSSxJQUFJQSxJQUFJLENBQUM3SyxHQUFELENBQWhCLEVBQXVCO0FBQ3JCLFdBQU82SyxJQUFQO0FBQ0Q7O0FBQ0QsT0FBSyxJQUFJRSxNQUFULElBQW1CRixJQUFuQixFQUF5QjtBQUN2QixVQUFNSixNQUFNLEdBQUd0RixpQkFBaUIsQ0FBQzBGLElBQUksQ0FBQ0UsTUFBRCxDQUFMLEVBQWUvSyxHQUFmLENBQWhDOztBQUNBLFFBQUl5SyxNQUFKLEVBQVk7QUFDVixhQUFPQSxNQUFQO0FBQ0Q7QUFDRjtBQUNGOztBQUVETyxNQUFNLENBQUNDLE9BQVAsR0FBaUI5TSxTQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyBldmVyeXRoaW5nIHdlIG5lZWQgdG8gcnVuIGEgJ2ZpbmQnXG4vLyBvcGVyYXRpb24sIGVuY29kZWQgaW4gdGhlIFJFU1QgQVBJIGZvcm1hdC5cblxudmFyIFNjaGVtYUNvbnRyb2xsZXIgPSByZXF1aXJlKCcuL0NvbnRyb2xsZXJzL1NjaGVtYUNvbnRyb2xsZXInKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHRyaWdnZXJzID0gcmVxdWlyZSgnLi90cmlnZ2VycycpO1xuY29uc3QgeyBjb250aW51ZVdoaWxlIH0gPSByZXF1aXJlKCdwYXJzZS9saWIvbm9kZS9wcm9taXNlVXRpbHMnKTtcbmNvbnN0IEFsd2F5c1NlbGVjdGVkS2V5cyA9IFsnb2JqZWN0SWQnLCAnY3JlYXRlZEF0JywgJ3VwZGF0ZWRBdCcsICdBQ0wnXTtcbi8vIHJlc3RPcHRpb25zIGNhbiBpbmNsdWRlOlxuLy8gICBza2lwXG4vLyAgIGxpbWl0XG4vLyAgIG9yZGVyXG4vLyAgIGNvdW50XG4vLyAgIGluY2x1ZGVcbi8vICAga2V5c1xuLy8gICBleGNsdWRlS2V5c1xuLy8gICByZWRpcmVjdENsYXNzTmFtZUZvcktleVxuLy8gICByZWFkUHJlZmVyZW5jZVxuLy8gICBpbmNsdWRlUmVhZFByZWZlcmVuY2Vcbi8vICAgc3VicXVlcnlSZWFkUHJlZmVyZW5jZVxuZnVuY3Rpb24gUmVzdFF1ZXJ5KFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGNsYXNzTmFtZSxcbiAgcmVzdFdoZXJlID0ge30sXG4gIHJlc3RPcHRpb25zID0ge30sXG4gIGNsaWVudFNESyxcbiAgcnVuQWZ0ZXJGaW5kID0gdHJ1ZVxuKSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmF1dGggPSBhdXRoO1xuICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgdGhpcy5yZXN0V2hlcmUgPSByZXN0V2hlcmU7XG4gIHRoaXMucmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucztcbiAgdGhpcy5jbGllbnRTREsgPSBjbGllbnRTREs7XG4gIHRoaXMucnVuQWZ0ZXJGaW5kID0gcnVuQWZ0ZXJGaW5kO1xuICB0aGlzLnJlc3BvbnNlID0gbnVsbDtcbiAgdGhpcy5maW5kT3B0aW9ucyA9IHt9O1xuXG4gIGlmICghdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgIGlmICghdGhpcy5hdXRoLnVzZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXN0V2hlcmUgPSB7XG4gICAgICAgICRhbmQ6IFtcbiAgICAgICAgICB0aGlzLnJlc3RXaGVyZSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1c2VyOiB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgICAgICAgIG9iamVjdElkOiB0aGlzLmF1dGgudXNlci5pZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgdGhpcy5kb0NvdW50ID0gZmFsc2U7XG4gIHRoaXMuaW5jbHVkZUFsbCA9IGZhbHNlO1xuXG4gIC8vIFRoZSBmb3JtYXQgZm9yIHRoaXMuaW5jbHVkZSBpcyBub3QgdGhlIHNhbWUgYXMgdGhlIGZvcm1hdCBmb3IgdGhlXG4gIC8vIGluY2x1ZGUgb3B0aW9uIC0gaXQncyB0aGUgcGF0aHMgd2Ugc2hvdWxkIGluY2x1ZGUsIGluIG9yZGVyLFxuICAvLyBzdG9yZWQgYXMgYXJyYXlzLCB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgd2UgbmVlZCB0byBpbmNsdWRlIGZvb1xuICAvLyBiZWZvcmUgaW5jbHVkaW5nIGZvby5iYXIuIEFsc28gaXQgc2hvdWxkIGRlZHVwZS5cbiAgLy8gRm9yIGV4YW1wbGUsIHBhc3NpbmcgYW4gYXJnIG9mIGluY2x1ZGU9Zm9vLmJhcixmb28uYmF6IGNvdWxkIGxlYWQgdG9cbiAgLy8gdGhpcy5pbmNsdWRlID0gW1snZm9vJ10sIFsnZm9vJywgJ2JheiddLCBbJ2ZvbycsICdiYXInXV1cbiAgdGhpcy5pbmNsdWRlID0gW107XG5cbiAgLy8gSWYgd2UgaGF2ZSBrZXlzLCB3ZSBwcm9iYWJseSB3YW50IHRvIGZvcmNlIHNvbWUgaW5jbHVkZXMgKG4tMSBsZXZlbClcbiAgLy8gU2VlIGlzc3VlOiBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvMzE4NVxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3RPcHRpb25zLCAna2V5cycpKSB7XG4gICAgY29uc3Qga2V5c0ZvckluY2x1ZGUgPSByZXN0T3B0aW9ucy5rZXlzXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLmZpbHRlcihrZXkgPT4ge1xuICAgICAgICAvLyBBdCBsZWFzdCAyIGNvbXBvbmVudHNcbiAgICAgICAgcmV0dXJuIGtleS5zcGxpdCgnLicpLmxlbmd0aCA+IDE7XG4gICAgICB9KVxuICAgICAgLm1hcChrZXkgPT4ge1xuICAgICAgICAvLyBTbGljZSB0aGUgbGFzdCBjb21wb25lbnQgKGEuYi5jIC0+IGEuYilcbiAgICAgICAgLy8gT3RoZXJ3aXNlIHdlJ2xsIGluY2x1ZGUgb25lIGxldmVsIHRvbyBtdWNoLlxuICAgICAgICByZXR1cm4ga2V5LnNsaWNlKDAsIGtleS5sYXN0SW5kZXhPZignLicpKTtcbiAgICAgIH0pXG4gICAgICAuam9pbignLCcpO1xuXG4gICAgLy8gQ29uY2F0IHRoZSBwb3NzaWJseSBwcmVzZW50IGluY2x1ZGUgc3RyaW5nIHdpdGggdGhlIG9uZSBmcm9tIHRoZSBrZXlzXG4gICAgLy8gRGVkdXAgLyBzb3J0aW5nIGlzIGhhbmRsZSBpbiAnaW5jbHVkZScgY2FzZS5cbiAgICBpZiAoa2V5c0ZvckluY2x1ZGUubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFyZXN0T3B0aW9ucy5pbmNsdWRlIHx8IHJlc3RPcHRpb25zLmluY2x1ZGUubGVuZ3RoID09IDApIHtcbiAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZSA9IGtleXNGb3JJbmNsdWRlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZSArPSAnLCcgKyBrZXlzRm9ySW5jbHVkZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBvcHRpb24gaW4gcmVzdE9wdGlvbnMpIHtcbiAgICBzd2l0Y2ggKG9wdGlvbikge1xuICAgICAgY2FzZSAna2V5cyc6IHtcbiAgICAgICAgY29uc3Qga2V5cyA9IHJlc3RPcHRpb25zLmtleXMuc3BsaXQoJywnKS5jb25jYXQoQWx3YXlzU2VsZWN0ZWRLZXlzKTtcbiAgICAgICAgdGhpcy5rZXlzID0gQXJyYXkuZnJvbShuZXcgU2V0KGtleXMpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdleGNsdWRlS2V5cyc6IHtcbiAgICAgICAgY29uc3QgZXhjbHVkZSA9IHJlc3RPcHRpb25zLmV4Y2x1ZGVLZXlzXG4gICAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgICAuZmlsdGVyKGsgPT4gQWx3YXlzU2VsZWN0ZWRLZXlzLmluZGV4T2YoaykgPCAwKTtcbiAgICAgICAgdGhpcy5leGNsdWRlS2V5cyA9IEFycmF5LmZyb20obmV3IFNldChleGNsdWRlKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnY291bnQnOlxuICAgICAgICB0aGlzLmRvQ291bnQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2luY2x1ZGVBbGwnOlxuICAgICAgICB0aGlzLmluY2x1ZGVBbGwgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2V4cGxhaW4nOlxuICAgICAgY2FzZSAnaGludCc6XG4gICAgICBjYXNlICdkaXN0aW5jdCc6XG4gICAgICBjYXNlICdwaXBlbGluZSc6XG4gICAgICBjYXNlICdza2lwJzpcbiAgICAgIGNhc2UgJ2xpbWl0JzpcbiAgICAgIGNhc2UgJ3JlYWRQcmVmZXJlbmNlJzpcbiAgICAgICAgdGhpcy5maW5kT3B0aW9uc1tvcHRpb25dID0gcmVzdE9wdGlvbnNbb3B0aW9uXTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdvcmRlcic6XG4gICAgICAgIHZhciBmaWVsZHMgPSByZXN0T3B0aW9ucy5vcmRlci5zcGxpdCgnLCcpO1xuICAgICAgICB0aGlzLmZpbmRPcHRpb25zLnNvcnQgPSBmaWVsZHMucmVkdWNlKChzb3J0TWFwLCBmaWVsZCkgPT4ge1xuICAgICAgICAgIGZpZWxkID0gZmllbGQudHJpbSgpO1xuICAgICAgICAgIGlmIChmaWVsZCA9PT0gJyRzY29yZScpIHtcbiAgICAgICAgICAgIHNvcnRNYXAuc2NvcmUgPSB7ICRtZXRhOiAndGV4dFNjb3JlJyB9O1xuICAgICAgICAgIH0gZWxzZSBpZiAoZmllbGRbMF0gPT0gJy0nKSB7XG4gICAgICAgICAgICBzb3J0TWFwW2ZpZWxkLnNsaWNlKDEpXSA9IC0xO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzb3J0TWFwW2ZpZWxkXSA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBzb3J0TWFwO1xuICAgICAgICB9LCB7fSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5jbHVkZSc6IHtcbiAgICAgICAgY29uc3QgcGF0aHMgPSByZXN0T3B0aW9ucy5pbmNsdWRlLnNwbGl0KCcsJyk7XG4gICAgICAgIGlmIChwYXRocy5pbmNsdWRlcygnKicpKSB7XG4gICAgICAgICAgdGhpcy5pbmNsdWRlQWxsID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBMb2FkIHRoZSBleGlzdGluZyBpbmNsdWRlcyAoZnJvbSBrZXlzKVxuICAgICAgICBjb25zdCBwYXRoU2V0ID0gcGF0aHMucmVkdWNlKChtZW1vLCBwYXRoKSA9PiB7XG4gICAgICAgICAgLy8gU3BsaXQgZWFjaCBwYXRocyBvbiAuIChhLmIuYyAtPiBbYSxiLGNdKVxuICAgICAgICAgIC8vIHJlZHVjZSB0byBjcmVhdGUgYWxsIHBhdGhzXG4gICAgICAgICAgLy8gKFthLGIsY10gLT4ge2E6IHRydWUsICdhLmInOiB0cnVlLCAnYS5iLmMnOiB0cnVlfSlcbiAgICAgICAgICByZXR1cm4gcGF0aC5zcGxpdCgnLicpLnJlZHVjZSgobWVtbywgcGF0aCwgaW5kZXgsIHBhcnRzKSA9PiB7XG4gICAgICAgICAgICBtZW1vW3BhcnRzLnNsaWNlKDAsIGluZGV4ICsgMSkuam9pbignLicpXSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgICB9LCBtZW1vKTtcbiAgICAgICAgfSwge30pO1xuXG4gICAgICAgIHRoaXMuaW5jbHVkZSA9IE9iamVjdC5rZXlzKHBhdGhTZXQpXG4gICAgICAgICAgLm1hcChzID0+IHtcbiAgICAgICAgICAgIHJldHVybiBzLnNwbGl0KCcuJyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGEubGVuZ3RoIC0gYi5sZW5ndGg7IC8vIFNvcnQgYnkgbnVtYmVyIG9mIGNvbXBvbmVudHNcbiAgICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdyZWRpcmVjdENsYXNzTmFtZUZvcktleSc6XG4gICAgICAgIHRoaXMucmVkaXJlY3RLZXkgPSByZXN0T3B0aW9ucy5yZWRpcmVjdENsYXNzTmFtZUZvcktleTtcbiAgICAgICAgdGhpcy5yZWRpcmVjdENsYXNzTmFtZSA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5jbHVkZVJlYWRQcmVmZXJlbmNlJzpcbiAgICAgIGNhc2UgJ3N1YnF1ZXJ5UmVhZFByZWZlcmVuY2UnOlxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgb3B0aW9uOiAnICsgb3B0aW9uKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gQSBjb252ZW5pZW50IG1ldGhvZCB0byBwZXJmb3JtIGFsbCB0aGUgc3RlcHMgb2YgcHJvY2Vzc2luZyBhIHF1ZXJ5XG4vLyBpbiBvcmRlci5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzcG9uc2UgLSBhbiBvYmplY3Qgd2l0aCBvcHRpb25hbCBrZXlzXG4vLyAncmVzdWx0cycgYW5kICdjb3VudCcuXG4vLyBUT0RPOiBjb25zb2xpZGF0ZSB0aGUgcmVwbGFjZVggZnVuY3Rpb25zXG5SZXN0UXVlcnkucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoZXhlY3V0ZU9wdGlvbnMpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnVpbGRSZXN0V2hlcmUoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUluY2x1ZGVBbGwoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUV4Y2x1ZGVLZXlzKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5GaW5kKGV4ZWN1dGVPcHRpb25zKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJ1bkNvdW50KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVJbmNsdWRlKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5BZnRlckZpbmRUcmlnZ2VyKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZXNwb25zZTtcbiAgICB9KTtcbn07XG5cblJlc3RRdWVyeS5wcm90b3R5cGUuZWFjaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICBjb25zdCB7IGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREsgfSA9IHRoaXM7XG4gIC8vIGlmIHRoZSBsaW1pdCBpcyBzZXQsIHVzZSBpdFxuICByZXN0T3B0aW9ucy5saW1pdCA9IHJlc3RPcHRpb25zLmxpbWl0IHx8IDEwMDtcbiAgcmVzdE9wdGlvbnMub3JkZXIgPSAnb2JqZWN0SWQnO1xuICBsZXQgZmluaXNoZWQgPSBmYWxzZTtcblxuICByZXR1cm4gY29udGludWVXaGlsZShcbiAgICAoKSA9PiB7XG4gICAgICByZXR1cm4gIWZpbmlzaGVkO1xuICAgIH0sXG4gICAgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREspO1xuICAgICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCBxdWVyeS5leGVjdXRlKCk7XG4gICAgICByZXN1bHRzLmZvckVhY2goY2FsbGJhY2spO1xuICAgICAgZmluaXNoZWQgPSByZXN1bHRzLmxlbmd0aCA8IHJlc3RPcHRpb25zLmxpbWl0O1xuICAgICAgaWYgKCFmaW5pc2hlZCkge1xuICAgICAgICByZXN0V2hlcmUub2JqZWN0SWQgPSBPYmplY3QuYXNzaWduKHt9LCByZXN0V2hlcmUub2JqZWN0SWQsIHtcbiAgICAgICAgICAkZ3Q6IHJlc3VsdHNbcmVzdWx0cy5sZW5ndGggLSAxXS5vYmplY3RJZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICApO1xufTtcblxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5idWlsZFJlc3RXaGVyZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlckFuZFJvbGVBQ0woKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUNsaWVudENsYXNzQ3JlYXRpb24oKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VTZWxlY3QoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VEb250U2VsZWN0KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBsYWNlSW5RdWVyeSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZU5vdEluUXVlcnkoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VFcXVhbGl0eSgpO1xuICAgIH0pO1xufTtcblxuLy8gVXNlcyB0aGUgQXV0aCBvYmplY3QgdG8gZ2V0IHRoZSBsaXN0IG9mIHJvbGVzLCBhZGRzIHRoZSB1c2VyIGlkXG5SZXN0UXVlcnkucHJvdG90eXBlLmdldFVzZXJBbmRSb2xlQUNMID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgdGhpcy5maW5kT3B0aW9ucy5hY2wgPSBbJyonXTtcblxuICBpZiAodGhpcy5hdXRoLnVzZXIpIHtcbiAgICByZXR1cm4gdGhpcy5hdXRoLmdldFVzZXJSb2xlcygpLnRoZW4ocm9sZXMgPT4ge1xuICAgICAgdGhpcy5maW5kT3B0aW9ucy5hY2wgPSB0aGlzLmZpbmRPcHRpb25zLmFjbC5jb25jYXQocm9sZXMsIFt0aGlzLmF1dGgudXNlci5pZF0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxufTtcblxuLy8gQ2hhbmdlcyB0aGUgY2xhc3NOYW1lIGlmIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IGlzIHNldC5cbi8vIFJldHVybnMgYSBwcm9taXNlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnJlZGlyZWN0S2V5KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIGNsYXNzIG5hbWUgYmFzZWQgb24gdGhlIHNjaGVtYVxuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAucmVkaXJlY3RDbGFzc05hbWVGb3JLZXkodGhpcy5jbGFzc05hbWUsIHRoaXMucmVkaXJlY3RLZXkpXG4gICAgLnRoZW4obmV3Q2xhc3NOYW1lID0+IHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lID0gbmV3Q2xhc3NOYW1lO1xuICAgICAgdGhpcy5yZWRpcmVjdENsYXNzTmFtZSA9IG5ld0NsYXNzTmFtZTtcbiAgICB9KTtcbn07XG5cbi8vIFZhbGlkYXRlcyB0aGlzIG9wZXJhdGlvbiBhZ2FpbnN0IHRoZSBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gY29uZmlnLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS52YWxpZGF0ZUNsaWVudENsYXNzQ3JlYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmIChcbiAgICB0aGlzLmNvbmZpZy5hbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gPT09IGZhbHNlICYmXG4gICAgIXRoaXMuYXV0aC5pc01hc3RlciAmJlxuICAgIFNjaGVtYUNvbnRyb2xsZXIuc3lzdGVtQ2xhc3Nlcy5pbmRleE9mKHRoaXMuY2xhc3NOYW1lKSA9PT0gLTFcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAubG9hZFNjaGVtYSgpXG4gICAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHNjaGVtYUNvbnRyb2xsZXIuaGFzQ2xhc3ModGhpcy5jbGFzc05hbWUpKVxuICAgICAgLnRoZW4oaGFzQ2xhc3MgPT4ge1xuICAgICAgICBpZiAoaGFzQ2xhc3MgIT09IHRydWUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgJ1RoaXMgdXNlciBpcyBub3QgYWxsb3dlZCB0byBhY2Nlc3MgJyArICdub24tZXhpc3RlbnQgY2xhc3M6ICcgKyB0aGlzLmNsYXNzTmFtZVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtSW5RdWVyeShpblF1ZXJ5T2JqZWN0LCBjbGFzc05hbWUsIHJlc3VsdHMpIHtcbiAgdmFyIHZhbHVlcyA9IFtdO1xuICBmb3IgKHZhciByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIHZhbHVlcy5wdXNoKHtcbiAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICBvYmplY3RJZDogcmVzdWx0Lm9iamVjdElkLFxuICAgIH0pO1xuICB9XG4gIGRlbGV0ZSBpblF1ZXJ5T2JqZWN0WyckaW5RdWVyeSddO1xuICBpZiAoQXJyYXkuaXNBcnJheShpblF1ZXJ5T2JqZWN0WyckaW4nXSkpIHtcbiAgICBpblF1ZXJ5T2JqZWN0WyckaW4nXSA9IGluUXVlcnlPYmplY3RbJyRpbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIGluUXVlcnlPYmplY3RbJyRpbiddID0gdmFsdWVzO1xuICB9XG59XG5cbi8vIFJlcGxhY2VzIGEgJGluUXVlcnkgY2xhdXNlIGJ5IHJ1bm5pbmcgdGhlIHN1YnF1ZXJ5LCBpZiB0aGVyZSBpcyBhblxuLy8gJGluUXVlcnkgY2xhdXNlLlxuLy8gVGhlICRpblF1ZXJ5IGNsYXVzZSB0dXJucyBpbnRvIGFuICRpbiB3aXRoIHZhbHVlcyB0aGF0IGFyZSBqdXN0XG4vLyBwb2ludGVycyB0byB0aGUgb2JqZWN0cyByZXR1cm5lZCBpbiB0aGUgc3VicXVlcnkuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VJblF1ZXJ5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaW5RdWVyeU9iamVjdCA9IGZpbmRPYmplY3RXaXRoS2V5KHRoaXMucmVzdFdoZXJlLCAnJGluUXVlcnknKTtcbiAgaWYgKCFpblF1ZXJ5T2JqZWN0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVGhlIGluUXVlcnkgdmFsdWUgbXVzdCBoYXZlIHByZWNpc2VseSB0d28ga2V5cyAtIHdoZXJlIGFuZCBjbGFzc05hbWVcbiAgdmFyIGluUXVlcnlWYWx1ZSA9IGluUXVlcnlPYmplY3RbJyRpblF1ZXJ5J107XG4gIGlmICghaW5RdWVyeVZhbHVlLndoZXJlIHx8ICFpblF1ZXJ5VmFsdWUuY2xhc3NOYW1lKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdpbXByb3BlciB1c2FnZSBvZiAkaW5RdWVyeScpO1xuICB9XG5cbiAgY29uc3QgYWRkaXRpb25hbE9wdGlvbnMgPSB7XG4gICAgcmVkaXJlY3RDbGFzc05hbWVGb3JLZXk6IGluUXVlcnlWYWx1ZS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSxcbiAgfTtcblxuICBpZiAodGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgYWRkaXRpb25hbE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgYWRkaXRpb25hbE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgfSBlbHNlIGlmICh0aGlzLnJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlKSB7XG4gICAgYWRkaXRpb25hbE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgdmFyIHN1YnF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShcbiAgICB0aGlzLmNvbmZpZyxcbiAgICB0aGlzLmF1dGgsXG4gICAgaW5RdWVyeVZhbHVlLmNsYXNzTmFtZSxcbiAgICBpblF1ZXJ5VmFsdWUud2hlcmUsXG4gICAgYWRkaXRpb25hbE9wdGlvbnNcbiAgKTtcbiAgcmV0dXJuIHN1YnF1ZXJ5LmV4ZWN1dGUoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICB0cmFuc2Zvcm1JblF1ZXJ5KGluUXVlcnlPYmplY3QsIHN1YnF1ZXJ5LmNsYXNzTmFtZSwgcmVzcG9uc2UucmVzdWx0cyk7XG4gICAgLy8gUmVjdXJzZSB0byByZXBlYXRcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlSW5RdWVyeSgpO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybU5vdEluUXVlcnkobm90SW5RdWVyeU9iamVjdCwgY2xhc3NOYW1lLCByZXN1bHRzKSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICB2YWx1ZXMucHVzaCh7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgb2JqZWN0SWQ6IHJlc3VsdC5vYmplY3RJZCxcbiAgICB9KTtcbiAgfVxuICBkZWxldGUgbm90SW5RdWVyeU9iamVjdFsnJG5vdEluUXVlcnknXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkobm90SW5RdWVyeU9iamVjdFsnJG5pbiddKSkge1xuICAgIG5vdEluUXVlcnlPYmplY3RbJyRuaW4nXSA9IG5vdEluUXVlcnlPYmplY3RbJyRuaW4nXS5jb25jYXQodmFsdWVzKTtcbiAgfSBlbHNlIHtcbiAgICBub3RJblF1ZXJ5T2JqZWN0WyckbmluJ10gPSB2YWx1ZXM7XG4gIH1cbn1cblxuLy8gUmVwbGFjZXMgYSAkbm90SW5RdWVyeSBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFuXG4vLyAkbm90SW5RdWVyeSBjbGF1c2UuXG4vLyBUaGUgJG5vdEluUXVlcnkgY2xhdXNlIHR1cm5zIGludG8gYSAkbmluIHdpdGggdmFsdWVzIHRoYXQgYXJlIGp1c3Rcbi8vIHBvaW50ZXJzIHRvIHRoZSBvYmplY3RzIHJldHVybmVkIGluIHRoZSBzdWJxdWVyeS5cblJlc3RRdWVyeS5wcm90b3R5cGUucmVwbGFjZU5vdEluUXVlcnkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub3RJblF1ZXJ5T2JqZWN0ID0gZmluZE9iamVjdFdpdGhLZXkodGhpcy5yZXN0V2hlcmUsICckbm90SW5RdWVyeScpO1xuICBpZiAoIW5vdEluUXVlcnlPYmplY3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgbm90SW5RdWVyeSB2YWx1ZSBtdXN0IGhhdmUgcHJlY2lzZWx5IHR3byBrZXlzIC0gd2hlcmUgYW5kIGNsYXNzTmFtZVxuICB2YXIgbm90SW5RdWVyeVZhbHVlID0gbm90SW5RdWVyeU9iamVjdFsnJG5vdEluUXVlcnknXTtcbiAgaWYgKCFub3RJblF1ZXJ5VmFsdWUud2hlcmUgfHwgIW5vdEluUXVlcnlWYWx1ZS5jbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ2ltcHJvcGVyIHVzYWdlIG9mICRub3RJblF1ZXJ5Jyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogbm90SW5RdWVyeVZhbHVlLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBub3RJblF1ZXJ5VmFsdWUuY2xhc3NOYW1lLFxuICAgIG5vdEluUXVlcnlWYWx1ZS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybU5vdEluUXVlcnkobm90SW5RdWVyeU9iamVjdCwgc3VicXVlcnkuY2xhc3NOYW1lLCByZXNwb25zZS5yZXN1bHRzKTtcbiAgICAvLyBSZWN1cnNlIHRvIHJlcGVhdFxuICAgIHJldHVybiB0aGlzLnJlcGxhY2VOb3RJblF1ZXJ5KCk7XG4gIH0pO1xufTtcblxuLy8gVXNlZCB0byBnZXQgdGhlIGRlZXBlc3Qgb2JqZWN0IGZyb20ganNvbiB1c2luZyBkb3Qgbm90YXRpb24uXG5jb25zdCBnZXREZWVwZXN0T2JqZWN0RnJvbUtleSA9IChqc29uLCBrZXksIGlkeCwgc3JjKSA9PiB7XG4gIGlmIChrZXkgaW4ganNvbikge1xuICAgIHJldHVybiBqc29uW2tleV07XG4gIH1cbiAgc3JjLnNwbGljZSgxKTsgLy8gRXhpdCBFYXJseVxufTtcblxuY29uc3QgdHJhbnNmb3JtU2VsZWN0ID0gKHNlbGVjdE9iamVjdCwga2V5LCBvYmplY3RzKSA9PiB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIgcmVzdWx0IG9mIG9iamVjdHMpIHtcbiAgICB2YWx1ZXMucHVzaChrZXkuc3BsaXQoJy4nKS5yZWR1Y2UoZ2V0RGVlcGVzdE9iamVjdEZyb21LZXksIHJlc3VsdCkpO1xuICB9XG4gIGRlbGV0ZSBzZWxlY3RPYmplY3RbJyRzZWxlY3QnXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZWN0T2JqZWN0WyckaW4nXSkpIHtcbiAgICBzZWxlY3RPYmplY3RbJyRpbiddID0gc2VsZWN0T2JqZWN0WyckaW4nXS5jb25jYXQodmFsdWVzKTtcbiAgfSBlbHNlIHtcbiAgICBzZWxlY3RPYmplY3RbJyRpbiddID0gdmFsdWVzO1xuICB9XG59O1xuXG4vLyBSZXBsYWNlcyBhICRzZWxlY3QgY2xhdXNlIGJ5IHJ1bm5pbmcgdGhlIHN1YnF1ZXJ5LCBpZiB0aGVyZSBpcyBhXG4vLyAkc2VsZWN0IGNsYXVzZS5cbi8vIFRoZSAkc2VsZWN0IGNsYXVzZSB0dXJucyBpbnRvIGFuICRpbiB3aXRoIHZhbHVlcyBzZWxlY3RlZCBvdXQgb2Zcbi8vIHRoZSBzdWJxdWVyeS5cbi8vIFJldHVybnMgYSBwb3NzaWJsZS1wcm9taXNlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlU2VsZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZWN0T2JqZWN0ID0gZmluZE9iamVjdFdpdGhLZXkodGhpcy5yZXN0V2hlcmUsICckc2VsZWN0Jyk7XG4gIGlmICghc2VsZWN0T2JqZWN0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVGhlIHNlbGVjdCB2YWx1ZSBtdXN0IGhhdmUgcHJlY2lzZWx5IHR3byBrZXlzIC0gcXVlcnkgYW5kIGtleVxuICB2YXIgc2VsZWN0VmFsdWUgPSBzZWxlY3RPYmplY3RbJyRzZWxlY3QnXTtcbiAgLy8gaU9TIFNESyBkb24ndCBzZW5kIHdoZXJlIGlmIG5vdCBzZXQsIGxldCBpdCBwYXNzXG4gIGlmIChcbiAgICAhc2VsZWN0VmFsdWUucXVlcnkgfHxcbiAgICAhc2VsZWN0VmFsdWUua2V5IHx8XG4gICAgdHlwZW9mIHNlbGVjdFZhbHVlLnF1ZXJ5ICE9PSAnb2JqZWN0JyB8fFxuICAgICFzZWxlY3RWYWx1ZS5xdWVyeS5jbGFzc05hbWUgfHxcbiAgICBPYmplY3Qua2V5cyhzZWxlY3RWYWx1ZSkubGVuZ3RoICE9PSAyXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnaW1wcm9wZXIgdXNhZ2Ugb2YgJHNlbGVjdCcpO1xuICB9XG5cbiAgY29uc3QgYWRkaXRpb25hbE9wdGlvbnMgPSB7XG4gICAgcmVkaXJlY3RDbGFzc05hbWVGb3JLZXk6IHNlbGVjdFZhbHVlLnF1ZXJ5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBzZWxlY3RWYWx1ZS5xdWVyeS5jbGFzc05hbWUsXG4gICAgc2VsZWN0VmFsdWUucXVlcnkud2hlcmUsXG4gICAgYWRkaXRpb25hbE9wdGlvbnNcbiAgKTtcbiAgcmV0dXJuIHN1YnF1ZXJ5LmV4ZWN1dGUoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICB0cmFuc2Zvcm1TZWxlY3Qoc2VsZWN0T2JqZWN0LCBzZWxlY3RWYWx1ZS5rZXksIHJlc3BvbnNlLnJlc3VsdHMpO1xuICAgIC8vIEtlZXAgcmVwbGFjaW5nICRzZWxlY3QgY2xhdXNlc1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2VTZWxlY3QoKTtcbiAgfSk7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1Eb250U2VsZWN0ID0gKGRvbnRTZWxlY3RPYmplY3QsIGtleSwgb2JqZWN0cykgPT4ge1xuICB2YXIgdmFsdWVzID0gW107XG4gIGZvciAodmFyIHJlc3VsdCBvZiBvYmplY3RzKSB7XG4gICAgdmFsdWVzLnB1c2goa2V5LnNwbGl0KCcuJykucmVkdWNlKGdldERlZXBlc3RPYmplY3RGcm9tS2V5LCByZXN1bHQpKTtcbiAgfVxuICBkZWxldGUgZG9udFNlbGVjdE9iamVjdFsnJGRvbnRTZWxlY3QnXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZG9udFNlbGVjdE9iamVjdFsnJG5pbiddKSkge1xuICAgIGRvbnRTZWxlY3RPYmplY3RbJyRuaW4nXSA9IGRvbnRTZWxlY3RPYmplY3RbJyRuaW4nXS5jb25jYXQodmFsdWVzKTtcbiAgfSBlbHNlIHtcbiAgICBkb250U2VsZWN0T2JqZWN0WyckbmluJ10gPSB2YWx1ZXM7XG4gIH1cbn07XG5cbi8vIFJlcGxhY2VzIGEgJGRvbnRTZWxlY3QgY2xhdXNlIGJ5IHJ1bm5pbmcgdGhlIHN1YnF1ZXJ5LCBpZiB0aGVyZSBpcyBhXG4vLyAkZG9udFNlbGVjdCBjbGF1c2UuXG4vLyBUaGUgJGRvbnRTZWxlY3QgY2xhdXNlIHR1cm5zIGludG8gYW4gJG5pbiB3aXRoIHZhbHVlcyBzZWxlY3RlZCBvdXQgb2Zcbi8vIHRoZSBzdWJxdWVyeS5cbi8vIFJldHVybnMgYSBwb3NzaWJsZS1wcm9taXNlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlRG9udFNlbGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRvbnRTZWxlY3RPYmplY3QgPSBmaW5kT2JqZWN0V2l0aEtleSh0aGlzLnJlc3RXaGVyZSwgJyRkb250U2VsZWN0Jyk7XG4gIGlmICghZG9udFNlbGVjdE9iamVjdCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFRoZSBkb250U2VsZWN0IHZhbHVlIG11c3QgaGF2ZSBwcmVjaXNlbHkgdHdvIGtleXMgLSBxdWVyeSBhbmQga2V5XG4gIHZhciBkb250U2VsZWN0VmFsdWUgPSBkb250U2VsZWN0T2JqZWN0WyckZG9udFNlbGVjdCddO1xuICBpZiAoXG4gICAgIWRvbnRTZWxlY3RWYWx1ZS5xdWVyeSB8fFxuICAgICFkb250U2VsZWN0VmFsdWUua2V5IHx8XG4gICAgdHlwZW9mIGRvbnRTZWxlY3RWYWx1ZS5xdWVyeSAhPT0gJ29iamVjdCcgfHxcbiAgICAhZG9udFNlbGVjdFZhbHVlLnF1ZXJ5LmNsYXNzTmFtZSB8fFxuICAgIE9iamVjdC5rZXlzKGRvbnRTZWxlY3RWYWx1ZSkubGVuZ3RoICE9PSAyXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnaW1wcm9wZXIgdXNhZ2Ugb2YgJGRvbnRTZWxlY3QnKTtcbiAgfVxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogZG9udFNlbGVjdFZhbHVlLnF1ZXJ5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBkb250U2VsZWN0VmFsdWUucXVlcnkuY2xhc3NOYW1lLFxuICAgIGRvbnRTZWxlY3RWYWx1ZS5xdWVyeS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybURvbnRTZWxlY3QoZG9udFNlbGVjdE9iamVjdCwgZG9udFNlbGVjdFZhbHVlLmtleSwgcmVzcG9uc2UucmVzdWx0cyk7XG4gICAgLy8gS2VlcCByZXBsYWNpbmcgJGRvbnRTZWxlY3QgY2xhdXNlc1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2VEb250U2VsZWN0KCk7XG4gIH0pO1xufTtcblxuY29uc3QgY2xlYW5SZXN1bHRBdXRoRGF0YSA9IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgZGVsZXRlIHJlc3VsdC5wYXNzd29yZDtcbiAgaWYgKHJlc3VsdC5hdXRoRGF0YSkge1xuICAgIE9iamVjdC5rZXlzKHJlc3VsdC5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICBpZiAocmVzdWx0LmF1dGhEYXRhW3Byb3ZpZGVyXSA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgcmVzdWx0LmF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChPYmplY3Qua2V5cyhyZXN1bHQuYXV0aERhdGEpLmxlbmd0aCA9PSAwKSB7XG4gICAgICBkZWxldGUgcmVzdWx0LmF1dGhEYXRhO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgcmVwbGFjZUVxdWFsaXR5Q29uc3RyYWludCA9IGNvbnN0cmFpbnQgPT4ge1xuICBpZiAodHlwZW9mIGNvbnN0cmFpbnQgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGNvbnN0cmFpbnQ7XG4gIH1cbiAgY29uc3QgZXF1YWxUb09iamVjdCA9IHt9O1xuICBsZXQgaGFzRGlyZWN0Q29uc3RyYWludCA9IGZhbHNlO1xuICBsZXQgaGFzT3BlcmF0b3JDb25zdHJhaW50ID0gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IGluIGNvbnN0cmFpbnQpIHtcbiAgICBpZiAoa2V5LmluZGV4T2YoJyQnKSAhPT0gMCkge1xuICAgICAgaGFzRGlyZWN0Q29uc3RyYWludCA9IHRydWU7XG4gICAgICBlcXVhbFRvT2JqZWN0W2tleV0gPSBjb25zdHJhaW50W2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGhhc09wZXJhdG9yQ29uc3RyYWludCA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmIChoYXNEaXJlY3RDb25zdHJhaW50ICYmIGhhc09wZXJhdG9yQ29uc3RyYWludCkge1xuICAgIGNvbnN0cmFpbnRbJyRlcSddID0gZXF1YWxUb09iamVjdDtcbiAgICBPYmplY3Qua2V5cyhlcXVhbFRvT2JqZWN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBkZWxldGUgY29uc3RyYWludFtrZXldO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBjb25zdHJhaW50O1xufTtcblxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlRXF1YWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgdGhpcy5yZXN0V2hlcmUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAoY29uc3Qga2V5IGluIHRoaXMucmVzdFdoZXJlKSB7XG4gICAgdGhpcy5yZXN0V2hlcmVba2V5XSA9IHJlcGxhY2VFcXVhbGl0eUNvbnN0cmFpbnQodGhpcy5yZXN0V2hlcmVba2V5XSk7XG4gIH1cbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB3aGV0aGVyIGl0IHdhcyBzdWNjZXNzZnVsLlxuLy8gUG9wdWxhdGVzIHRoaXMucmVzcG9uc2Ugd2l0aCBhbiBvYmplY3QgdGhhdCBvbmx5IGhhcyAncmVzdWx0cycuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJ1bkZpbmQgPSBmdW5jdGlvbiAob3B0aW9ucyA9IHt9KSB7XG4gIGlmICh0aGlzLmZpbmRPcHRpb25zLmxpbWl0ID09PSAwKSB7XG4gICAgdGhpcy5yZXNwb25zZSA9IHsgcmVzdWx0czogW10gfTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgY29uc3QgZmluZE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmZpbmRPcHRpb25zKTtcbiAgaWYgKHRoaXMua2V5cykge1xuICAgIGZpbmRPcHRpb25zLmtleXMgPSB0aGlzLmtleXMubWFwKGtleSA9PiB7XG4gICAgICByZXR1cm4ga2V5LnNwbGl0KCcuJylbMF07XG4gICAgfSk7XG4gIH1cbiAgaWYgKG9wdGlvbnMub3ApIHtcbiAgICBmaW5kT3B0aW9ucy5vcCA9IG9wdGlvbnMub3A7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgLmZpbmQodGhpcy5jbGFzc05hbWUsIHRoaXMucmVzdFdoZXJlLCBmaW5kT3B0aW9ucywgdGhpcy5hdXRoKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmIGZpbmRPcHRpb25zLmV4cGxhaW4gIT09IHRydWUpIHtcbiAgICAgICAgZm9yICh2YXIgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICBjbGVhblJlc3VsdEF1dGhEYXRhKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5jb25maWcuZmlsZXNDb250cm9sbGVyLmV4cGFuZEZpbGVzSW5PYmplY3QodGhpcy5jb25maWcsIHJlc3VsdHMpO1xuXG4gICAgICBpZiAodGhpcy5yZWRpcmVjdENsYXNzTmFtZSkge1xuICAgICAgICBmb3IgKHZhciByIG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICByLmNsYXNzTmFtZSA9IHRoaXMucmVkaXJlY3RDbGFzc05hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMucmVzcG9uc2UgPSB7IHJlc3VsdHM6IHJlc3VsdHMgfTtcbiAgICB9KTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB3aGV0aGVyIGl0IHdhcyBzdWNjZXNzZnVsLlxuLy8gUG9wdWxhdGVzIHRoaXMucmVzcG9uc2UuY291bnQgd2l0aCB0aGUgY291bnRcblJlc3RRdWVyeS5wcm90b3R5cGUucnVuQ291bnQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5kb0NvdW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuZmluZE9wdGlvbnMuY291bnQgPSB0cnVlO1xuICBkZWxldGUgdGhpcy5maW5kT3B0aW9ucy5za2lwO1xuICBkZWxldGUgdGhpcy5maW5kT3B0aW9ucy5saW1pdDtcbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQodGhpcy5jbGFzc05hbWUsIHRoaXMucmVzdFdoZXJlLCB0aGlzLmZpbmRPcHRpb25zKS50aGVuKGMgPT4ge1xuICAgIHRoaXMucmVzcG9uc2UuY291bnQgPSBjO1xuICB9KTtcbn07XG5cbi8vIEF1Z21lbnRzIHRoaXMucmVzcG9uc2Ugd2l0aCBhbGwgcG9pbnRlcnMgb24gYW4gb2JqZWN0XG5SZXN0UXVlcnkucHJvdG90eXBlLmhhbmRsZUluY2x1ZGVBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5pbmNsdWRlQWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKClcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHNjaGVtYUNvbnRyb2xsZXIuZ2V0T25lU2NoZW1hKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgY29uc3QgaW5jbHVkZUZpZWxkcyA9IFtdO1xuICAgICAgY29uc3Qga2V5RmllbGRzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHNjaGVtYS5maWVsZHMpIHtcbiAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgICAgaW5jbHVkZUZpZWxkcy5wdXNoKFtmaWVsZF0pO1xuICAgICAgICAgIGtleUZpZWxkcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQWRkIGZpZWxkcyB0byBpbmNsdWRlLCBrZXlzLCByZW1vdmUgZHVwc1xuICAgICAgdGhpcy5pbmNsdWRlID0gWy4uLm5ldyBTZXQoWy4uLnRoaXMuaW5jbHVkZSwgLi4uaW5jbHVkZUZpZWxkc10pXTtcbiAgICAgIC8vIGlmIHRoaXMua2V5cyBub3Qgc2V0LCB0aGVuIGFsbCBrZXlzIGFyZSBhbHJlYWR5IGluY2x1ZGVkXG4gICAgICBpZiAodGhpcy5rZXlzKSB7XG4gICAgICAgIHRoaXMua2V5cyA9IFsuLi5uZXcgU2V0KFsuLi50aGlzLmtleXMsIC4uLmtleUZpZWxkc10pXTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8vIFVwZGF0ZXMgcHJvcGVydHkgYHRoaXMua2V5c2AgdG8gY29udGFpbiBhbGwga2V5cyBidXQgdGhlIG9uZXMgdW5zZWxlY3RlZC5cblJlc3RRdWVyeS5wcm90b3R5cGUuaGFuZGxlRXhjbHVkZUtleXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5leGNsdWRlS2V5cykge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAodGhpcy5rZXlzKSB7XG4gICAgdGhpcy5rZXlzID0gdGhpcy5rZXlzLmZpbHRlcihrID0+ICF0aGlzLmV4Y2x1ZGVLZXlzLmluY2x1ZGVzKGspKTtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoKVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEodGhpcy5jbGFzc05hbWUpKVxuICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhzY2hlbWEuZmllbGRzKTtcbiAgICAgIHRoaXMua2V5cyA9IGZpZWxkcy5maWx0ZXIoayA9PiAhdGhpcy5leGNsdWRlS2V5cy5pbmNsdWRlcyhrKSk7XG4gICAgfSk7XG59O1xuXG4vLyBBdWdtZW50cyB0aGlzLnJlc3BvbnNlIHdpdGggZGF0YSBhdCB0aGUgcGF0aHMgcHJvdmlkZWQgaW4gdGhpcy5pbmNsdWRlLlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5oYW5kbGVJbmNsdWRlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5pbmNsdWRlLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBhdGhSZXNwb25zZSA9IGluY2x1ZGVQYXRoKFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICB0aGlzLnJlc3BvbnNlLFxuICAgIHRoaXMuaW5jbHVkZVswXSxcbiAgICB0aGlzLnJlc3RPcHRpb25zXG4gICk7XG4gIGlmIChwYXRoUmVzcG9uc2UudGhlbikge1xuICAgIHJldHVybiBwYXRoUmVzcG9uc2UudGhlbihuZXdSZXNwb25zZSA9PiB7XG4gICAgICB0aGlzLnJlc3BvbnNlID0gbmV3UmVzcG9uc2U7XG4gICAgICB0aGlzLmluY2x1ZGUgPSB0aGlzLmluY2x1ZGUuc2xpY2UoMSk7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVJbmNsdWRlKCk7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodGhpcy5pbmNsdWRlLmxlbmd0aCA+IDApIHtcbiAgICB0aGlzLmluY2x1ZGUgPSB0aGlzLmluY2x1ZGUuc2xpY2UoMSk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5jbHVkZSgpO1xuICB9XG5cbiAgcmV0dXJuIHBhdGhSZXNwb25zZTtcbn07XG5cbi8vUmV0dXJucyBhIHByb21pc2Ugb2YgYSBwcm9jZXNzZWQgc2V0IG9mIHJlc3VsdHNcblJlc3RRdWVyeS5wcm90b3R5cGUucnVuQWZ0ZXJGaW5kVHJpZ2dlciA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnJlc3BvbnNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICghdGhpcy5ydW5BZnRlckZpbmQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gQXZvaWQgZG9pbmcgYW55IHNldHVwIGZvciB0cmlnZ2VycyBpZiB0aGVyZSBpcyBubyAnYWZ0ZXJGaW5kJyB0cmlnZ2VyIGZvciB0aGlzIGNsYXNzLlxuICBjb25zdCBoYXNBZnRlckZpbmRIb29rID0gdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyhcbiAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckZpbmQsXG4gICAgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZFxuICApO1xuICBpZiAoIWhhc0FmdGVyRmluZEhvb2spIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gU2tpcCBBZ2dyZWdhdGUgYW5kIERpc3RpbmN0IFF1ZXJpZXNcbiAgaWYgKHRoaXMuZmluZE9wdGlvbnMucGlwZWxpbmUgfHwgdGhpcy5maW5kT3B0aW9ucy5kaXN0aW5jdCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNvbnN0IGpzb24gPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnJlc3RPcHRpb25zKTtcbiAganNvbi53aGVyZSA9IHRoaXMucmVzdFdoZXJlO1xuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KHRoaXMuY2xhc3NOYW1lKTtcbiAgcGFyc2VRdWVyeS53aXRoSlNPTihqc29uKTtcbiAgLy8gUnVuIGFmdGVyRmluZCB0cmlnZ2VyIGFuZCBzZXQgdGhlIG5ldyByZXN1bHRzXG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1bkFmdGVyRmluZFRyaWdnZXIoXG4gICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckZpbmQsXG4gICAgICB0aGlzLmF1dGgsXG4gICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgIHRoaXMucmVzcG9uc2UucmVzdWx0cyxcbiAgICAgIHRoaXMuY29uZmlnLFxuICAgICAgcGFyc2VRdWVyeVxuICAgIClcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIC8vIEVuc3VyZSB3ZSBwcm9wZXJseSBzZXQgdGhlIGNsYXNzTmFtZSBiYWNrXG4gICAgICBpZiAodGhpcy5yZWRpcmVjdENsYXNzTmFtZSkge1xuICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3VsdHMgPSByZXN1bHRzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpIHtcbiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC50b0pTT04oKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0LmNsYXNzTmFtZSA9IHRoaXMucmVkaXJlY3RDbGFzc05hbWU7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3VsdHMgPSByZXN1bHRzO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuLy8gQWRkcyBpbmNsdWRlZCB2YWx1ZXMgdG8gdGhlIHJlc3BvbnNlLlxuLy8gUGF0aCBpcyBhIGxpc3Qgb2YgZmllbGQgbmFtZXMuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYW4gYXVnbWVudGVkIHJlc3BvbnNlLlxuZnVuY3Rpb24gaW5jbHVkZVBhdGgoY29uZmlnLCBhdXRoLCByZXNwb25zZSwgcGF0aCwgcmVzdE9wdGlvbnMgPSB7fSkge1xuICB2YXIgcG9pbnRlcnMgPSBmaW5kUG9pbnRlcnMocmVzcG9uc2UucmVzdWx0cywgcGF0aCk7XG4gIGlmIChwb2ludGVycy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuICBjb25zdCBwb2ludGVyc0hhc2ggPSB7fTtcbiAgZm9yICh2YXIgcG9pbnRlciBvZiBwb2ludGVycykge1xuICAgIGlmICghcG9pbnRlcikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHBvaW50ZXIuY2xhc3NOYW1lO1xuICAgIC8vIG9ubHkgaW5jbHVkZSB0aGUgZ29vZCBwb2ludGVyc1xuICAgIGlmIChjbGFzc05hbWUpIHtcbiAgICAgIHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdID0gcG9pbnRlcnNIYXNoW2NsYXNzTmFtZV0gfHwgbmV3IFNldCgpO1xuICAgICAgcG9pbnRlcnNIYXNoW2NsYXNzTmFtZV0uYWRkKHBvaW50ZXIub2JqZWN0SWQpO1xuICAgIH1cbiAgfVxuICBjb25zdCBpbmNsdWRlUmVzdE9wdGlvbnMgPSB7fTtcbiAgaWYgKHJlc3RPcHRpb25zLmtleXMpIHtcbiAgICBjb25zdCBrZXlzID0gbmV3IFNldChyZXN0T3B0aW9ucy5rZXlzLnNwbGl0KCcsJykpO1xuICAgIGNvbnN0IGtleVNldCA9IEFycmF5LmZyb20oa2V5cykucmVkdWNlKChzZXQsIGtleSkgPT4ge1xuICAgICAgY29uc3Qga2V5UGF0aCA9IGtleS5zcGxpdCgnLicpO1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgZm9yIChpOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aFtpXSAhPSBrZXlQYXRoW2ldKSB7XG4gICAgICAgICAgcmV0dXJuIHNldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGkgPCBrZXlQYXRoLmxlbmd0aCkge1xuICAgICAgICBzZXQuYWRkKGtleVBhdGhbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNldDtcbiAgICB9LCBuZXcgU2V0KCkpO1xuICAgIGlmIChrZXlTZXQuc2l6ZSA+IDApIHtcbiAgICAgIGluY2x1ZGVSZXN0T3B0aW9ucy5rZXlzID0gQXJyYXkuZnJvbShrZXlTZXQpLmpvaW4oJywnKTtcbiAgICB9XG4gIH1cblxuICBpZiAocmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgaW5jbHVkZVJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIGluY2x1ZGVSZXN0T3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSByZXN0T3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAocmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBpbmNsdWRlUmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIGNvbnN0IHF1ZXJ5UHJvbWlzZXMgPSBPYmplY3Qua2V5cyhwb2ludGVyc0hhc2gpLm1hcChjbGFzc05hbWUgPT4ge1xuICAgIGNvbnN0IG9iamVjdElkcyA9IEFycmF5LmZyb20ocG9pbnRlcnNIYXNoW2NsYXNzTmFtZV0pO1xuICAgIGxldCB3aGVyZTtcbiAgICBpZiAob2JqZWN0SWRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgd2hlcmUgPSB7IG9iamVjdElkOiBvYmplY3RJZHNbMF0gfTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hlcmUgPSB7IG9iamVjdElkOiB7ICRpbjogb2JqZWN0SWRzIH0gfTtcbiAgICB9XG4gICAgdmFyIHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgd2hlcmUsIGluY2x1ZGVSZXN0T3B0aW9ucyk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoeyBvcDogJ2dldCcgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHJlc3VsdHMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHRzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gR2V0IHRoZSBvYmplY3RzIGZvciBhbGwgdGhlc2Ugb2JqZWN0IGlkc1xuICByZXR1cm4gUHJvbWlzZS5hbGwocXVlcnlQcm9taXNlcykudGhlbihyZXNwb25zZXMgPT4ge1xuICAgIHZhciByZXBsYWNlID0gcmVzcG9uc2VzLnJlZHVjZSgocmVwbGFjZSwgaW5jbHVkZVJlc3BvbnNlKSA9PiB7XG4gICAgICBmb3IgKHZhciBvYmogb2YgaW5jbHVkZVJlc3BvbnNlLnJlc3VsdHMpIHtcbiAgICAgICAgb2JqLl9fdHlwZSA9ICdPYmplY3QnO1xuICAgICAgICBvYmouY2xhc3NOYW1lID0gaW5jbHVkZVJlc3BvbnNlLmNsYXNzTmFtZTtcblxuICAgICAgICBpZiAob2JqLmNsYXNzTmFtZSA9PSAnX1VzZXInICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgICAgICAgZGVsZXRlIG9iai5zZXNzaW9uVG9rZW47XG4gICAgICAgICAgZGVsZXRlIG9iai5hdXRoRGF0YTtcbiAgICAgICAgfVxuICAgICAgICByZXBsYWNlW29iai5vYmplY3RJZF0gPSBvYmo7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVwbGFjZTtcbiAgICB9LCB7fSk7XG5cbiAgICB2YXIgcmVzcCA9IHtcbiAgICAgIHJlc3VsdHM6IHJlcGxhY2VQb2ludGVycyhyZXNwb25zZS5yZXN1bHRzLCBwYXRoLCByZXBsYWNlKSxcbiAgICB9O1xuICAgIGlmIChyZXNwb25zZS5jb3VudCkge1xuICAgICAgcmVzcC5jb3VudCA9IHJlc3BvbnNlLmNvdW50O1xuICAgIH1cbiAgICByZXR1cm4gcmVzcDtcbiAgfSk7XG59XG5cbi8vIE9iamVjdCBtYXkgYmUgYSBsaXN0IG9mIFJFU1QtZm9ybWF0IG9iamVjdCB0byBmaW5kIHBvaW50ZXJzIGluLCBvclxuLy8gaXQgbWF5IGJlIGEgc2luZ2xlIG9iamVjdC5cbi8vIElmIHRoZSBwYXRoIHlpZWxkcyB0aGluZ3MgdGhhdCBhcmVuJ3QgcG9pbnRlcnMsIHRoaXMgdGhyb3dzIGFuIGVycm9yLlxuLy8gUGF0aCBpcyBhIGxpc3Qgb2YgZmllbGRzIHRvIHNlYXJjaCBpbnRvLlxuLy8gUmV0dXJucyBhIGxpc3Qgb2YgcG9pbnRlcnMgaW4gUkVTVCBmb3JtYXQuXG5mdW5jdGlvbiBmaW5kUG9pbnRlcnMob2JqZWN0LCBwYXRoKSB7XG4gIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHZhciBhbnN3ZXIgPSBbXTtcbiAgICBmb3IgKHZhciB4IG9mIG9iamVjdCkge1xuICAgICAgYW5zd2VyID0gYW5zd2VyLmNvbmNhdChmaW5kUG9pbnRlcnMoeCwgcGF0aCkpO1xuICAgIH1cbiAgICByZXR1cm4gYW5zd2VyO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdvYmplY3QnIHx8ICFvYmplY3QpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBpZiAocGF0aC5sZW5ndGggPT0gMCkge1xuICAgIGlmIChvYmplY3QgPT09IG51bGwgfHwgb2JqZWN0Ll9fdHlwZSA9PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiBbb2JqZWN0XTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgdmFyIHN1Ym9iamVjdCA9IG9iamVjdFtwYXRoWzBdXTtcbiAgaWYgKCFzdWJvYmplY3QpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGZpbmRQb2ludGVycyhzdWJvYmplY3QsIHBhdGguc2xpY2UoMSkpO1xufVxuXG4vLyBPYmplY3QgbWF5IGJlIGEgbGlzdCBvZiBSRVNULWZvcm1hdCBvYmplY3RzIHRvIHJlcGxhY2UgcG9pbnRlcnNcbi8vIGluLCBvciBpdCBtYXkgYmUgYSBzaW5nbGUgb2JqZWN0LlxuLy8gUGF0aCBpcyBhIGxpc3Qgb2YgZmllbGRzIHRvIHNlYXJjaCBpbnRvLlxuLy8gcmVwbGFjZSBpcyBhIG1hcCBmcm9tIG9iamVjdCBpZCAtPiBvYmplY3QuXG4vLyBSZXR1cm5zIHNvbWV0aGluZyBhbmFsb2dvdXMgdG8gb2JqZWN0LCBidXQgd2l0aCB0aGUgYXBwcm9wcmlhdGVcbi8vIHBvaW50ZXJzIGluZmxhdGVkLlxuZnVuY3Rpb24gcmVwbGFjZVBvaW50ZXJzKG9iamVjdCwgcGF0aCwgcmVwbGFjZSkge1xuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICByZXR1cm4gb2JqZWN0XG4gICAgICAubWFwKG9iaiA9PiByZXBsYWNlUG9pbnRlcnMob2JqLCBwYXRoLCByZXBsYWNlKSlcbiAgICAgIC5maWx0ZXIob2JqID0+IHR5cGVvZiBvYmogIT09ICd1bmRlZmluZWQnKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0JyB8fCAhb2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChvYmplY3QgJiYgb2JqZWN0Ll9fdHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICByZXR1cm4gcmVwbGFjZVtvYmplY3Qub2JqZWN0SWRdO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG5cbiAgdmFyIHN1Ym9iamVjdCA9IG9iamVjdFtwYXRoWzBdXTtcbiAgaWYgKCFzdWJvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG4gIHZhciBuZXdzdWIgPSByZXBsYWNlUG9pbnRlcnMoc3Vib2JqZWN0LCBwYXRoLnNsaWNlKDEpLCByZXBsYWNlKTtcbiAgdmFyIGFuc3dlciA9IHt9O1xuICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKGtleSA9PSBwYXRoWzBdKSB7XG4gICAgICBhbnN3ZXJba2V5XSA9IG5ld3N1YjtcbiAgICB9IGVsc2Uge1xuICAgICAgYW5zd2VyW2tleV0gPSBvYmplY3Rba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFuc3dlcjtcbn1cblxuLy8gRmluZHMgYSBzdWJvYmplY3QgdGhhdCBoYXMgdGhlIGdpdmVuIGtleSwgaWYgdGhlcmUgaXMgb25lLlxuLy8gUmV0dXJucyB1bmRlZmluZWQgb3RoZXJ3aXNlLlxuZnVuY3Rpb24gZmluZE9iamVjdFdpdGhLZXkocm9vdCwga2V5KSB7XG4gIGlmICh0eXBlb2Ygcm9vdCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHJvb3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIGZvciAodmFyIGl0ZW0gb2Ygcm9vdCkge1xuICAgICAgY29uc3QgYW5zd2VyID0gZmluZE9iamVjdFdpdGhLZXkoaXRlbSwga2V5KTtcbiAgICAgIGlmIChhbnN3ZXIpIHtcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKHJvb3QgJiYgcm9vdFtrZXldKSB7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cbiAgZm9yICh2YXIgc3Via2V5IGluIHJvb3QpIHtcbiAgICBjb25zdCBhbnN3ZXIgPSBmaW5kT2JqZWN0V2l0aEtleShyb290W3N1YmtleV0sIGtleSk7XG4gICAgaWYgKGFuc3dlcikge1xuICAgICAgcmV0dXJuIGFuc3dlcjtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSZXN0UXVlcnk7XG4iXX0= \ No newline at end of file diff --git a/lib/RestWrite.js b/lib/RestWrite.js deleted file mode 100644 index 4ba32bcb48..0000000000 --- a/lib/RestWrite.js +++ /dev/null @@ -1,1480 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _RestQuery = _interopRequireDefault(require("./RestQuery")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _logger = _interopRequireDefault(require("./logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// A RestWrite encapsulates everything we need to run an operation -// that writes to the database. -// This could be either a "create" or an "update". -var SchemaController = require('./Controllers/SchemaController'); - -var deepcopy = require('deepcopy'); - -const Auth = require('./Auth'); - -var cryptoUtils = require('./cryptoUtils'); - -var passwordCrypto = require('./password'); - -var Parse = require('parse/node'); - -var triggers = require('./triggers'); - -var ClientSDK = require('./ClientSDK'); - -// query and data are both provided in REST API format. So data -// types are encoded by plain old objects. -// If query is null, this is a "create" and the data in data should be -// created. -// Otherwise this is an "update" - the object matching the query -// should get updated with data. -// RestWrite will handle objectId, createdAt, and updatedAt for -// everything. It also knows to use triggers and special modifications -// for the _User class. -function RestWrite(config, auth, className, query, data, originalData, clientSDK, context, action) { - if (auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Cannot perform a write operation when using readOnlyMasterKey'); - } - - this.config = config; - this.auth = auth; - this.className = className; - this.clientSDK = clientSDK; - this.storage = {}; - this.runOptions = {}; - this.context = context || {}; - - if (action) { - this.runOptions.action = action; - } - - if (!query) { - if (this.config.allowCustomObjectId) { - if (Object.prototype.hasOwnProperty.call(data, 'objectId') && !data.objectId) { - throw new Parse.Error(Parse.Error.MISSING_OBJECT_ID, 'objectId must not be empty, null or undefined'); - } - } else { - if (data.objectId) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.'); - } - - if (data.id) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'id is an invalid field name.'); - } - } - } // When the operation is complete, this.response may have several - // fields. - // response: the actual data to be returned - // status: the http status code. if not present, treated like a 200 - // location: the location header. if not present, no location header - - - this.response = null; // Processing this operation may mutate our data, so we operate on a - // copy - - this.query = deepcopy(query); - this.data = deepcopy(data); // We never change originalData, so we do not need a deep copy - - this.originalData = originalData; // The timestamp we'll use for this whole operation - - this.updatedAt = Parse._encode(new Date()).iso; // Shared SchemaController to be reused to reduce the number of loadSchema() calls per request - // Once set the schemaData should be immutable - - this.validSchemaController = null; -} // A convenient method to perform all the steps of processing the -// write, in order. -// Returns a promise for a {response, status, location} object. -// status and location are optional. - - -RestWrite.prototype.execute = function () { - return Promise.resolve().then(() => { - return this.getUserAndRoleACL(); - }).then(() => { - return this.validateClientClassCreation(); - }).then(() => { - return this.handleInstallation(); - }).then(() => { - return this.handleSession(); - }).then(() => { - return this.validateAuthData(); - }).then(() => { - return this.runBeforeSaveTrigger(); - }).then(() => { - return this.deleteEmailResetTokenIfNeeded(); - }).then(() => { - return this.validateSchema(); - }).then(schemaController => { - this.validSchemaController = schemaController; - return this.setRequiredFieldsIfNeeded(); - }).then(() => { - return this.transformUser(); - }).then(() => { - return this.expandFilesForExistingObjects(); - }).then(() => { - return this.destroyDuplicatedSessions(); - }).then(() => { - return this.runDatabaseOperation(); - }).then(() => { - return this.createSessionTokenIfNeeded(); - }).then(() => { - return this.handleFollowup(); - }).then(() => { - return this.runAfterSaveTrigger(); - }).then(() => { - return this.cleanUserAuthData(); - }).then(() => { - return this.response; - }); -}; // Uses the Auth object to get the list of roles, adds the user id - - -RestWrite.prototype.getUserAndRoleACL = function () { - if (this.auth.isMaster) { - return Promise.resolve(); - } - - this.runOptions.acl = ['*']; - - if (this.auth.user) { - return this.auth.getUserRoles().then(roles => { - this.runOptions.acl = this.runOptions.acl.concat(roles, [this.auth.user.id]); - return; - }); - } else { - return Promise.resolve(); - } -}; // Validates this operation against the allowClientClassCreation config. - - -RestWrite.prototype.validateClientClassCreation = function () { - if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { - return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { - if (hasClass !== true) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); - } - }); - } else { - return Promise.resolve(); - } -}; // Validates this operation against the schema. - - -RestWrite.prototype.validateSchema = function () { - return this.config.database.validateObject(this.className, this.data, this.query, this.runOptions); -}; // Runs any beforeSave triggers against this operation. -// Any change leads to our data being mutated. - - -RestWrite.prototype.runBeforeSaveTrigger = function () { - if (this.response) { - return; - } // Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class. - - - if (!triggers.triggerExists(this.className, triggers.Types.beforeSave, this.config.applicationId)) { - return Promise.resolve(); - } // Cloud code gets a bit of extra data for its objects - - - var extraData = { - className: this.className - }; - - if (this.query && this.query.objectId) { - extraData.objectId = this.query.objectId; - } - - let originalObject = null; - const updatedObject = this.buildUpdatedObject(extraData); - - if (this.query && this.query.objectId) { - // This is an update for existing object. - originalObject = triggers.inflate(extraData, this.originalData); - } - - return Promise.resolve().then(() => { - // Before calling the trigger, validate the permissions for the save operation - let databasePromise = null; - - if (this.query) { - // Validate for updating - databasePromise = this.config.database.update(this.className, this.query, this.data, this.runOptions, false, true); - } else { - // Validate for creating - databasePromise = this.config.database.create(this.className, this.data, this.runOptions, true); - } // In the case that there is no permission for the operation, it throws an error - - - return databasePromise.then(result => { - if (!result || result.length <= 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - }); - }).then(() => { - return triggers.maybeRunTrigger(triggers.Types.beforeSave, this.auth, updatedObject, originalObject, this.config, this.context); - }).then(response => { - if (response && response.object) { - this.storage.fieldsChangedByTrigger = _lodash.default.reduce(response.object, (result, value, key) => { - if (!_lodash.default.isEqual(this.data[key], value)) { - result.push(key); - } - - return result; - }, []); - this.data = response.object; // We should delete the objectId for an update write - - if (this.query && this.query.objectId) { - delete this.data.objectId; - } - } - }); -}; - -RestWrite.prototype.runBeforeLoginTrigger = async function (userData) { - // Avoid doing any setup for triggers if there is no 'beforeLogin' trigger - if (!triggers.triggerExists(this.className, triggers.Types.beforeLogin, this.config.applicationId)) { - return; - } // Cloud code gets a bit of extra data for its objects - - - const extraData = { - className: this.className - }; // Expand file objects - - this.config.filesController.expandFilesInObject(this.config, userData); - const user = triggers.inflate(extraData, userData); // no need to return a response - - await triggers.maybeRunTrigger(triggers.Types.beforeLogin, this.auth, user, null, this.config, this.context); -}; - -RestWrite.prototype.setRequiredFieldsIfNeeded = function () { - if (this.data) { - return this.validSchemaController.getAllClasses().then(allClasses => { - const schema = allClasses.find(oneClass => oneClass.className === this.className); - - const setRequiredFieldIfNeeded = (fieldName, setDefault) => { - if (this.data[fieldName] === undefined || this.data[fieldName] === null || this.data[fieldName] === '' || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete') { - if (setDefault && schema.fields[fieldName] && schema.fields[fieldName].defaultValue !== null && schema.fields[fieldName].defaultValue !== undefined && (this.data[fieldName] === undefined || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete')) { - this.data[fieldName] = schema.fields[fieldName].defaultValue; - this.storage.fieldsChangedByTrigger = this.storage.fieldsChangedByTrigger || []; - - if (this.storage.fieldsChangedByTrigger.indexOf(fieldName) < 0) { - this.storage.fieldsChangedByTrigger.push(fieldName); - } - } else if (schema.fields[fieldName] && schema.fields[fieldName].required === true) { - throw new Parse.Error(Parse.Error.VALIDATION_ERROR, `${fieldName} is required`); - } - } - }; // Add default fields - - - this.data.updatedAt = this.updatedAt; - - if (!this.query) { - this.data.createdAt = this.updatedAt; // Only assign new objectId if we are creating new object - - if (!this.data.objectId) { - this.data.objectId = cryptoUtils.newObjectId(this.config.objectIdSize); - } - - if (schema) { - Object.keys(schema.fields).forEach(fieldName => { - setRequiredFieldIfNeeded(fieldName, true); - }); - } - } else if (schema) { - Object.keys(this.data).forEach(fieldName => { - setRequiredFieldIfNeeded(fieldName, false); - }); - } - }); - } - - return Promise.resolve(); -}; // Transforms auth data for a user object. -// Does nothing if this isn't a user object. -// Returns a promise for when we're done if it can't finish this tick. - - -RestWrite.prototype.validateAuthData = function () { - if (this.className !== '_User') { - return; - } - - if (!this.query && !this.data.authData) { - if (typeof this.data.username !== 'string' || _lodash.default.isEmpty(this.data.username)) { - throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'bad or missing username'); - } - - if (typeof this.data.password !== 'string' || _lodash.default.isEmpty(this.data.password)) { - throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'password is required'); - } - } - - if (this.data.authData && !Object.keys(this.data.authData).length || !Object.prototype.hasOwnProperty.call(this.data, 'authData')) { - // Handle saving authData to {} or if authData doesn't exist - return; - } else if (Object.prototype.hasOwnProperty.call(this.data, 'authData') && !this.data.authData) { - // Handle saving authData to null - throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); - } - - var authData = this.data.authData; - var providers = Object.keys(authData); - - if (providers.length > 0) { - const canHandleAuthData = providers.reduce((canHandle, provider) => { - var providerAuthData = authData[provider]; - var hasToken = providerAuthData && providerAuthData.id; - return canHandle && (hasToken || providerAuthData == null); - }, true); - - if (canHandleAuthData) { - return this.handleAuthData(authData); - } - } - - throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); -}; - -RestWrite.prototype.handleAuthDataValidation = function (authData) { - const validations = Object.keys(authData).map(provider => { - if (authData[provider] === null) { - return Promise.resolve(); - } - - const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider); - - if (!validateAuthData) { - throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); - } - - return validateAuthData(authData[provider]); - }); - return Promise.all(validations); -}; - -RestWrite.prototype.findUsersWithAuthData = function (authData) { - const providers = Object.keys(authData); - const query = providers.reduce((memo, provider) => { - if (!authData[provider]) { - return memo; - } - - const queryKey = `authData.${provider}.id`; - const query = {}; - query[queryKey] = authData[provider].id; - memo.push(query); - return memo; - }, []).filter(q => { - return typeof q !== 'undefined'; - }); - let findPromise = Promise.resolve([]); - - if (query.length > 0) { - findPromise = this.config.database.find(this.className, { - $or: query - }, {}); - } - - return findPromise; -}; - -RestWrite.prototype.filteredObjectsByACL = function (objects) { - if (this.auth.isMaster) { - return objects; - } - - return objects.filter(object => { - if (!object.ACL) { - return true; // legacy users that have no ACL field on them - } // Regular users that have been locked out. - - - return object.ACL && Object.keys(object.ACL).length > 0; - }); -}; - -RestWrite.prototype.handleAuthData = function (authData) { - let results; - return this.findUsersWithAuthData(authData).then(async r => { - results = this.filteredObjectsByACL(r); - - if (results.length == 1) { - this.storage['authProvider'] = Object.keys(authData).join(','); - const userResult = results[0]; - const mutatedAuthData = {}; - Object.keys(authData).forEach(provider => { - const providerData = authData[provider]; - const userAuthData = userResult.authData[provider]; - - if (!_lodash.default.isEqual(providerData, userAuthData)) { - mutatedAuthData[provider] = providerData; - } - }); - const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; - let userId; - - if (this.query && this.query.objectId) { - userId = this.query.objectId; - } else if (this.auth && this.auth.user && this.auth.user.id) { - userId = this.auth.user.id; - } - - if (!userId || userId === userResult.objectId) { - // no user making the call - // OR the user making the call is the right one - // Login with auth data - delete results[0].password; // need to set the objectId first otherwise location has trailing undefined - - this.data.objectId = userResult.objectId; - - if (!this.query || !this.query.objectId) { - // this a login call, no userId passed - this.response = { - response: userResult, - location: this.location() - }; // Run beforeLogin hook before storing any updates - // to authData on the db; changes to userResult - // will be ignored. - - await this.runBeforeLoginTrigger(deepcopy(userResult)); - } // If we didn't change the auth data, just keep going - - - if (!hasMutatedAuthData) { - return; - } // We have authData that is updated on login - // that can happen when token are refreshed, - // We should update the token and let the user in - // We should only check the mutated keys - - - return this.handleAuthDataValidation(mutatedAuthData).then(async () => { - // IF we have a response, we'll skip the database operation / beforeSave / afterSave etc... - // we need to set it up there. - // We are supposed to have a response only on LOGIN with authData, so we skip those - // If we're not logging in, but just updating the current user, we can safely skip that part - if (this.response) { - // Assign the new authData in the response - Object.keys(mutatedAuthData).forEach(provider => { - this.response.response.authData[provider] = mutatedAuthData[provider]; - }); // Run the DB update directly, as 'master' - // Just update the authData part - // Then we're good for the user, early exit of sorts - - return this.config.database.update(this.className, { - objectId: this.data.objectId - }, { - authData: mutatedAuthData - }, {}); - } - }); - } else if (userId) { - // Trying to update auth data but users - // are different - if (userResult.objectId !== userId) { - throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); - } // No auth data was mutated, just keep going - - - if (!hasMutatedAuthData) { - return; - } - } - } - - return this.handleAuthDataValidation(authData).then(() => { - if (results.length > 1) { - // More than 1 user with the passed id's - throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); - } - }); - }); -}; // The non-third-party parts of User transformation - - -RestWrite.prototype.transformUser = function () { - var promise = Promise.resolve(); - - if (this.className !== '_User') { - return promise; - } - - if (!this.auth.isMaster && 'emailVerified' in this.data) { - const error = `Clients aren't allowed to manually update email verification.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } // Do not cleanup session if objectId is not set - - - if (this.query && this.objectId()) { - // If we're updating a _User object, we need to clear out the cache for that user. Find all their - // session tokens, and remove them from the cache. - promise = new _RestQuery.default(this.config, Auth.master(this.config), '_Session', { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.objectId() - } - }).execute().then(results => { - results.results.forEach(session => this.config.cacheController.user.del(session.sessionToken)); - }); - } - - return promise.then(() => { - // Transform the password - if (this.data.password === undefined) { - // ignore only if undefined. should proceed if empty ('') - return Promise.resolve(); - } - - if (this.query) { - this.storage['clearSessions'] = true; // Generate a new session only if the user requested - - if (!this.auth.isMaster) { - this.storage['generateNewSession'] = true; - } - } - - return this._validatePasswordPolicy().then(() => { - return passwordCrypto.hash(this.data.password).then(hashedPassword => { - this.data._hashed_password = hashedPassword; - delete this.data.password; - }); - }); - }).then(() => { - return this._validateUserName(); - }).then(() => { - return this._validateEmail(); - }); -}; - -RestWrite.prototype._validateUserName = function () { - // Check for username uniqueness - if (!this.data.username) { - if (!this.query) { - this.data.username = cryptoUtils.randomString(25); - this.responseShouldHaveUsername = true; - } - - return Promise.resolve(); - } - /* - Usernames should be unique when compared case insensitively - Users should be able to make case sensitive usernames and - login using the case they entered. I.e. 'Snoopy' should preclude - 'snoopy' as a valid username. - */ - - - return this.config.database.find(this.className, { - username: this.data.username, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1, - caseInsensitive: true - }, {}, this.validSchemaController).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); - } - - return; - }); -}; -/* - As with usernames, Parse should not allow case insensitive collisions of email. - unlike with usernames (which can have case insensitive collisions in the case of - auth adapters), emails should never have a case insensitive collision. - - This behavior can be enforced through a properly configured index see: - https://docs.mongodb.com/manual/core/index-case-insensitive/#create-a-case-insensitive-index - which could be implemented instead of this code based validation. - - Given that this lookup should be a relatively low use case and that the case sensitive - unique index will be used by the db for the query, this is an adequate solution. -*/ - - -RestWrite.prototype._validateEmail = function () { - if (!this.data.email || this.data.email.__op === 'Delete') { - return Promise.resolve(); - } // Validate basic email address format - - - if (!this.data.email.match(/^.+@.+$/)) { - return Promise.reject(new Parse.Error(Parse.Error.INVALID_EMAIL_ADDRESS, 'Email address format is invalid.')); - } // Case insensitive match, see note above function. - - - return this.config.database.find(this.className, { - email: this.data.email, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1, - caseInsensitive: true - }, {}, this.validSchemaController).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); - } - - if (!this.data.authData || !Object.keys(this.data.authData).length || Object.keys(this.data.authData).length === 1 && Object.keys(this.data.authData)[0] === 'anonymous') { - // We updated the email, send a new validation - this.storage['sendVerificationEmail'] = true; - this.config.userController.setEmailVerifyToken(this.data); - } - }); -}; - -RestWrite.prototype._validatePasswordPolicy = function () { - if (!this.config.passwordPolicy) return Promise.resolve(); - return this._validatePasswordRequirements().then(() => { - return this._validatePasswordHistory(); - }); -}; - -RestWrite.prototype._validatePasswordRequirements = function () { - // check if the password conforms to the defined password policy if configured - // If we specified a custom error in our configuration use it. - // Example: "Passwords must include a Capital Letter, Lowercase Letter, and a number." - // - // This is especially useful on the generic "password reset" page, - // as it allows the programmer to communicate specific requirements instead of: - // a. making the user guess whats wrong - // b. making a custom password reset page that shows the requirements - const policyError = this.config.passwordPolicy.validationError ? this.config.passwordPolicy.validationError : 'Password does not meet the Password Policy requirements.'; - const containsUsernameError = 'Password cannot contain your username.'; // check whether the password meets the password strength requirements - - if (this.config.passwordPolicy.patternValidator && !this.config.passwordPolicy.patternValidator(this.data.password) || this.config.passwordPolicy.validatorCallback && !this.config.passwordPolicy.validatorCallback(this.data.password)) { - return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError)); - } // check whether password contain username - - - if (this.config.passwordPolicy.doNotAllowUsername === true) { - if (this.data.username) { - // username is not passed during password reset - if (this.data.password.indexOf(this.data.username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); - } else { - // retrieve the User object using objectId during password reset - return this.config.database.find('_User', { - objectId: this.objectId() - }).then(results => { - if (results.length != 1) { - throw undefined; - } - - if (this.data.password.indexOf(results[0].username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); - return Promise.resolve(); - }); - } - } - - return Promise.resolve(); -}; - -RestWrite.prototype._validatePasswordHistory = function () { - // check whether password is repeating from specified history - if (this.query && this.config.passwordPolicy.maxPasswordHistory) { - return this.config.database.find('_User', { - objectId: this.objectId() - }, { - keys: ['_password_history', '_hashed_password'] - }).then(results => { - if (results.length != 1) { - throw undefined; - } - - const user = results[0]; - let oldPasswords = []; - if (user._password_history) oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory - 1); - oldPasswords.push(user.password); - const newPassword = this.data.password; // compare the new password hash with all old password hashes - - const promises = oldPasswords.map(function (hash) { - return passwordCrypto.compare(newPassword, hash).then(result => { - if (result) // reject if there is a match - return Promise.reject('REPEAT_PASSWORD'); - return Promise.resolve(); - }); - }); // wait for all comparisons to complete - - return Promise.all(promises).then(() => { - return Promise.resolve(); - }).catch(err => { - if (err === 'REPEAT_PASSWORD') // a match was found - return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, `New password should not be the same as last ${this.config.passwordPolicy.maxPasswordHistory} passwords.`)); - throw err; - }); - }); - } - - return Promise.resolve(); -}; - -RestWrite.prototype.createSessionTokenIfNeeded = function () { - if (this.className !== '_User') { - return; - } // Don't generate session for updating user (this.query is set) unless authData exists - - - if (this.query && !this.data.authData) { - return; - } // Don't generate new sessionToken if linking via sessionToken - - - if (this.auth.user && this.data.authData) { - return; - } - - if (!this.storage['authProvider'] && // signup call, with - this.config.preventLoginWithUnverifiedEmail && // no login without verification - this.config.verifyUserEmails) { - // verification is on - return; // do not create the session token in that case! - } - - return this.createSessionToken(); -}; - -RestWrite.prototype.createSessionToken = async function () { - // cloud installationId from Cloud Code, - // never create session tokens from there. - if (this.auth.installationId && this.auth.installationId === 'cloud') { - return; - } - - const { - sessionData, - createSession - } = Auth.createSession(this.config, { - userId: this.objectId(), - createdWith: { - action: this.storage['authProvider'] ? 'login' : 'signup', - authProvider: this.storage['authProvider'] || 'password' - }, - installationId: this.auth.installationId - }); - - if (this.response && this.response.response) { - this.response.response.sessionToken = sessionData.sessionToken; - } - - return createSession(); -}; // Delete email reset tokens if user is changing password or email. - - -RestWrite.prototype.deleteEmailResetTokenIfNeeded = function () { - if (this.className !== '_User' || this.query === null) { - // null query means create - return; - } - - if ('password' in this.data || 'email' in this.data) { - const addOps = { - _perishable_token: { - __op: 'Delete' - }, - _perishable_token_expires_at: { - __op: 'Delete' - } - }; - this.data = Object.assign(this.data, addOps); - } -}; - -RestWrite.prototype.destroyDuplicatedSessions = function () { - // Only for _Session, and at creation time - if (this.className != '_Session' || this.query) { - return; - } // Destroy the sessions in 'Background' - - - const { - user, - installationId, - sessionToken - } = this.data; - - if (!user || !installationId) { - return; - } - - if (!user.objectId) { - return; - } - - this.config.database.destroy('_Session', { - user, - installationId, - sessionToken: { - $ne: sessionToken - } - }, {}, this.validSchemaController); -}; // Handles any followup logic - - -RestWrite.prototype.handleFollowup = function () { - if (this.storage && this.storage['clearSessions'] && this.config.revokeSessionOnPasswordReset) { - var sessionQuery = { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.objectId() - } - }; - delete this.storage['clearSessions']; - return this.config.database.destroy('_Session', sessionQuery).then(this.handleFollowup.bind(this)); - } - - if (this.storage && this.storage['generateNewSession']) { - delete this.storage['generateNewSession']; - return this.createSessionToken().then(this.handleFollowup.bind(this)); - } - - if (this.storage && this.storage['sendVerificationEmail']) { - delete this.storage['sendVerificationEmail']; // Fire and forget! - - this.config.userController.sendVerificationEmail(this.data); - return this.handleFollowup.bind(this); - } -}; // Handles the _Session class specialness. -// Does nothing if this isn't an _Session object. - - -RestWrite.prototype.handleSession = function () { - if (this.response || this.className !== '_Session') { - return; - } - - if (!this.auth.user && !this.auth.isMaster) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token required.'); - } // TODO: Verify proper error to throw - - - if (this.data.ACL) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'Cannot set ' + 'ACL on a Session.'); - } - - if (this.query) { - if (this.data.user && !this.auth.isMaster && this.data.user.objectId != this.auth.user.id) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); - } else if (this.data.installationId) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); - } else if (this.data.sessionToken) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); - } - } - - if (!this.query && !this.auth.isMaster) { - const additionalSessionData = {}; - - for (var key in this.data) { - if (key === 'objectId' || key === 'user') { - continue; - } - - additionalSessionData[key] = this.data[key]; - } - - const { - sessionData, - createSession - } = Auth.createSession(this.config, { - userId: this.auth.user.id, - createdWith: { - action: 'create' - }, - additionalSessionData - }); - return createSession().then(results => { - if (!results.response) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Error creating session.'); - } - - sessionData['objectId'] = results.response['objectId']; - this.response = { - status: 201, - location: results.location, - response: sessionData - }; - }); - } -}; // Handles the _Installation class specialness. -// Does nothing if this isn't an installation object. -// If an installation is found, this can mutate this.query and turn a create -// into an update. -// Returns a promise for when we're done if it can't finish this tick. - - -RestWrite.prototype.handleInstallation = function () { - if (this.response || this.className !== '_Installation') { - return; - } - - if (!this.query && !this.data.deviceToken && !this.data.installationId && !this.auth.installationId) { - throw new Parse.Error(135, 'at least one ID field (deviceToken, installationId) ' + 'must be specified in this operation'); - } // If the device token is 64 characters long, we assume it is for iOS - // and lowercase it. - - - if (this.data.deviceToken && this.data.deviceToken.length == 64) { - this.data.deviceToken = this.data.deviceToken.toLowerCase(); - } // We lowercase the installationId if present - - - if (this.data.installationId) { - this.data.installationId = this.data.installationId.toLowerCase(); - } - - let installationId = this.data.installationId; // If data.installationId is not set and we're not master, we can lookup in auth - - if (!installationId && !this.auth.isMaster) { - installationId = this.auth.installationId; - } - - if (installationId) { - installationId = installationId.toLowerCase(); - } // Updating _Installation but not updating anything critical - - - if (this.query && !this.data.deviceToken && !installationId && !this.data.deviceType) { - return; - } - - var promise = Promise.resolve(); - var idMatch; // Will be a match on either objectId or installationId - - var objectIdMatch; - var installationIdMatch; - var deviceTokenMatches = []; // Instead of issuing 3 reads, let's do it with one OR. - - const orQueries = []; - - if (this.query && this.query.objectId) { - orQueries.push({ - objectId: this.query.objectId - }); - } - - if (installationId) { - orQueries.push({ - installationId: installationId - }); - } - - if (this.data.deviceToken) { - orQueries.push({ - deviceToken: this.data.deviceToken - }); - } - - if (orQueries.length == 0) { - return; - } - - promise = promise.then(() => { - return this.config.database.find('_Installation', { - $or: orQueries - }, {}); - }).then(results => { - results.forEach(result => { - if (this.query && this.query.objectId && result.objectId == this.query.objectId) { - objectIdMatch = result; - } - - if (result.installationId == installationId) { - installationIdMatch = result; - } - - if (result.deviceToken == this.data.deviceToken) { - deviceTokenMatches.push(result); - } - }); // Sanity checks when running a query - - if (this.query && this.query.objectId) { - if (!objectIdMatch) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for update.'); - } - - if (this.data.installationId && objectIdMatch.installationId && this.data.installationId !== objectIdMatch.installationId) { - throw new Parse.Error(136, 'installationId may not be changed in this ' + 'operation'); - } - - if (this.data.deviceToken && objectIdMatch.deviceToken && this.data.deviceToken !== objectIdMatch.deviceToken && !this.data.installationId && !objectIdMatch.installationId) { - throw new Parse.Error(136, 'deviceToken may not be changed in this ' + 'operation'); - } - - if (this.data.deviceType && this.data.deviceType && this.data.deviceType !== objectIdMatch.deviceType) { - throw new Parse.Error(136, 'deviceType may not be changed in this ' + 'operation'); - } - } - - if (this.query && this.query.objectId && objectIdMatch) { - idMatch = objectIdMatch; - } - - if (installationId && installationIdMatch) { - idMatch = installationIdMatch; - } // need to specify deviceType only if it's new - - - if (!this.query && !this.data.deviceType && !idMatch) { - throw new Parse.Error(135, 'deviceType must be specified in this operation'); - } - }).then(() => { - if (!idMatch) { - if (!deviceTokenMatches.length) { - return; - } else if (deviceTokenMatches.length == 1 && (!deviceTokenMatches[0]['installationId'] || !installationId)) { - // Single match on device token but none on installationId, and either - // the passed object or the match is missing an installationId, so we - // can just return the match. - return deviceTokenMatches[0]['objectId']; - } else if (!this.data.installationId) { - throw new Parse.Error(132, 'Must specify installationId when deviceToken ' + 'matches multiple Installation objects'); - } else { - // Multiple device token matches and we specified an installation ID, - // or a single match where both the passed and matching objects have - // an installation ID. Try cleaning out old installations that match - // the deviceToken, and return nil to signal that a new object should - // be created. - var delQuery = { - deviceToken: this.data.deviceToken, - installationId: { - $ne: installationId - } - }; - - if (this.data.appIdentifier) { - delQuery['appIdentifier'] = this.data.appIdentifier; - } - - this.config.database.destroy('_Installation', delQuery).catch(err => { - if (err.code == Parse.Error.OBJECT_NOT_FOUND) { - // no deletions were made. Can be ignored. - return; - } // rethrow the error - - - throw err; - }); - return; - } - } else { - if (deviceTokenMatches.length == 1 && !deviceTokenMatches[0]['installationId']) { - // Exactly one device token match and it doesn't have an installation - // ID. This is the one case where we want to merge with the existing - // object. - const delQuery = { - objectId: idMatch.objectId - }; - return this.config.database.destroy('_Installation', delQuery).then(() => { - return deviceTokenMatches[0]['objectId']; - }).catch(err => { - if (err.code == Parse.Error.OBJECT_NOT_FOUND) { - // no deletions were made. Can be ignored - return; - } // rethrow the error - - - throw err; - }); - } else { - if (this.data.deviceToken && idMatch.deviceToken != this.data.deviceToken) { - // We're setting the device token on an existing installation, so - // we should try cleaning out old installations that match this - // device token. - const delQuery = { - deviceToken: this.data.deviceToken - }; // We have a unique install Id, use that to preserve - // the interesting installation - - if (this.data.installationId) { - delQuery['installationId'] = { - $ne: this.data.installationId - }; - } else if (idMatch.objectId && this.data.objectId && idMatch.objectId == this.data.objectId) { - // we passed an objectId, preserve that instalation - delQuery['objectId'] = { - $ne: idMatch.objectId - }; - } else { - // What to do here? can't really clean up everything... - return idMatch.objectId; - } - - if (this.data.appIdentifier) { - delQuery['appIdentifier'] = this.data.appIdentifier; - } - - this.config.database.destroy('_Installation', delQuery).catch(err => { - if (err.code == Parse.Error.OBJECT_NOT_FOUND) { - // no deletions were made. Can be ignored. - return; - } // rethrow the error - - - throw err; - }); - } // In non-merge scenarios, just return the installation match id - - - return idMatch.objectId; - } - } - }).then(objId => { - if (objId) { - this.query = { - objectId: objId - }; - delete this.data.objectId; - delete this.data.createdAt; - } // TODO: Validate ops (add/remove on channels, $inc on badge, etc.) - - }); - return promise; -}; // If we short-circuted the object response - then we need to make sure we expand all the files, -// since this might not have a query, meaning it won't return the full result back. -// TODO: (nlutsenko) This should die when we move to per-class based controllers on _Session/_User - - -RestWrite.prototype.expandFilesForExistingObjects = function () { - // Check whether we have a short-circuited response - only then run expansion. - if (this.response && this.response.response) { - this.config.filesController.expandFilesInObject(this.config, this.response.response); - } -}; - -RestWrite.prototype.runDatabaseOperation = function () { - if (this.response) { - return; - } - - if (this.className === '_Role') { - this.config.cacheController.role.clear(); - } - - if (this.className === '_User' && this.query && this.auth.isUnauthenticated()) { - throw new Parse.Error(Parse.Error.SESSION_MISSING, `Cannot modify user ${this.query.objectId}.`); - } - - if (this.className === '_Product' && this.data.download) { - this.data.downloadName = this.data.download.name; - } // TODO: Add better detection for ACL, ensuring a user can't be locked from - // their own user record. - - - if (this.data.ACL && this.data.ACL['*unresolved']) { - throw new Parse.Error(Parse.Error.INVALID_ACL, 'Invalid ACL.'); - } - - if (this.query) { - // Force the user to not lockout - // Matched with parse.com - if (this.className === '_User' && this.data.ACL && this.auth.isMaster !== true) { - this.data.ACL[this.query.objectId] = { - read: true, - write: true - }; - } // update password timestamp if user password is being changed - - - if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { - this.data._password_changed_at = Parse._encode(new Date()); - } // Ignore createdAt when update - - - delete this.data.createdAt; - let defer = Promise.resolve(); // if password history is enabled then save the current password to history - - if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordHistory) { - defer = this.config.database.find('_User', { - objectId: this.objectId() - }, { - keys: ['_password_history', '_hashed_password'] - }).then(results => { - if (results.length != 1) { - throw undefined; - } - - const user = results[0]; - let oldPasswords = []; - - if (user._password_history) { - oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory); - } //n-1 passwords go into history including last password - - - while (oldPasswords.length > Math.max(0, this.config.passwordPolicy.maxPasswordHistory - 2)) { - oldPasswords.shift(); - } - - oldPasswords.push(user.password); - this.data._password_history = oldPasswords; - }); - } - - return defer.then(() => { - // Run an update - return this.config.database.update(this.className, this.query, this.data, this.runOptions, false, false, this.validSchemaController).then(response => { - response.updatedAt = this.updatedAt; - - this._updateResponseWithData(response, this.data); - - this.response = { - response - }; - }); - }); - } else { - // Set the default ACL and password timestamp for the new _User - if (this.className === '_User') { - var ACL = this.data.ACL; // default public r/w ACL - - if (!ACL) { - ACL = {}; - ACL['*'] = { - read: true, - write: false - }; - } // make sure the user is not locked down - - - ACL[this.data.objectId] = { - read: true, - write: true - }; - this.data.ACL = ACL; // password timestamp to be used when password expiry policy is enforced - - if (this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { - this.data._password_changed_at = Parse._encode(new Date()); - } - } // Run a create - - - return this.config.database.create(this.className, this.data, this.runOptions, false, this.validSchemaController).catch(error => { - if (this.className !== '_User' || error.code !== Parse.Error.DUPLICATE_VALUE) { - throw error; - } // Quick check, if we were able to infer the duplicated field name - - - if (error && error.userInfo && error.userInfo.duplicated_field === 'username') { - throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); - } - - if (error && error.userInfo && error.userInfo.duplicated_field === 'email') { - throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); - } // If this was a failed user creation due to username or email already taken, we need to - // check whether it was username or email and return the appropriate error. - // Fallback to the original method - // TODO: See if we can later do this without additional queries by using named indexes. - - - return this.config.database.find(this.className, { - username: this.data.username, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1 - }).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); - } - - return this.config.database.find(this.className, { - email: this.data.email, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1 - }); - }).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); - } - - throw new Parse.Error(Parse.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - }); - }).then(response => { - response.objectId = this.data.objectId; - response.createdAt = this.data.createdAt; - - if (this.responseShouldHaveUsername) { - response.username = this.data.username; - } - - this._updateResponseWithData(response, this.data); - - this.response = { - status: 201, - response, - location: this.location() - }; - }); - } -}; // Returns nothing - doesn't wait for the trigger. - - -RestWrite.prototype.runAfterSaveTrigger = function () { - if (!this.response || !this.response.response) { - return; - } // Avoid doing any setup for triggers if there is no 'afterSave' trigger for this class. - - - const hasAfterSaveHook = triggers.triggerExists(this.className, triggers.Types.afterSave, this.config.applicationId); - const hasLiveQuery = this.config.liveQueryController.hasLiveQuery(this.className); - - if (!hasAfterSaveHook && !hasLiveQuery) { - return Promise.resolve(); - } - - var extraData = { - className: this.className - }; - - if (this.query && this.query.objectId) { - extraData.objectId = this.query.objectId; - } // Build the original object, we only do this for a update write. - - - let originalObject; - - if (this.query && this.query.objectId) { - originalObject = triggers.inflate(extraData, this.originalData); - } // Build the inflated object, different from beforeSave, originalData is not empty - // since developers can change data in the beforeSave. - - - const updatedObject = this.buildUpdatedObject(extraData); - - updatedObject._handleSaveResponse(this.response.response, this.response.status || 200); - - this.config.database.loadSchema().then(schemaController => { - // Notifiy LiveQueryServer if possible - const perms = schemaController.getClassLevelPermissions(updatedObject.className); - this.config.liveQueryController.onAfterSave(updatedObject.className, updatedObject, originalObject, perms); - }); // Run afterSave trigger - - return triggers.maybeRunTrigger(triggers.Types.afterSave, this.auth, updatedObject, originalObject, this.config, this.context).then(result => { - if (result && typeof result === 'object') { - this.response.response = result; - } - }).catch(function (err) { - _logger.default.warn('afterSave caught an error', err); - }); -}; // A helper to figure out what location this operation happens at. - - -RestWrite.prototype.location = function () { - var middle = this.className === '_User' ? '/users/' : '/classes/' + this.className + '/'; - const mount = this.config.mount || this.config.serverURL; - return mount + middle + this.data.objectId; -}; // A helper to get the object id for this operation. -// Because it could be either on the query or on the data - - -RestWrite.prototype.objectId = function () { - return this.data.objectId || this.query.objectId; -}; // Returns a copy of the data and delete bad keys (_auth_data, _hashed_password...) - - -RestWrite.prototype.sanitizedData = function () { - const data = Object.keys(this.data).reduce((data, key) => { - // Regexp comes from Parse.Object.prototype.validate - if (!/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { - delete data[key]; - } - - return data; - }, deepcopy(this.data)); - return Parse._decode(undefined, data); -}; // Returns an updated copy of the object - - -RestWrite.prototype.buildUpdatedObject = function (extraData) { - const updatedObject = triggers.inflate(extraData, this.originalData); - Object.keys(this.data).reduce(function (data, key) { - if (key.indexOf('.') > 0) { - // subdocument key with dot notation ('x.y':v => 'x':{'y':v}) - const splittedKey = key.split('.'); - const parentProp = splittedKey[0]; - let parentVal = updatedObject.get(parentProp); - - if (typeof parentVal !== 'object') { - parentVal = {}; - } - - parentVal[splittedKey[1]] = data[key]; - updatedObject.set(parentProp, parentVal); - delete data[key]; - } - - return data; - }, deepcopy(this.data)); - updatedObject.set(this.sanitizedData()); - return updatedObject; -}; - -RestWrite.prototype.cleanUserAuthData = function () { - if (this.response && this.response.response && this.className === '_User') { - const user = this.response.response; - - if (user.authData) { - Object.keys(user.authData).forEach(provider => { - if (user.authData[provider] === null) { - delete user.authData[provider]; - } - }); - - if (Object.keys(user.authData).length == 0) { - delete user.authData; - } - } - } -}; - -RestWrite.prototype._updateResponseWithData = function (response, data) { - if (_lodash.default.isEmpty(this.storage.fieldsChangedByTrigger)) { - return response; - } - - const clientSupportsDelete = ClientSDK.supportsForwardDelete(this.clientSDK); - this.storage.fieldsChangedByTrigger.forEach(fieldName => { - const dataValue = data[fieldName]; - - if (!Object.prototype.hasOwnProperty.call(response, fieldName)) { - response[fieldName] = dataValue; - } // Strips operations from responses - - - if (response[fieldName] && response[fieldName].__op) { - delete response[fieldName]; - - if (clientSupportsDelete && dataValue.__op == 'Delete') { - response[fieldName] = dataValue; - } - } - }); - return response; -}; - -var _default = RestWrite; -exports.default = _default; -module.exports = RestWrite; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0V3JpdGUuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJkZWVwY29weSIsIkF1dGgiLCJjcnlwdG9VdGlscyIsInBhc3N3b3JkQ3J5cHRvIiwiUGFyc2UiLCJ0cmlnZ2VycyIsIkNsaWVudFNESyIsIlJlc3RXcml0ZSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJxdWVyeSIsImRhdGEiLCJvcmlnaW5hbERhdGEiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiYWN0aW9uIiwiaXNSZWFkT25seSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInN0b3JhZ2UiLCJydW5PcHRpb25zIiwiYWxsb3dDdXN0b21PYmplY3RJZCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm9iamVjdElkIiwiTUlTU0lOR19PQkpFQ1RfSUQiLCJJTlZBTElEX0tFWV9OQU1FIiwiaWQiLCJyZXNwb25zZSIsInVwZGF0ZWRBdCIsIl9lbmNvZGUiLCJEYXRlIiwiaXNvIiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwiZXhlY3V0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldFVzZXJBbmRSb2xlQUNMIiwidmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uIiwiaGFuZGxlSW5zdGFsbGF0aW9uIiwiaGFuZGxlU2Vzc2lvbiIsInZhbGlkYXRlQXV0aERhdGEiLCJydW5CZWZvcmVTYXZlVHJpZ2dlciIsImRlbGV0ZUVtYWlsUmVzZXRUb2tlbklmTmVlZGVkIiwidmFsaWRhdGVTY2hlbWEiLCJzY2hlbWFDb250cm9sbGVyIiwic2V0UmVxdWlyZWRGaWVsZHNJZk5lZWRlZCIsInRyYW5zZm9ybVVzZXIiLCJleHBhbmRGaWxlc0ZvckV4aXN0aW5nT2JqZWN0cyIsImRlc3Ryb3lEdXBsaWNhdGVkU2Vzc2lvbnMiLCJydW5EYXRhYmFzZU9wZXJhdGlvbiIsImNyZWF0ZVNlc3Npb25Ub2tlbklmTmVlZGVkIiwiaGFuZGxlRm9sbG93dXAiLCJydW5BZnRlclNhdmVUcmlnZ2VyIiwiY2xlYW5Vc2VyQXV0aERhdGEiLCJpc01hc3RlciIsImFjbCIsInVzZXIiLCJnZXRVc2VyUm9sZXMiLCJyb2xlcyIsImNvbmNhdCIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsInN5c3RlbUNsYXNzZXMiLCJpbmRleE9mIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiaGFzQ2xhc3MiLCJ2YWxpZGF0ZU9iamVjdCIsInRyaWdnZXJFeGlzdHMiLCJUeXBlcyIsImJlZm9yZVNhdmUiLCJhcHBsaWNhdGlvbklkIiwiZXh0cmFEYXRhIiwib3JpZ2luYWxPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwiYnVpbGRVcGRhdGVkT2JqZWN0IiwiaW5mbGF0ZSIsImRhdGFiYXNlUHJvbWlzZSIsInVwZGF0ZSIsImNyZWF0ZSIsInJlc3VsdCIsImxlbmd0aCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJtYXliZVJ1blRyaWdnZXIiLCJvYmplY3QiLCJmaWVsZHNDaGFuZ2VkQnlUcmlnZ2VyIiwiXyIsInJlZHVjZSIsInZhbHVlIiwia2V5IiwiaXNFcXVhbCIsInB1c2giLCJydW5CZWZvcmVMb2dpblRyaWdnZXIiLCJ1c2VyRGF0YSIsImJlZm9yZUxvZ2luIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsImdldEFsbENsYXNzZXMiLCJhbGxDbGFzc2VzIiwic2NoZW1hIiwiZmluZCIsIm9uZUNsYXNzIiwic2V0UmVxdWlyZWRGaWVsZElmTmVlZGVkIiwiZmllbGROYW1lIiwic2V0RGVmYXVsdCIsInVuZGVmaW5lZCIsIl9fb3AiLCJmaWVsZHMiLCJkZWZhdWx0VmFsdWUiLCJyZXF1aXJlZCIsIlZBTElEQVRJT05fRVJST1IiLCJjcmVhdGVkQXQiLCJuZXdPYmplY3RJZCIsIm9iamVjdElkU2l6ZSIsImtleXMiLCJmb3JFYWNoIiwiYXV0aERhdGEiLCJ1c2VybmFtZSIsImlzRW1wdHkiLCJVU0VSTkFNRV9NSVNTSU5HIiwicGFzc3dvcmQiLCJQQVNTV09SRF9NSVNTSU5HIiwiVU5TVVBQT1JURURfU0VSVklDRSIsInByb3ZpZGVycyIsImNhbkhhbmRsZUF1dGhEYXRhIiwiY2FuSGFuZGxlIiwicHJvdmlkZXIiLCJwcm92aWRlckF1dGhEYXRhIiwiaGFzVG9rZW4iLCJoYW5kbGVBdXRoRGF0YSIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsInZhbGlkYXRpb25zIiwibWFwIiwiYXV0aERhdGFNYW5hZ2VyIiwiZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIiLCJhbGwiLCJmaW5kVXNlcnNXaXRoQXV0aERhdGEiLCJtZW1vIiwicXVlcnlLZXkiLCJmaWx0ZXIiLCJxIiwiZmluZFByb21pc2UiLCIkb3IiLCJmaWx0ZXJlZE9iamVjdHNCeUFDTCIsIm9iamVjdHMiLCJBQ0wiLCJyZXN1bHRzIiwiciIsImpvaW4iLCJ1c2VyUmVzdWx0IiwibXV0YXRlZEF1dGhEYXRhIiwicHJvdmlkZXJEYXRhIiwidXNlckF1dGhEYXRhIiwiaGFzTXV0YXRlZEF1dGhEYXRhIiwidXNlcklkIiwibG9jYXRpb24iLCJBQ0NPVU5UX0FMUkVBRFlfTElOS0VEIiwicHJvbWlzZSIsImVycm9yIiwiUmVzdFF1ZXJ5IiwibWFzdGVyIiwiX190eXBlIiwic2Vzc2lvbiIsImNhY2hlQ29udHJvbGxlciIsImRlbCIsInNlc3Npb25Ub2tlbiIsIl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5IiwiaGFzaCIsImhhc2hlZFBhc3N3b3JkIiwiX2hhc2hlZF9wYXNzd29yZCIsIl92YWxpZGF0ZVVzZXJOYW1lIiwiX3ZhbGlkYXRlRW1haWwiLCJyYW5kb21TdHJpbmciLCJyZXNwb25zZVNob3VsZEhhdmVVc2VybmFtZSIsIiRuZSIsImxpbWl0IiwiY2FzZUluc2Vuc2l0aXZlIiwiVVNFUk5BTUVfVEFLRU4iLCJlbWFpbCIsIm1hdGNoIiwicmVqZWN0IiwiSU5WQUxJRF9FTUFJTF9BRERSRVNTIiwiRU1BSUxfVEFLRU4iLCJ1c2VyQ29udHJvbGxlciIsInNldEVtYWlsVmVyaWZ5VG9rZW4iLCJwYXNzd29yZFBvbGljeSIsIl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzIiwiX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5IiwicG9saWN5RXJyb3IiLCJ2YWxpZGF0aW9uRXJyb3IiLCJjb250YWluc1VzZXJuYW1lRXJyb3IiLCJwYXR0ZXJuVmFsaWRhdG9yIiwidmFsaWRhdG9yQ2FsbGJhY2siLCJkb05vdEFsbG93VXNlcm5hbWUiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJvbGRQYXNzd29yZHMiLCJfcGFzc3dvcmRfaGlzdG9yeSIsInRha2UiLCJuZXdQYXNzd29yZCIsInByb21pc2VzIiwiY29tcGFyZSIsImNhdGNoIiwiZXJyIiwicHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCIsInZlcmlmeVVzZXJFbWFpbHMiLCJjcmVhdGVTZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsImNyZWF0ZWRXaXRoIiwiYXV0aFByb3ZpZGVyIiwiYWRkT3BzIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiYXNzaWduIiwiZGVzdHJveSIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJzZXNzaW9uUXVlcnkiLCJiaW5kIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiYWRkaXRpb25hbFNlc3Npb25EYXRhIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwic3RhdHVzIiwiZGV2aWNlVG9rZW4iLCJ0b0xvd2VyQ2FzZSIsImRldmljZVR5cGUiLCJpZE1hdGNoIiwib2JqZWN0SWRNYXRjaCIsImluc3RhbGxhdGlvbklkTWF0Y2giLCJkZXZpY2VUb2tlbk1hdGNoZXMiLCJvclF1ZXJpZXMiLCJkZWxRdWVyeSIsImFwcElkZW50aWZpZXIiLCJjb2RlIiwib2JqSWQiLCJyb2xlIiwiY2xlYXIiLCJpc1VuYXV0aGVudGljYXRlZCIsIlNFU1NJT05fTUlTU0lORyIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwibmFtZSIsIklOVkFMSURfQUNMIiwicmVhZCIsIndyaXRlIiwibWF4UGFzc3dvcmRBZ2UiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsImRlZmVyIiwiTWF0aCIsIm1heCIsInNoaWZ0IiwiX3VwZGF0ZVJlc3BvbnNlV2l0aERhdGEiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1c2VySW5mbyIsImR1cGxpY2F0ZWRfZmllbGQiLCJoYXNBZnRlclNhdmVIb29rIiwiYWZ0ZXJTYXZlIiwiaGFzTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsIl9oYW5kbGVTYXZlUmVzcG9uc2UiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIm9uQWZ0ZXJTYXZlIiwibG9nZ2VyIiwid2FybiIsIm1pZGRsZSIsIm1vdW50Iiwic2VydmVyVVJMIiwic2FuaXRpemVkRGF0YSIsInRlc3QiLCJfZGVjb2RlIiwic3BsaXR0ZWRLZXkiLCJzcGxpdCIsInBhcmVudFByb3AiLCJwYXJlbnRWYWwiLCJnZXQiLCJzZXQiLCJjbGllbnRTdXBwb3J0c0RlbGV0ZSIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImRhdGFWYWx1ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFhQTs7QUFDQTs7QUFDQTs7OztBQWZBO0FBQ0E7QUFDQTtBQUVBLElBQUlBLGdCQUFnQixHQUFHQyxPQUFPLENBQUMsZ0NBQUQsQ0FBOUI7O0FBQ0EsSUFBSUMsUUFBUSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUF0Qjs7QUFFQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxRQUFELENBQXBCOztBQUNBLElBQUlHLFdBQVcsR0FBR0gsT0FBTyxDQUFDLGVBQUQsQ0FBekI7O0FBQ0EsSUFBSUksY0FBYyxHQUFHSixPQUFPLENBQUMsWUFBRCxDQUE1Qjs7QUFDQSxJQUFJSyxLQUFLLEdBQUdMLE9BQU8sQ0FBQyxZ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QUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0ssUUFBckMsRUFBK0M0RSxTQUEvQyxDQUFMLEVBQWdFO0FBQzlENUUsTUFBQUEsUUFBUSxDQUFDNEUsU0FBRCxDQUFSLEdBQXNCaUwsU0FBdEI7QUFDRCxLQUxzRCxDQU92RDs7O0FBQ0EsUUFBSTdQLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixJQUF1QjVFLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixDQUFvQkcsSUFBL0MsRUFBcUQ7QUFDbkQsYUFBTy9FLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBZjs7QUFDQSxVQUFJK0ssb0JBQW9CLElBQUlFLFNBQVMsQ0FBQzlLLElBQVYsSUFBa0IsUUFBOUMsRUFBd0Q7QUFDdEQvRSxRQUFBQSxRQUFRLENBQUM0RSxTQUFELENBQVIsR0FBc0JpTCxTQUF0QjtBQUNEO0FBQ0Y7QUFDRixHQWREO0FBZUEsU0FBTzdQLFFBQVA7QUFDRCxDQXJCRDs7ZUF1QmV4QixTOztBQUNmc1IsTUFBTSxDQUFDQyxPQUFQLEdBQWlCdlIsU0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIFJlc3RXcml0ZSBlbmNhcHN1bGF0ZXMgZXZlcnl0aGluZyB3ZSBuZWVkIHRvIHJ1biBhbiBvcGVyYXRpb25cbi8vIHRoYXQgd3JpdGVzIHRvIHRoZSBkYXRhYmFzZS5cbi8vIFRoaXMgY291bGQgYmUgZWl0aGVyIGEgXCJjcmVhdGVcIiBvciBhbiBcInVwZGF0ZVwiLlxuXG52YXIgU2NoZW1hQ29udHJvbGxlciA9IHJlcXVpcmUoJy4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xudmFyIGRlZXBjb3B5ID0gcmVxdWlyZSgnZGVlcGNvcHknKTtcblxuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xudmFyIGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xudmFyIHBhc3N3b3JkQ3J5cHRvID0gcmVxdWlyZSgnLi9wYXNzd29yZCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xudmFyIHRyaWdnZXJzID0gcmVxdWlyZSgnLi90cmlnZ2VycycpO1xudmFyIENsaWVudFNESyA9IHJlcXVpcmUoJy4vQ2xpZW50U0RLJyk7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4vUmVzdFF1ZXJ5JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcblxuLy8gcXVlcnkgYW5kIGRhdGEgYXJlIGJvdGggcHJvdmlkZWQgaW4gUkVTVCBBUEkgZm9ybWF0LiBTbyBkYXRhXG4vLyB0eXBlcyBhcmUgZW5jb2RlZCBieSBwbGFpbiBvbGQgb2JqZWN0cy5cbi8vIElmIHF1ZXJ5IGlzIG51bGwsIHRoaXMgaXMgYSBcImNyZWF0ZVwiIGFuZCB0aGUgZGF0YSBpbiBkYXRhIHNob3VsZCBiZVxuLy8gY3JlYXRlZC5cbi8vIE90aGVyd2lzZSB0aGlzIGlzIGFuIFwidXBkYXRlXCIgLSB0aGUgb2JqZWN0IG1hdGNoaW5nIHRoZSBxdWVyeVxuLy8gc2hvdWxkIGdldCB1cGRhdGVkIHdpdGggZGF0YS5cbi8vIFJlc3RXcml0ZSB3aWxsIGhhbmRsZSBvYmplY3RJZCwgY3JlYXRlZEF0LCBhbmQgdXBkYXRlZEF0IGZvclxuLy8gZXZlcnl0aGluZy4gSXQgYWxzbyBrbm93cyB0byB1c2UgdHJpZ2dlcnMgYW5kIHNwZWNpYWwgbW9kaWZpY2F0aW9uc1xuLy8gZm9yIHRoZSBfVXNlciBjbGFzcy5cbmZ1bmN0aW9uIFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcXVlcnksIGRhdGEsIG9yaWdpbmFsRGF0YSwgY2xpZW50U0RLLCBjb250ZXh0LCBhY3Rpb24pIHtcbiAgaWYgKGF1dGguaXNSZWFkT25seSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAnQ2Fubm90IHBlcmZvcm0gYSB3cml0ZSBvcGVyYXRpb24gd2hlbiB1c2luZyByZWFkT25seU1hc3RlcktleSdcbiAgICApO1xuICB9XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmF1dGggPSBhdXRoO1xuICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgdGhpcy5jbGllbnRTREsgPSBjbGllbnRTREs7XG4gIHRoaXMuc3RvcmFnZSA9IHt9O1xuICB0aGlzLnJ1bk9wdGlvbnMgPSB7fTtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dCB8fCB7fTtcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgdGhpcy5ydW5PcHRpb25zLmFjdGlvbiA9IGFjdGlvbjtcbiAgfVxuXG4gIGlmICghcXVlcnkpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYWxsb3dDdXN0b21PYmplY3RJZCkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCAnb2JqZWN0SWQnKSAmJiAhZGF0YS5vYmplY3RJZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuTUlTU0lOR19PQkpFQ1RfSUQsXG4gICAgICAgICAgJ29iamVjdElkIG11c3Qgbm90IGJlIGVtcHR5LCBudWxsIG9yIHVuZGVmaW5lZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGEub2JqZWN0SWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsICdvYmplY3RJZCBpcyBhbiBpbnZhbGlkIGZpZWxkIG5hbWUuJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5pZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgJ2lkIGlzIGFuIGludmFsaWQgZmllbGQgbmFtZS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXaGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGUsIHRoaXMucmVzcG9uc2UgbWF5IGhhdmUgc2V2ZXJhbFxuICAvLyBmaWVsZHMuXG4gIC8vIHJlc3BvbnNlOiB0aGUgYWN0dWFsIGRhdGEgdG8gYmUgcmV0dXJuZWRcbiAgLy8gc3RhdHVzOiB0aGUgaHR0cCBzdGF0dXMgY29kZS4gaWYgbm90IHByZXNlbnQsIHRyZWF0ZWQgbGlrZSBhIDIwMFxuICAvLyBsb2NhdGlvbjogdGhlIGxvY2F0aW9uIGhlYWRlci4gaWYgbm90IHByZXNlbnQsIG5vIGxvY2F0aW9uIGhlYWRlclxuICB0aGlzLnJlc3BvbnNlID0gbnVsbDtcblxuICAvLyBQcm9jZXNzaW5nIHRoaXMgb3BlcmF0aW9uIG1heSBtdXRhdGUgb3VyIGRhdGEsIHNvIHdlIG9wZXJhdGUgb24gYVxuICAvLyBjb3B5XG4gIHRoaXMucXVlcnkgPSBkZWVwY29weShxdWVyeSk7XG4gIHRoaXMuZGF0YSA9IGRlZXBjb3B5KGRhdGEpO1xuICAvLyBXZSBuZXZlciBjaGFuZ2Ugb3JpZ2luYWxEYXRhLCBzbyB3ZSBkbyBub3QgbmVlZCBhIGRlZXAgY29weVxuICB0aGlzLm9yaWdpbmFsRGF0YSA9IG9yaWdpbmFsRGF0YTtcblxuICAvLyBUaGUgdGltZXN0YW1wIHdlJ2xsIHVzZSBmb3IgdGhpcyB3aG9sZSBvcGVyYXRpb25cbiAgdGhpcy51cGRhdGVkQXQgPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpLmlzbztcblxuICAvLyBTaGFyZWQgU2NoZW1hQ29udHJvbGxlciB0byBiZSByZXVzZWQgdG8gcmVkdWNlIHRoZSBudW1iZXIgb2YgbG9hZFNjaGVtYSgpIGNhbGxzIHBlciByZXF1ZXN0XG4gIC8vIE9uY2Ugc2V0IHRoZSBzY2hlbWFEYXRhIHNob3VsZCBiZSBpbW11dGFibGVcbiAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIgPSBudWxsO1xufVxuXG4vLyBBIGNvbnZlbmllbnQgbWV0aG9kIHRvIHBlcmZvcm0gYWxsIHRoZSBzdGVwcyBvZiBwcm9jZXNzaW5nIHRoZVxuLy8gd3JpdGUsIGluIG9yZGVyLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlLCBzdGF0dXMsIGxvY2F0aW9ufSBvYmplY3QuXG4vLyBzdGF0dXMgYW5kIGxvY2F0aW9uIGFyZSBvcHRpb25hbC5cblJlc3RXcml0ZS5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlckFuZFJvbGVBQ0woKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5zdGFsbGF0aW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVTZXNzaW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUF1dGhEYXRhKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5CZWZvcmVTYXZlVHJpZ2dlcigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlRW1haWxSZXNldFRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlU2NoZW1hKCk7XG4gICAgfSlcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcbiAgICAgIHJldHVybiB0aGlzLnNldFJlcXVpcmVkRmllbGRzSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybVVzZXIoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmV4cGFuZEZpbGVzRm9yRXhpc3RpbmdPYmplY3RzKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5kZXN0cm95RHVwbGljYXRlZFNlc3Npb25zKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5EYXRhYmFzZU9wZXJhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZvbGxvd3VwKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5BZnRlclNhdmVUcmlnZ2VyKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jbGVhblVzZXJBdXRoRGF0YSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVzcG9uc2U7XG4gICAgfSk7XG59O1xuXG4vLyBVc2VzIHRoZSBBdXRoIG9iamVjdCB0byBnZXQgdGhlIGxpc3Qgb2Ygcm9sZXMsIGFkZHMgdGhlIHVzZXIgaWRcblJlc3RXcml0ZS5wcm90b3R5cGUuZ2V0VXNlckFuZFJvbGVBQ0wgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICB0aGlzLnJ1bk9wdGlvbnMuYWNsID0gWycqJ107XG5cbiAgaWYgKHRoaXMuYXV0aC51c2VyKSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aC5nZXRVc2VyUm9sZXMoKS50aGVuKHJvbGVzID0+IHtcbiAgICAgIHRoaXMucnVuT3B0aW9ucy5hY2wgPSB0aGlzLnJ1bk9wdGlvbnMuYWNsLmNvbmNhdChyb2xlcywgW3RoaXMuYXV0aC51c2VyLmlkXSk7XG4gICAgICByZXR1cm47XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG4vLyBWYWxpZGF0ZXMgdGhpcyBvcGVyYXRpb24gYWdhaW5zdCB0aGUgYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIGNvbmZpZy5cblJlc3RXcml0ZS5wcm90b3R5cGUudmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAoXG4gICAgdGhpcy5jb25maWcuYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uID09PSBmYWxzZSAmJlxuICAgICF0aGlzLmF1dGguaXNNYXN0ZXIgJiZcbiAgICBTY2hlbWFDb250cm9sbGVyLnN5c3RlbUNsYXNzZXMuaW5kZXhPZih0aGlzLmNsYXNzTmFtZSkgPT09IC0xXG4gICkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmxvYWRTY2hlbWEoKVxuICAgICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmhhc0NsYXNzKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGhhc0NsYXNzID0+IHtcbiAgICAgICAgaWYgKGhhc0NsYXNzICE9PSB0cnVlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgICAgICdUaGlzIHVzZXIgaXMgbm90IGFsbG93ZWQgdG8gYWNjZXNzICcgKyAnbm9uLWV4aXN0ZW50IGNsYXNzOiAnICsgdGhpcy5jbGFzc05hbWVcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn07XG5cbi8vIFZhbGlkYXRlcyB0aGlzIG9wZXJhdGlvbiBhZ2FpbnN0IHRoZSBzY2hlbWEuXG5SZXN0V3JpdGUucHJvdG90eXBlLnZhbGlkYXRlU2NoZW1hID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudmFsaWRhdGVPYmplY3QoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdGhpcy5kYXRhLFxuICAgIHRoaXMucXVlcnksXG4gICAgdGhpcy5ydW5PcHRpb25zXG4gICk7XG59O1xuXG4vLyBSdW5zIGFueSBiZWZvcmVTYXZlIHRyaWdnZXJzIGFnYWluc3QgdGhpcyBvcGVyYXRpb24uXG4vLyBBbnkgY2hhbmdlIGxlYWRzIHRvIG91ciBkYXRhIGJlaW5nIG11dGF0ZWQuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkJlZm9yZVNhdmVUcmlnZ2VyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2JlZm9yZVNhdmUnIHRyaWdnZXIgZm9yIHRoaXMgY2xhc3MuXG4gIGlmIChcbiAgICAhdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyh0aGlzLmNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZSwgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZClcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gQ2xvdWQgY29kZSBnZXRzIGEgYml0IG9mIGV4dHJhIGRhdGEgZm9yIGl0cyBvYmplY3RzXG4gIHZhciBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIGV4dHJhRGF0YS5vYmplY3RJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gIH1cblxuICBsZXQgb3JpZ2luYWxPYmplY3QgPSBudWxsO1xuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdGhpcy5idWlsZFVwZGF0ZWRPYmplY3QoZXh0cmFEYXRhKTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIC8vIFRoaXMgaXMgYW4gdXBkYXRlIGZvciBleGlzdGluZyBvYmplY3QuXG4gICAgb3JpZ2luYWxPYmplY3QgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdGhpcy5vcmlnaW5hbERhdGEpO1xuICB9XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gQmVmb3JlIGNhbGxpbmcgdGhlIHRyaWdnZXIsIHZhbGlkYXRlIHRoZSBwZXJtaXNzaW9ucyBmb3IgdGhlIHNhdmUgb3BlcmF0aW9uXG4gICAgICBsZXQgZGF0YWJhc2VQcm9taXNlID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZvciB1cGRhdGluZ1xuICAgICAgICBkYXRhYmFzZVByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgdGhpcy5xdWVyeSxcbiAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgdGhpcy5ydW5PcHRpb25zLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZvciBjcmVhdGluZ1xuICAgICAgICBkYXRhYmFzZVByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5jcmVhdGUoXG4gICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgdGhpcy5kYXRhLFxuICAgICAgICAgIHRoaXMucnVuT3B0aW9ucyxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBJbiB0aGUgY2FzZSB0aGF0IHRoZXJlIGlzIG5vIHBlcm1pc3Npb24gZm9yIHRoZSBvcGVyYXRpb24sIGl0IHRocm93cyBhbiBlcnJvclxuICAgICAgcmV0dXJuIGRhdGFiYXNlUHJvbWlzZS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmICghcmVzdWx0IHx8IHJlc3VsdC5sZW5ndGggPD0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTYXZlLFxuICAgICAgICB0aGlzLmF1dGgsXG4gICAgICAgIHVwZGF0ZWRPYmplY3QsXG4gICAgICAgIG9yaWdpbmFsT2JqZWN0LFxuICAgICAgICB0aGlzLmNvbmZpZyxcbiAgICAgICAgdGhpcy5jb250ZXh0XG4gICAgICApO1xuICAgIH0pXG4gICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLm9iamVjdCkge1xuICAgICAgICB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlciA9IF8ucmVkdWNlKFxuICAgICAgICAgIHJlc3BvbnNlLm9iamVjdCxcbiAgICAgICAgICAocmVzdWx0LCB2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoIV8uaXNFcXVhbCh0aGlzLmRhdGFba2V5XSwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgW11cbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5kYXRhID0gcmVzcG9uc2Uub2JqZWN0O1xuICAgICAgICAvLyBXZSBzaG91bGQgZGVsZXRlIHRoZSBvYmplY3RJZCBmb3IgYW4gdXBkYXRlIHdyaXRlXG4gICAgICAgIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5kYXRhLm9iamVjdElkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkJlZm9yZUxvZ2luVHJpZ2dlciA9IGFzeW5jIGZ1bmN0aW9uICh1c2VyRGF0YSkge1xuICAvLyBBdm9pZCBkb2luZyBhbnkgc2V0dXAgZm9yIHRyaWdnZXJzIGlmIHRoZXJlIGlzIG5vICdiZWZvcmVMb2dpbicgdHJpZ2dlclxuICBpZiAoXG4gICAgIXRyaWdnZXJzLnRyaWdnZXJFeGlzdHModGhpcy5jbGFzc05hbWUsIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUxvZ2luLCB0aGlzLmNvbmZpZy5hcHBsaWNhdGlvbklkKVxuICApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBDbG91ZCBjb2RlIGdldHMgYSBiaXQgb2YgZXh0cmEgZGF0YSBmb3IgaXRzIG9iamVjdHNcbiAgY29uc3QgZXh0cmFEYXRhID0geyBjbGFzc05hbWU6IHRoaXMuY2xhc3NOYW1lIH07XG5cbiAgLy8gRXhwYW5kIGZpbGUgb2JqZWN0c1xuICB0aGlzLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdCh0aGlzLmNvbmZpZywgdXNlckRhdGEpO1xuXG4gIGNvbnN0IHVzZXIgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdXNlckRhdGEpO1xuXG4gIC8vIG5vIG5lZWQgdG8gcmV0dXJuIGEgcmVzcG9uc2VcbiAgYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUxvZ2luLFxuICAgIHRoaXMuYXV0aCxcbiAgICB1c2VyLFxuICAgIG51bGwsXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5jb250ZXh0XG4gICk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLnNldFJlcXVpcmVkRmllbGRzSWZOZWVkZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIuZ2V0QWxsQ2xhc3NlcygpLnRoZW4oYWxsQ2xhc3NlcyA9PiB7XG4gICAgICBjb25zdCBzY2hlbWEgPSBhbGxDbGFzc2VzLmZpbmQob25lQ2xhc3MgPT4gb25lQ2xhc3MuY2xhc3NOYW1lID09PSB0aGlzLmNsYXNzTmFtZSk7XG4gICAgICBjb25zdCBzZXRSZXF1aXJlZEZpZWxkSWZOZWVkZWQgPSAoZmllbGROYW1lLCBzZXREZWZhdWx0KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPT09IG51bGwgfHxcbiAgICAgICAgICB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gJycgfHxcbiAgICAgICAgICAodHlwZW9mIHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSAnb2JqZWN0JyAmJiB0aGlzLmRhdGFbZmllbGROYW1lXS5fX29wID09PSAnRGVsZXRlJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgc2V0RGVmYXVsdCAmJlxuICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdICYmXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uZGVmYXVsdFZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICh0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgICh0eXBlb2YgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPT09ICdvYmplY3QnICYmIHRoaXMuZGF0YVtmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YVtmaWVsZE5hbWVdID0gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLmRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyID0gdGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIgfHwgW107XG4gICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIuaW5kZXhPZihmaWVsZE5hbWUpIDwgMCkge1xuICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnJlcXVpcmVkID09PSB0cnVlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgYCR7ZmllbGROYW1lfSBpcyByZXF1aXJlZGApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gQWRkIGRlZmF1bHQgZmllbGRzXG4gICAgICB0aGlzLmRhdGEudXBkYXRlZEF0ID0gdGhpcy51cGRhdGVkQXQ7XG4gICAgICBpZiAoIXRoaXMucXVlcnkpIHtcbiAgICAgICAgdGhpcy5kYXRhLmNyZWF0ZWRBdCA9IHRoaXMudXBkYXRlZEF0O1xuXG4gICAgICAgIC8vIE9ubHkgYXNzaWduIG5ldyBvYmplY3RJZCBpZiB3ZSBhcmUgY3JlYXRpbmcgbmV3IG9iamVjdFxuICAgICAgICBpZiAoIXRoaXMuZGF0YS5vYmplY3RJZCkge1xuICAgICAgICAgIHRoaXMuZGF0YS5vYmplY3RJZCA9IGNyeXB0b1V0aWxzLm5ld09iamVjdElkKHRoaXMuY29uZmlnLm9iamVjdElkU2l6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjaGVtYSkge1xuICAgICAgICAgIE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgIHNldFJlcXVpcmVkRmllbGRJZk5lZWRlZChmaWVsZE5hbWUsIHRydWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNjaGVtYSkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICBzZXRSZXF1aXJlZEZpZWxkSWZOZWVkZWQoZmllbGROYW1lLCBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cbi8vIFRyYW5zZm9ybXMgYXV0aCBkYXRhIGZvciBhIHVzZXIgb2JqZWN0LlxuLy8gRG9lcyBub3RoaW5nIGlmIHRoaXMgaXNuJ3QgYSB1c2VyIG9iamVjdC5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciB3aGVuIHdlJ3JlIGRvbmUgaWYgaXQgY2FuJ3QgZmluaXNoIHRoaXMgdGljay5cblJlc3RXcml0ZS5wcm90b3R5cGUudmFsaWRhdGVBdXRoRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCF0aGlzLnF1ZXJ5ICYmICF0aGlzLmRhdGEuYXV0aERhdGEpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuZGF0YS51c2VybmFtZSAhPT0gJ3N0cmluZycgfHwgXy5pc0VtcHR5KHRoaXMuZGF0YS51c2VybmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5VU0VSTkFNRV9NSVNTSU5HLCAnYmFkIG9yIG1pc3NpbmcgdXNlcm5hbWUnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0aGlzLmRhdGEucGFzc3dvcmQgIT09ICdzdHJpbmcnIHx8IF8uaXNFbXB0eSh0aGlzLmRhdGEucGFzc3dvcmQpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUEFTU1dPUkRfTUlTU0lORywgJ3Bhc3N3b3JkIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKFxuICAgICh0aGlzLmRhdGEuYXV0aERhdGEgJiYgIU9iamVjdC5rZXlzKHRoaXMuZGF0YS5hdXRoRGF0YSkubGVuZ3RoKSB8fFxuICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5kYXRhLCAnYXV0aERhdGEnKVxuICApIHtcbiAgICAvLyBIYW5kbGUgc2F2aW5nIGF1dGhEYXRhIHRvIHt9IG9yIGlmIGF1dGhEYXRhIGRvZXNuJ3QgZXhpc3RcbiAgICByZXR1cm47XG4gIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuZGF0YSwgJ2F1dGhEYXRhJykgJiYgIXRoaXMuZGF0YS5hdXRoRGF0YSkge1xuICAgIC8vIEhhbmRsZSBzYXZpbmcgYXV0aERhdGEgdG8gbnVsbFxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLlVOU1VQUE9SVEVEX1NFUlZJQ0UsXG4gICAgICAnVGhpcyBhdXRoZW50aWNhdGlvbiBtZXRob2QgaXMgdW5zdXBwb3J0ZWQuJ1xuICAgICk7XG4gIH1cblxuICB2YXIgYXV0aERhdGEgPSB0aGlzLmRhdGEuYXV0aERhdGE7XG4gIHZhciBwcm92aWRlcnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSk7XG4gIGlmIChwcm92aWRlcnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGNhbkhhbmRsZUF1dGhEYXRhID0gcHJvdmlkZXJzLnJlZHVjZSgoY2FuSGFuZGxlLCBwcm92aWRlcikgPT4ge1xuICAgICAgdmFyIHByb3ZpZGVyQXV0aERhdGEgPSBhdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICB2YXIgaGFzVG9rZW4gPSBwcm92aWRlckF1dGhEYXRhICYmIHByb3ZpZGVyQXV0aERhdGEuaWQ7XG4gICAgICByZXR1cm4gY2FuSGFuZGxlICYmIChoYXNUb2tlbiB8fCBwcm92aWRlckF1dGhEYXRhID09IG51bGwpO1xuICAgIH0sIHRydWUpO1xuICAgIGlmIChjYW5IYW5kbGVBdXRoRGF0YSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQXV0aERhdGEoYXV0aERhdGEpO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgUGFyc2UuRXJyb3IuVU5TVVBQT1JURURfU0VSVklDRSxcbiAgICAnVGhpcyBhdXRoZW50aWNhdGlvbiBtZXRob2QgaXMgdW5zdXBwb3J0ZWQuJ1xuICApO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24gPSBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgY29uc3QgdmFsaWRhdGlvbnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSkubWFwKHByb3ZpZGVyID0+IHtcbiAgICBpZiAoYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGNvbnN0IHZhbGlkYXRlQXV0aERhdGEgPSB0aGlzLmNvbmZpZy5hdXRoRGF0YU1hbmFnZXIuZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIocHJvdmlkZXIpO1xuICAgIGlmICghdmFsaWRhdGVBdXRoRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5VTlNVUFBPUlRFRF9TRVJWSUNFLFxuICAgICAgICAnVGhpcyBhdXRoZW50aWNhdGlvbiBtZXRob2QgaXMgdW5zdXBwb3J0ZWQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGFbcHJvdmlkZXJdKTtcbiAgfSk7XG4gIHJldHVybiBQcm9taXNlLmFsbCh2YWxpZGF0aW9ucyk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmZpbmRVc2Vyc1dpdGhBdXRoRGF0YSA9IGZ1bmN0aW9uIChhdXRoRGF0YSkge1xuICBjb25zdCBwcm92aWRlcnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSk7XG4gIGNvbnN0IHF1ZXJ5ID0gcHJvdmlkZXJzXG4gICAgLnJlZHVjZSgobWVtbywgcHJvdmlkZXIpID0+IHtcbiAgICAgIGlmICghYXV0aERhdGFbcHJvdmlkZXJdKSB7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgfVxuICAgICAgY29uc3QgcXVlcnlLZXkgPSBgYXV0aERhdGEuJHtwcm92aWRlcn0uaWRgO1xuICAgICAgY29uc3QgcXVlcnkgPSB7fTtcbiAgICAgIHF1ZXJ5W3F1ZXJ5S2V5XSA9IGF1dGhEYXRhW3Byb3ZpZGVyXS5pZDtcbiAgICAgIG1lbW8ucHVzaChxdWVyeSk7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9LCBbXSlcbiAgICAuZmlsdGVyKHEgPT4ge1xuICAgICAgcmV0dXJuIHR5cGVvZiBxICE9PSAndW5kZWZpbmVkJztcbiAgICB9KTtcblxuICBsZXQgZmluZFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoW10pO1xuICBpZiAocXVlcnkubGVuZ3RoID4gMCkge1xuICAgIGZpbmRQcm9taXNlID0gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCh0aGlzLmNsYXNzTmFtZSwgeyAkb3I6IHF1ZXJ5IH0sIHt9KTtcbiAgfVxuXG4gIHJldHVybiBmaW5kUHJvbWlzZTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuZmlsdGVyZWRPYmplY3RzQnlBQ0wgPSBmdW5jdGlvbiAob2JqZWN0cykge1xuICBpZiAodGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIG9iamVjdHM7XG4gIH1cbiAgcmV0dXJuIG9iamVjdHMuZmlsdGVyKG9iamVjdCA9PiB7XG4gICAgaWYgKCFvYmplY3QuQUNMKSB7XG4gICAgICByZXR1cm4gdHJ1ZTsgLy8gbGVnYWN5IHVzZXJzIHRoYXQgaGF2ZSBubyBBQ0wgZmllbGQgb24gdGhlbVxuICAgIH1cbiAgICAvLyBSZWd1bGFyIHVzZXJzIHRoYXQgaGF2ZSBiZWVuIGxvY2tlZCBvdXQuXG4gICAgcmV0dXJuIG9iamVjdC5BQ0wgJiYgT2JqZWN0LmtleXMob2JqZWN0LkFDTCkubGVuZ3RoID4gMDtcbiAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUF1dGhEYXRhID0gZnVuY3Rpb24gKGF1dGhEYXRhKSB7XG4gIGxldCByZXN1bHRzO1xuICByZXR1cm4gdGhpcy5maW5kVXNlcnNXaXRoQXV0aERhdGEoYXV0aERhdGEpLnRoZW4oYXN5bmMgciA9PiB7XG4gICAgcmVzdWx0cyA9IHRoaXMuZmlsdGVyZWRPYmplY3RzQnlBQ0wocik7XG5cbiAgICBpZiAocmVzdWx0cy5sZW5ndGggPT0gMSkge1xuICAgICAgdGhpcy5zdG9yYWdlWydhdXRoUHJvdmlkZXInXSA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKS5qb2luKCcsJyk7XG5cbiAgICAgIGNvbnN0IHVzZXJSZXN1bHQgPSByZXN1bHRzWzBdO1xuICAgICAgY29uc3QgbXV0YXRlZEF1dGhEYXRhID0ge307XG4gICAgICBPYmplY3Qua2V5cyhhdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyRGF0YSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgY29uc3QgdXNlckF1dGhEYXRhID0gdXNlclJlc3VsdC5hdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgIGlmICghXy5pc0VxdWFsKHByb3ZpZGVyRGF0YSwgdXNlckF1dGhEYXRhKSkge1xuICAgICAgICAgIG11dGF0ZWRBdXRoRGF0YVtwcm92aWRlcl0gPSBwcm92aWRlckRhdGE7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgY29uc3QgaGFzTXV0YXRlZEF1dGhEYXRhID0gT2JqZWN0LmtleXMobXV0YXRlZEF1dGhEYXRhKS5sZW5ndGggIT09IDA7XG4gICAgICBsZXQgdXNlcklkO1xuICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICB1c2VySWQgPSB0aGlzLnF1ZXJ5Lm9iamVjdElkO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmF1dGggJiYgdGhpcy5hdXRoLnVzZXIgJiYgdGhpcy5hdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgdXNlcklkID0gdGhpcy5hdXRoLnVzZXIuaWQ7XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXJJZCB8fCB1c2VySWQgPT09IHVzZXJSZXN1bHQub2JqZWN0SWQpIHtcbiAgICAgICAgLy8gbm8gdXNlciBtYWtpbmcgdGhlIGNhbGxcbiAgICAgICAgLy8gT1IgdGhlIHVzZXIgbWFraW5nIHRoZSBjYWxsIGlzIHRoZSByaWdodCBvbmVcbiAgICAgICAgLy8gTG9naW4gd2l0aCBhdXRoIGRhdGFcbiAgICAgICAgZGVsZXRlIHJlc3VsdHNbMF0ucGFzc3dvcmQ7XG5cbiAgICAgICAgLy8gbmVlZCB0byBzZXQgdGhlIG9iamVjdElkIGZpcnN0IG90aGVyd2lzZSBsb2NhdGlvbiBoYXMgdHJhaWxpbmcgdW5kZWZpbmVkXG4gICAgICAgIHRoaXMuZGF0YS5vYmplY3RJZCA9IHVzZXJSZXN1bHQub2JqZWN0SWQ7XG5cbiAgICAgICAgaWYgKCF0aGlzLnF1ZXJ5IHx8ICF0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgICAgICAgLy8gdGhpcyBhIGxvZ2luIGNhbGwsIG5vIHVzZXJJZCBwYXNzZWRcbiAgICAgICAgICB0aGlzLnJlc3BvbnNlID0ge1xuICAgICAgICAgICAgcmVzcG9uc2U6IHVzZXJSZXN1bHQsXG4gICAgICAgICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbigpLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gUnVuIGJlZm9yZUxvZ2luIGhvb2sgYmVmb3JlIHN0b3JpbmcgYW55IHVwZGF0ZXNcbiAgICAgICAgICAvLyB0byBhdXRoRGF0YSBvbiB0aGUgZGI7IGNoYW5nZXMgdG8gdXNlclJlc3VsdFxuICAgICAgICAgIC8vIHdpbGwgYmUgaWdub3JlZC5cbiAgICAgICAgICBhd2FpdCB0aGlzLnJ1bkJlZm9yZUxvZ2luVHJpZ2dlcihkZWVwY29weSh1c2VyUmVzdWx0KSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB3ZSBkaWRuJ3QgY2hhbmdlIHRoZSBhdXRoIGRhdGEsIGp1c3Qga2VlcCBnb2luZ1xuICAgICAgICBpZiAoIWhhc011dGF0ZWRBdXRoRGF0YSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBXZSBoYXZlIGF1dGhEYXRhIHRoYXQgaXMgdXBkYXRlZCBvbiBsb2dpblxuICAgICAgICAvLyB0aGF0IGNhbiBoYXBwZW4gd2hlbiB0b2tlbiBhcmUgcmVmcmVzaGVkLFxuICAgICAgICAvLyBXZSBzaG91bGQgdXBkYXRlIHRoZSB0b2tlbiBhbmQgbGV0IHRoZSB1c2VyIGluXG4gICAgICAgIC8vIFdlIHNob3VsZCBvbmx5IGNoZWNrIHRoZSBtdXRhdGVkIGtleXNcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQXV0aERhdGFWYWxpZGF0aW9uKG11dGF0ZWRBdXRoRGF0YSkudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgLy8gSUYgd2UgaGF2ZSBhIHJlc3BvbnNlLCB3ZSdsbCBza2lwIHRoZSBkYXRhYmFzZSBvcGVyYXRpb24gLyBiZWZvcmVTYXZlIC8gYWZ0ZXJTYXZlIGV0Yy4uLlxuICAgICAgICAgIC8vIHdlIG5lZWQgdG8gc2V0IGl0IHVwIHRoZXJlLlxuICAgICAgICAgIC8vIFdlIGFyZSBzdXBwb3NlZCB0byBoYXZlIGEgcmVzcG9uc2Ugb25seSBvbiBMT0dJTiB3aXRoIGF1dGhEYXRhLCBzbyB3ZSBza2lwIHRob3NlXG4gICAgICAgICAgLy8gSWYgd2UncmUgbm90IGxvZ2dpbmcgaW4sIGJ1dCBqdXN0IHVwZGF0aW5nIHRoZSBjdXJyZW50IHVzZXIsIHdlIGNhbiBzYWZlbHkgc2tpcCB0aGF0IHBhcnRcbiAgICAgICAgICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgICAgICAgICAgLy8gQXNzaWduIHRoZSBuZXcgYXV0aERhdGEgaW4gdGhlIHJlc3BvbnNlXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhtdXRhdGVkQXV0aERhdGEpLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlLmF1dGhEYXRhW3Byb3ZpZGVyXSA9IG11dGF0ZWRBdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUnVuIHRoZSBEQiB1cGRhdGUgZGlyZWN0bHksIGFzICdtYXN0ZXInXG4gICAgICAgICAgICAvLyBKdXN0IHVwZGF0ZSB0aGUgYXV0aERhdGEgcGFydFxuICAgICAgICAgICAgLy8gVGhlbiB3ZSdyZSBnb29kIGZvciB0aGUgdXNlciwgZWFybHkgZXhpdCBvZiBzb3J0c1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgIHsgb2JqZWN0SWQ6IHRoaXMuZGF0YS5vYmplY3RJZCB9LFxuICAgICAgICAgICAgICB7IGF1dGhEYXRhOiBtdXRhdGVkQXV0aERhdGEgfSxcbiAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodXNlcklkKSB7XG4gICAgICAgIC8vIFRyeWluZyB0byB1cGRhdGUgYXV0aCBkYXRhIGJ1dCB1c2Vyc1xuICAgICAgICAvLyBhcmUgZGlmZmVyZW50XG4gICAgICAgIGlmICh1c2VyUmVzdWx0Lm9iamVjdElkICE9PSB1c2VySWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuQUNDT1VOVF9BTFJFQURZX0xJTktFRCwgJ3RoaXMgYXV0aCBpcyBhbHJlYWR5IHVzZWQnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBhdXRoIGRhdGEgd2FzIG11dGF0ZWQsIGp1c3Qga2VlcCBnb2luZ1xuICAgICAgICBpZiAoIWhhc011dGF0ZWRBdXRoRGF0YSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24oYXV0aERhdGEpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMSkge1xuICAgICAgICAvLyBNb3JlIHRoYW4gMSB1c2VyIHdpdGggdGhlIHBhc3NlZCBpZCdzXG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5BQ0NPVU5UX0FMUkVBRFlfTElOS0VELCAndGhpcyBhdXRoIGlzIGFscmVhZHkgdXNlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn07XG5cbi8vIFRoZSBub24tdGhpcmQtcGFydHkgcGFydHMgb2YgVXNlciB0cmFuc2Zvcm1hdGlvblxuUmVzdFdyaXRlLnByb3RvdHlwZS50cmFuc2Zvcm1Vc2VyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuXG4gIGlmICh0aGlzLmNsYXNzTmFtZSAhPT0gJ19Vc2VyJykge1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgaWYgKCF0aGlzLmF1dGguaXNNYXN0ZXIgJiYgJ2VtYWlsVmVyaWZpZWQnIGluIHRoaXMuZGF0YSkge1xuICAgIGNvbnN0IGVycm9yID0gYENsaWVudHMgYXJlbid0IGFsbG93ZWQgdG8gbWFudWFsbHkgdXBkYXRlIGVtYWlsIHZlcmlmaWNhdGlvbi5gO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gIH1cblxuICAvLyBEbyBub3QgY2xlYW51cCBzZXNzaW9uIGlmIG9iamVjdElkIGlzIG5vdCBzZXRcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5vYmplY3RJZCgpKSB7XG4gICAgLy8gSWYgd2UncmUgdXBkYXRpbmcgYSBfVXNlciBvYmplY3QsIHdlIG5lZWQgdG8gY2xlYXIgb3V0IHRoZSBjYWNoZSBmb3IgdGhhdCB1c2VyLiBGaW5kIGFsbCB0aGVpclxuICAgIC8vIHNlc3Npb24gdG9rZW5zLCBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgY2FjaGUuXG4gICAgcHJvbWlzZSA9IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIEF1dGgubWFzdGVyKHRoaXMuY29uZmlnKSwgJ19TZXNzaW9uJywge1xuICAgICAgdXNlcjoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpLFxuICAgICAgfSxcbiAgICB9KVxuICAgICAgLmV4ZWN1dGUoKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIHJlc3VsdHMucmVzdWx0cy5mb3JFYWNoKHNlc3Npb24gPT5cbiAgICAgICAgICB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXIudXNlci5kZWwoc2Vzc2lvbi5zZXNzaW9uVG9rZW4pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBwcm9taXNlXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gVHJhbnNmb3JtIHRoZSBwYXNzd29yZFxuICAgICAgaWYgKHRoaXMuZGF0YS5wYXNzd29yZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGlnbm9yZSBvbmx5IGlmIHVuZGVmaW5lZC4gc2hvdWxkIHByb2NlZWQgaWYgZW1wdHkgKCcnKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgICAgIHRoaXMuc3RvcmFnZVsnY2xlYXJTZXNzaW9ucyddID0gdHJ1ZTtcbiAgICAgICAgLy8gR2VuZXJhdGUgYSBuZXcgc2Vzc2lvbiBvbmx5IGlmIHRoZSB1c2VyIHJlcXVlc3RlZFxuICAgICAgICBpZiAoIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgICAgICAgIHRoaXMuc3RvcmFnZVsnZ2VuZXJhdGVOZXdTZXNzaW9uJ10gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5KCkudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBwYXNzd29yZENyeXB0by5oYXNoKHRoaXMuZGF0YS5wYXNzd29yZCkudGhlbihoYXNoZWRQYXNzd29yZCA9PiB7XG4gICAgICAgICAgdGhpcy5kYXRhLl9oYXNoZWRfcGFzc3dvcmQgPSBoYXNoZWRQYXNzd29yZDtcbiAgICAgICAgICBkZWxldGUgdGhpcy5kYXRhLnBhc3N3b3JkO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlVXNlck5hbWUoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUVtYWlsKCk7XG4gICAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLl92YWxpZGF0ZVVzZXJOYW1lID0gZnVuY3Rpb24gKCkge1xuICAvLyBDaGVjayBmb3IgdXNlcm5hbWUgdW5pcXVlbmVzc1xuICBpZiAoIXRoaXMuZGF0YS51c2VybmFtZSkge1xuICAgIGlmICghdGhpcy5xdWVyeSkge1xuICAgICAgdGhpcy5kYXRhLnVzZXJuYW1lID0gY3J5cHRvVXRpbHMucmFuZG9tU3RyaW5nKDI1KTtcbiAgICAgIHRoaXMucmVzcG9uc2VTaG91bGRIYXZlVXNlcm5hbWUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLypcbiAgICBVc2VybmFtZXMgc2hvdWxkIGJlIHVuaXF1ZSB3aGVuIGNvbXBhcmVkIGNhc2UgaW5zZW5zaXRpdmVseVxuXG4gICAgVXNlcnMgc2hvdWxkIGJlIGFibGUgdG8gbWFrZSBjYXNlIHNlbnNpdGl2ZSB1c2VybmFtZXMgYW5kXG4gICAgbG9naW4gdXNpbmcgdGhlIGNhc2UgdGhleSBlbnRlcmVkLiAgSS5lLiAnU25vb3B5JyBzaG91bGQgcHJlY2x1ZGVcbiAgICAnc25vb3B5JyBhcyBhIHZhbGlkIHVzZXJuYW1lLlxuICAqL1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAuZmluZChcbiAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAge1xuICAgICAgICB1c2VybmFtZTogdGhpcy5kYXRhLnVzZXJuYW1lLFxuICAgICAgICBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgfSxcbiAgICAgIHsgbGltaXQ6IDEsIGNhc2VJbnNlbnNpdGl2ZTogdHJ1ZSB9LFxuICAgICAge30sXG4gICAgICB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlclxuICAgIClcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLlVTRVJOQU1FX1RBS0VOLFxuICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHVzZXJuYW1lLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9KTtcbn07XG5cbi8qXG4gIEFzIHdpdGggdXNlcm5hbWVzLCBQYXJzZSBzaG91bGQgbm90IGFsbG93IGNhc2UgaW5zZW5zaXRpdmUgY29sbGlzaW9ucyBvZiBlbWFpbC5cbiAgdW5saWtlIHdpdGggdXNlcm5hbWVzICh3aGljaCBjYW4gaGF2ZSBjYXNlIGluc2Vuc2l0aXZlIGNvbGxpc2lvbnMgaW4gdGhlIGNhc2Ugb2ZcbiAgYXV0aCBhZGFwdGVycyksIGVtYWlscyBzaG91bGQgbmV2ZXIgaGF2ZSBhIGNhc2UgaW5zZW5zaXRpdmUgY29sbGlzaW9uLlxuXG4gIFRoaXMgYmVoYXZpb3IgY2FuIGJlIGVuZm9yY2VkIHRocm91Z2ggYSBwcm9wZXJseSBjb25maWd1cmVkIGluZGV4IHNlZTpcbiAgaHR0cHM6Ly9kb2NzLm1vbmdvZGIuY29tL21hbnVhbC9jb3JlL2luZGV4LWNhc2UtaW5zZW5zaXRpdmUvI2NyZWF0ZS1hLWNhc2UtaW5zZW5zaXRpdmUtaW5kZXhcbiAgd2hpY2ggY291bGQgYmUgaW1wbGVtZW50ZWQgaW5zdGVhZCBvZiB0aGlzIGNvZGUgYmFzZWQgdmFsaWRhdGlvbi5cblxuICBHaXZlbiB0aGF0IHRoaXMgbG9va3VwIHNob3VsZCBiZSBhIHJlbGF0aXZlbHkgbG93IHVzZSBjYXNlIGFuZCB0aGF0IHRoZSBjYXNlIHNlbnNpdGl2ZVxuICB1bmlxdWUgaW5kZXggd2lsbCBiZSB1c2VkIGJ5IHRoZSBkYiBmb3IgdGhlIHF1ZXJ5LCB0aGlzIGlzIGFuIGFkZXF1YXRlIHNvbHV0aW9uLlxuKi9cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlRW1haWwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5kYXRhLmVtYWlsIHx8IHRoaXMuZGF0YS5lbWFpbC5fX29wID09PSAnRGVsZXRlJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBWYWxpZGF0ZSBiYXNpYyBlbWFpbCBhZGRyZXNzIGZvcm1hdFxuICBpZiAoIXRoaXMuZGF0YS5lbWFpbC5tYXRjaCgvXi4rQC4rJC8pKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUywgJ0VtYWlsIGFkZHJlc3MgZm9ybWF0IGlzIGludmFsaWQuJylcbiAgICApO1xuICB9XG4gIC8vIENhc2UgaW5zZW5zaXRpdmUgbWF0Y2gsIHNlZSBub3RlIGFib3ZlIGZ1bmN0aW9uLlxuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAuZmluZChcbiAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAge1xuICAgICAgICBlbWFpbDogdGhpcy5kYXRhLmVtYWlsLFxuICAgICAgICBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgfSxcbiAgICAgIHsgbGltaXQ6IDEsIGNhc2VJbnNlbnNpdGl2ZTogdHJ1ZSB9LFxuICAgICAge30sXG4gICAgICB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlclxuICAgIClcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLkVNQUlMX1RBS0VOLFxuICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVtYWlsIGFkZHJlc3MuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5kYXRhLmF1dGhEYXRhIHx8XG4gICAgICAgICFPYmplY3Qua2V5cyh0aGlzLmRhdGEuYXV0aERhdGEpLmxlbmd0aCB8fFxuICAgICAgICAoT2JqZWN0LmtleXModGhpcy5kYXRhLmF1dGhEYXRhKS5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmRhdGEuYXV0aERhdGEpWzBdID09PSAnYW5vbnltb3VzJylcbiAgICAgICkge1xuICAgICAgICAvLyBXZSB1cGRhdGVkIHRoZSBlbWFpbCwgc2VuZCBhIG5ldyB2YWxpZGF0aW9uXG4gICAgICAgIHRoaXMuc3RvcmFnZVsnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJ10gPSB0cnVlO1xuICAgICAgICB0aGlzLmNvbmZpZy51c2VyQ29udHJvbGxlci5zZXRFbWFpbFZlcmlmeVRva2VuKHRoaXMuZGF0YSk7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5ID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5KSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIHJldHVybiB0aGlzLl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzKCkudGhlbigoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5KCk7XG4gIH0pO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5fdmFsaWRhdGVQYXNzd29yZFJlcXVpcmVtZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gY2hlY2sgaWYgdGhlIHBhc3N3b3JkIGNvbmZvcm1zIHRvIHRoZSBkZWZpbmVkIHBhc3N3b3JkIHBvbGljeSBpZiBjb25maWd1cmVkXG4gIC8vIElmIHdlIHNwZWNpZmllZCBhIGN1c3RvbSBlcnJvciBpbiBvdXIgY29uZmlndXJhdGlvbiB1c2UgaXQuXG4gIC8vIEV4YW1wbGU6IFwiUGFzc3dvcmRzIG11c3QgaW5jbHVkZSBhIENhcGl0YWwgTGV0dGVyLCBMb3dlcmNhc2UgTGV0dGVyLCBhbmQgYSBudW1iZXIuXCJcbiAgLy9cbiAgLy8gVGhpcyBpcyBlc3BlY2lhbGx5IHVzZWZ1bCBvbiB0aGUgZ2VuZXJpYyBcInBhc3N3b3JkIHJlc2V0XCIgcGFnZSxcbiAgLy8gYXMgaXQgYWxsb3dzIHRoZSBwcm9ncmFtbWVyIHRvIGNvbW11bmljYXRlIHNwZWNpZmljIHJlcXVpcmVtZW50cyBpbnN0ZWFkIG9mOlxuICAvLyBhLiBtYWtpbmcgdGhlIHVzZXIgZ3Vlc3Mgd2hhdHMgd3JvbmdcbiAgLy8gYi4gbWFraW5nIGEgY3VzdG9tIHBhc3N3b3JkIHJlc2V0IHBhZ2UgdGhhdCBzaG93cyB0aGUgcmVxdWlyZW1lbnRzXG4gIGNvbnN0IHBvbGljeUVycm9yID0gdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kudmFsaWRhdGlvbkVycm9yXG4gICAgPyB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS52YWxpZGF0aW9uRXJyb3JcbiAgICA6ICdQYXNzd29yZCBkb2VzIG5vdCBtZWV0IHRoZSBQYXNzd29yZCBQb2xpY3kgcmVxdWlyZW1lbnRzLic7XG4gIGNvbnN0IGNvbnRhaW5zVXNlcm5hbWVFcnJvciA9ICdQYXNzd29yZCBjYW5ub3QgY29udGFpbiB5b3VyIHVzZXJuYW1lLic7XG5cbiAgLy8gY2hlY2sgd2hldGhlciB0aGUgcGFzc3dvcmQgbWVldHMgdGhlIHBhc3N3b3JkIHN0cmVuZ3RoIHJlcXVpcmVtZW50c1xuICBpZiAoXG4gICAgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgJiZcbiAgICAgICF0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5wYXR0ZXJuVmFsaWRhdG9yKHRoaXMuZGF0YS5wYXNzd29yZCkpIHx8XG4gICAgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnZhbGlkYXRvckNhbGxiYWNrICYmXG4gICAgICAhdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sodGhpcy5kYXRhLnBhc3N3b3JkKSlcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBwb2xpY3lFcnJvcikpO1xuICB9XG5cbiAgLy8gY2hlY2sgd2hldGhlciBwYXNzd29yZCBjb250YWluIHVzZXJuYW1lXG4gIGlmICh0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgPT09IHRydWUpIHtcbiAgICBpZiAodGhpcy5kYXRhLnVzZXJuYW1lKSB7XG4gICAgICAvLyB1c2VybmFtZSBpcyBub3QgcGFzc2VkIGR1cmluZyBwYXNzd29yZCByZXNldFxuICAgICAgaWYgKHRoaXMuZGF0YS5wYXNzd29yZC5pbmRleE9mKHRoaXMuZGF0YS51c2VybmFtZSkgPj0gMClcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBjb250YWluc1VzZXJuYW1lRXJyb3IpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcmV0cmlldmUgdGhlIFVzZXIgb2JqZWN0IHVzaW5nIG9iamVjdElkIGR1cmluZyBwYXNzd29yZCByZXNldFxuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpIH0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmRhdGEucGFzc3dvcmQuaW5kZXhPZihyZXN1bHRzWzBdLnVzZXJuYW1lKSA+PSAwKVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBjb250YWluc1VzZXJuYW1lRXJyb3IpXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjaGVjayB3aGV0aGVyIHBhc3N3b3JkIGlzIHJlcGVhdGluZyBmcm9tIHNwZWNpZmllZCBoaXN0b3J5XG4gIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmZpbmQoXG4gICAgICAgICdfVXNlcicsXG4gICAgICAgIHsgb2JqZWN0SWQ6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgICB7IGtleXM6IFsnX3Bhc3N3b3JkX2hpc3RvcnknLCAnX2hhc2hlZF9wYXNzd29yZCddIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgbGV0IG9sZFBhc3N3b3JkcyA9IFtdO1xuICAgICAgICBpZiAodXNlci5fcGFzc3dvcmRfaGlzdG9yeSlcbiAgICAgICAgICBvbGRQYXNzd29yZHMgPSBfLnRha2UoXG4gICAgICAgICAgICB1c2VyLl9wYXNzd29yZF9oaXN0b3J5LFxuICAgICAgICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5IC0gMVxuICAgICAgICAgICk7XG4gICAgICAgIG9sZFBhc3N3b3Jkcy5wdXNoKHVzZXIucGFzc3dvcmQpO1xuICAgICAgICBjb25zdCBuZXdQYXNzd29yZCA9IHRoaXMuZGF0YS5wYXNzd29yZDtcbiAgICAgICAgLy8gY29tcGFyZSB0aGUgbmV3IHBhc3N3b3JkIGhhc2ggd2l0aCBhbGwgb2xkIHBhc3N3b3JkIGhhc2hlc1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG9sZFBhc3N3b3Jkcy5tYXAoZnVuY3Rpb24gKGhhc2gpIHtcbiAgICAgICAgICByZXR1cm4gcGFzc3dvcmRDcnlwdG8uY29tcGFyZShuZXdQYXNzd29yZCwgaGFzaCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3VsdClcbiAgICAgICAgICAgICAgLy8gcmVqZWN0IGlmIHRoZXJlIGlzIGEgbWF0Y2hcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdSRVBFQVRfUEFTU1dPUkQnKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHdhaXQgZm9yIGFsbCBjb21wYXJpc29ucyB0byBjb21wbGV0ZVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyID09PSAnUkVQRUFUX1BBU1NXT1JEJylcbiAgICAgICAgICAgICAgLy8gYSBtYXRjaCB3YXMgZm91bmRcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsXG4gICAgICAgICAgICAgICAgICBgTmV3IHBhc3N3b3JkIHNob3VsZCBub3QgYmUgdGhlIHNhbWUgYXMgbGFzdCAke3RoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeX0gcGFzc3dvcmRzLmBcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmNyZWF0ZVNlc3Npb25Ub2tlbklmTmVlZGVkID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gRG9uJ3QgZ2VuZXJhdGUgc2Vzc2lvbiBmb3IgdXBkYXRpbmcgdXNlciAodGhpcy5xdWVyeSBpcyBzZXQpIHVubGVzcyBhdXRoRGF0YSBleGlzdHNcbiAgaWYgKHRoaXMucXVlcnkgJiYgIXRoaXMuZGF0YS5hdXRoRGF0YSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBEb24ndCBnZW5lcmF0ZSBuZXcgc2Vzc2lvblRva2VuIGlmIGxpbmtpbmcgdmlhIHNlc3Npb25Ub2tlblxuICBpZiAodGhpcy5hdXRoLnVzZXIgJiYgdGhpcy5kYXRhLmF1dGhEYXRhKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChcbiAgICAhdGhpcy5zdG9yYWdlWydhdXRoUHJvdmlkZXInXSAmJiAvLyBzaWdudXAgY2FsbCwgd2l0aFxuICAgIHRoaXMuY29uZmlnLnByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwgJiYgLy8gbm8gbG9naW4gd2l0aG91dCB2ZXJpZmljYXRpb25cbiAgICB0aGlzLmNvbmZpZy52ZXJpZnlVc2VyRW1haWxzXG4gICkge1xuICAgIC8vIHZlcmlmaWNhdGlvbiBpcyBvblxuICAgIHJldHVybjsgLy8gZG8gbm90IGNyZWF0ZSB0aGUgc2Vzc2lvbiB0b2tlbiBpbiB0aGF0IGNhc2UhXG4gIH1cbiAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuKCk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmNyZWF0ZVNlc3Npb25Ub2tlbiA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgLy8gY2xvdWQgaW5zdGFsbGF0aW9uSWQgZnJvbSBDbG91ZCBDb2RlLFxuICAvLyBuZXZlciBjcmVhdGUgc2Vzc2lvbiB0b2tlbnMgZnJvbSB0aGVyZS5cbiAgaWYgKHRoaXMuYXV0aC5pbnN0YWxsYXRpb25JZCAmJiB0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWQgPT09ICdjbG91ZCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24odGhpcy5jb25maWcsIHtcbiAgICB1c2VySWQ6IHRoaXMub2JqZWN0SWQoKSxcbiAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgYWN0aW9uOiB0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddID8gJ2xvZ2luJyA6ICdzaWdudXAnLFxuICAgICAgYXV0aFByb3ZpZGVyOiB0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddIHx8ICdwYXNzd29yZCcsXG4gICAgfSxcbiAgICBpbnN0YWxsYXRpb25JZDogdGhpcy5hdXRoLmluc3RhbGxhdGlvbklkLFxuICB9KTtcblxuICBpZiAodGhpcy5yZXNwb25zZSAmJiB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlKSB7XG4gICAgdGhpcy5yZXNwb25zZS5yZXNwb25zZS5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uRGF0YS5zZXNzaW9uVG9rZW47XG4gIH1cblxuICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpO1xufTtcblxuLy8gRGVsZXRlIGVtYWlsIHJlc2V0IHRva2VucyBpZiB1c2VyIGlzIGNoYW5naW5nIHBhc3N3b3JkIG9yIGVtYWlsLlxuUmVzdFdyaXRlLnByb3RvdHlwZS5kZWxldGVFbWFpbFJlc2V0VG9rZW5JZk5lZWRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInIHx8IHRoaXMucXVlcnkgPT09IG51bGwpIHtcbiAgICAvLyBudWxsIHF1ZXJ5IG1lYW5zIGNyZWF0ZVxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICgncGFzc3dvcmQnIGluIHRoaXMuZGF0YSB8fCAnZW1haWwnIGluIHRoaXMuZGF0YSkge1xuICAgIGNvbnN0IGFkZE9wcyA9IHtcbiAgICAgIF9wZXJpc2hhYmxlX3Rva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgICBfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0OiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgfTtcbiAgICB0aGlzLmRhdGEgPSBPYmplY3QuYXNzaWduKHRoaXMuZGF0YSwgYWRkT3BzKTtcbiAgfVxufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5kZXN0cm95RHVwbGljYXRlZFNlc3Npb25zID0gZnVuY3Rpb24gKCkge1xuICAvLyBPbmx5IGZvciBfU2Vzc2lvbiwgYW5kIGF0IGNyZWF0aW9uIHRpbWVcbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9ICdfU2Vzc2lvbicgfHwgdGhpcy5xdWVyeSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBEZXN0cm95IHRoZSBzZXNzaW9ucyBpbiAnQmFja2dyb3VuZCdcbiAgY29uc3QgeyB1c2VyLCBpbnN0YWxsYXRpb25JZCwgc2Vzc2lvblRva2VuIH0gPSB0aGlzLmRhdGE7XG4gIGlmICghdXNlciB8fCAhaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKCF1c2VyLm9iamVjdElkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koXG4gICAgJ19TZXNzaW9uJyxcbiAgICB7XG4gICAgICB1c2VyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQsXG4gICAgICBzZXNzaW9uVG9rZW46IHsgJG5lOiBzZXNzaW9uVG9rZW4gfSxcbiAgICB9LFxuICAgIHt9LFxuICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyXG4gICk7XG59O1xuXG4vLyBIYW5kbGVzIGFueSBmb2xsb3d1cCBsb2dpY1xuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVGb2xsb3d1cCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc3RvcmFnZSAmJiB0aGlzLnN0b3JhZ2VbJ2NsZWFyU2Vzc2lvbnMnXSAmJiB0aGlzLmNvbmZpZy5yZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0KSB7XG4gICAgdmFyIHNlc3Npb25RdWVyeSA9IHtcbiAgICAgIHVzZXI6IHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgb2JqZWN0SWQ6IHRoaXMub2JqZWN0SWQoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBkZWxldGUgdGhpcy5zdG9yYWdlWydjbGVhclNlc3Npb25zJ107XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuZGVzdHJveSgnX1Nlc3Npb24nLCBzZXNzaW9uUXVlcnkpXG4gICAgICAudGhlbih0aGlzLmhhbmRsZUZvbGxvd3VwLmJpbmQodGhpcykpO1xuICB9XG5cbiAgaWYgKHRoaXMuc3RvcmFnZSAmJiB0aGlzLnN0b3JhZ2VbJ2dlbmVyYXRlTmV3U2Vzc2lvbiddKSB7XG4gICAgZGVsZXRlIHRoaXMuc3RvcmFnZVsnZ2VuZXJhdGVOZXdTZXNzaW9uJ107XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuKCkudGhlbih0aGlzLmhhbmRsZUZvbGxvd3VwLmJpbmQodGhpcykpO1xuICB9XG5cbiAgaWYgKHRoaXMuc3RvcmFnZSAmJiB0aGlzLnN0b3JhZ2VbJ3NlbmRWZXJpZmljYXRpb25FbWFpbCddKSB7XG4gICAgZGVsZXRlIHRoaXMuc3RvcmFnZVsnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJ107XG4gICAgLy8gRmlyZSBhbmQgZm9yZ2V0IVxuICAgIHRoaXMuY29uZmlnLnVzZXJDb250cm9sbGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbCh0aGlzLmRhdGEpO1xuICAgIHJldHVybiB0aGlzLmhhbmRsZUZvbGxvd3VwLmJpbmQodGhpcyk7XG4gIH1cbn07XG5cbi8vIEhhbmRsZXMgdGhlIF9TZXNzaW9uIGNsYXNzIHNwZWNpYWxuZXNzLlxuLy8gRG9lcyBub3RoaW5nIGlmIHRoaXMgaXNuJ3QgYW4gX1Nlc3Npb24gb2JqZWN0LlxuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVTZXNzaW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSB8fCB0aGlzLmNsYXNzTmFtZSAhPT0gJ19TZXNzaW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghdGhpcy5hdXRoLnVzZXIgJiYgIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdTZXNzaW9uIHRva2VuIHJlcXVpcmVkLicpO1xuICB9XG5cbiAgLy8gVE9ETzogVmVyaWZ5IHByb3BlciBlcnJvciB0byB0aHJvd1xuICBpZiAodGhpcy5kYXRhLkFDTCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCAnQ2Fubm90IHNldCAnICsgJ0FDTCBvbiBhIFNlc3Npb24uJyk7XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSkge1xuICAgIGlmICh0aGlzLmRhdGEudXNlciAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyICYmIHRoaXMuZGF0YS51c2VyLm9iamVjdElkICE9IHRoaXMuYXV0aC51c2VyLmlkKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YS5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRoaXMucXVlcnkgJiYgIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgIGNvbnN0IGFkZGl0aW9uYWxTZXNzaW9uRGF0YSA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmRhdGEpIHtcbiAgICAgIGlmIChrZXkgPT09ICdvYmplY3RJZCcgfHwga2V5ID09PSAndXNlcicpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBhZGRpdGlvbmFsU2Vzc2lvbkRhdGFba2V5XSA9IHRoaXMuZGF0YVtrZXldO1xuICAgIH1cblxuICAgIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IEF1dGguY3JlYXRlU2Vzc2lvbih0aGlzLmNvbmZpZywge1xuICAgICAgdXNlcklkOiB0aGlzLmF1dGgudXNlci5pZCxcbiAgICAgIGNyZWF0ZWRXaXRoOiB7XG4gICAgICAgIGFjdGlvbjogJ2NyZWF0ZScsXG4gICAgICB9LFxuICAgICAgYWRkaXRpb25hbFNlc3Npb25EYXRhLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNyZWF0ZVNlc3Npb24oKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKCFyZXN1bHRzLnJlc3BvbnNlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdFcnJvciBjcmVhdGluZyBzZXNzaW9uLicpO1xuICAgICAgfVxuICAgICAgc2Vzc2lvbkRhdGFbJ29iamVjdElkJ10gPSByZXN1bHRzLnJlc3BvbnNlWydvYmplY3RJZCddO1xuICAgICAgdGhpcy5yZXNwb25zZSA9IHtcbiAgICAgICAgc3RhdHVzOiAyMDEsXG4gICAgICAgIGxvY2F0aW9uOiByZXN1bHRzLmxvY2F0aW9uLFxuICAgICAgICByZXNwb25zZTogc2Vzc2lvbkRhdGEsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59O1xuXG4vLyBIYW5kbGVzIHRoZSBfSW5zdGFsbGF0aW9uIGNsYXNzIHNwZWNpYWxuZXNzLlxuLy8gRG9lcyBub3RoaW5nIGlmIHRoaXMgaXNuJ3QgYW4gaW5zdGFsbGF0aW9uIG9iamVjdC5cbi8vIElmIGFuIGluc3RhbGxhdGlvbiBpcyBmb3VuZCwgdGhpcyBjYW4gbXV0YXRlIHRoaXMucXVlcnkgYW5kIHR1cm4gYSBjcmVhdGVcbi8vIGludG8gYW4gdXBkYXRlLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZW4gd2UncmUgZG9uZSBpZiBpdCBjYW4ndCBmaW5pc2ggdGhpcyB0aWNrLlxuUmVzdFdyaXRlLnByb3RvdHlwZS5oYW5kbGVJbnN0YWxsYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlc3BvbnNlIHx8IHRoaXMuY2xhc3NOYW1lICE9PSAnX0luc3RhbGxhdGlvbicpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoXG4gICAgIXRoaXMucXVlcnkgJiZcbiAgICAhdGhpcy5kYXRhLmRldmljZVRva2VuICYmXG4gICAgIXRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCAmJlxuICAgICF0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWRcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgMTM1LFxuICAgICAgJ2F0IGxlYXN0IG9uZSBJRCBmaWVsZCAoZGV2aWNlVG9rZW4sIGluc3RhbGxhdGlvbklkKSAnICsgJ211c3QgYmUgc3BlY2lmaWVkIGluIHRoaXMgb3BlcmF0aW9uJ1xuICAgICk7XG4gIH1cblxuICAvLyBJZiB0aGUgZGV2aWNlIHRva2VuIGlzIDY0IGNoYXJhY3RlcnMgbG9uZywgd2UgYXNzdW1lIGl0IGlzIGZvciBpT1NcbiAgLy8gYW5kIGxvd2VyY2FzZSBpdC5cbiAgaWYgKHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJiB0aGlzLmRhdGEuZGV2aWNlVG9rZW4ubGVuZ3RoID09IDY0KSB7XG4gICAgdGhpcy5kYXRhLmRldmljZVRva2VuID0gdGhpcy5kYXRhLmRldmljZVRva2VuLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvLyBXZSBsb3dlcmNhc2UgdGhlIGluc3RhbGxhdGlvbklkIGlmIHByZXNlbnRcbiAgaWYgKHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgIHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCA9IHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZC50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgbGV0IGluc3RhbGxhdGlvbklkID0gdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkO1xuXG4gIC8vIElmIGRhdGEuaW5zdGFsbGF0aW9uSWQgaXMgbm90IHNldCBhbmQgd2UncmUgbm90IG1hc3Rlciwgd2UgY2FuIGxvb2t1cCBpbiBhdXRoXG4gIGlmICghaW5zdGFsbGF0aW9uSWQgJiYgIXRoaXMuYXV0aC5pc01hc3Rlcikge1xuICAgIGluc3RhbGxhdGlvbklkID0gdGhpcy5hdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG5cbiAgaWYgKGluc3RhbGxhdGlvbklkKSB7XG4gICAgaW5zdGFsbGF0aW9uSWQgPSBpbnN0YWxsYXRpb25JZC50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLy8gVXBkYXRpbmcgX0luc3RhbGxhdGlvbiBidXQgbm90IHVwZGF0aW5nIGFueXRoaW5nIGNyaXRpY2FsXG4gIGlmICh0aGlzLnF1ZXJ5ICYmICF0aGlzLmRhdGEuZGV2aWNlVG9rZW4gJiYgIWluc3RhbGxhdGlvbklkICYmICF0aGlzLmRhdGEuZGV2aWNlVHlwZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgdmFyIGlkTWF0Y2g7IC8vIFdpbGwgYmUgYSBtYXRjaCBvbiBlaXRoZXIgb2JqZWN0SWQgb3IgaW5zdGFsbGF0aW9uSWRcbiAgdmFyIG9iamVjdElkTWF0Y2g7XG4gIHZhciBpbnN0YWxsYXRpb25JZE1hdGNoO1xuICB2YXIgZGV2aWNlVG9rZW5NYXRjaGVzID0gW107XG5cbiAgLy8gSW5zdGVhZCBvZiBpc3N1aW5nIDMgcmVhZHMsIGxldCdzIGRvIGl0IHdpdGggb25lIE9SLlxuICBjb25zdCBvclF1ZXJpZXMgPSBbXTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIG9yUXVlcmllcy5wdXNoKHtcbiAgICAgIG9iamVjdElkOiB0aGlzLnF1ZXJ5Lm9iamVjdElkLFxuICAgIH0pO1xuICB9XG4gIGlmIChpbnN0YWxsYXRpb25JZCkge1xuICAgIG9yUXVlcmllcy5wdXNoKHtcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcbiAgfVxuICBpZiAodGhpcy5kYXRhLmRldmljZVRva2VuKSB7XG4gICAgb3JRdWVyaWVzLnB1c2goeyBkZXZpY2VUb2tlbjogdGhpcy5kYXRhLmRldmljZVRva2VuIH0pO1xuICB9XG5cbiAgaWYgKG9yUXVlcmllcy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByb21pc2UgPSBwcm9taXNlXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQoXG4gICAgICAgICdfSW5zdGFsbGF0aW9uJyxcbiAgICAgICAge1xuICAgICAgICAgICRvcjogb3JRdWVyaWVzLFxuICAgICAgICB9LFxuICAgICAgICB7fVxuICAgICAgKTtcbiAgICB9KVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQgJiYgcmVzdWx0Lm9iamVjdElkID09IHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgICBvYmplY3RJZE1hdGNoID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQuaW5zdGFsbGF0aW9uSWQgPT0gaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZE1hdGNoID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQuZGV2aWNlVG9rZW4gPT0gdGhpcy5kYXRhLmRldmljZVRva2VuKSB7XG4gICAgICAgICAgZGV2aWNlVG9rZW5NYXRjaGVzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNhbml0eSBjaGVja3Mgd2hlbiBydW5uaW5nIGEgcXVlcnlcbiAgICAgIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgaWYgKCFvYmplY3RJZE1hdGNoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kIGZvciB1cGRhdGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCAmJlxuICAgICAgICAgIG9iamVjdElkTWF0Y2guaW5zdGFsbGF0aW9uSWQgJiZcbiAgICAgICAgICB0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQgIT09IG9iamVjdElkTWF0Y2guaW5zdGFsbGF0aW9uSWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgJ2luc3RhbGxhdGlvbklkIG1heSBub3QgYmUgY2hhbmdlZCBpbiB0aGlzICcgKyAnb3BlcmF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJlxuICAgICAgICAgIG9iamVjdElkTWF0Y2guZGV2aWNlVG9rZW4gJiZcbiAgICAgICAgICB0aGlzLmRhdGEuZGV2aWNlVG9rZW4gIT09IG9iamVjdElkTWF0Y2guZGV2aWNlVG9rZW4gJiZcbiAgICAgICAgICAhdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkICYmXG4gICAgICAgICAgIW9iamVjdElkTWF0Y2guaW5zdGFsbGF0aW9uSWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgJ2RldmljZVRva2VuIG1heSBub3QgYmUgY2hhbmdlZCBpbiB0aGlzICcgKyAnb3BlcmF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUeXBlICYmXG4gICAgICAgICAgdGhpcy5kYXRhLmRldmljZVR5cGUgJiZcbiAgICAgICAgICB0aGlzLmRhdGEuZGV2aWNlVHlwZSAhPT0gb2JqZWN0SWRNYXRjaC5kZXZpY2VUeXBlXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxMzYsICdkZXZpY2VUeXBlIG1heSBub3QgYmUgY2hhbmdlZCBpbiB0aGlzICcgKyAnb3BlcmF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCAmJiBvYmplY3RJZE1hdGNoKSB7XG4gICAgICAgIGlkTWF0Y2ggPSBvYmplY3RJZE1hdGNoO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5zdGFsbGF0aW9uSWQgJiYgaW5zdGFsbGF0aW9uSWRNYXRjaCkge1xuICAgICAgICBpZE1hdGNoID0gaW5zdGFsbGF0aW9uSWRNYXRjaDtcbiAgICAgIH1cbiAgICAgIC8vIG5lZWQgdG8gc3BlY2lmeSBkZXZpY2VUeXBlIG9ubHkgaWYgaXQncyBuZXdcbiAgICAgIGlmICghdGhpcy5xdWVyeSAmJiAhdGhpcy5kYXRhLmRldmljZVR5cGUgJiYgIWlkTWF0Y2gpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNSwgJ2RldmljZVR5cGUgbXVzdCBiZSBzcGVjaWZpZWQgaW4gdGhpcyBvcGVyYXRpb24nKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGlmICghaWRNYXRjaCkge1xuICAgICAgICBpZiAoIWRldmljZVRva2VuTWF0Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgZGV2aWNlVG9rZW5NYXRjaGVzLmxlbmd0aCA9PSAxICYmXG4gICAgICAgICAgKCFkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ2luc3RhbGxhdGlvbklkJ10gfHwgIWluc3RhbGxhdGlvbklkKVxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBTaW5nbGUgbWF0Y2ggb24gZGV2aWNlIHRva2VuIGJ1dCBub25lIG9uIGluc3RhbGxhdGlvbklkLCBhbmQgZWl0aGVyXG4gICAgICAgICAgLy8gdGhlIHBhc3NlZCBvYmplY3Qgb3IgdGhlIG1hdGNoIGlzIG1pc3NpbmcgYW4gaW5zdGFsbGF0aW9uSWQsIHNvIHdlXG4gICAgICAgICAgLy8gY2FuIGp1c3QgcmV0dXJuIHRoZSBtYXRjaC5cbiAgICAgICAgICByZXR1cm4gZGV2aWNlVG9rZW5NYXRjaGVzWzBdWydvYmplY3RJZCddO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAxMzIsXG4gICAgICAgICAgICAnTXVzdCBzcGVjaWZ5IGluc3RhbGxhdGlvbklkIHdoZW4gZGV2aWNlVG9rZW4gJyArXG4gICAgICAgICAgICAgICdtYXRjaGVzIG11bHRpcGxlIEluc3RhbGxhdGlvbiBvYmplY3RzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTXVsdGlwbGUgZGV2aWNlIHRva2VuIG1hdGNoZXMgYW5kIHdlIHNwZWNpZmllZCBhbiBpbnN0YWxsYXRpb24gSUQsXG4gICAgICAgICAgLy8gb3IgYSBzaW5nbGUgbWF0Y2ggd2hlcmUgYm90aCB0aGUgcGFzc2VkIGFuZCBtYXRjaGluZyBvYmplY3RzIGhhdmVcbiAgICAgICAgICAvLyBhbiBpbnN0YWxsYXRpb24gSUQuIFRyeSBjbGVhbmluZyBvdXQgb2xkIGluc3RhbGxhdGlvbnMgdGhhdCBtYXRjaFxuICAgICAgICAgIC8vIHRoZSBkZXZpY2VUb2tlbiwgYW5kIHJldHVybiBuaWwgdG8gc2lnbmFsIHRoYXQgYSBuZXcgb2JqZWN0IHNob3VsZFxuICAgICAgICAgIC8vIGJlIGNyZWF0ZWQuXG4gICAgICAgICAgdmFyIGRlbFF1ZXJ5ID0ge1xuICAgICAgICAgICAgZGV2aWNlVG9rZW46IHRoaXMuZGF0YS5kZXZpY2VUb2tlbixcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiB7XG4gICAgICAgICAgICAgICRuZTogaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHRoaXMuZGF0YS5hcHBJZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBkZWxRdWVyeVsnYXBwSWRlbnRpZmllciddID0gdGhpcy5kYXRhLmFwcElkZW50aWZpZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koJ19JbnN0YWxsYXRpb24nLCBkZWxRdWVyeSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICAgIC8vIG5vIGRlbGV0aW9ucyB3ZXJlIG1hZGUuIENhbiBiZSBpZ25vcmVkLlxuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByZXRocm93IHRoZSBlcnJvclxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRldmljZVRva2VuTWF0Y2hlcy5sZW5ndGggPT0gMSAmJiAhZGV2aWNlVG9rZW5NYXRjaGVzWzBdWydpbnN0YWxsYXRpb25JZCddKSB7XG4gICAgICAgICAgLy8gRXhhY3RseSBvbmUgZGV2aWNlIHRva2VuIG1hdGNoIGFuZCBpdCBkb2Vzbid0IGhhdmUgYW4gaW5zdGFsbGF0aW9uXG4gICAgICAgICAgLy8gSUQuIFRoaXMgaXMgdGhlIG9uZSBjYXNlIHdoZXJlIHdlIHdhbnQgdG8gbWVyZ2Ugd2l0aCB0aGUgZXhpc3RpbmdcbiAgICAgICAgICAvLyBvYmplY3QuXG4gICAgICAgICAgY29uc3QgZGVsUXVlcnkgPSB7IG9iamVjdElkOiBpZE1hdGNoLm9iamVjdElkIH07XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgICAgICAuZGVzdHJveSgnX0luc3RhbGxhdGlvbicsIGRlbFF1ZXJ5KVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlVG9rZW5NYXRjaGVzWzBdWydvYmplY3RJZCddO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICAgICAgICAgIC8vIG5vIGRlbGV0aW9ucyB3ZXJlIG1hZGUuIENhbiBiZSBpZ25vcmVkXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIHJldGhyb3cgdGhlIGVycm9yXG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmRhdGEuZGV2aWNlVG9rZW4gJiYgaWRNYXRjaC5kZXZpY2VUb2tlbiAhPSB0aGlzLmRhdGEuZGV2aWNlVG9rZW4pIHtcbiAgICAgICAgICAgIC8vIFdlJ3JlIHNldHRpbmcgdGhlIGRldmljZSB0b2tlbiBvbiBhbiBleGlzdGluZyBpbnN0YWxsYXRpb24sIHNvXG4gICAgICAgICAgICAvLyB3ZSBzaG91bGQgdHJ5IGNsZWFuaW5nIG91dCBvbGQgaW5zdGFsbGF0aW9ucyB0aGF0IG1hdGNoIHRoaXNcbiAgICAgICAgICAgIC8vIGRldmljZSB0b2tlbi5cbiAgICAgICAgICAgIGNvbnN0IGRlbFF1ZXJ5ID0ge1xuICAgICAgICAgICAgICBkZXZpY2VUb2tlbjogdGhpcy5kYXRhLmRldmljZVRva2VuLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFdlIGhhdmUgYSB1bmlxdWUgaW5zdGFsbCBJZCwgdXNlIHRoYXQgdG8gcHJlc2VydmVcbiAgICAgICAgICAgIC8vIHRoZSBpbnRlcmVzdGluZyBpbnN0YWxsYXRpb25cbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgICAgICAgZGVsUXVlcnlbJ2luc3RhbGxhdGlvbklkJ10gPSB7XG4gICAgICAgICAgICAgICAgJG5lOiB0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICBpZE1hdGNoLm9iamVjdElkICYmXG4gICAgICAgICAgICAgIHRoaXMuZGF0YS5vYmplY3RJZCAmJlxuICAgICAgICAgICAgICBpZE1hdGNoLm9iamVjdElkID09IHRoaXMuZGF0YS5vYmplY3RJZFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIC8vIHdlIHBhc3NlZCBhbiBvYmplY3RJZCwgcHJlc2VydmUgdGhhdCBpbnN0YWxhdGlvblxuICAgICAgICAgICAgICBkZWxRdWVyeVsnb2JqZWN0SWQnXSA9IHtcbiAgICAgICAgICAgICAgICAkbmU6IGlkTWF0Y2gub2JqZWN0SWQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBXaGF0IHRvIGRvIGhlcmU/IGNhbid0IHJlYWxseSBjbGVhbiB1cCBldmVyeXRoaW5nLi4uXG4gICAgICAgICAgICAgIHJldHVybiBpZE1hdGNoLm9iamVjdElkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5hcHBJZGVudGlmaWVyKSB7XG4gICAgICAgICAgICAgIGRlbFF1ZXJ5WydhcHBJZGVudGlmaWVyJ10gPSB0aGlzLmRhdGEuYXBwSWRlbnRpZmllcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koJ19JbnN0YWxsYXRpb24nLCBkZWxRdWVyeSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAgICAgICAvLyBubyBkZWxldGlvbnMgd2VyZSBtYWRlLiBDYW4gYmUgaWdub3JlZC5cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gcmV0aHJvdyB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEluIG5vbi1tZXJnZSBzY2VuYXJpb3MsIGp1c3QgcmV0dXJuIHRoZSBpbnN0YWxsYXRpb24gbWF0Y2ggaWRcbiAgICAgICAgICByZXR1cm4gaWRNYXRjaC5vYmplY3RJZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4ob2JqSWQgPT4ge1xuICAgICAgaWYgKG9iaklkKSB7XG4gICAgICAgIHRoaXMucXVlcnkgPSB7IG9iamVjdElkOiBvYmpJZCB9O1xuICAgICAgICBkZWxldGUgdGhpcy5kYXRhLm9iamVjdElkO1xuICAgICAgICBkZWxldGUgdGhpcy5kYXRhLmNyZWF0ZWRBdDtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE86IFZhbGlkYXRlIG9wcyAoYWRkL3JlbW92ZSBvbiBjaGFubmVscywgJGluYyBvbiBiYWRnZSwgZXRjLilcbiAgICB9KTtcbiAgcmV0dXJuIHByb21pc2U7XG59O1xuXG4vLyBJZiB3ZSBzaG9ydC1jaXJjdXRlZCB0aGUgb2JqZWN0IHJlc3BvbnNlIC0gdGhlbiB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB3ZSBleHBhbmQgYWxsIHRoZSBmaWxlcyxcbi8vIHNpbmNlIHRoaXMgbWlnaHQgbm90IGhhdmUgYSBxdWVyeSwgbWVhbmluZyBpdCB3b24ndCByZXR1cm4gdGhlIGZ1bGwgcmVzdWx0IGJhY2suXG4vLyBUT0RPOiAobmx1dHNlbmtvKSBUaGlzIHNob3VsZCBkaWUgd2hlbiB3ZSBtb3ZlIHRvIHBlci1jbGFzcyBiYXNlZCBjb250cm9sbGVycyBvbiBfU2Vzc2lvbi9fVXNlclxuUmVzdFdyaXRlLnByb3RvdHlwZS5leHBhbmRGaWxlc0ZvckV4aXN0aW5nT2JqZWN0cyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gQ2hlY2sgd2hldGhlciB3ZSBoYXZlIGEgc2hvcnQtY2lyY3VpdGVkIHJlc3BvbnNlIC0gb25seSB0aGVuIHJ1biBleHBhbnNpb24uXG4gIGlmICh0aGlzLnJlc3BvbnNlICYmIHRoaXMucmVzcG9uc2UucmVzcG9uc2UpIHtcbiAgICB0aGlzLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdCh0aGlzLmNvbmZpZywgdGhpcy5yZXNwb25zZS5yZXNwb25zZSk7XG4gIH1cbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUucnVuRGF0YWJhc2VPcGVyYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlc3BvbnNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1JvbGUnKSB7XG4gICAgdGhpcy5jb25maWcuY2FjaGVDb250cm9sbGVyLnJvbGUuY2xlYXIoKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiB0aGlzLnF1ZXJ5ICYmIHRoaXMuYXV0aC5pc1VuYXV0aGVudGljYXRlZCgpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuU0VTU0lPTl9NSVNTSU5HLFxuICAgICAgYENhbm5vdCBtb2RpZnkgdXNlciAke3RoaXMucXVlcnkub2JqZWN0SWR9LmBcbiAgICApO1xuICB9XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1Byb2R1Y3QnICYmIHRoaXMuZGF0YS5kb3dubG9hZCkge1xuICAgIHRoaXMuZGF0YS5kb3dubG9hZE5hbWUgPSB0aGlzLmRhdGEuZG93bmxvYWQubmFtZTtcbiAgfVxuXG4gIC8vIFRPRE86IEFkZCBiZXR0ZXIgZGV0ZWN0aW9uIGZvciBBQ0wsIGVuc3VyaW5nIGEgdXNlciBjYW4ndCBiZSBsb2NrZWQgZnJvbVxuICAvLyAgICAgICB0aGVpciBvd24gdXNlciByZWNvcmQuXG4gIGlmICh0aGlzLmRhdGEuQUNMICYmIHRoaXMuZGF0YS5BQ0xbJyp1bnJlc29sdmVkJ10pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9BQ0wsICdJbnZhbGlkIEFDTC4nKTtcbiAgfVxuXG4gIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgLy8gRm9yY2UgdGhlIHVzZXIgdG8gbm90IGxvY2tvdXRcbiAgICAvLyBNYXRjaGVkIHdpdGggcGFyc2UuY29tXG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmIHRoaXMuZGF0YS5BQ0wgJiYgdGhpcy5hdXRoLmlzTWFzdGVyICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLmRhdGEuQUNMW3RoaXMucXVlcnkub2JqZWN0SWRdID0geyByZWFkOiB0cnVlLCB3cml0ZTogdHJ1ZSB9O1xuICAgIH1cbiAgICAvLyB1cGRhdGUgcGFzc3dvcmQgdGltZXN0YW1wIGlmIHVzZXIgcGFzc3dvcmQgaXMgYmVpbmcgY2hhbmdlZFxuICAgIGlmIChcbiAgICAgIHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgICB0aGlzLmRhdGEuX2hhc2hlZF9wYXNzd29yZCAmJlxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlXG4gICAgKSB7XG4gICAgICB0aGlzLmRhdGEuX3Bhc3N3b3JkX2NoYW5nZWRfYXQgPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpO1xuICAgIH1cbiAgICAvLyBJZ25vcmUgY3JlYXRlZEF0IHdoZW4gdXBkYXRlXG4gICAgZGVsZXRlIHRoaXMuZGF0YS5jcmVhdGVkQXQ7XG5cbiAgICBsZXQgZGVmZXIgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAvLyBpZiBwYXNzd29yZCBoaXN0b3J5IGlzIGVuYWJsZWQgdGhlbiBzYXZlIHRoZSBjdXJyZW50IHBhc3N3b3JkIHRvIGhpc3RvcnlcbiAgICBpZiAoXG4gICAgICB0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJlxuICAgICAgdGhpcy5kYXRhLl9oYXNoZWRfcGFzc3dvcmQgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnlcbiAgICApIHtcbiAgICAgIGRlZmVyID0gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgLmZpbmQoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7IG9iamVjdElkOiB0aGlzLm9iamVjdElkKCkgfSxcbiAgICAgICAgICB7IGtleXM6IFsnX3Bhc3N3b3JkX2hpc3RvcnknLCAnX2hhc2hlZF9wYXNzd29yZCddIH1cbiAgICAgICAgKVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgICBsZXQgb2xkUGFzc3dvcmRzID0gW107XG4gICAgICAgICAgaWYgKHVzZXIuX3Bhc3N3b3JkX2hpc3RvcnkpIHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3JkcyA9IF8udGFrZShcbiAgICAgICAgICAgICAgdXNlci5fcGFzc3dvcmRfaGlzdG9yeSxcbiAgICAgICAgICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvL24tMSBwYXNzd29yZHMgZ28gaW50byBoaXN0b3J5IGluY2x1ZGluZyBsYXN0IHBhc3N3b3JkXG4gICAgICAgICAgd2hpbGUgKFxuICAgICAgICAgICAgb2xkUGFzc3dvcmRzLmxlbmd0aCA+IE1hdGgubWF4KDAsIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSAtIDIpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBvbGRQYXNzd29yZHMuc2hpZnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2xkUGFzc3dvcmRzLnB1c2godXNlci5wYXNzd29yZCk7XG4gICAgICAgICAgdGhpcy5kYXRhLl9wYXNzd29yZF9oaXN0b3J5ID0gb2xkUGFzc3dvcmRzO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVmZXIudGhlbigoKSA9PiB7XG4gICAgICAvLyBSdW4gYW4gdXBkYXRlXG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgLnVwZGF0ZShcbiAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICB0aGlzLnF1ZXJ5LFxuICAgICAgICAgIHRoaXMuZGF0YSxcbiAgICAgICAgICB0aGlzLnJ1bk9wdGlvbnMsXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXJcbiAgICAgICAgKVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgcmVzcG9uc2UudXBkYXRlZEF0ID0gdGhpcy51cGRhdGVkQXQ7XG4gICAgICAgICAgdGhpcy5fdXBkYXRlUmVzcG9uc2VXaXRoRGF0YShyZXNwb25zZSwgdGhpcy5kYXRhKTtcbiAgICAgICAgICB0aGlzLnJlc3BvbnNlID0geyByZXNwb25zZSB9O1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBTZXQgdGhlIGRlZmF1bHQgQUNMIGFuZCBwYXNzd29yZCB0aW1lc3RhbXAgZm9yIHRoZSBuZXcgX1VzZXJcbiAgICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgIHZhciBBQ0wgPSB0aGlzLmRhdGEuQUNMO1xuICAgICAgLy8gZGVmYXVsdCBwdWJsaWMgci93IEFDTFxuICAgICAgaWYgKCFBQ0wpIHtcbiAgICAgICAgQUNMID0ge307XG4gICAgICAgIEFDTFsnKiddID0geyByZWFkOiB0cnVlLCB3cml0ZTogZmFsc2UgfTtcbiAgICAgIH1cbiAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgdXNlciBpcyBub3QgbG9ja2VkIGRvd25cbiAgICAgIEFDTFt0aGlzLmRhdGEub2JqZWN0SWRdID0geyByZWFkOiB0cnVlLCB3cml0ZTogdHJ1ZSB9O1xuICAgICAgdGhpcy5kYXRhLkFDTCA9IEFDTDtcbiAgICAgIC8vIHBhc3N3b3JkIHRpbWVzdGFtcCB0byBiZSB1c2VkIHdoZW4gcGFzc3dvcmQgZXhwaXJ5IHBvbGljeSBpcyBlbmZvcmNlZFxuICAgICAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlKSB7XG4gICAgICAgIHRoaXMuZGF0YS5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUnVuIGEgY3JlYXRlXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuY3JlYXRlKHRoaXMuY2xhc3NOYW1lLCB0aGlzLmRhdGEsIHRoaXMucnVuT3B0aW9ucywgZmFsc2UsIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInIHx8IGVycm9yLmNvZGUgIT09IFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUXVpY2sgY2hlY2ssIGlmIHdlIHdlcmUgYWJsZSB0byBpbmZlciB0aGUgZHVwbGljYXRlZCBmaWVsZCBuYW1lXG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci51c2VySW5mbyAmJiBlcnJvci51c2VySW5mby5kdXBsaWNhdGVkX2ZpZWxkID09PSAndXNlcm5hbWUnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuVVNFUk5BTUVfVEFLRU4sXG4gICAgICAgICAgICAnQWNjb3VudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyB1c2VybmFtZS4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci51c2VySW5mbyAmJiBlcnJvci51c2VySW5mby5kdXBsaWNhdGVkX2ZpZWxkID09PSAnZW1haWwnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRU1BSUxfVEFLRU4sXG4gICAgICAgICAgICAnQWNjb3VudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyBlbWFpbCBhZGRyZXNzLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhpcyB3YXMgYSBmYWlsZWQgdXNlciBjcmVhdGlvbiBkdWUgdG8gdXNlcm5hbWUgb3IgZW1haWwgYWxyZWFkeSB0YWtlbiwgd2UgbmVlZCB0b1xuICAgICAgICAvLyBjaGVjayB3aGV0aGVyIGl0IHdhcyB1c2VybmFtZSBvciBlbWFpbCBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBlcnJvci5cbiAgICAgICAgLy8gRmFsbGJhY2sgdG8gdGhlIG9yaWdpbmFsIG1ldGhvZFxuICAgICAgICAvLyBUT0RPOiBTZWUgaWYgd2UgY2FuIGxhdGVyIGRvIHRoaXMgd2l0aG91dCBhZGRpdGlvbmFsIHF1ZXJpZXMgYnkgdXNpbmcgbmFtZWQgaW5kZXhlcy5cbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgICAgLmZpbmQoXG4gICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdXNlcm5hbWU6IHRoaXMuZGF0YS51c2VybmFtZSxcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IHsgJG5lOiB0aGlzLm9iamVjdElkKCkgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IGxpbWl0OiAxIH1cbiAgICAgICAgICApXG4gICAgICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5VU0VSTkFNRV9UQUtFTixcbiAgICAgICAgICAgICAgICAnQWNjb3VudCBhbHJlYWR5IGV4aXN0cyBmb3IgdGhpcyB1c2VybmFtZS4nXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgIHsgZW1haWw6IHRoaXMuZGF0YS5lbWFpbCwgb2JqZWN0SWQ6IHsgJG5lOiB0aGlzLm9iamVjdElkKCkgfSB9LFxuICAgICAgICAgICAgICB7IGxpbWl0OiAxIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLkVNQUlMX1RBS0VOLFxuICAgICAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVtYWlsIGFkZHJlc3MuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJlc3BvbnNlLm9iamVjdElkID0gdGhpcy5kYXRhLm9iamVjdElkO1xuICAgICAgICByZXNwb25zZS5jcmVhdGVkQXQgPSB0aGlzLmRhdGEuY3JlYXRlZEF0O1xuXG4gICAgICAgIGlmICh0aGlzLnJlc3BvbnNlU2hvdWxkSGF2ZVVzZXJuYW1lKSB7XG4gICAgICAgICAgcmVzcG9uc2UudXNlcm5hbWUgPSB0aGlzLmRhdGEudXNlcm5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlUmVzcG9uc2VXaXRoRGF0YShyZXNwb25zZSwgdGhpcy5kYXRhKTtcbiAgICAgICAgdGhpcy5yZXNwb25zZSA9IHtcbiAgICAgICAgICBzdGF0dXM6IDIwMSxcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbigpLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cbn07XG5cbi8vIFJldHVybnMgbm90aGluZyAtIGRvZXNuJ3Qgd2FpdCBmb3IgdGhlIHRyaWdnZXIuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkFmdGVyU2F2ZVRyaWdnZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5yZXNwb25zZSB8fCAhdGhpcy5yZXNwb25zZS5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2FmdGVyU2F2ZScgdHJpZ2dlciBmb3IgdGhpcyBjbGFzcy5cbiAgY29uc3QgaGFzQWZ0ZXJTYXZlSG9vayA9IHRyaWdnZXJzLnRyaWdnZXJFeGlzdHMoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlLFxuICAgIHRoaXMuY29uZmlnLmFwcGxpY2F0aW9uSWRcbiAgKTtcbiAgY29uc3QgaGFzTGl2ZVF1ZXJ5ID0gdGhpcy5jb25maWcubGl2ZVF1ZXJ5Q29udHJvbGxlci5oYXNMaXZlUXVlcnkodGhpcy5jbGFzc05hbWUpO1xuICBpZiAoIWhhc0FmdGVyU2F2ZUhvb2sgJiYgIWhhc0xpdmVRdWVyeSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIHZhciBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIGV4dHJhRGF0YS5vYmplY3RJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gIH1cblxuICAvLyBCdWlsZCB0aGUgb3JpZ2luYWwgb2JqZWN0LCB3ZSBvbmx5IGRvIHRoaXMgZm9yIGEgdXBkYXRlIHdyaXRlLlxuICBsZXQgb3JpZ2luYWxPYmplY3Q7XG4gIGlmICh0aGlzLnF1ZXJ5ICYmIHRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICBvcmlnaW5hbE9iamVjdCA9IHRyaWdnZXJzLmluZmxhdGUoZXh0cmFEYXRhLCB0aGlzLm9yaWdpbmFsRGF0YSk7XG4gIH1cblxuICAvLyBCdWlsZCB0aGUgaW5mbGF0ZWQgb2JqZWN0LCBkaWZmZXJlbnQgZnJvbSBiZWZvcmVTYXZlLCBvcmlnaW5hbERhdGEgaXMgbm90IGVtcHR5XG4gIC8vIHNpbmNlIGRldmVsb3BlcnMgY2FuIGNoYW5nZSBkYXRhIGluIHRoZSBiZWZvcmVTYXZlLlxuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdGhpcy5idWlsZFVwZGF0ZWRPYmplY3QoZXh0cmFEYXRhKTtcbiAgdXBkYXRlZE9iamVjdC5faGFuZGxlU2F2ZVJlc3BvbnNlKHRoaXMucmVzcG9uc2UucmVzcG9uc2UsIHRoaXMucmVzcG9uc2Uuc3RhdHVzIHx8IDIwMCk7XG5cbiAgdGhpcy5jb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSgpLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiB7XG4gICAgLy8gTm90aWZpeSBMaXZlUXVlcnlTZXJ2ZXIgaWYgcG9zc2libGVcbiAgICBjb25zdCBwZXJtcyA9IHNjaGVtYUNvbnRyb2xsZXIuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKHVwZGF0ZWRPYmplY3QuY2xhc3NOYW1lKTtcbiAgICB0aGlzLmNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLm9uQWZ0ZXJTYXZlKFxuICAgICAgdXBkYXRlZE9iamVjdC5jbGFzc05hbWUsXG4gICAgICB1cGRhdGVkT2JqZWN0LFxuICAgICAgb3JpZ2luYWxPYmplY3QsXG4gICAgICBwZXJtc1xuICAgICk7XG4gIH0pO1xuXG4gIC8vIFJ1biBhZnRlclNhdmUgdHJpZ2dlclxuICByZXR1cm4gdHJpZ2dlcnNcbiAgICAubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlLFxuICAgICAgdGhpcy5hdXRoLFxuICAgICAgdXBkYXRlZE9iamVjdCxcbiAgICAgIG9yaWdpbmFsT2JqZWN0LFxuICAgICAgdGhpcy5jb25maWcsXG4gICAgICB0aGlzLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGlmIChyZXN1bHQgJiYgdHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZXNwb25zZSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBsb2dnZXIud2FybignYWZ0ZXJTYXZlIGNhdWdodCBhbiBlcnJvcicsIGVycik7XG4gICAgfSk7XG59O1xuXG4vLyBBIGhlbHBlciB0byBmaWd1cmUgb3V0IHdoYXQgbG9jYXRpb24gdGhpcyBvcGVyYXRpb24gaGFwcGVucyBhdC5cblJlc3RXcml0ZS5wcm90b3R5cGUubG9jYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBtaWRkbGUgPSB0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyA/ICcvdXNlcnMvJyA6ICcvY2xhc3Nlcy8nICsgdGhpcy5jbGFzc05hbWUgKyAnLyc7XG4gIGNvbnN0IG1vdW50ID0gdGhpcy5jb25maWcubW91bnQgfHwgdGhpcy5jb25maWcuc2VydmVyVVJMO1xuICByZXR1cm4gbW91bnQgKyBtaWRkbGUgKyB0aGlzLmRhdGEub2JqZWN0SWQ7XG59O1xuXG4vLyBBIGhlbHBlciB0byBnZXQgdGhlIG9iamVjdCBpZCBmb3IgdGhpcyBvcGVyYXRpb24uXG4vLyBCZWNhdXNlIGl0IGNvdWxkIGJlIGVpdGhlciBvbiB0aGUgcXVlcnkgb3Igb24gdGhlIGRhdGFcblJlc3RXcml0ZS5wcm90b3R5cGUub2JqZWN0SWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLmRhdGEub2JqZWN0SWQgfHwgdGhpcy5xdWVyeS5vYmplY3RJZDtcbn07XG5cbi8vIFJldHVybnMgYSBjb3B5IG9mIHRoZSBkYXRhIGFuZCBkZWxldGUgYmFkIGtleXMgKF9hdXRoX2RhdGEsIF9oYXNoZWRfcGFzc3dvcmQuLi4pXG5SZXN0V3JpdGUucHJvdG90eXBlLnNhbml0aXplZERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGRhdGEgPSBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLnJlZHVjZSgoZGF0YSwga2V5KSA9PiB7XG4gICAgLy8gUmVnZXhwIGNvbWVzIGZyb20gUGFyc2UuT2JqZWN0LnByb3RvdHlwZS52YWxpZGF0ZVxuICAgIGlmICghL15bQS1aYS16XVswLTlBLVphLXpfXSokLy50ZXN0KGtleSkpIHtcbiAgICAgIGRlbGV0ZSBkYXRhW2tleV07XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9LCBkZWVwY29weSh0aGlzLmRhdGEpKTtcbiAgcmV0dXJuIFBhcnNlLl9kZWNvZGUodW5kZWZpbmVkLCBkYXRhKTtcbn07XG5cbi8vIFJldHVybnMgYW4gdXBkYXRlZCBjb3B5IG9mIHRoZSBvYmplY3RcblJlc3RXcml0ZS5wcm90b3R5cGUuYnVpbGRVcGRhdGVkT2JqZWN0ID0gZnVuY3Rpb24gKGV4dHJhRGF0YSkge1xuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdHJpZ2dlcnMuaW5mbGF0ZShleHRyYURhdGEsIHRoaXMub3JpZ2luYWxEYXRhKTtcbiAgT2JqZWN0LmtleXModGhpcy5kYXRhKS5yZWR1Y2UoZnVuY3Rpb24gKGRhdGEsIGtleSkge1xuICAgIGlmIChrZXkuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgLy8gc3ViZG9jdW1lbnQga2V5IHdpdGggZG90IG5vdGF0aW9uICgneC55Jzp2ID0+ICd4Jzp7J3knOnZ9KVxuICAgICAgY29uc3Qgc3BsaXR0ZWRLZXkgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICAgIGNvbnN0IHBhcmVudFByb3AgPSBzcGxpdHRlZEtleVswXTtcbiAgICAgIGxldCBwYXJlbnRWYWwgPSB1cGRhdGVkT2JqZWN0LmdldChwYXJlbnRQcm9wKTtcbiAgICAgIGlmICh0eXBlb2YgcGFyZW50VmFsICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBwYXJlbnRWYWwgPSB7fTtcbiAgICAgIH1cbiAgICAgIHBhcmVudFZhbFtzcGxpdHRlZEtleVsxXV0gPSBkYXRhW2tleV07XG4gICAgICB1cGRhdGVkT2JqZWN0LnNldChwYXJlbnRQcm9wLCBwYXJlbnRWYWwpO1xuICAgICAgZGVsZXRlIGRhdGFba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0sIGRlZXBjb3B5KHRoaXMuZGF0YSkpO1xuXG4gIHVwZGF0ZWRPYmplY3Quc2V0KHRoaXMuc2FuaXRpemVkRGF0YSgpKTtcbiAgcmV0dXJuIHVwZGF0ZWRPYmplY3Q7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmNsZWFuVXNlckF1dGhEYXRhID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSAmJiB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlICYmIHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgY29uc3QgdXNlciA9IHRoaXMucmVzcG9uc2UucmVzcG9uc2U7XG4gICAgaWYgKHVzZXIuYXV0aERhdGEpIHtcbiAgICAgIE9iamVjdC5rZXlzKHVzZXIuYXV0aERhdGEpLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgICAgICBpZiAodXNlci5hdXRoRGF0YVtwcm92aWRlcl0gPT09IG51bGwpIHtcbiAgICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHVzZXIuYXV0aERhdGEpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGRlbGV0ZSB1c2VyLmF1dGhEYXRhO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5fdXBkYXRlUmVzcG9uc2VXaXRoRGF0YSA9IGZ1bmN0aW9uIChyZXNwb25zZSwgZGF0YSkge1xuICBpZiAoXy5pc0VtcHR5KHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyKSkge1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuICBjb25zdCBjbGllbnRTdXBwb3J0c0RlbGV0ZSA9IENsaWVudFNESy5zdXBwb3J0c0ZvcndhcmREZWxldGUodGhpcy5jbGllbnRTREspO1xuICB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgY29uc3QgZGF0YVZhbHVlID0gZGF0YVtmaWVsZE5hbWVdO1xuXG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzcG9uc2UsIGZpZWxkTmFtZSkpIHtcbiAgICAgIHJlc3BvbnNlW2ZpZWxkTmFtZV0gPSBkYXRhVmFsdWU7XG4gICAgfVxuXG4gICAgLy8gU3RyaXBzIG9wZXJhdGlvbnMgZnJvbSByZXNwb25zZXNcbiAgICBpZiAocmVzcG9uc2VbZmllbGROYW1lXSAmJiByZXNwb25zZVtmaWVsZE5hbWVdLl9fb3ApIHtcbiAgICAgIGRlbGV0ZSByZXNwb25zZVtmaWVsZE5hbWVdO1xuICAgICAgaWYgKGNsaWVudFN1cHBvcnRzRGVsZXRlICYmIGRhdGFWYWx1ZS5fX29wID09ICdEZWxldGUnKSB7XG4gICAgICAgIHJlc3BvbnNlW2ZpZWxkTmFtZV0gPSBkYXRhVmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3BvbnNlO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgUmVzdFdyaXRlO1xubW9kdWxlLmV4cG9ydHMgPSBSZXN0V3JpdGU7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/AggregateRouter.js b/lib/Routers/AggregateRouter.js deleted file mode 100644 index 7cd8518618..0000000000 --- a/lib/Routers/AggregateRouter.js +++ /dev/null @@ -1,153 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AggregateRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _UsersRouter = _interopRequireDefault(require("./UsersRouter")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const BASE_KEYS = ['where', 'distinct', 'pipeline', 'hint', 'explain']; -const PIPELINE_KEYS = ['addFields', 'bucket', 'bucketAuto', 'collStats', 'count', 'currentOp', 'facet', 'geoNear', 'graphLookup', 'group', 'indexStats', 'limit', 'listLocalSessions', 'listSessions', 'lookup', 'match', 'out', 'project', 'redact', 'replaceRoot', 'sample', 'skip', 'sort', 'sortByCount', 'unwind']; -const ALLOWED_KEYS = [...BASE_KEYS, ...PIPELINE_KEYS]; - -class AggregateRouter extends _ClassesRouter.default { - handleFind(req) { - const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); - const options = {}; - - if (body.distinct) { - options.distinct = String(body.distinct); - } - - if (body.hint) { - options.hint = body.hint; - delete body.hint; - } - - if (body.explain) { - options.explain = body.explain; - delete body.explain; - } - - if (body.readPreference) { - options.readPreference = body.readPreference; - delete body.readPreference; - } - - options.pipeline = AggregateRouter.getPipeline(body); - - if (typeof body.where === 'string') { - body.where = JSON.parse(body.where); - } - - return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { - for (const result of response.results) { - if (typeof result === 'object') { - _UsersRouter.default.removeHiddenProperties(result); - } - } - - return { - response - }; - }); - } - /* Builds a pipeline from the body. Originally the body could be passed as a single object, - * and now we support many options - * - * Array - * - * body: [{ - * group: { objectId: '$name' }, - * }] - * - * Object - * - * body: { - * group: { objectId: '$name' }, - * } - * - * - * Pipeline Operator with an Array or an Object - * - * body: { - * pipeline: { - * group: { objectId: '$name' }, - * } - * } - * - */ - - - static getPipeline(body) { - let pipeline = body.pipeline || body; - - if (!Array.isArray(pipeline)) { - pipeline = Object.keys(pipeline).map(key => { - return { - [key]: pipeline[key] - }; - }); - } - - return pipeline.map(stage => { - const keys = Object.keys(stage); - - if (keys.length != 1) { - throw new Error(`Pipeline stages should only have one key found ${keys.join(', ')}`); - } - - return AggregateRouter.transformStage(keys[0], stage); - }); - } - - static transformStage(stageName, stage) { - if (ALLOWED_KEYS.indexOf(stageName) === -1) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${stageName}`); - } - - if (stageName === 'group') { - if (Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. Please use objectId instead of _id`); - } - - if (!Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. objectId is required`); - } - - stage[stageName]._id = stage[stageName].objectId; - delete stage[stageName].objectId; - } - - return { - [`$${stageName}`]: stage[stageName] - }; - } - - mountRoutes() { - this.route('GET', '/aggregate/:className', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleFind(req); - }); - } - -} - -exports.AggregateRouter = AggregateRouter; -var _default = AggregateRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJCQVNFX0tFWVMiLCJQSVBFTElORV9LRVlTIiwiQUxMT1dFRF9LRVlTIiwiQWdncmVnYXRlUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImhhbmRsZUZpbmQiLCJyZXEiLCJib2R5IiwiT2JqZWN0IiwiYXNzaWduIiwiSlNPTkZyb21RdWVyeSIsInF1ZXJ5Iiwib3B0aW9ucyIsImRpc3RpbmN0IiwiU3RyaW5nIiwiaGludCIsImV4cGxhaW4iLCJyZWFkUHJlZmVyZW5jZSIsInBpcGVsaW5lIiwiZ2V0UGlwZWxpbmUiLCJ3aGVyZSIsIkpTT04iLCJwYXJzZSIsInJlc3QiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsImNsYXNzTmFtZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0IiwicmVzdWx0cyIsIlVzZXJzUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsIkFycmF5IiwiaXNBcnJheSIsImtleXMiLCJtYXAiLCJrZXkiLCJzdGFnZSIsImxlbmd0aCIsIkVycm9yIiwiam9pbiIsInRyYW5zZm9ybVN0YWdlIiwic3RhZ2VOYW1lIiwiaW5kZXhPZiIsIlBhcnNlIiwiSU5WQUxJRF9RVUVSWSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9pZCIsIm9iamVjdElkIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFNBQVMsR0FBRyxDQUFDLE9BQUQsRUFBVSxVQUFWLEVBQXNCLFVBQXRCLEVBQWtDLE1BQWxDLEVBQTBDLFNBQTFDLENBQWxCO0FBRUEsTUFBTUMsYUFBYSxHQUFHLENBQ3BCLFdBRG9CLEVBRXBCLFFBRm9CLEVBR3BCLFlBSG9CLEVBSXBCLFdBSm9CLEVBS3BCLE9BTG9CLEVBTXBCLFdBTm9CLEVBT3BCLE9BUG9CLEVBUXBCLFNBUm9CLEVBU3BCLGFBVG9CLEVBVXBCLE9BVm9CLEVBV3BCLFlBWG9CLEVBWXBCLE9BWm9CLEVBYXBCLG1CQWJvQixFQWNwQixjQWRvQixFQWVwQixRQWZvQixFQWdCcEIsT0FoQm9CLEVBaUJwQixLQWpCb0IsRUFrQnBCLFNBbEJvQixFQW1CcEIsUUFuQm9CLEVBb0JwQixhQXBCb0IsRUFxQnBCLFFBckJvQixFQXNCcEIsTUF0Qm9CLEVBdUJwQixNQXZCb0IsRUF3QnBCLGFBeEJvQixFQXlCcEIsUUF6Qm9CLENBQXRCO0FBNEJBLE1BQU1DLFlBQVksR0FBRyxDQUFDLEdBQUdGLFNBQUosRUFBZSxHQUFHQyxhQUFsQixDQUFyQjs7QUFFTyxNQUFNRSxlQUFOLFNBQThCQyxzQkFBOUIsQ0FBNEM7QUFDakRDLEVBQUFBLFVBQVUsQ0FBQ0MsR0FBRCxFQUFNO0FBQ2QsVUFBTUMsSUFBSSxHQUFHQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0gsR0FBRyxDQUFDQyxJQUFsQixFQUF3QkgsdUJBQWNNLGFBQWQsQ0FBNEJKLEdBQUcsQ0FBQ0ssS0FBaEMsQ0FBeEIsQ0FBYjtBQUNBLFVBQU1DLE9BQU8sR0FBRyxFQUFoQjs7QUFDQSxRQUFJTCxJQUFJLENBQUNNLFFBQVQsRUFBbUI7QUFDakJELE1BQUFBLE9BQU8sQ0FBQ0MsUUFBUixHQUFtQkMsTUFBTSxDQUFDUCxJQUFJLENBQUNNLFFBQU4sQ0FBekI7QUFDRDs7QUFDRCxRQUFJTixJQUFJLENBQUNRLElBQVQsRUFBZTtBQUNiSCxNQUFBQSxPQUFPLENBQUNHLElBQVIsR0FBZVIsSUFBSSxDQUFDUSxJQUFwQjtBQUNBLGFBQU9SLElBQUksQ0FBQ1EsSUFBWjtBQUNEOztBQUNELFFBQUlSLElBQUksQ0FBQ1MsT0FBVCxFQUFrQjtBQUNoQkosTUFBQUEsT0FBTyxDQUFDSSxPQUFSLEdBQWtCVCxJQUFJLENBQUNTLE9BQXZCO0FBQ0EsYUFBT1QsSUFBSSxDQUFDUyxPQUFaO0FBQ0Q7O0FBQ0QsUUFBSVQsSUFBSSxDQUFDVSxjQUFULEVBQXlCO0FBQ3ZCTCxNQUFBQSxPQUFPLENBQUNLLGNBQVIsR0FBeUJWLElBQUksQ0FBQ1UsY0FBOUI7QUFDQSxhQUFPVixJQUFJLENBQUNVLGNBQVo7QUFDRDs7QUFDREwsSUFBQUEsT0FBTyxDQUFDTSxRQUFSLEdBQW1CZixlQUFlLENBQUNnQixXQUFoQixDQUE0QlosSUFBNUIsQ0FBbkI7O0FBQ0EsUUFBSSxPQUFPQSxJQUFJLENBQUNhLEtBQVosS0FBc0IsUUFBMUIsRUFBb0M7QUFDbENiLE1BQUFBLElBQUksQ0FBQ2EsS0FBTCxHQUFhQyxJQUFJLENBQUNDLEtBQUwsQ0FBV2YsSUFBSSxDQUFDYSxLQUFoQixDQUFiO0FBQ0Q7O0FBQ0QsV0FBT0csY0FDSkMsSUFESSxDQUVIbEIsR0FBRyxDQUFDbUIsTUFGRCxFQUdIbkIsR0FBRyxDQUFDb0IsSUFIRCxFQUlILEtBQUtDLFNBQUwsQ0FBZXJCLEdBQWYsQ0FKRyxFQUtIQyxJQUFJLENBQUNhLEtBTEYsRUFNSFIsT0FORyxFQU9ITixHQUFHLENBQUNzQixJQUFKLENBQVNDLFNBUE4sRUFRSHZCLEdBQUcsQ0FBQ3NCLElBQUosQ0FBU0UsT0FSTixFQVVKQyxJQVZJLENBVUNDLFFBQVEsSUFBSTtBQUNoQixXQUFLLE1BQU1DLE1BQVgsSUFBcUJELFFBQVEsQ0FBQ0UsT0FBOUIsRUFBdUM7QUFDckMsWUFBSSxPQUFPRCxNQUFQLEtBQWtCLFFBQXRCLEVBQWdDO0FBQzlCRSwrQkFBWUMsc0JBQVosQ0FBbUNILE1BQW5DO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPO0FBQUVELFFBQUFBO0FBQUYsT0FBUDtBQUNELEtBakJJLENBQVA7QUFrQkQ7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeUJBLFNBQU9iLFdBQVAsQ0FBbUJaLElBQW5CLEVBQXlCO0FBQ3ZCLFFBQUlXLFFBQVEsR0FBR1gsSUFBSSxDQUFDVyxRQUFMLElBQWlCWCxJQUFoQzs7QUFDQSxRQUFJLENBQUM4QixLQUFLLENBQUNDLE9BQU4sQ0FBY3BCLFFBQWQsQ0FBTCxFQUE4QjtBQUM1QkEsTUFBQUEsUUFBUSxHQUFHVixNQUFNLENBQUMrQixJQUFQLENBQVlyQixRQUFaLEVBQXNCc0IsR0FBdEIsQ0FBMEJDLEdBQUcsSUFBSTtBQUMxQyxlQUFPO0FBQUUsV0FBQ0EsR0FBRCxHQUFPdkIsUUFBUSxDQUFDdUIsR0FBRDtBQUFqQixTQUFQO0FBQ0QsT0FGVSxDQUFYO0FBR0Q7O0FBRUQsV0FBT3ZCLFFBQVEsQ0FBQ3NCLEdBQVQsQ0FBYUUsS0FBSyxJQUFJO0FBQzNCLFlBQU1ILElBQUksR0FBRy9CLE1BQU0sQ0FBQytCLElBQVAsQ0FBWUcsS0FBWixDQUFiOztBQUNBLFVBQUlILElBQUksQ0FBQ0ksTUFBTCxJQUFlLENBQW5CLEVBQXNCO0FBQ3BCLGNBQU0sSUFBSUMsS0FBSixDQUFXLGtEQUFpREwsSUFBSSxDQUFDTSxJQUFMLENBQVUsSUFBVixDQUFnQixFQUE1RSxDQUFOO0FBQ0Q7O0FBQ0QsYUFBTzFDLGVBQWUsQ0FBQzJDLGNBQWhCLENBQStCUCxJQUFJLENBQUMsQ0FBRCxDQUFuQyxFQUF3Q0csS0FBeEMsQ0FBUDtBQUNELEtBTk0sQ0FBUDtBQU9EOztBQUVELFNBQU9JLGNBQVAsQ0FBc0JDLFNBQXRCLEVBQWlDTCxLQUFqQyxFQUF3QztBQUN0QyxRQUFJeEMsWUFBWSxDQUFDOEMsT0FBYixDQUFxQkQsU0FBckIsTUFBb0MsQ0FBQyxDQUF6QyxFQUE0QztBQUMxQyxZQUFNLElBQUlFLGNBQU1MLEtBQVYsQ0FBZ0JLLGNBQU1MLEtBQU4sQ0FBWU0sYUFBNUIsRUFBNEMsZ0NBQStCSCxTQUFVLEVBQXJGLENBQU47QUFDRDs7QUFDRCxRQUFJQSxTQUFTLEtBQUssT0FBbEIsRUFBMkI7QUFDekIsVUFBSXZDLE1BQU0sQ0FBQzJDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ1gsS0FBSyxDQUFDSyxTQUFELENBQTFDLEVBQXVELEtBQXZELENBQUosRUFBbUU7QUFDakUsY0FBTSxJQUFJRSxjQUFNTCxLQUFWLENBQ0pLLGNBQU1MLEtBQU4sQ0FBWU0sYUFEUixFQUVILHdFQUZHLENBQU47QUFJRDs7QUFDRCxVQUFJLENBQUMxQyxNQUFNLENBQUMyQyxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNYLEtBQUssQ0FBQ0ssU0FBRCxDQUExQyxFQUF1RCxVQUF2RCxDQUFMLEVBQXlFO0FBQ3ZFLGNBQU0sSUFBSUUsY0FBTUwsS0FBVixDQUNKSyxjQUFNTCxLQUFOLENBQVlNLGFBRFIsRUFFSCwwREFGRyxDQUFOO0FBSUQ7O0FBQ0RSLE1BQUFBLEtBQUssQ0FBQ0ssU0FBRCxDQUFMLENBQWlCTyxHQUFqQixHQUF1QlosS0FBSyxDQUFDSyxTQUFELENBQUwsQ0FBaUJRLFFBQXhDO0FBQ0EsYUFBT2IsS0FBSyxDQUFDSyxTQUFELENBQUwsQ0FBaUJRLFFBQXhCO0FBQ0Q7O0FBQ0QsV0FBTztBQUFFLE9BQUUsSUFBR1IsU0FBVSxFQUFmLEdBQW1CTCxLQUFLLENBQUNLLFNBQUQ7QUFBMUIsS0FBUDtBQUNEOztBQUVEUyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQix1QkFBbEIsRUFBMkNDLFVBQVUsQ0FBQ0MsNkJBQXRELEVBQXFGckQsR0FBRyxJQUFJO0FBQzFGLGFBQU8sS0FBS0QsVUFBTCxDQUFnQkMsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUFoSGdEOzs7ZUFtSHBDSCxlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgVXNlcnNSb3V0ZXIgZnJvbSAnLi9Vc2Vyc1JvdXRlcic7XG5cbmNvbnN0IEJBU0VfS0VZUyA9IFsnd2hlcmUnLCAnZGlzdGluY3QnLCAncGlwZWxpbmUnLCAnaGludCcsICdleHBsYWluJ107XG5cbmNvbnN0IFBJUEVMSU5FX0tFWVMgPSBbXG4gICdhZGRGaWVsZHMnLFxuICAnYnVja2V0JyxcbiAgJ2J1Y2tldEF1dG8nLFxuICAnY29sbFN0YXRzJyxcbiAgJ2NvdW50JyxcbiAgJ2N1cnJlbnRPcCcsXG4gICdmYWNldCcsXG4gICdnZW9OZWFyJyxcbiAgJ2dyYXBoTG9va3VwJyxcbiAgJ2dyb3VwJyxcbiAgJ2luZGV4U3RhdHMnLFxuICAnbGltaXQnLFxuICAnbGlzdExvY2FsU2Vzc2lvbnMnLFxuICAnbGlzdFNlc3Npb25zJyxcbiAgJ2xvb2t1cCcsXG4gICdtYXRjaCcsXG4gICdvdXQnLFxuICAncHJvamVjdCcsXG4gICdyZWRhY3QnLFxuICAncmVwbGFjZVJvb3QnLFxuICAnc2FtcGxlJyxcbiAgJ3NraXAnLFxuICAnc29ydCcsXG4gICdzb3J0QnlDb3VudCcsXG4gICd1bndpbmQnLFxuXTtcblxuY29uc3QgQUxMT1dFRF9LRVlTID0gWy4uLkJBU0VfS0VZUywgLi4uUElQRUxJTkVfS0VZU107XG5cbmV4cG9ydCBjbGFzcyBBZ2dyZWdhdGVSb3V0ZXIgZXh0ZW5kcyBDbGFzc2VzUm91dGVyIHtcbiAgaGFuZGxlRmluZChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICBpZiAoYm9keS5kaXN0aW5jdCkge1xuICAgICAgb3B0aW9ucy5kaXN0aW5jdCA9IFN0cmluZyhib2R5LmRpc3RpbmN0KTtcbiAgICB9XG4gICAgaWYgKGJvZHkuaGludCkge1xuICAgICAgb3B0aW9ucy5oaW50ID0gYm9keS5oaW50O1xuICAgICAgZGVsZXRlIGJvZHkuaGludDtcbiAgICB9XG4gICAgaWYgKGJvZHkuZXhwbGFpbikge1xuICAgICAgb3B0aW9ucy5leHBsYWluID0gYm9keS5leHBsYWluO1xuICAgICAgZGVsZXRlIGJvZHkuZXhwbGFpbjtcbiAgICB9XG4gICAgaWYgKGJvZHkucmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSBib2R5LnJlYWRQcmVmZXJlbmNlO1xuICAgICAgZGVsZXRlIGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIG9wdGlvbnMucGlwZWxpbmUgPSBBZ2dyZWdhdGVSb3V0ZXIuZ2V0UGlwZWxpbmUoYm9keSk7XG4gICAgaWYgKHR5cGVvZiBib2R5LndoZXJlID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keS53aGVyZSA9IEpTT04ucGFyc2UoYm9keS53aGVyZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiByZXNwb25zZS5yZXN1bHRzKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qIEJ1aWxkcyBhIHBpcGVsaW5lIGZyb20gdGhlIGJvZHkuIE9yaWdpbmFsbHkgdGhlIGJvZHkgY291bGQgYmUgcGFzc2VkIGFzIGEgc2luZ2xlIG9iamVjdCxcbiAgICogYW5kIG5vdyB3ZSBzdXBwb3J0IG1hbnkgb3B0aW9uc1xuICAgKlxuICAgKiBBcnJheVxuICAgKlxuICAgKiBib2R5OiBbe1xuICAgKiAgIGdyb3VwOiB7IG9iamVjdElkOiAnJG5hbWUnIH0sXG4gICAqIH1dXG4gICAqXG4gICAqIE9iamVjdFxuICAgKlxuICAgKiBib2R5OiB7XG4gICAqICAgZ3JvdXA6IHsgb2JqZWN0SWQ6ICckbmFtZScgfSxcbiAgICogfVxuICAgKlxuICAgKlxuICAgKiBQaXBlbGluZSBPcGVyYXRvciB3aXRoIGFuIEFycmF5IG9yIGFuIE9iamVjdFxuICAgKlxuICAgKiBib2R5OiB7XG4gICAqICAgcGlwZWxpbmU6IHtcbiAgICogICAgIGdyb3VwOiB7IG9iamVjdElkOiAnJG5hbWUnIH0sXG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqL1xuICBzdGF0aWMgZ2V0UGlwZWxpbmUoYm9keSkge1xuICAgIGxldCBwaXBlbGluZSA9IGJvZHkucGlwZWxpbmUgfHwgYm9keTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGlwZWxpbmUpKSB7XG4gICAgICBwaXBlbGluZSA9IE9iamVjdC5rZXlzKHBpcGVsaW5lKS5tYXAoa2V5ID0+IHtcbiAgICAgICAgcmV0dXJuIHsgW2tleV06IHBpcGVsaW5lW2tleV0gfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwaXBlbGluZS5tYXAoc3RhZ2UgPT4ge1xuICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHN0YWdlKTtcbiAgICAgIGlmIChrZXlzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUGlwZWxpbmUgc3RhZ2VzIHNob3VsZCBvbmx5IGhhdmUgb25lIGtleSBmb3VuZCAke2tleXMuam9pbignLCAnKX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBBZ2dyZWdhdGVSb3V0ZXIudHJhbnNmb3JtU3RhZ2Uoa2V5c1swXSwgc3RhZ2UpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zZm9ybVN0YWdlKHN0YWdlTmFtZSwgc3RhZ2UpIHtcbiAgICBpZiAoQUxMT1dFRF9LRVlTLmluZGV4T2Yoc3RhZ2VOYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCBgSW52YWxpZCBwYXJhbWV0ZXIgZm9yIHF1ZXJ5OiAke3N0YWdlTmFtZX1gKTtcbiAgICB9XG4gICAgaWYgKHN0YWdlTmFtZSA9PT0gJ2dyb3VwJykge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdGFnZVtzdGFnZU5hbWVdLCAnX2lkJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEludmFsaWQgcGFyYW1ldGVyIGZvciBxdWVyeTogZ3JvdXAuIFBsZWFzZSB1c2Ugb2JqZWN0SWQgaW5zdGVhZCBvZiBfaWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdGFnZVtzdGFnZU5hbWVdLCAnb2JqZWN0SWQnKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW52YWxpZCBwYXJhbWV0ZXIgZm9yIHF1ZXJ5OiBncm91cC4gb2JqZWN0SWQgaXMgcmVxdWlyZWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBzdGFnZVtzdGFnZU5hbWVdLl9pZCA9IHN0YWdlW3N0YWdlTmFtZV0ub2JqZWN0SWQ7XG4gICAgICBkZWxldGUgc3RhZ2Vbc3RhZ2VOYW1lXS5vYmplY3RJZDtcbiAgICB9XG4gICAgcmV0dXJuIHsgW2AkJHtzdGFnZU5hbWV9YF06IHN0YWdlW3N0YWdlTmFtZV0gfTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvYWdncmVnYXRlLzpjbGFzc05hbWUnLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFnZ3JlZ2F0ZVJvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/AnalyticsRouter.js b/lib/Routers/AnalyticsRouter.js deleted file mode 100644 index d37290b37f..0000000000 --- a/lib/Routers/AnalyticsRouter.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.AnalyticsRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// AnalyticsRouter.js -function appOpened(req) { - const analyticsController = req.config.analyticsController; - return analyticsController.appOpened(req); -} - -function trackEvent(req) { - const analyticsController = req.config.analyticsController; - return analyticsController.trackEvent(req); -} - -class AnalyticsRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('POST', '/events/AppOpened', appOpened); - this.route('POST', '/events/:eventName', trackEvent); - } - -} - -exports.AnalyticsRouter = AnalyticsRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJhcHBPcGVuZWQiLCJyZXEiLCJhbmFseXRpY3NDb250cm9sbGVyIiwiY29uZmlnIiwidHJhY2tFdmVudCIsIkFuYWx5dGljc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFEQTtBQUdBLFNBQVNBLFNBQVQsQ0FBbUJDLEdBQW5CLEVBQXdCO0FBQ3RCLFFBQU1DLG1CQUFtQixHQUFHRCxHQUFHLENBQUNFLE1BQUosQ0FBV0QsbUJBQXZDO0FBQ0EsU0FBT0EsbUJBQW1CLENBQUNGLFNBQXBCLENBQThCQyxHQUE5QixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0csVUFBVCxDQUFvQkgsR0FBcEIsRUFBeUI7QUFDdkIsUUFBTUMsbUJBQW1CLEdBQUdELEdBQUcsQ0FBQ0UsTUFBSixDQUFXRCxtQkFBdkM7QUFDQSxTQUFPQSxtQkFBbUIsQ0FBQ0UsVUFBcEIsQ0FBK0JILEdBQS9CLENBQVA7QUFDRDs7QUFFTSxNQUFNSSxlQUFOLFNBQThCQyxzQkFBOUIsQ0FBNEM7QUFDakRDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLG1CQUFuQixFQUF3Q1IsU0FBeEM7QUFDQSxTQUFLUSxLQUFMLENBQVcsTUFBWCxFQUFtQixvQkFBbkIsRUFBeUNKLFVBQXpDO0FBQ0Q7O0FBSmdEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5hbHl0aWNzUm91dGVyLmpzXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcblxuZnVuY3Rpb24gYXBwT3BlbmVkKHJlcSkge1xuICBjb25zdCBhbmFseXRpY3NDb250cm9sbGVyID0gcmVxLmNvbmZpZy5hbmFseXRpY3NDb250cm9sbGVyO1xuICByZXR1cm4gYW5hbHl0aWNzQ29udHJvbGxlci5hcHBPcGVuZWQocmVxKTtcbn1cblxuZnVuY3Rpb24gdHJhY2tFdmVudChyZXEpIHtcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlciA9IHJlcS5jb25maWcuYW5hbHl0aWNzQ29udHJvbGxlcjtcbiAgcmV0dXJuIGFuYWx5dGljc0NvbnRyb2xsZXIudHJhY2tFdmVudChyZXEpO1xufVxuXG5leHBvcnQgY2xhc3MgQW5hbHl0aWNzUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy9BcHBPcGVuZWQnLCBhcHBPcGVuZWQpO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy86ZXZlbnROYW1lJywgdHJhY2tFdmVudCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/AudiencesRouter.js b/lib/Routers/AudiencesRouter.js deleted file mode 100644 index 684d3e42a2..0000000000 --- a/lib/Routers/AudiencesRouter.js +++ /dev/null @@ -1,70 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AudiencesRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class AudiencesRouter extends _ClassesRouter.default { - className() { - return '_Audience'; - } - - handleFind(req) { - const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); - - const options = _ClassesRouter.default.optionsFromBody(body); - - return _rest.default.find(req.config, req.auth, '_Audience', body.where, options, req.info.clientSDK, req.info.context).then(response => { - response.results.forEach(item => { - item.query = JSON.parse(item.query); - }); - return { - response: response - }; - }); - } - - handleGet(req) { - return super.handleGet(req).then(data => { - data.response.query = JSON.parse(data.response.query); - return data; - }); - } - - mountRoutes() { - this.route('GET', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleFind(req); - }); - this.route('GET', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleGet(req); - }); - this.route('POST', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleCreate(req); - }); - this.route('PUT', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleDelete(req); - }); - } - -} - -exports.AudiencesRouter = AudiencesRouter; -var _default = AudiencesRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0F1ZGllbmNlc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJBdWRpZW5jZXNSb3V0ZXIiLCJDbGFzc2VzUm91dGVyIiwiY2xhc3NOYW1lIiwiaGFuZGxlRmluZCIsInJlcSIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwicmVzdCIsImZpbmQiLCJjb25maWciLCJhdXRoIiwid2hlcmUiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsInJlc3VsdHMiLCJmb3JFYWNoIiwiaXRlbSIsIkpTT04iLCJwYXJzZSIsImhhbmRsZUdldCIsImRhdGEiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRU8sTUFBTUEsZUFBTixTQUE4QkMsc0JBQTlCLENBQTRDO0FBQ2pEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFdBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUVBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILFdBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEJBLE1BQUFBLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQkMsT0FBakIsQ0FBeUJDLElBQUksSUFBSTtBQUMvQkEsUUFBQUEsSUFBSSxDQUFDZixLQUFMLEdBQWFnQixJQUFJLENBQUNDLEtBQUwsQ0FBV0YsSUFBSSxDQUFDZixLQUFoQixDQUFiO0FBQ0QsT0FGRDtBQUlBLGFBQU87QUFBRVksUUFBQUEsUUFBUSxFQUFFQTtBQUFaLE9BQVA7QUFDRCxLQWhCSSxDQUFQO0FBaUJEOztBQUVETSxFQUFBQSxTQUFTLENBQUN2QixHQUFELEVBQU07QUFDYixXQUFPLE1BQU11QixTQUFOLENBQWdCdkIsR0FBaEIsRUFBcUJnQixJQUFyQixDQUEwQlEsSUFBSSxJQUFJO0FBQ3ZDQSxNQUFBQSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBZCxHQUFzQmdCLElBQUksQ0FBQ0MsS0FBTCxDQUFXRSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBekIsQ0FBdEI7QUFFQSxhQUFPbUIsSUFBUDtBQUNELEtBSk0sQ0FBUDtBQUtEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixpQkFBbEIsRUFBcUNDLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFNUIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0QsVUFBTCxDQUFnQkMsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLMEIsS0FBTCxDQUNFLEtBREYsRUFFRSwyQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU1QixHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUt1QixTQUFMLENBQWV2QixHQUFmLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLGlCQUFuQixFQUFzQ0MsVUFBVSxDQUFDQyw2QkFBakQsRUFBZ0Y1QixHQUFHLElBQUk7QUFDckYsYUFBTyxLQUFLNkIsWUFBTCxDQUFrQjdCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBSzBCLEtBQUwsQ0FDRSxLQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLOEIsWUFBTCxDQUFrQjlCLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FDRSxRQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLK0IsWUFBTCxDQUFrQi9CLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUQ7O0FBbkVnRDs7O2VBc0VwQ0osZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgQXVkaWVuY2VzUm91dGVyIGV4dGVuZHMgQ2xhc3Nlc1JvdXRlciB7XG4gIGNsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ19BdWRpZW5jZSc7XG4gIH1cblxuICBoYW5kbGVGaW5kKHJlcSkge1xuICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHJlcS5ib2R5LCBDbGFzc2VzUm91dGVyLkpTT05Gcm9tUXVlcnkocmVxLnF1ZXJ5KSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IENsYXNzZXNSb3V0ZXIub3B0aW9uc0Zyb21Cb2R5KGJvZHkpO1xuXG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19BdWRpZW5jZScsXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bHRzLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgaXRlbS5xdWVyeSA9IEpTT04ucGFyc2UoaXRlbS5xdWVyeSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBoYW5kbGVHZXQocmVxKSB7XG4gICAgcmV0dXJuIHN1cGVyLmhhbmRsZUdldChyZXEpLnRoZW4oZGF0YSA9PiB7XG4gICAgICBkYXRhLnJlc3BvbnNlLnF1ZXJ5ID0gSlNPTi5wYXJzZShkYXRhLnJlc3BvbnNlLnF1ZXJ5KTtcblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3B1c2hfYXVkaWVuY2VzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlR2V0KHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9wdXNoX2F1ZGllbmNlcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVXBkYXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdWRpZW5jZXNSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/ClassesRouter.js b/lib/Routers/ClassesRouter.js deleted file mode 100644 index e3b3e93fd2..0000000000 --- a/lib/Routers/ClassesRouter.js +++ /dev/null @@ -1,231 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.ClassesRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _middlewares = require("../middlewares"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const ALLOWED_GET_QUERY_KEYS = ['keys', 'include', 'excludeKeys', 'readPreference', 'includeReadPreference', 'subqueryReadPreference']; - -class ClassesRouter extends _PromiseRouter.default { - className(req) { - return req.params.className; - } - - handleFind(req) { - const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); - const options = ClassesRouter.optionsFromBody(body); - - if (req.config.maxLimit && body.limit > req.config.maxLimit) { - // Silently replace the limit on the query with the max configured - options.limit = Number(req.config.maxLimit); - } - - if (body.redirectClassNameForKey) { - options.redirectClassNameForKey = String(body.redirectClassNameForKey); - } - - if (typeof body.where === 'string') { - body.where = JSON.parse(body.where); - } - - return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { - return { - response: response - }; - }); - } // Returns a promise for a {response} object. - - - handleGet(req) { - const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); - const options = {}; - - for (const key of Object.keys(body)) { - if (ALLOWED_GET_QUERY_KEYS.indexOf(key) === -1) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Improper encode of parameter'); - } - } - - if (typeof body.keys === 'string') { - options.keys = body.keys; - } - - if (body.include) { - options.include = String(body.include); - } - - if (typeof body.excludeKeys == 'string') { - options.excludeKeys = body.excludeKeys; - } - - if (typeof body.readPreference === 'string') { - options.readPreference = body.readPreference; - } - - if (typeof body.includeReadPreference === 'string') { - options.includeReadPreference = body.includeReadPreference; - } - - if (typeof body.subqueryReadPreference === 'string') { - options.subqueryReadPreference = body.subqueryReadPreference; - } - - return _rest.default.get(req.config, req.auth, this.className(req), req.params.objectId, options, req.info.clientSDK).then(response => { - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - if (this.className(req) === '_User') { - delete response.results[0].sessionToken; - const user = response.results[0]; - - if (req.auth.user && user.objectId == req.auth.user.id) { - // Force the session token - response.results[0].sessionToken = req.info.sessionToken; - } - } - - return { - response: response.results[0] - }; - }); - } - - handleCreate(req) { - return _rest.default.create(req.config, req.auth, this.className(req), req.body, req.info.clientSDK, req.info.context); - } - - handleUpdate(req) { - const where = { - objectId: req.params.objectId - }; - return _rest.default.update(req.config, req.auth, this.className(req), where, req.body, req.info.clientSDK, req.info.context); - } - - handleDelete(req) { - return _rest.default.del(req.config, req.auth, this.className(req), req.params.objectId, req.info.context).then(() => { - return { - response: {} - }; - }); - } - - static JSONFromQuery(query) { - const json = {}; - - for (const [key, value] of _lodash.default.entries(query)) { - try { - json[key] = JSON.parse(value); - } catch (e) { - json[key] = value; - } - } - - return json; - } - - static optionsFromBody(body) { - const allowConstraints = ['skip', 'limit', 'order', 'count', 'keys', 'excludeKeys', 'include', 'includeAll', 'redirectClassNameForKey', 'where', 'readPreference', 'includeReadPreference', 'subqueryReadPreference', 'hint', 'explain']; - - for (const key of Object.keys(body)) { - if (allowConstraints.indexOf(key) === -1) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${key}`); - } - } - - const options = {}; - - if (body.skip) { - options.skip = Number(body.skip); - } - - if (body.limit || body.limit === 0) { - options.limit = Number(body.limit); - } else { - options.limit = Number(100); - } - - if (body.order) { - options.order = String(body.order); - } - - if (body.count) { - options.count = true; - } - - if (typeof body.keys == 'string') { - options.keys = body.keys; - } - - if (typeof body.excludeKeys == 'string') { - options.excludeKeys = body.excludeKeys; - } - - if (body.include) { - options.include = String(body.include); - } - - if (body.includeAll) { - options.includeAll = true; - } - - if (typeof body.readPreference === 'string') { - options.readPreference = body.readPreference; - } - - if (typeof body.includeReadPreference === 'string') { - options.includeReadPreference = body.includeReadPreference; - } - - if (typeof body.subqueryReadPreference === 'string') { - options.subqueryReadPreference = body.subqueryReadPreference; - } - - if (body.hint && (typeof body.hint === 'string' || typeof body.hint === 'object')) { - options.hint = body.hint; - } - - if (body.explain) { - options.explain = body.explain; - } - - return options; - } - - mountRoutes() { - this.route('GET', '/classes/:className', req => { - return this.handleFind(req); - }); - this.route('GET', '/classes/:className/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/classes/:className', _middlewares.promiseEnsureIdempotency, req => { - return this.handleCreate(req); - }); - this.route('PUT', '/classes/:className/:objectId', _middlewares.promiseEnsureIdempotency, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/classes/:className/:objectId', req => { - return this.handleDelete(req); - }); - } - -} - -exports.ClassesRouter = ClassesRouter; -var _default = ClassesRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiQUxMT1dFRF9HRVRfUVVFUllfS0VZUyIsIkNsYXNzZXNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiY2xhc3NOYW1lIiwicmVxIiwicGFyYW1zIiwiaGFuZGxlRmluZCIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwiY29uZmlnIiwibWF4TGltaXQiLCJsaW1pdCIsIk51bWJlciIsInJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IiwiU3RyaW5nIiwid2hlcmUiLCJKU09OIiwicGFyc2UiLCJyZXN0IiwiZmluZCIsImF1dGgiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsImhhbmRsZUdldCIsImtleSIsImtleXMiLCJpbmRleE9mIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJpbmNsdWRlIiwiZXhjbHVkZUtleXMiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJnZXQiLCJvYmplY3RJZCIsInJlc3VsdHMiLCJsZW5ndGgiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwic2Vzc2lvblRva2VuIiwidXNlciIsImlkIiwiaGFuZGxlQ3JlYXRlIiwiY3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwidXBkYXRlIiwiaGFuZGxlRGVsZXRlIiwiZGVsIiwianNvbiIsInZhbHVlIiwiXyIsImVudHJpZXMiLCJlIiwiYWxsb3dDb25zdHJhaW50cyIsInNraXAiLCJvcmRlciIsImNvdW50IiwiaW5jbHVkZUFsbCIsImhpbnQiLCJleHBsYWluIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNB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cG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuY29uc3QgQUxMT1dFRF9HRVRfUVVFUllfS0VZUyA9IFtcbiAgJ2tleXMnLFxuICAnaW5jbHVkZScsXG4gICdleGNsdWRlS2V5cycsXG4gICdyZWFkUHJlZmVyZW5jZScsXG4gICdpbmNsdWRlUmVhZFByZWZlcmVuY2UnLFxuICAnc3VicXVlcnlSZWFkUHJlZmVyZW5jZScsXG5dO1xuXG5leHBvcnQgY2xhc3MgQ2xhc3Nlc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjbGFzc05hbWUocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICB9XG5cbiAgaGFuZGxlRmluZChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSBDbGFzc2VzUm91dGVyLm9wdGlvbnNGcm9tQm9keShib2R5KTtcbiAgICBpZiAocmVxLmNvbmZpZy5tYXhMaW1pdCAmJiBib2R5LmxpbWl0ID4gcmVxLmNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgLy8gU2lsZW50bHkgcmVwbGFjZSB0aGUgbGltaXQgb24gdGhlIHF1ZXJ5IHdpdGggdGhlIG1heCBjb25maWd1cmVkXG4gICAgICBvcHRpb25zLmxpbWl0ID0gTnVtYmVyKHJlcS5jb25maWcubWF4TGltaXQpO1xuICAgIH1cbiAgICBpZiAoYm9keS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSkge1xuICAgICAgb3B0aW9ucy5yZWRpcmVjdENsYXNzTmFtZUZvcktleSA9IFN0cmluZyhib2R5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LndoZXJlID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keS53aGVyZSA9IEpTT04ucGFyc2UoYm9keS53aGVyZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlfSBvYmplY3QuXG4gIGhhbmRsZUdldChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGJvZHkpKSB7XG4gICAgICBpZiAoQUxMT1dFRF9HRVRfUVVFUllfS0VZUy5pbmRleE9mKGtleSkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnSW1wcm9wZXIgZW5jb2RlIG9mIHBhcmFtZXRlcicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYm9keS5rZXlzID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5rZXlzID0gYm9keS5rZXlzO1xuICAgIH1cbiAgICBpZiAoYm9keS5pbmNsdWRlKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGUgPSBTdHJpbmcoYm9keS5pbmNsdWRlKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdFxuICAgICAgLmdldChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIHJlcS5wYXJhbXMub2JqZWN0SWQsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNES1xuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNsYXNzTmFtZShyZXEpID09PSAnX1VzZXInKSB7XG4gICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLnJlc3VsdHNbMF0uc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG5cbiAgICAgICAgICBpZiAocmVxLmF1dGgudXNlciAmJiB1c2VyLm9iamVjdElkID09IHJlcS5hdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSBzZXNzaW9uIHRva2VuXG4gICAgICAgICAgICByZXNwb25zZS5yZXN1bHRzWzBdLnNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlLnJlc3VsdHNbMF0gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlQ3JlYXRlKHJlcSkge1xuICAgIHJldHVybiByZXN0LmNyZWF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICByZXEuYm9keSxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlKHJlcSkge1xuICAgIGNvbnN0IHdoZXJlID0geyBvYmplY3RJZDogcmVxLnBhcmFtcy5vYmplY3RJZCB9O1xuICAgIHJldHVybiByZXN0LnVwZGF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICB3aGVyZSxcbiAgICAgIHJlcS5ib2R5LFxuICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5kZWwocmVxLmNvbmZpZywgcmVxLmF1dGgsIHRoaXMuY2xhc3NOYW1lKHJlcSksIHJlcS5wYXJhbXMub2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBzdGF0aWMgSlNPTkZyb21RdWVyeShxdWVyeSkge1xuICAgIGNvbnN0IGpzb24gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBfLmVudHJpZXMocXVlcnkpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBqc29uW2tleV0gPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAganNvbltrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgc3RhdGljIG9wdGlvbnNGcm9tQm9keShib2R5KSB7XG4gICAgY29uc3QgYWxsb3dDb25zdHJhaW50cyA9IFtcbiAgICAgICdza2lwJyxcbiAgICAgICdsaW1pdCcsXG4gICAgICAnb3JkZXInLFxuICAgICAgJ2NvdW50JyxcbiAgICAgICdrZXlzJyxcbiAgICAgICdleGNsdWRlS2V5cycsXG4gICAgICAnaW5jbHVkZScsXG4gICAgICAnaW5jbHVkZUFsbCcsXG4gICAgICAncmVkaXJlY3RDbGFzc05hbWVGb3JLZXknLFxuICAgICAgJ3doZXJlJyxcbiAgICAgICdyZWFkUHJlZmVyZW5jZScsXG4gICAgICAnaW5jbHVkZVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdzdWJxdWVyeVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdoaW50JyxcbiAgICAgICdleHBsYWluJyxcbiAgICBdO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYm9keSkpIHtcbiAgICAgIGlmIChhbGxvd0NvbnN0cmFpbnRzLmluZGV4T2Yoa2V5KSA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6ICR7a2V5fWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgaWYgKGJvZHkuc2tpcCkge1xuICAgICAgb3B0aW9ucy5za2lwID0gTnVtYmVyKGJvZHkuc2tpcCk7XG4gICAgfVxuICAgIGlmIChib2R5LmxpbWl0IHx8IGJvZHkubGltaXQgPT09IDApIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoYm9keS5saW1pdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoMTAwKTtcbiAgICB9XG4gICAgaWYgKGJvZHkub3JkZXIpIHtcbiAgICAgIG9wdGlvbnMub3JkZXIgPSBTdHJpbmcoYm9keS5vcmRlcik7XG4gICAgfVxuICAgIGlmIChib2R5LmNvdW50KSB7XG4gICAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmtleXMgPT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMua2V5cyA9IGJvZHkua2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKGJvZHkuaW5jbHVkZSkge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlID0gU3RyaW5nKGJvZHkuaW5jbHVkZSk7XG4gICAgfVxuICAgIGlmIChib2R5LmluY2x1ZGVBbGwpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5yZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSBib2R5LnJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSBib2R5LmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChib2R5LmhpbnQgJiYgKHR5cGVvZiBib2R5LmhpbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBib2R5LmhpbnQgPT09ICdvYmplY3QnKSkge1xuICAgICAgb3B0aW9ucy5oaW50ID0gYm9keS5oaW50O1xuICAgIH1cbiAgICBpZiAoYm9keS5leHBsYWluKSB7XG4gICAgICBvcHRpb25zLmV4cGxhaW4gPSBib2R5LmV4cGxhaW47XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvY2xhc3Nlcy86Y2xhc3NOYW1lLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2xhc3Nlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/CloudCodeRouter.js b/lib/Routers/CloudCodeRouter.js deleted file mode 100644 index 423ee10a50..0000000000 --- a/lib/Routers/CloudCodeRouter.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.CloudCodeRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _rest = _interopRequireDefault(require("../rest")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const triggers = require('../triggers'); - -const middleware = require('../middlewares'); - -function formatJobSchedule(job_schedule) { - if (typeof job_schedule.startAfter === 'undefined') { - job_schedule.startAfter = new Date().toISOString(); - } - - return job_schedule; -} - -function validateJobSchedule(config, job_schedule) { - const jobs = triggers.getJobs(config.applicationId) || {}; - - if (job_schedule.jobName && !jobs[job_schedule.jobName]) { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Cannot Schedule a job that is not deployed'); - } -} - -class CloudCodeRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobs); - this.route('GET', '/cloud_code/jobs/data', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobsData); - this.route('POST', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.createJob); - this.route('PUT', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.editJob); - this.route('DELETE', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.deleteJob); - } - - static getJobs(req) { - return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { - return { - response: scheduledJobs.results - }; - }); - } - - static getJobsData(req) { - const config = req.config; - const jobs = triggers.getJobs(config.applicationId) || {}; - return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { - return { - response: { - in_use: scheduledJobs.results.map(job => job.jobName), - jobs: Object.keys(jobs) - } - }; - }); - } - - static createJob(req) { - const { - job_schedule - } = req.body; - validateJobSchedule(req.config, job_schedule); - return _rest.default.create(req.config, req.auth, '_JobSchedule', formatJobSchedule(job_schedule), req.client, req.info.context); - } - - static editJob(req) { - const { - objectId - } = req.params; - const { - job_schedule - } = req.body; - validateJobSchedule(req.config, job_schedule); - return _rest.default.update(req.config, req.auth, '_JobSchedule', { - objectId - }, formatJobSchedule(job_schedule), undefined, req.info.context).then(response => { - return { - response - }; - }); - } - - static deleteJob(req) { - const { - objectId - } = req.params; - return _rest.default.del(req.config, req.auth, '_JobSchedule', objectId, req.info.context).then(response => { - return { - response - }; - }); - } - -} - -exports.CloudCodeRouter = CloudCodeRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Nsb3VkQ29kZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJ0cmlnZ2VycyIsInJlcXVpcmUiLCJtaWRkbGV3YXJlIiwiZm9ybWF0Sm9iU2NoZWR1bGUiLCJqb2Jfc2NoZWR1bGUiLCJzdGFydEFmdGVyIiwiRGF0ZSIsInRvSVNPU3RyaW5nIiwidmFsaWRhdGVKb2JTY2hlZHVsZSIsImNvbmZpZyIsImpvYnMiLCJnZXRKb2JzIiwiYXBwbGljYXRpb25JZCIsImpvYk5hbWUiLCJQYXJzZSIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiQ2xvdWRDb2RlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImdldEpvYnNEYXRhIiwiY3JlYXRlSm9iIiwiZWRpdEpvYiIsImRlbGV0ZUpvYiIsInJlcSIsInJlc3QiLCJmaW5kIiwiYXV0aCIsInRoZW4iLCJzY2hlZHVsZWRKb2JzIiwicmVzcG9uc2UiLCJyZXN1bHRzIiwiaW5fdXNlIiwibWFwIiwiam9iIiwiT2JqZWN0Iiwia2V5cyIsImJvZHkiLCJjcmVhdGUiLCJjbGllbnQiLCJpbmZvIiwiY29udGV4dCIsIm9iamVjdElkIiwicGFyYW1zIiwidXBkYXRlIiwidW5kZWZpbmVkIiwiZGVsIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFDQSxNQUFNQSxRQUFRLEdBQUdDLE9BQU8sQ0FBQyxhQUFELENBQXhCOztBQUNBLE1BQU1DLFVBQVUsR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTFCOztBQUVBLFNBQVNFLGlCQUFULENBQTJCQyxZQUEzQixFQUF5QztBQUN2QyxNQUFJLE9BQU9BLFlBQVksQ0FBQ0MsVUFBcEIsS0FBbUMsV0FBdkMsRUFBb0Q7QUFDbERELElBQUFBLFlBQVksQ0FBQ0MsVUFBYixHQUEwQixJQUFJQyxJQUFKLEdBQVdDLFdBQVgsRUFB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dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5jb25zdCB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5jb25zdCBtaWRkbGV3YXJlID0gcmVxdWlyZSgnLi4vbWlkZGxld2FyZXMnKTtcblxuZnVuY3Rpb24gZm9ybWF0Sm9iU2NoZWR1bGUoam9iX3NjaGVkdWxlKSB7XG4gIGlmICh0eXBlb2Ygam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIGpvYl9zY2hlZHVsZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKb2JTY2hlZHVsZShjb25maWcsIGpvYl9zY2hlZHVsZSkge1xuICBjb25zdCBqb2JzID0gdHJpZ2dlcnMuZ2V0Sm9icyhjb25maWcuYXBwbGljYXRpb25JZCkgfHwge307XG4gIGlmIChqb2Jfc2NoZWR1bGUuam9iTmFtZSAmJiAham9ic1tqb2Jfc2NoZWR1bGUuam9iTmFtZV0pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAnQ2Fubm90IFNjaGVkdWxlIGEgam9iIHRoYXQgaXMgbm90IGRlcGxveWVkJ1xuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENsb3VkQ29kZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgQ2xvdWRDb2RlUm91dGVyLmdldEpvYnNcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnR0VUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzL2RhdGEnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5nZXRKb2JzRGF0YVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBDbG91ZENvZGVSb3V0ZXIuY3JlYXRlSm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5lZGl0Sm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5kZWxldGVKb2JcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnMocmVxKSB7XG4gICAgcmV0dXJuIHJlc3QuZmluZChyZXEuY29uZmlnLCByZXEuYXV0aCwgJ19Kb2JTY2hlZHVsZScsIHt9LCB7fSkudGhlbihzY2hlZHVsZWRKb2JzID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlOiBzY2hlZHVsZWRKb2JzLnJlc3VsdHMsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnNEYXRhKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3Qgam9icyA9IHRyaWdnZXJzLmdldEpvYnMoY29uZmlnLmFwcGxpY2F0aW9uSWQpIHx8IHt9O1xuICAgIHJldHVybiByZXN0LmZpbmQocmVxLmNvbmZpZywgcmVxLmF1dGgsICdfSm9iU2NoZWR1bGUnLCB7fSwge30pLnRoZW4oc2NoZWR1bGVkSm9icyA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGluX3VzZTogc2NoZWR1bGVkSm9icy5yZXN1bHRzLm1hcChqb2IgPT4gam9iLmpvYk5hbWUpLFxuICAgICAgICAgIGpvYnM6IE9iamVjdC5rZXlzKGpvYnMpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVKb2IocmVxKSB7XG4gICAgY29uc3QgeyBqb2Jfc2NoZWR1bGUgfSA9IHJlcS5ib2R5O1xuICAgIHZhbGlkYXRlSm9iU2NoZWR1bGUocmVxLmNvbmZpZywgam9iX3NjaGVkdWxlKTtcbiAgICByZXR1cm4gcmVzdC5jcmVhdGUoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgIGZvcm1hdEpvYlNjaGVkdWxlKGpvYl9zY2hlZHVsZSksXG4gICAgICByZXEuY2xpZW50LFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZWRpdEpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IHsgam9iX3NjaGVkdWxlIH0gPSByZXEuYm9keTtcbiAgICB2YWxpZGF0ZUpvYlNjaGVkdWxlKHJlcS5jb25maWcsIGpvYl9zY2hlZHVsZSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC51cGRhdGUoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIHJlcS5hdXRoLFxuICAgICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgICAgeyBvYmplY3RJZCB9LFxuICAgICAgICBmb3JtYXRKb2JTY2hlZHVsZShqb2Jfc2NoZWR1bGUpLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGRlbGV0ZUpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZGVsKHJlcS5jb25maWcsIHJlcS5hdXRoLCAnX0pvYlNjaGVkdWxlJywgb2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Routers/FeaturesRouter.js b/lib/Routers/FeaturesRouter.js deleted file mode 100644 index 51c3c26849..0000000000 --- a/lib/Routers/FeaturesRouter.js +++ /dev/null @@ -1,79 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FeaturesRouter = void 0; - -var _package = require("../../package.json"); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class FeaturesRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/serverInfo', middleware.promiseEnforceMasterKeyAccess, req => { - const { - config - } = req; - const features = { - globalConfig: { - create: true, - read: true, - update: true, - delete: true - }, - hooks: { - create: true, - read: true, - update: true, - delete: true - }, - cloudCode: { - jobs: true - }, - logs: { - level: true, - size: true, - order: true, - until: true, - from: true - }, - push: { - immediatePush: config.hasPushSupport, - scheduledPush: config.hasPushScheduledSupport, - storedPushData: config.hasPushSupport, - pushAudiences: true, - localization: true - }, - schemas: { - addField: true, - removeField: true, - addClass: true, - removeClass: true, - clearAllDataFromClass: true, - exportClass: false, - editClassLevelPermissions: true, - editPointerPermissions: true - } - }; - return { - response: { - features: features, - parseServerVersion: _package.version - } - }; - }); - } - -} - -exports.FeaturesRouter = FeaturesRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZlYXR1cmVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkZlYXR1cmVzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXEiLCJjb25maWciLCJmZWF0dXJlcyIsImdsb2JhbENvbmZpZyIsImNyZWF0ZSIsInJlYWQiLCJ1cGRhdGUiLCJkZWxldGUiLCJob29rcyIsImNsb3VkQ29kZSIsImpvYnMiLCJsb2dzIiwibGV2ZWwiLCJzaXplIiwib3JkZXIiLCJ1bnRpbCIsImZyb20iLCJwdXNoIiwiaW1tZWRpYXRlUHVzaCIsImhhc1B1c2hTdXBwb3J0Iiwic2NoZWR1bGVkUHVzaCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0Iiwic3RvcmVkUHVzaERhdGEiLCJwdXNoQXVkaWVuY2VzIiwibG9jYWxpemF0aW9uIiwic2NoZW1hcyIsImFkZEZpZWxkIiwicmVtb3ZlRmllbGQiLCJhZGRDbGFzcyIsInJlbW92ZUNsYXNzIiwiY2xlYXJBbGxEYXRhRnJvbUNsYXNzIiwiZXhwb3J0Q2xhc3MiLCJlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiZWRpdFBvaW50ZXJQZXJtaXNzaW9ucyIsInJlc3BvbnNlIiwicGFyc2VTZXJ2ZXJWZXJzaW9uIiwidmVyc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVPLE1BQU1BLGNBQU4sU0FBNkJDLHNCQUE3QixDQUEyQztBQUNoREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsYUFBbEIsRUFBaUNDLFVBQVUsQ0FBQ0MsNkJBQTVDLEVBQTJFQyxHQUFHLElBQUk7QUFDaEYsWUFBTTtBQUFFQyxRQUFBQTtBQUFGLFVBQWFELEdBQW5CO0FBQ0EsWUFBTUUsUUFBUSxHQUFHO0FBQ2ZDLFFBQUFBLFlBQVksRUFBRTtBQUNaQyxVQUFBQSxNQUFNLEVBQUUsSUFESTtBQUVaQyxVQUFBQSxJQUFJLEVBQUUsSUFGTTtBQUdaQyxVQUFBQSxNQUFNLEVBQUUsSUFISTtBQUlaQyxVQUFBQSxNQUFNLEVBQUU7QUFKSSxTQURDO0FBT2ZDLFFBQUFBLEtBQUssRUFBRTtBQUNMSixVQUFBQSxNQUFNLEVBQUUsSUFESDtBQUVMQyxVQUFBQSxJQUFJLEVBQUUsSUFGRDtBQUdMQyxVQUFBQSxNQUFNLEVBQUUsSUFISDtBQUlMQyxVQUFBQSxNQUFNLEVBQUU7QUFKSCxTQVBRO0FBYWZFLFFBQUFBLFNBQVMsRUFBRTtBQUNUQyxVQUFBQSxJQUFJLEVBQUU7QUFERyxTQWJJO0FBZ0JmQyxRQUFBQSxJQUFJLEVBQUU7QUFDSkMsVUFBQUEsS0FBSyxFQUFFLElBREg7QUFFSkMsVUFBQUEsSUFBSSxFQUFFLElBRkY7QUFHSkMsVUFBQUEsS0FBSyxFQUFFLElBSEg7QUFJSkMsVUFBQUEsS0FBSyxFQUFFLElBSkg7QUFLSkMsVUFBQUEsSUFBSSxFQUFFO0FBTEYsU0FoQlM7QUF1QmZDLFFBQUFBLElBQUksRUFBRTtBQUNKQyxVQUFBQSxhQUFhLEVBQUVqQixNQUFNLENBQUNrQixjQURsQjtBQUVKQyxVQUFBQSxhQUFhLEVBQUVuQixNQUFNLENBQUNvQix1QkFGbEI7QUFHSkMsVUFBQUEsY0FBYyxFQUFFckIsTUFBTSxDQUFDa0IsY0FIbkI7QUFJSkksVUFBQUEsYUFBYSxFQUFFLElBSlg7QUFLSkMsVUFBQUEsWUFBWSxFQUFFO0FBTFYsU0F2QlM7QUE4QmZDLFFBQUFBLE9BQU8sRUFBRTtBQUNQQyxVQUFBQSxRQUFRLEVBQUUsSUFESDtBQUVQQyxVQUFBQSxXQUFXLEVBQUUsSUFGTjtBQUdQQyxVQUFBQSxRQUFRLEVBQUUsSUFISDtBQUlQQyxVQUFBQSxXQUFXLEVBQUUsSUFKTjtBQUtQQyxVQUFBQSxxQkFBcUIsRUFBRSxJQUxoQjtBQU1QQyxVQUFBQSxXQUFXLEVBQUUsS0FOTjtBQU9QQyxVQUFBQSx5QkFBeUIsRUFBRSxJQVBwQjtBQVFQQyxVQUFBQSxzQkFBc0IsRUFBRTtBQVJqQjtBQTlCTSxPQUFqQjtBQTBDQSxhQUFPO0FBQ0xDLFFBQUFBLFFBQVEsRUFBRTtBQUNSaEMsVUFBQUEsUUFBUSxFQUFFQSxRQURGO0FBRVJpQyxVQUFBQSxrQkFBa0IsRUFBRUM7QUFGWjtBQURMLE9BQVA7QUFNRCxLQWxERDtBQW1ERDs7QUFyRCtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgRmVhdHVyZXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zZXJ2ZXJJbmZvJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSByZXE7XG4gICAgICBjb25zdCBmZWF0dXJlcyA9IHtcbiAgICAgICAgZ2xvYmFsQ29uZmlnOiB7XG4gICAgICAgICAgY3JlYXRlOiB0cnVlLFxuICAgICAgICAgIHJlYWQ6IHRydWUsXG4gICAgICAgICAgdXBkYXRlOiB0cnVlLFxuICAgICAgICAgIGRlbGV0ZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgaG9va3M6IHtcbiAgICAgICAgICBjcmVhdGU6IHRydWUsXG4gICAgICAgICAgcmVhZDogdHJ1ZSxcbiAgICAgICAgICB1cGRhdGU6IHRydWUsXG4gICAgICAgICAgZGVsZXRlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjbG91ZENvZGU6IHtcbiAgICAgICAgICBqb2JzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBsb2dzOiB7XG4gICAgICAgICAgbGV2ZWw6IHRydWUsXG4gICAgICAgICAgc2l6ZTogdHJ1ZSxcbiAgICAgICAgICBvcmRlcjogdHJ1ZSxcbiAgICAgICAgICB1bnRpbDogdHJ1ZSxcbiAgICAgICAgICBmcm9tOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBwdXNoOiB7XG4gICAgICAgICAgaW1tZWRpYXRlUHVzaDogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHNjaGVkdWxlZFB1c2g6IGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICAgICAgICBzdG9yZWRQdXNoRGF0YTogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHB1c2hBdWRpZW5jZXM6IHRydWUsXG4gICAgICAgICAgbG9jYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgYWRkRmllbGQ6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlRmllbGQ6IHRydWUsXG4gICAgICAgICAgYWRkQ2xhc3M6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlQ2xhc3M6IHRydWUsXG4gICAgICAgICAgY2xlYXJBbGxEYXRhRnJvbUNsYXNzOiB0cnVlLFxuICAgICAgICAgIGV4cG9ydENsYXNzOiBmYWxzZSxcbiAgICAgICAgICBlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zOiB0cnVlLFxuICAgICAgICAgIGVkaXRQb2ludGVyUGVybWlzc2lvbnM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGZlYXR1cmVzOiBmZWF0dXJlcyxcbiAgICAgICAgICBwYXJzZVNlcnZlclZlcnNpb246IHZlcnNpb24sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/FilesRouter.js b/lib/Routers/FilesRouter.js deleted file mode 100644 index 9927bbfe57..0000000000 --- a/lib/Routers/FilesRouter.js +++ /dev/null @@ -1,260 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FilesRouter = void 0; - -var _express = _interopRequireDefault(require("express")); - -var _bodyParser = _interopRequireDefault(require("body-parser")); - -var Middlewares = _interopRequireWildcard(require("../middlewares")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _mime = _interopRequireDefault(require("mime")); - -var _logger = _interopRequireDefault(require("../logger")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const triggers = require('../triggers'); - -const http = require('http'); - -const downloadFileFromURI = uri => { - return new Promise((res, rej) => { - http.get(uri, response => { - response.setDefaultEncoding('base64'); - let body = `data:${response.headers['content-type']};base64,`; - response.on('data', data => body += data); - response.on('end', () => res(body)); - }).on('error', e => { - rej(`Error downloading file from ${uri}: ${e.message}`); - }); - }); -}; - -const addFileDataIfNeeded = async file => { - if (file._source.format === 'uri') { - const base64 = await downloadFileFromURI(file._source.uri); - file._previousSave = file; - file._data = base64; - file._requestTask = null; - } - - return file; -}; - -class FilesRouter { - expressRouter({ - maxUploadSize = '20Mb' - } = {}) { - var router = _express.default.Router(); - - router.get('/files/:appId/:filename', this.getHandler); - router.get('/files/:appId/metadata/:filename', this.metadataHandler); - router.post('/files', function (req, res, next) { - next(new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename not provided.')); - }); - router.post('/files/:filename', _bodyParser.default.raw({ - type: () => { - return true; - }, - limit: maxUploadSize - }), // Allow uploads without Content-Type, or with any Content-Type. - Middlewares.handleParseHeaders, this.createHandler); - router.delete('/files/:filename', Middlewares.handleParseHeaders, Middlewares.enforceMasterKeyAccess, this.deleteHandler); - return router; - } - - getHandler(req, res) { - const config = _Config.default.get(req.params.appId); - - const filesController = config.filesController; - const filename = req.params.filename; - - const contentType = _mime.default.getType(filename); - - if (isFileStreamable(req, filesController)) { - filesController.handleFileStream(config, filename, req, res, contentType).catch(() => { - res.status(404); - res.set('Content-Type', 'text/plain'); - res.end('File not found.'); - }); - } else { - filesController.getFileData(config, filename).then(data => { - res.status(200); - res.set('Content-Type', contentType); - res.set('Content-Length', data.length); - res.end(data); - }).catch(() => { - res.status(404); - res.set('Content-Type', 'text/plain'); - res.end('File not found.'); - }); - } - } - - async createHandler(req, res, next) { - const config = req.config; - const filesController = config.filesController; - const { - filename - } = req.params; - const contentType = req.get('Content-type'); - - if (!req.body || !req.body.length) { - next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.')); - return; - } - - const error = filesController.validateFilename(filename); - - if (error) { - next(error); - return; - } - - const base64 = req.body.toString('base64'); - const file = new _node.default.File(filename, { - base64 - }, contentType); - const { - metadata = {}, - tags = {} - } = req.fileData || {}; - file.setTags(tags); - file.setMetadata(metadata); - const fileSize = Buffer.byteLength(req.body); - const fileObject = { - file, - fileSize - }; - - try { - // run beforeSaveFile trigger - const triggerResult = await triggers.maybeRunFileTrigger(triggers.Types.beforeSaveFile, fileObject, config, req.auth); - let saveResult; // if a new ParseFile is returned check if it's an already saved file - - if (triggerResult instanceof _node.default.File) { - fileObject.file = triggerResult; - - if (triggerResult.url()) { - // set fileSize to null because we wont know how big it is here - fileObject.fileSize = null; - saveResult = { - url: triggerResult.url(), - name: triggerResult._name - }; - } - } // if the file returned by the trigger has already been saved skip saving anything - - - if (!saveResult) { - // if the ParseFile returned is type uri, download the file before saving it - await addFileDataIfNeeded(fileObject.file); // update fileSize - - const bufferData = Buffer.from(fileObject.file._data, 'base64'); - fileObject.fileSize = Buffer.byteLength(bufferData); // save file - - const createFileResult = await filesController.createFile(config, fileObject.file._name, bufferData, fileObject.file._source.type, { - tags: fileObject.file._tags, - metadata: fileObject.file._metadata - }); // update file with new data - - fileObject.file._name = createFileResult.name; - fileObject.file._url = createFileResult.url; - fileObject.file._requestTask = null; - fileObject.file._previousSave = Promise.resolve(fileObject.file); - saveResult = { - url: createFileResult.url, - name: createFileResult.name - }; - } // run afterSaveFile trigger - - - await triggers.maybeRunFileTrigger(triggers.Types.afterSaveFile, fileObject, config, req.auth); - res.status(201); - res.set('Location', saveResult.url); - res.json(saveResult); - } catch (e) { - _logger.default.error('Error creating a file: ', e); - - const error = triggers.resolveError(e, { - code: _node.default.Error.FILE_SAVE_ERROR, - message: `Could not store file: ${fileObject.file._name}.` - }); - next(error); - } - } - - async deleteHandler(req, res, next) { - try { - const { - filesController - } = req.config; - const { - filename - } = req.params; // run beforeDeleteFile trigger - - const file = new _node.default.File(filename); - file._url = filesController.adapter.getFileLocation(req.config, filename); - const fileObject = { - file, - fileSize: null - }; - await triggers.maybeRunFileTrigger(triggers.Types.beforeDeleteFile, fileObject, req.config, req.auth); // delete file - - await filesController.deleteFile(req.config, filename); // run afterDeleteFile trigger - - await triggers.maybeRunFileTrigger(triggers.Types.afterDeleteFile, fileObject, req.config, req.auth); - res.status(200); // TODO: return useful JSON here? - - res.end(); - } catch (e) { - _logger.default.error('Error deleting a file: ', e); - - const error = triggers.resolveError(e, { - code: _node.default.Error.FILE_DELETE_ERROR, - message: 'Could not delete file.' - }); - next(error); - } - } - - async metadataHandler(req, res) { - const config = _Config.default.get(req.params.appId); - - const { - filesController - } = config; - const { - filename - } = req.params; - - try { - const data = await filesController.getMetadata(filename); - res.status(200); - res.json(data); - } catch (e) { - res.status(200); - res.json({}); - } - } - -} - -exports.FilesRouter = FilesRouter; - -function isFileStreamable(req, filesController) { - return req.get('Range') && typeof filesController.adapter.handleFileStream === 'function'; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZpbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbInRyaWdnZXJzIiwicmVxdWlyZSIsImh0dHAiLCJkb3dubG9hZEZpbGVGcm9tVVJJIiwidXJpIiwiUHJvbWlzZSIsInJlcyIsInJlaiIsImdldCIsInJlc3BvbnNlIiwic2V0RGVmYXVsdEVuY29kaW5nIiwiYm9keSIsImhlYWRlcnMiLCJvbiIsImRhdGEiLCJlIiwibWVzc2FnZSIsImFkZEZpbGVEYXRhSWZOZWVkZWQiLCJmaWxlIiwiX3NvdXJjZSIsImZvcm1hdCIsImJhc2U2NCIsIl9wcmV2aW91c1NhdmUiLCJfZGF0YSIsIl9yZXF1ZXN0VGFzayIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsIm1heFVwbG9hZFNpemUiLCJyb3V0ZXIiLCJleHByZXNzIiwiUm91dGVyIiwiZ2V0SGFuZGxlciIsIm1ldGFkYXRhSGFuZGxlciIsInBvc3QiLCJyZXEiLCJuZXh0IiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIiwiQm9keVBhcnNlciIsInJhdyIsInR5cGUiLCJsaW1pdCIsIk1pZGRsZXdhcmVzIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiY3JlYXRlSGFuZGxlciIsImRlbGV0ZSIsImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJkZWxldGVIYW5kbGVyIiwiY29uZmlnIiwiQ29uZmlnIiwicGFyYW1zIiwiYXBwSWQiLCJmaWxlc0NvbnRyb2xsZXIiLCJmaWxlbmFtZSIsImNvbnRlbnRUeXBlIiwibWltZSIsImdldFR5cGUiLCJpc0ZpbGVTdHJlYW1hYmxlIiwiaGFuZGxlRmlsZVN0cmVhbSIsImNhdGNoIiwic3RhdHVzIiwic2V0IiwiZW5kIiwiZ2V0RmlsZURhdGEiLCJ0aGVuIiwibGVuZ3RoIiwiRklMRV9TQVZFX0VSUk9SIiwiZXJyb3IiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwidG9TdHJpbmciLCJGaWxlIiwibWV0YWRhdGEiLCJ0YWdzIiwiZmlsZURhdGEiLCJzZXRUYWdzIiwic2V0TWV0YWRhdGEiLCJmaWxlU2l6ZSIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJmaWxlT2JqZWN0IiwidHJpZ2dlclJlc3VsdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJUeXBlcyIsImJlZm9yZVNhdmVGaWxlIiwiYXV0aCIsInNhdmVSZXN1bHQiLCJ1cmwiLCJuYW1lIiwiX25hbWUiLCJidWZmZXJEYXRhIiwiZnJvbSIsImNyZWF0ZUZpbGVSZXN1bHQiLCJjcmVhdGVGaWxlIiwiX3RhZ3MiLCJfbWV0YWRhdGEiLCJfdXJsIiwicmVzb2x2ZSIsImFmdGVyU2F2ZUZpbGUiLCJqc29uIiwibG9nZ2VyIiwicmVzb2x2ZUVycm9yIiwiY29kZSIsImFkYXB0ZXIiLCJnZXRGaWxlTG9jYXRpb24iLCJiZWZvcmVEZWxldGVGaWxlIiwiZGVsZXRlRmlsZSIsImFmdGVyRGVsZXRlRmlsZSIsIkZJTEVfREVMRVRFX0VSUk9SIiwiZ2V0TWV0YWRhdGEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFDQSxNQUFNQSxRQUFRLEdBQUdDLE9BQU8sQ0FBQyxhQUFELENBQXhCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLE1BQUQsQ0FBcEI7O0FBRUEsTUFBTUUsbUJBQW1CLEdBQUdDLEdBQUcsSUFBSTtBQUNqQyxTQUFPLElBQUlDLE9BQUosQ0FBWSxDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUMvQkwsSUFBQUEsSUFBSSxDQUNETSxHQURILENBQ09KLEdBRFAsRUFDWUssUUFBUSxJQUFJO0FBQ3BCQSxNQUFBQSxRQUFRLENBQUNDLGtCQUFULENBQTRCLFFBQTVCO0FBQ0EsVUFBSUMsSUFBSSxHQUFJLFFBQU9GLFFBQVEsQ0FBQ0csT0FBVCxDQUFpQixjQUFqQixDQUFpQyxVQUFwRDtBQUNBSCxNQUFBQSxRQUFRLENBQUNJLEVBQVQsQ0FBWSxNQUFaLEVBQW9CQyxJQUFJLElBQUtILElB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QkFBVCxDQUEwQnhCLEdBQTFCLEVBQStCbUIsZUFBL0IsRUFBZ0Q7QUFDOUMsU0FBT25CLEdBQUcsQ0FBQzFCLEdBQUosQ0FBUSxPQUFSLEtBQW9CLE9BQU82QyxlQUFlLENBQUNrRCxPQUFoQixDQUF3QjVDLGdCQUEvQixLQUFvRCxVQUEvRTtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgQm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQgKiBhcyBNaWRkbGV3YXJlcyBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgbWltZSBmcm9tICdtaW1lJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmNvbnN0IHRyaWdnZXJzID0gcmVxdWlyZSgnLi4vdHJpZ2dlcnMnKTtcbmNvbnN0IGh0dHAgPSByZXF1aXJlKCdodHRwJyk7XG5cbmNvbnN0IGRvd25sb2FkRmlsZUZyb21VUkkgPSB1cmkgPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlcywgcmVqKSA9PiB7XG4gICAgaHR0cFxuICAgICAgLmdldCh1cmksIHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmVzcG9uc2Uuc2V0RGVmYXVsdEVuY29kaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgbGV0IGJvZHkgPSBgZGF0YToke3Jlc3BvbnNlLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddfTtiYXNlNjQsYDtcbiAgICAgICAgcmVzcG9uc2Uub24oJ2RhdGEnLCBkYXRhID0+IChib2R5ICs9IGRhdGEpKTtcbiAgICAgICAgcmVzcG9uc2Uub24oJ2VuZCcsICgpID0+IHJlcyhib2R5KSk7XG4gICAgICB9KVxuICAgICAgLm9uKCdlcnJvcicsIGUgPT4ge1xuICAgICAgICByZWooYEVycm9yIGRvd25sb2FkaW5nIGZpbGUgZnJvbSAke3VyaX06ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfSk7XG4gIH0pO1xufTtcblxuY29uc3QgYWRkRmlsZURhdGFJZk5lZWRlZCA9IGFzeW5jIGZpbGUgPT4ge1xuICBpZiAoZmlsZS5fc291cmNlLmZvcm1hdCA9PT0gJ3VyaScpIHtcbiAgICBjb25zdCBiYXNlNjQgPSBhd2FpdCBkb3dubG9hZEZpbGVGcm9tVVJJKGZpbGUuX3NvdXJjZS51cmkpO1xuICAgIGZpbGUuX3ByZXZpb3VzU2F2ZSA9IGZpbGU7XG4gICAgZmlsZS5fZGF0YSA9IGJhc2U2NDtcbiAgICBmaWxlLl9yZXF1ZXN0VGFzayA9IG51bGw7XG4gIH1cbiAgcmV0dXJuIGZpbGU7XG59O1xuXG5leHBvcnQgY2xhc3MgRmlsZXNSb3V0ZXIge1xuICBleHByZXNzUm91dGVyKHsgbWF4VXBsb2FkU2l6ZSA9ICcyME1iJyB9ID0ge30pIHtcbiAgICB2YXIgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIuZ2V0KCcvZmlsZXMvOmFwcElkLzpmaWxlbmFtZScsIHRoaXMuZ2V0SGFuZGxlcik7XG4gICAgcm91dGVyLmdldCgnL2ZpbGVzLzphcHBJZC9tZXRhZGF0YS86ZmlsZW5hbWUnLCB0aGlzLm1ldGFkYXRhSGFuZGxlcik7XG5cbiAgICByb3V0ZXIucG9zdCgnL2ZpbGVzJywgZnVuY3Rpb24gKHJlcSwgcmVzLCBuZXh0KSB7XG4gICAgICBuZXh0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSwgJ0ZpbGVuYW1lIG5vdCBwcm92aWRlZC4nKSk7XG4gICAgfSk7XG5cbiAgICByb3V0ZXIucG9zdChcbiAgICAgICcvZmlsZXMvOmZpbGVuYW1lJyxcbiAgICAgIEJvZHlQYXJzZXIucmF3KHtcbiAgICAgICAgdHlwZTogKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICBsaW1pdDogbWF4VXBsb2FkU2l6ZSxcbiAgICAgIH0pLCAvLyBBbGxvdyB1cGxvYWRzIHdpdGhvdXQgQ29udGVudC1UeXBlLCBvciB3aXRoIGFueSBDb250ZW50LVR5cGUuXG4gICAgICBNaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUhlYWRlcnMsXG4gICAgICB0aGlzLmNyZWF0ZUhhbmRsZXJcbiAgICApO1xuXG4gICAgcm91dGVyLmRlbGV0ZShcbiAgICAgICcvZmlsZXMvOmZpbGVuYW1lJyxcbiAgICAgIE1pZGRsZXdhcmVzLmhhbmRsZVBhcnNlSGVhZGVycyxcbiAgICAgIE1pZGRsZXdhcmVzLmVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmRlbGV0ZUhhbmRsZXJcbiAgICApO1xuICAgIHJldHVybiByb3V0ZXI7XG4gIH1cblxuICBnZXRIYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChyZXEucGFyYW1zLmFwcElkKTtcbiAgICBjb25zdCBmaWxlc0NvbnRyb2xsZXIgPSBjb25maWcuZmlsZXNDb250cm9sbGVyO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gcmVxLnBhcmFtcy5maWxlbmFtZTtcbiAgICBjb25zdCBjb250ZW50VHlwZSA9IG1pbWUuZ2V0VHlwZShmaWxlbmFtZSk7XG4gICAgaWYgKGlzRmlsZVN0cmVhbWFibGUocmVxLCBmaWxlc0NvbnRyb2xsZXIpKSB7XG4gICAgICBmaWxlc0NvbnRyb2xsZXIuaGFuZGxlRmlsZVN0cmVhbShjb25maWcsIGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDQpO1xuICAgICAgICByZXMuc2V0KCdDb250ZW50LVR5cGUnLCAndGV4dC9wbGFpbicpO1xuICAgICAgICByZXMuZW5kKCdGaWxlIG5vdCBmb3VuZC4nKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaWxlc0NvbnRyb2xsZXJcbiAgICAgICAgLmdldEZpbGVEYXRhKGNvbmZpZywgZmlsZW5hbWUpXG4gICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgICAgICByZXMuc2V0KCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG4gICAgICAgICAgcmVzLnNldCgnQ29udGVudC1MZW5ndGgnLCBkYXRhLmxlbmd0aCk7XG4gICAgICAgICAgcmVzLmVuZChkYXRhKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwNCk7XG4gICAgICAgICAgcmVzLnNldCgnQ29udGVudC1UeXBlJywgJ3RleHQvcGxhaW4nKTtcbiAgICAgICAgICByZXMuZW5kKCdGaWxlIG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY3JlYXRlSGFuZGxlcihyZXEsIHJlcywgbmV4dCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgZmlsZXNDb250cm9sbGVyID0gY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVxLmdldCgnQ29udGVudC10eXBlJyk7XG5cbiAgICBpZiAoIXJlcS5ib2R5IHx8ICFyZXEuYm9keS5sZW5ndGgpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUiwgJ0ludmFsaWQgZmlsZSB1cGxvYWQuJykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVycm9yID0gZmlsZXNDb250cm9sbGVyLnZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZTY0ID0gcmVxLmJvZHkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGZpbGUgPSBuZXcgUGFyc2UuRmlsZShmaWxlbmFtZSwgeyBiYXNlNjQgfSwgY29udGVudFR5cGUpO1xuICAgIGNvbnN0IHsgbWV0YWRhdGEgPSB7fSwgdGFncyA9IHt9IH0gPSByZXEuZmlsZURhdGEgfHwge307XG4gICAgZmlsZS5zZXRUYWdzKHRhZ3MpO1xuICAgIGZpbGUuc2V0TWV0YWRhdGEobWV0YWRhdGEpO1xuICAgIGNvbnN0IGZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgocmVxLmJvZHkpO1xuICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplIH07XG4gICAgdHJ5IHtcbiAgICAgIC8vIHJ1biBiZWZvcmVTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCB0cmlnZ2VyUmVzdWx0ID0gYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5GaWxlVHJpZ2dlcihcbiAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZUZpbGUsXG4gICAgICAgIGZpbGVPYmplY3QsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICBsZXQgc2F2ZVJlc3VsdDtcbiAgICAgIC8vIGlmIGEgbmV3IFBhcnNlRmlsZSBpcyByZXR1cm5lZCBjaGVjayBpZiBpdCdzIGFuIGFscmVhZHkgc2F2ZWQgZmlsZVxuICAgICAgaWYgKHRyaWdnZXJSZXN1bHQgaW5zdGFuY2VvZiBQYXJzZS5GaWxlKSB7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZSA9IHRyaWdnZXJSZXN1bHQ7XG4gICAgICAgIGlmICh0cmlnZ2VyUmVzdWx0LnVybCgpKSB7XG4gICAgICAgICAgLy8gc2V0IGZpbGVTaXplIHRvIG51bGwgYmVjYXVzZSB3ZSB3b250IGtub3cgaG93IGJpZyBpdCBpcyBoZXJlXG4gICAgICAgICAgZmlsZU9iamVjdC5maWxlU2l6ZSA9IG51bGw7XG4gICAgICAgICAgc2F2ZVJlc3VsdCA9IHtcbiAgICAgICAgICAgIHVybDogdHJpZ2dlclJlc3VsdC51cmwoKSxcbiAgICAgICAgICAgIG5hbWU6IHRyaWdnZXJSZXN1bHQuX25hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gaWYgdGhlIGZpbGUgcmV0dXJuZWQgYnkgdGhlIHRyaWdnZXIgaGFzIGFscmVhZHkgYmVlbiBzYXZlZCBza2lwIHNhdmluZyBhbnl0aGluZ1xuICAgICAgaWYgKCFzYXZlUmVzdWx0KSB7XG4gICAgICAgIC8vIGlmIHRoZSBQYXJzZUZpbGUgcmV0dXJuZWQgaXMgdHlwZSB1cmksIGRvd25sb2FkIHRoZSBmaWxlIGJlZm9yZSBzYXZpbmcgaXRcbiAgICAgICAgYXdhaXQgYWRkRmlsZURhdGFJZk5lZWRlZChmaWxlT2JqZWN0LmZpbGUpO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZVNpemVcbiAgICAgICAgY29uc3QgYnVmZmVyRGF0YSA9IEJ1ZmZlci5mcm9tKGZpbGVPYmplY3QuZmlsZS5fZGF0YSwgJ2Jhc2U2NCcpO1xuICAgICAgICBmaWxlT2JqZWN0LmZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgoYnVmZmVyRGF0YSk7XG4gICAgICAgIC8vIHNhdmUgZmlsZVxuICAgICAgICBjb25zdCBjcmVhdGVGaWxlUmVzdWx0ID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmNyZWF0ZUZpbGUoXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSxcbiAgICAgICAgICBidWZmZXJEYXRhLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fc291cmNlLnR5cGUsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGFnczogZmlsZU9iamVjdC5maWxlLl90YWdzLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGZpbGVPYmplY3QuZmlsZS5fbWV0YWRhdGEsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZSB3aXRoIG5ldyBkYXRhXG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSA9IGNyZWF0ZUZpbGVSZXN1bHQubmFtZTtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl91cmwgPSBjcmVhdGVGaWxlUmVzdWx0LnVybDtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl9yZXF1ZXN0VGFzayA9IG51bGw7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fcHJldmlvdXNTYXZlID0gUHJvbWlzZS5yZXNvbHZlKGZpbGVPYmplY3QuZmlsZSk7XG4gICAgICAgIHNhdmVSZXN1bHQgPSB7XG4gICAgICAgICAgdXJsOiBjcmVhdGVGaWxlUmVzdWx0LnVybCxcbiAgICAgICAgICBuYW1lOiBjcmVhdGVGaWxlUmVzdWx0Lm5hbWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBydW4gYWZ0ZXJTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcS5hdXRoXG4gICAgICApO1xuICAgICAgcmVzLnN0YXR1cygyMDEpO1xuICAgICAgcmVzLnNldCgnTG9jYXRpb24nLCBzYXZlUmVzdWx0LnVybCk7XG4gICAgICByZXMuanNvbihzYXZlUmVzdWx0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUixcbiAgICAgICAgbWVzc2FnZTogYENvdWxkIG5vdCBzdG9yZSBmaWxlOiAke2ZpbGVPYmplY3QuZmlsZS5fbmFtZX0uYCxcbiAgICAgIH0pO1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGVsZXRlSGFuZGxlcihyZXEsIHJlcywgbmV4dCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZpbGVzQ29udHJvbGxlciB9ID0gcmVxLmNvbmZpZztcbiAgICAgIGNvbnN0IHsgZmlsZW5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICAvLyBydW4gYmVmb3JlRGVsZXRlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCBmaWxlID0gbmV3IFBhcnNlLkZpbGUoZmlsZW5hbWUpO1xuICAgICAgZmlsZS5fdXJsID0gZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKHJlcS5jb25maWcsIGZpbGVuYW1lKTtcbiAgICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplOiBudWxsIH07XG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVEZWxldGVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aFxuICAgICAgKTtcbiAgICAgIC8vIGRlbGV0ZSBmaWxlXG4gICAgICBhd2FpdCBmaWxlc0NvbnRyb2xsZXIuZGVsZXRlRmlsZShyZXEuY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgICAvLyBydW4gYWZ0ZXJEZWxldGVGaWxlIHRyaWdnZXJcbiAgICAgIGF3YWl0IHRyaWdnZXJzLm1heWJlUnVuRmlsZVRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlRmlsZSxcbiAgICAgICAgZmlsZU9iamVjdCxcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICByZXMuc3RhdHVzKDIwMCk7XG4gICAgICAvLyBUT0RPOiByZXR1cm4gdXNlZnVsIEpTT04gaGVyZT9cbiAgICAgIHJlcy5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGRlbGV0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfREVMRVRFX0VSUk9SLFxuICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlbGV0ZSBmaWxlLicsXG4gICAgICB9KTtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG1ldGFkYXRhSGFuZGxlcihyZXEsIHJlcykge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCk7XG4gICAgY29uc3QgeyBmaWxlc0NvbnRyb2xsZXIgfSA9IGNvbmZpZztcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmdldE1ldGFkYXRhKGZpbGVuYW1lKTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKHt9KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNGaWxlU3RyZWFtYWJsZShyZXEsIGZpbGVzQ29udHJvbGxlcikge1xuICByZXR1cm4gcmVxLmdldCgnUmFuZ2UnKSAmJiB0eXBlb2YgZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuaGFuZGxlRmlsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/FunctionsRouter.js b/lib/Routers/FunctionsRouter.js deleted file mode 100644 index 0e5c6b67d3..0000000000 --- a/lib/Routers/FunctionsRouter.js +++ /dev/null @@ -1,181 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FunctionsRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _middlewares = require("../middlewares"); - -var _StatusHandler = require("../StatusHandler"); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _logger = require("../logger"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// FunctionsRouter.js -var Parse = require('parse/node').Parse, - triggers = require('../triggers'); - -function parseObject(obj) { - if (Array.isArray(obj)) { - return obj.map(item => { - return parseObject(item); - }); - } else if (obj && obj.__type == 'Date') { - return Object.assign(new Date(obj.iso), obj); - } else if (obj && obj.__type == 'File') { - return Parse.File.fromJSON(obj); - } else if (obj && typeof obj === 'object') { - return parseParams(obj); - } else { - return obj; - } -} - -function parseParams(params) { - return _lodash.default.mapValues(params, parseObject); -} - -class FunctionsRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('POST', '/functions/:functionName', _middlewares.promiseEnsureIdempotency, FunctionsRouter.handleCloudFunction); - this.route('POST', '/jobs/:jobName', _middlewares.promiseEnsureIdempotency, _middlewares.promiseEnforceMasterKeyAccess, function (req) { - return FunctionsRouter.handleCloudJob(req); - }); - this.route('POST', '/jobs', _middlewares.promiseEnforceMasterKeyAccess, function (req) { - return FunctionsRouter.handleCloudJob(req); - }); - } - - static handleCloudJob(req) { - const jobName = req.params.jobName || req.body.jobName; - const applicationId = req.config.applicationId; - const jobHandler = (0, _StatusHandler.jobStatusHandler)(req.config); - const jobFunction = triggers.getJob(jobName, applicationId); - - if (!jobFunction) { - throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid job.'); - } - - let params = Object.assign({}, req.body, req.query); - params = parseParams(params); - const request = { - params: params, - log: req.config.loggerController, - headers: req.config.headers, - ip: req.config.ip, - jobName, - message: jobHandler.setMessage.bind(jobHandler) - }; - return jobHandler.setRunning(jobName, params).then(jobStatus => { - request.jobId = jobStatus.objectId; // run the function async - - process.nextTick(() => { - Promise.resolve().then(() => { - return jobFunction(request); - }).then(result => { - jobHandler.setSucceeded(result); - }, error => { - jobHandler.setFailed(error); - }); - }); - return { - headers: { - 'X-Parse-Job-Status-Id': jobStatus.objectId - }, - response: {} - }; - }); - } - - static createResponseObject(resolve, reject) { - return { - success: function (result) { - resolve({ - response: { - result: Parse._encode(result) - } - }); - }, - error: function (message) { - const error = triggers.resolveError(message); - reject(error); - } - }; - } - - static handleCloudFunction(req) { - const functionName = req.params.functionName; - const applicationId = req.config.applicationId; - const theFunction = triggers.getFunction(functionName, applicationId); - - if (!theFunction) { - throw new Parse.Error(Parse.Error.SCRIPT_FAILED, `Invalid function: "${functionName}"`); - } - - let params = Object.assign({}, req.body, req.query); - params = parseParams(params); - const request = { - params: params, - master: req.auth && req.auth.isMaster, - user: req.auth && req.auth.user, - installationId: req.info.installationId, - log: req.config.loggerController, - headers: req.config.headers, - ip: req.config.ip, - functionName, - context: req.info.context - }; - return new Promise(function (resolve, reject) { - const userString = req.auth && req.auth.user ? req.auth.user.id : undefined; - - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(params)); - - const { - success, - error - } = FunctionsRouter.createResponseObject(result => { - try { - const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result.response.result)); - - _logger.logger.info(`Ran cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { - functionName, - params, - user: userString - }); - - resolve(result); - } catch (e) { - reject(e); - } - }, error => { - try { - _logger.logger.error(`Failed running cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Error: ` + JSON.stringify(error), { - functionName, - error, - params, - user: userString - }); - - reject(error); - } catch (e) { - reject(e); - } - }); - return Promise.resolve().then(() => { - return triggers.maybeRunValidator(request, functionName); - }).then(() => { - return theFunction(request); - }).then(success, error); - }); - } - -} - -exports.FunctionsRouter = FunctionsRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ0cmlnZ2VycyIsInBhcnNlT2JqZWN0Iiwib2JqIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwiaXRlbSIsIl9fdHlwZSIsIk9iamVjdCIsImFzc2lnbiIsIkRhdGUiLCJpc28iLCJGaWxlIiwiZnJvbUpTT04iLCJwYXJzZVBhcmFtcyIsInBhcmFtcyIsIl8iLCJtYXBWYWx1ZXMiLCJGdW5jdGlvbnNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInJlcSIsImhhbmRsZUNsb3VkSm9iIiwiam9iTmFtZSIsImJvZHkiLCJhcHBsaWNhdGlvbklkIiwiY29uZmlnIiwiam9iSGFuZGxlciIsImpvYkZ1bmN0aW9uIiwiZ2V0Sm9iIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwicXVlcnkiLCJyZXF1ZXN0IiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImhlYWRlcnMiLCJpcCIsIm1lc3NhZ2UiLCJzZXRNZXNzYWdlIiwiYmluZCIsInNldFJ1bm5pbmciLCJ0aGVuIiwiam9iU3RhdHVzIiwiam9iSWQiLCJvYmplY3RJZCIsInByb2Nlc3MiLCJuZXh0VGljayIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0Iiwic2V0U3VjY2VlZGVkIiwiZXJyb3IiLCJzZXRGYWlsZWQiLCJyZXNwb25zZSIsImNyZWF0ZVJlc3BvbnNlT2JqZWN0IiwicmVqZWN0Iiwic3VjY2VzcyIsIl9lbmNvZGUiLCJyZXNvbHZlRXJyb3IiLCJmdW5jdGlvbk5hbWUiLCJ0aGVGdW5jdGlvbiIsImdldEZ1bmN0aW9uIiwibWFzdGVyIiwiYXV0aCIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwiaW5mbyIsImNvbnRleHQiLCJ1c2VyU3RyaW5nIiwiaWQiLCJ1bmRlZmluZWQiLCJjbGVhbklucHV0IiwibG9nZ2VyIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsImNsZWFuUmVzdWx0IiwiZSIsIm1heWJlUnVuVmFsaWRhdG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFUQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxRQUFRLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBRHBCOztBQVNBLFNBQVNFLFdBQVQsQ0FBcUJDLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlDLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBRyxDQUFDRyxHQUFKLENBQVFDLElBQUksSUFBSTtBQUNyQixhQUFPTCxXQUFXLENBQUNLLElBQUQsQ0FBbEI7QUFDRCxLQUZNLENBQVA7QUFHRCxHQUpELE1BSU8sSUFBSUosR0FBRyxJQUFJQSxHQUFHLENBQUNLLE1BQUosSUFBYyxNQUF6QixFQUFpQztBQUN0QyxXQUFPQyxNQUFNLENBQUNDLE1BQVAsQ0FBYyxJQUFJQyxJQUFKLENBQVNSLEdBQUcsQ0FBQ1MsR0FBYixDQUFkLEVBQWlDVCxHQUFqQyxDQUFQO0FBQ0QsR0FGTSxNQUVBLElBQUlBLEdBQUcsSUFBSUEsR0FBRyxDQUFDSyxNQUFKLElBQWMsTUFBekIsRUFBaUM7QUFDdEMsV0FBT1QsS0FBSyxDQUFDYyxJQUFOLENBQVdDLFFBQVgsQ0FBb0JYLEdBQXBCLENBQVA7QUFDRCxHQUZNLE1BRUEsSUFBSUEsR0FBRyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUExQixFQUFvQztBQUN6QyxXQUFPWSxXQUFXLENBQUNaLEdBQUQsQ0FBbEI7QUFDRCxHQUZNLE1BRUE7QUFDTCxXQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7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LEVBQW9DMkIsWUFBcEMsQ0FBUDtBQUNELE9BSEksRUFJSmxCLElBSkksQ0FJQyxNQUFNO0FBQ1YsZUFBT21CLFdBQVcsQ0FBQzVCLE9BQUQsQ0FBbEI7QUFDRCxPQU5JLEVBT0pTLElBUEksQ0FPQ2UsT0FQRCxFQU9VTCxLQVBWLENBQVA7QUFRRCxLQTlDTSxDQUFQO0FBK0NEOztBQXZKZ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBGdW5jdGlvbnNSb3V0ZXIuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5cbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHsgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCB7IGpvYlN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuXG5mdW5jdGlvbiBwYXJzZU9iamVjdChvYmopIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBvYmoubWFwKGl0ZW0gPT4ge1xuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0KGl0ZW0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdEYXRlJykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBEYXRlKG9iai5pc28pLCBvYmopO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdGaWxlJykge1xuICAgIHJldHVybiBQYXJzZS5GaWxlLmZyb21KU09OKG9iaik7XG4gIH0gZWxzZSBpZiAob2JqICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHBhcnNlUGFyYW1zKG9iaik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtcyhwYXJhbXMpIHtcbiAgcmV0dXJuIF8ubWFwVmFsdWVzKHBhcmFtcywgcGFyc2VPYmplY3QpO1xufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25zUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIEZ1bmN0aW9uc1JvdXRlci5oYW5kbGVDbG91ZEZ1bmN0aW9uXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9qb2JzLzpqb2JOYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgZnVuY3Rpb24gKHJlcSkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkSm9iKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9qb2JzJywgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAgIHJldHVybiBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRKb2IocmVxKTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVDbG91ZEpvYihyZXEpIHtcbiAgICBjb25zdCBqb2JOYW1lID0gcmVxLnBhcmFtcy5qb2JOYW1lIHx8IHJlcS5ib2R5LmpvYk5hbWU7XG4gICAgY29uc3QgYXBwbGljYXRpb25JZCA9IHJlcS5jb25maWcuYXBwbGljYXRpb25JZDtcbiAgICBjb25zdCBqb2JIYW5kbGVyID0gam9iU3RhdHVzSGFuZGxlcihyZXEuY29uZmlnKTtcbiAgICBjb25zdCBqb2JGdW5jdGlvbiA9IHRyaWdnZXJzLmdldEpvYihqb2JOYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgICBpZiAoIWpvYkZ1bmN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCwgJ0ludmFsaWQgam9iLicpO1xuICAgIH1cbiAgICBsZXQgcGFyYW1zID0gT2JqZWN0LmFzc2lnbih7fSwgcmVxLmJvZHksIHJlcS5xdWVyeSk7XG4gICAgcGFyYW1zID0gcGFyc2VQYXJhbXMocGFyYW1zKTtcbiAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICBsb2c6IHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICAgIGhlYWRlcnM6IHJlcS5jb25maWcuaGVhZGVycyxcbiAgICAgIGlwOiByZXEuY29uZmlnLmlwLFxuICAgICAgam9iTmFtZSxcbiAgICAgIG1lc3NhZ2U6IGpvYkhhbmRsZXIuc2V0TWVzc2FnZS5iaW5kKGpvYkhhbmRsZXIpLFxuICAgIH07XG5cbiAgICByZXR1cm4gam9iSGFuZGxlci5zZXRSdW5uaW5nKGpvYk5hbWUsIHBhcmFtcykudGhlbihqb2JTdGF0dXMgPT4ge1xuICAgICAgcmVxdWVzdC5qb2JJZCA9IGpvYlN0YXR1cy5vYmplY3RJZDtcbiAgICAgIC8vIHJ1biB0aGUgZnVuY3Rpb24gYXN5bmNcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBqb2JGdW5jdGlvbihyZXF1ZXN0KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgam9iSGFuZGxlci5zZXRTdWNjZWVkZWQocmVzdWx0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIGpvYkhhbmRsZXIuc2V0RmFpbGVkKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCc6IGpvYlN0YXR1cy5vYmplY3RJZCxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSZXNwb25zZU9iamVjdChyZXNvbHZlLCByZWplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgcmVzdWx0OiBQYXJzZS5fZW5jb2RlKHJlc3VsdCksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gdHJpZ2dlcnMucmVzb2x2ZUVycm9yKG1lc3NhZ2UpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBoYW5kbGVDbG91ZEZ1bmN0aW9uKHJlcSkge1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgIGNvbnN0IGFwcGxpY2F0aW9uSWQgPSByZXEuY29uZmlnLmFwcGxpY2F0aW9uSWQ7XG4gICAgY29uc3QgdGhlRnVuY3Rpb24gPSB0cmlnZ2Vycy5nZXRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuXG4gICAgaWYgKCF0aGVGdW5jdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsIGBJbnZhbGlkIGZ1bmN0aW9uOiBcIiR7ZnVuY3Rpb25OYW1lfVwiYCk7XG4gICAgfVxuICAgIGxldCBwYXJhbXMgPSBPYmplY3QuYXNzaWduKHt9LCByZXEuYm9keSwgcmVxLnF1ZXJ5KTtcbiAgICBwYXJhbXMgPSBwYXJzZVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgIG1hc3RlcjogcmVxLmF1dGggJiYgcmVxLmF1dGguaXNNYXN0ZXIsXG4gICAgICB1c2VyOiByZXEuYXV0aCAmJiByZXEuYXV0aC51c2VyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5pbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgbG9nOiByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgICBoZWFkZXJzOiByZXEuY29uZmlnLmhlYWRlcnMsXG4gICAgICBpcDogcmVxLmNvbmZpZy5pcCxcbiAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgIGNvbnRleHQ6IHJlcS5pbmZvLmNvbnRleHQsXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBjb25zdCB1c2VyU3RyaW5nID0gcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgIGNvbnN0IHsgc3VjY2VzcywgZXJyb3IgfSA9IEZ1bmN0aW9uc1JvdXRlci5jcmVhdGVSZXNwb25zZU9iamVjdChcbiAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY2xlYW5SZXN1bHQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KHJlc3VsdC5yZXNwb25zZS5yZXN1bHQpKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICBgUmFuIGNsb3VkIGZ1bmN0aW9uICR7ZnVuY3Rpb25OYW1lfSBmb3IgdXNlciAke3VzZXJTdHJpbmd9IHdpdGg6XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBjbG91ZCBmdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX0gZm9yIHVzZXIgJHt1c2VyU3RyaW5nfSB3aXRoOlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvciksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBmdW5jdGlvbk5hbWUpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoZUZ1bmN0aW9uKHJlcXVlc3QpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/GlobalConfigRouter.js b/lib/Routers/GlobalConfigRouter.js deleted file mode 100644 index 7156f27974..0000000000 --- a/lib/Routers/GlobalConfigRouter.js +++ /dev/null @@ -1,95 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GlobalConfigRouter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// global_config.js -class GlobalConfigRouter extends _PromiseRouter.default { - getGlobalConfig(req) { - return req.config.database.find('_GlobalConfig', { - objectId: '1' - }, { - limit: 1 - }).then(results => { - if (results.length != 1) { - // If there is no config in the database - return empty config. - return { - response: { - params: {} - } - }; - } - - const globalConfig = results[0]; - - if (!req.auth.isMaster && globalConfig.masterKeyOnly !== undefined) { - for (const param in globalConfig.params) { - if (globalConfig.masterKeyOnly[param]) { - delete globalConfig.params[param]; - delete globalConfig.masterKeyOnly[param]; - } - } - } - - return { - response: { - params: globalConfig.params, - masterKeyOnly: globalConfig.masterKeyOnly - } - }; - }); - } - - updateGlobalConfig(req) { - if (req.auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the config."); - } - - const params = req.body.params; - const masterKeyOnly = req.body.masterKeyOnly || {}; // Transform in dot notation to make sure it works - - const update = Object.keys(params).reduce((acc, key) => { - acc[`params.${key}`] = params[key]; - acc[`masterKeyOnly.${key}`] = masterKeyOnly[key] || false; - return acc; - }, {}); - return req.config.database.update('_GlobalConfig', { - objectId: '1' - }, update, { - upsert: true - }).then(() => ({ - response: { - result: true - } - })); - } - - mountRoutes() { - this.route('GET', '/config', req => { - return this.getGlobalConfig(req); - }); - this.route('PUT', '/config', middleware.promiseEnforceMasterKeyAccess, req => { - return this.updateGlobalConfig(req); - }); - } - -} - -exports.GlobalConfigRouter = GlobalConfigRouter; -var _default = GlobalConfigRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dsb2JhbENvbmZpZ1JvdXRlci5qcyJdLCJuYW1lcyI6WyJHbG9iYWxDb25maWdSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiZ2V0R2xvYmFsQ29uZmlnIiwicmVxIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwib2JqZWN0SWQiLCJsaW1pdCIsInRoZW4iLCJyZXN1bHRzIiwibGVuZ3RoIiwicmVzcG9uc2UiLCJwYXJhbXMiLCJnbG9iYWxDb25maWciLCJhdXRoIiwiaXNNYXN0ZXIiLCJtYXN0ZXJLZXlPbmx5IiwidW5kZWZpbmVkIiwicGFyYW0iLCJ1cGRhdGVHbG9iYWxDb25maWciLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwidXBkYXRlIiwiT2JqZWN0Iiwia2V5cyIsInJlZHVjZSIsImFjYyIsImtleSIsInVwc2VydCIsInJlc3VsdCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFIQTtBQUtPLE1BQU1BLGtCQUFOLFNBQWlDQyxzQkFBakMsQ0FBK0M7QUFDcERDLEVBQUFBLGVBQWUsQ0FBQ0MsR0FBRCxFQUFNO0FBQ25CLFdBQU9BLEdBQUcsQ0FBQ0MsTUFBSixDQUFXQyxRQUFYLENBQ0pDLElBREksQ0FDQyxlQURELEVBQ2tCO0FBQUVDLE1BQUFBLFFBQVEsRUFBRTtBQUFaLEtBRGxCLEVBQ3FDO0FBQUVDLE1BQUFBLEtBQUssRUFBRTtBQUFULEtBRHJDLEVBRUpDLElBRkksQ0FFQ0MsT0FBTyxJQUFJO0FBQ2YsVUFBSUEsT0FBTyxDQUFDQyxNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCO0FBQ0EsZUFBTztBQUFFQyxVQUFBQSxRQUFRLEVBQUU7QUFBRUMsWUFBQUEsTUFBTSxFQUFFO0FBQVY7QUFBWixTQUFQO0FBQ0Q7O0FBQ0QsWUFBTUMsWUFBWSxHQUFHSixPQUFPLENBQUMsQ0FBRCxDQUE1Qjs7QUFDQSxVQUFJLENBQUNQLEdBQUcsQ0FBQ1ksSUFBSixDQUFTQyxRQUFWLElBQXNCRixZQUFZLENBQUNHLGFBQWIsS0FBK0JDLFNBQXpELEVBQW9FO0FBQ2xFLGFBQUssTUFBTUMsS0FBWCxJQUFvQkwsWUFBWSxDQUFDRCxNQUFqQyxFQUF5QztBQUN2QyxjQUFJQyxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQUosRUFBdUM7QUFDckMsbUJBQU9MLFlBQVksQ0FBQ0QsTUFBYixDQUFvQk0sS0FBcEIsQ0FBUDtBQUNBLG1CQUFPTCxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsYUFBTztBQUNMUCxRQUFBQSxRQUFRLEVBQUU7QUFDUkMsVUFBQUEsTUFBTSxFQUFFQyxZQUFZLENBQUNELE1BRGI7QUFFUkksVUFBQUEsYUFBYSxFQUFFSCxZQUFZLENBQUNHO0FBRnBCO0FBREwsT0FBUDtBQU1ELEtBdEJJLENBQVA7QUF1QkQ7O0FBRURHLEVBQUFBLGtCQUFrQixDQUFDakIsR0FBRCxFQUFNO0FBQ3RCLFFBQUlBLEdBQUcsQ0FBQ1ksSUFBSixDQUFTTSxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUoseURBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1YLE1BQU0sR0FBR1YsR0FBRyxDQUFDc0IsSUFBSixDQUFTWixNQUF4QjtBQUNBLFVBQU1JLGFBQWEsR0FBR2QsR0FBRyxDQUFDc0IsSUFBSixDQUFTUixhQUFULElBQTBCLEVBQWhELENBUnNCLENBU3RCOztBQUNBLFVBQU1TLE1BQU0sR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlmLE1BQVosRUFBb0JnQixNQUFwQixDQUEyQixDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUN0REQsTUFBQUEsR0FBRyxDQUFFLFVBQVNDLEdBQUksRUFBZixDQUFILEdBQXVCbEIsTUFBTSxDQUFDa0IsR0FBRCxDQUE3QjtBQUNBRCxNQUFBQSxHQUFHLENBQUUsaUJBQWdCQyxHQUFJLEVBQXRCLENBQUgsR0FBOEJkLGFBQWEsQ0FBQ2MsR0FBRCxDQUFiLElBQXNCLEtBQXBEO0FBQ0EsYUFBT0QsR0FBUDtBQUNELEtBSmMsRUFJWixFQUpZLENBQWY7QUFLQSxXQUFPM0IsR0FBRyxDQUFDQyxNQUFKLENBQVdDLFFBQVgsQ0FDSnFCLE1BREksQ0FDRyxlQURILEVBQ29CO0FBQUVuQixNQUFBQSxRQUFRLEVBQUU7QUFBWixLQURwQixFQUN1Q21CLE1BRHZDLEVBQytDO0FBQUVNLE1BQUFBLE1BQU0sRUFBRTtBQUFWLEtBRC9DLEVBRUp2QixJQUZJLENBRUMsT0FBTztBQUFFRyxNQUFBQSxRQUFRLEVBQUU7QUFBRXFCLFFBQUFBLE1BQU0sRUFBRTtBQUFWO0FBQVosS0FBUCxDQUZELENBQVA7QUFHRDs7QUFFREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsU0FBbEIsRUFBNkJoQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRCxlQUFMLENBQXFCQyxHQUFyQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtnQyxLQUFMLENBQVcsS0FBWCxFQUFrQixTQUFsQixFQUE2QkMsVUFBVSxDQUFDQyw2QkFBeEMsRUFBdUVsQyxHQUFHLElBQUk7QUFDNUUsYUFBTyxLQUFLaUIsa0JBQUwsQ0FBd0JqQixHQUF4QixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQXREbUQ7OztlQXlEdkNILGtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZ2xvYmFsX2NvbmZpZy5qc1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgKiBhcyBtaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuZXhwb3J0IGNsYXNzIEdsb2JhbENvbmZpZ1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBnZXRHbG9iYWxDb25maWcocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5maW5kKCdfR2xvYmFsQ29uZmlnJywgeyBvYmplY3RJZDogJzEnIH0sIHsgbGltaXQ6IDEgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNvbmZpZyBpbiB0aGUgZGF0YWJhc2UgLSByZXR1cm4gZW1wdHkgY29uZmlnLlxuICAgICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7IHBhcmFtczoge30gfSB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdsb2JhbENvbmZpZyA9IHJlc3VsdHNbMF07XG4gICAgICAgIGlmICghcmVxLmF1dGguaXNNYXN0ZXIgJiYgZ2xvYmFsQ29uZmlnLm1hc3RlcktleU9ubHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcGFyYW0gaW4gZ2xvYmFsQ29uZmlnLnBhcmFtcykge1xuICAgICAgICAgICAgaWYgKGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5W3BhcmFtXSkge1xuICAgICAgICAgICAgICBkZWxldGUgZ2xvYmFsQ29uZmlnLnBhcmFtc1twYXJhbV07XG4gICAgICAgICAgICAgIGRlbGV0ZSBnbG9iYWxDb25maWcubWFzdGVyS2V5T25seVtwYXJhbV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHBhcmFtczogZ2xvYmFsQ29uZmlnLnBhcmFtcyxcbiAgICAgICAgICAgIG1hc3RlcktleU9ubHk6IGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUdsb2JhbENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIGNvbmZpZy5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zID0gcmVxLmJvZHkucGFyYW1zO1xuICAgIGNvbnN0IG1hc3RlcktleU9ubHkgPSByZXEuYm9keS5tYXN0ZXJLZXlPbmx5IHx8IHt9O1xuICAgIC8vIFRyYW5zZm9ybSBpbiBkb3Qgbm90YXRpb24gdG8gbWFrZSBzdXJlIGl0IHdvcmtzXG4gICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMocGFyYW1zKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBhY2NbYHBhcmFtcy4ke2tleX1gXSA9IHBhcmFtc1trZXldO1xuICAgICAgYWNjW2BtYXN0ZXJLZXlPbmx5LiR7a2V5fWBdID0gbWFzdGVyS2V5T25seVtrZXldIHx8IGZhbHNlO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC51cGRhdGUoJ19HbG9iYWxDb25maWcnLCB7IG9iamVjdElkOiAnMScgfSwgdXBkYXRlLCB7IHVwc2VydDogdHJ1ZSB9KVxuICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHsgcmVzdWx0OiB0cnVlIH0gfSkpO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jb25maWcnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9jb25maWcnLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR2xvYmFsQ29uZmlnUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/GraphQLRouter.js b/lib/Routers/GraphQLRouter.js deleted file mode 100644 index 67a92b3032..0000000000 --- a/lib/Routers/GraphQLRouter.js +++ /dev/null @@ -1,55 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GraphQLRouter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const GraphQLConfigPath = '/graphql-config'; - -class GraphQLRouter extends _PromiseRouter.default { - async getGraphQLConfig(req) { - const result = await req.config.parseGraphQLController.getGraphQLConfig(); - return { - response: result - }; - } - - async updateGraphQLConfig(req) { - if (req.auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the GraphQL config."); - } - - const data = await req.config.parseGraphQLController.updateGraphQLConfig(req.body.params); - return { - response: data - }; - } - - mountRoutes() { - this.route('GET', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { - return this.getGraphQLConfig(req); - }); - this.route('PUT', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { - return this.updateGraphQLConfig(req); - }); - } - -} - -exports.GraphQLRouter = GraphQLRouter; -var _default = GraphQLRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dyYXBoUUxSb3V0ZXIuanMiXSwibmFtZXMiOlsiR3JhcGhRTENvbmZpZ1BhdGgiLCJHcmFwaFFMUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImdldEdyYXBoUUxDb25maWciLCJyZXEiLCJyZXN1bHQiLCJjb25maWciLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwicmVzcG9uc2UiLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImRhdGEiLCJib2R5IiwicGFyYW1zIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLGlCQUFpQixHQUFHLGlCQUExQjs7QUFFTyxNQUFNQyxhQUFOLFNBQTRCQyxzQkFBNUIsQ0FBMEM7QUFDL0MsUUFBTUMsZ0JBQU4sQ0FBdUJDLEdBQXZCLEVBQTRCO0FBQzFCLFVBQU1DLE1BQU0sR0FBRyxNQUFNRCxHQUFHLENBQUNFLE1BQUosQ0FBV0Msc0JBQVgsQ0FBa0NKLGdCQUFsQyxFQUFyQjtBQUNBLFdBQU87QUFDTEssTUFBQUEsUUFBUSxFQUFFSDtBQURMLEtBQVA7QUFHRDs7QUFFRCxRQUFNSSxtQkFBTixDQUEwQkwsR0FBMUIsRUFBK0I7QUFDN0IsUUFBSUEsR0FBRyxDQUFDTSxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixpRUFGSSxDQUFOO0FBSUQ7O0FBQ0QsVUFBTUMsSUFBSSxHQUFHLE1BQU1YLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxzQkFBWCxDQUFrQ0UsbUJBQWxDLENBQXNETCxHQUFHLENBQUNZLElBQUosQ0FBU0MsTUFBL0QsQ0FBbkI7QUFDQSxXQUFPO0FBQ0xULE1BQUFBLFFBQVEsRUFBRU87QUFETCxLQUFQO0FBR0Q7O0FBRURHLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxLQUFYLEVBQWtCbkIsaUJBQWxCLEVBQXFDb0IsVUFBVSxDQUFDQyw2QkFBaEQsRUFBK0VqQixHQUFHLElBQUk7QUFDcEYsYUFBTyxLQUFLRCxnQkFBTCxDQUFzQkMsR0FBdEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLZSxLQUFMLENBQVcsS0FBWCxFQUFrQm5CLGlCQUFsQixFQUFxQ29CLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFakIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0ssbUJBQUwsQ0FBeUJMLEdBQXpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBNUI4Qzs7O2VBK0JsQ0gsYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmNvbnN0IEdyYXBoUUxDb25maWdQYXRoID0gJy9ncmFwaHFsLWNvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBHcmFwaFFMUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIGFzeW5jIGdldEdyYXBoUUxDb25maWcocmVxKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLmdldEdyYXBoUUxDb25maWcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IHJlc3VsdCxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIEdyYXBoUUwgY29uZmlnLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcocmVxLmJvZHkucGFyYW1zKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IGRhdGEsXG4gICAgfTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BVVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdyYXBoUUxSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/HooksRouter.js b/lib/Routers/HooksRouter.js deleted file mode 100644 index b93d5e0543..0000000000 --- a/lib/Routers/HooksRouter.js +++ /dev/null @@ -1,144 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.HooksRouter = void 0; - -var _node = require("parse/node"); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class HooksRouter extends _PromiseRouter.default { - createHook(aHook, config) { - return config.hooksController.createHook(aHook).then(hook => ({ - response: hook - })); - } - - updateHook(aHook, config) { - return config.hooksController.updateHook(aHook).then(hook => ({ - response: hook - })); - } - - handlePost(req) { - return this.createHook(req.body, req.config); - } - - handleGetFunctions(req) { - var hooksController = req.config.hooksController; - - if (req.params.functionName) { - return hooksController.getFunction(req.params.functionName).then(foundFunction => { - if (!foundFunction) { - throw new _node.Parse.Error(143, `no function named: ${req.params.functionName} is defined`); - } - - return Promise.resolve({ - response: foundFunction - }); - }); - } - - return hooksController.getFunctions().then(functions => { - return { - response: functions || [] - }; - }, err => { - throw err; - }); - } - - handleGetTriggers(req) { - var hooksController = req.config.hooksController; - - if (req.params.className && req.params.triggerName) { - return hooksController.getTrigger(req.params.className, req.params.triggerName).then(foundTrigger => { - if (!foundTrigger) { - throw new _node.Parse.Error(143, `class ${req.params.className} does not exist`); - } - - return Promise.resolve({ - response: foundTrigger - }); - }); - } - - return hooksController.getTriggers().then(triggers => ({ - response: triggers || [] - })); - } - - handleDelete(req) { - var hooksController = req.config.hooksController; - - if (req.params.functionName) { - return hooksController.deleteFunction(req.params.functionName).then(() => ({ - response: {} - })); - } else if (req.params.className && req.params.triggerName) { - return hooksController.deleteTrigger(req.params.className, req.params.triggerName).then(() => ({ - response: {} - })); - } - - return Promise.resolve({ - response: {} - }); - } - - handleUpdate(req) { - var hook; - - if (req.params.functionName && req.body.url) { - hook = {}; - hook.functionName = req.params.functionName; - hook.url = req.body.url; - } else if (req.params.className && req.params.triggerName && req.body.url) { - hook = {}; - hook.className = req.params.className; - hook.triggerName = req.params.triggerName; - hook.url = req.body.url; - } else { - throw new _node.Parse.Error(143, 'invalid hook declaration'); - } - - return this.updateHook(hook, req.config); - } - - handlePut(req) { - var body = req.body; - - if (body.__op == 'Delete') { - return this.handleDelete(req); - } else { - return this.handleUpdate(req); - } - } - - mountRoutes() { - this.route('GET', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); - this.route('GET', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); - this.route('GET', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); - this.route('GET', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); - this.route('POST', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); - this.route('POST', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); - this.route('PUT', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); - this.route('PUT', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); - } - -} - -exports.HooksRouter = HooksRouter; -var _default = HooksRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0hvb2tzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkhvb2tzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImNyZWF0ZUhvb2siLCJhSG9vayIsImNvbmZpZyIsImhvb2tzQ29udHJvbGxlciIsInRoZW4iLCJob29rIiwicmVzcG9uc2UiLCJ1cGRhdGVIb29rIiwiaGFuZGxlUG9zdCIsInJlcSIsImJvZHkiLCJoYW5kbGVHZXRGdW5jdGlvbnMiLCJwYXJhbXMiLCJmdW5jdGlvbk5hbWUiLCJnZXRGdW5jdGlvbiIsImZvdW5kRnVuY3Rpb24iLCJQYXJzZSIsIkVycm9yIiwiUHJvbWlzZSIsInJlc29sdmUiLCJnZXRGdW5jdGlvbnMiLCJmdW5jdGlvbnMiLCJlcnIiLCJoYW5kbGVHZXRUcmlnZ2VycyIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlciIsImZvdW5kVHJpZ2dlciIsImdldFRyaWdnZXJzIiwidHJpZ2dlcnMiLCJoYW5kbGVEZWxldGUiLCJkZWxldGVGdW5jdGlvbiIsImRlbGV0ZVRyaWdnZXIiLCJoYW5kbGVVcGRhdGUiLCJ1cmwiLCJoYW5kbGVQdXQiLCJfX29wIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImJpbmQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFVBQVUsQ0FBQ0MsS0FBRCxFQUFRQyxNQUFSLEVBQWdCO0FBQ3hCLFdBQU9BLE1BQU0sQ0FBQ0MsZUFBUCxDQUF1QkgsVUFBdkIsQ0FBa0NDLEtBQWxDLEVBQXlDRyxJQUF6QyxDQUE4Q0MsSUFBSSxLQUFLO0FBQUVDLE1BQUFBLFFBQVEsRUFBRUQ7QUFBWixLQUFMLENBQWxELENBQVA7QUFDRDs7QUFFREUsRUFBQUEsVUFBVSxDQUFDTixLQUFELEVBQVFDLE1BQVIsRUFBZ0I7QUFDeEIsV0FBT0EsTUFBTSxDQUFDQyxlQUFQLENBQXVCSSxVQUF2QixDQUFrQ04sS0FBbEMsRUFBeUNHLElBQXpDLENBQThDQyxJQUFJLEtBQUs7QUFBRUMsTUFBQUEsUUFBUSxFQUFFRDtBQUFaLEtBQUwsQ0FBbEQsQ0FBUDtBQUNEOztBQUVERyxFQUFBQSxVQUFVLENBQUNDLEdBQUQsRUFBTTtBQUNkLFdBQU8sS0FBS1QsVUFBTCxDQUFnQlMsR0FBRyxDQUFDQyxJQUFwQixFQUEwQkQsR0FBRyxDQUFDUCxNQUE5QixDQUFQO0FBQ0Q7O0FBRURTLEVBQUFBLGtCQUFrQixDQUFDRixHQUFELEVBQU07QUFDdEIsUUFBSU4sZUFBZSxHQUFHTSxHQUFHLENBQUNQLE1BQUosQ0FBV0MsZUFBakM7O0FBQ0EsUUFBSU0sR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQWYsRUFBNkI7QUFDM0IsYUFBT1YsZUFBZSxDQUFDVyxXQUFoQixDQUE0QkwsR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQXZDLEVBQXFEVCxJQUFyRCxDQUEwRFcsYUFBYSxJQUFJO0FBQ2hGLFlBQUksQ0FBQ0EsYUFBTCxFQUFvQjtBQUNsQixnQkFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCLEdBQWhCLEVBQXNCLHNCQUFxQlIsR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQWEsYUFBbkUsQ0FBTjtBQUNEOztBQUNELGVBQU9LLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUFFYixVQUFBQSxRQUFRLEVBQUVTO0FBQVosU0FBaEIsQ0FBUDtBQUNELE9BTE0sQ0FBUDtBQU1EOztBQUVELFdBQU9aLGVBQWUsQ0FBQ2lCLFlBQWhCLEdBQStCaEIsSUFBL0IsQ0FDTGlCLFNBQVMsSUFBSTtBQUNYLGFBQU87QUFBRWYsUUFBQUEsUUFBUSxFQUFFZSxTQUFTLElBQUk7QUFBekIsT0FBUDtBQUNELEtBSEksRUFJTEMsR0FBRyxJQUFJO0FBQ0wsWUFBTUEsR0FBTjtBQUNELEtBTkksQ0FBUDtBQVFEOztBQUVEQyxFQUFBQSxpQkFBaUIsQ0FBQ2QsR0FBRCxFQUFNO0FBQ3JCLFFBQUlOLGVBQWUsR0FBR00sR0FBRyxDQUFDUCxNQUFKLENBQVdDLGVBQWpDOztBQUNBLFFBQUlNLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQUFYLElBQXdCZixHQUFHLENBQUNHLE1BQUosQ0FBV2EsV0FBdkMsRUFBb0Q7QUFDbEQsYUFBT3RCLGVBQWUsQ0FDbkJ1QixVQURJLENBQ09qQixHQUFHLENBQUNHLE1BQUosQ0FBV1ksU0FEbEIsRUFDNkJmLEdBQUcsQ0FBQ0csTUFBSixDQUFXYSxXQUR4QyxFQUVKckIsSUFGSSxDQUVDdUIsWUFBWSxJQUFJO0FBQ3BCLFlBQUksQ0FBQ0EsWUFBTCxFQUFtQjtBQUNqQixnQkFBTSxJQUFJWCxZQUFNQyxLQUFWLENBQWdCLEdBQWhCLEVBQXNCLFNBQVFSLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQUFVLGlCQUFuRCxDQUFOO0FBQ0Q7O0FBQ0QsZUFBT04sT0FBTyxDQUFDQyxPQUFSLENBQWdCO0FBQUViLFVBQUFBLFFBQVEsRUFBRXFCO0FBQVosU0FBaEIsQ0FBUDtBQUNELE9BUEksQ0FBUDtBQVFEOztBQUVELFdBQU94QixlQUFlLENBQUN5QixXQUFoQixHQUE4QnhCLElBQTlCLENBQW1DeUIsUUFBUSxLQUFLO0FBQUV2QixNQUFBQSxRQUFRLEVBQUV1QixRQUFRLElBQUk7QUFBeEIsS0FBTCxDQUEzQyxDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLFlBQVksQ0FBQ3JCLEdBQUQsRUFBTTtBQUNoQixRQUFJTixlQUFlLEdBQUdNLEdBQUcsQ0FBQ1AsTUFBSixDQUFXQyxlQUFqQzs7QUFDQSxRQUFJTSxHQUFHLENBQUNHLE1BQUosQ0FBV0MsWUFBZixFQUE2QjtBQUMzQixhQUFPVixlQUFlLENBQUM0QixjQUFoQixDQUErQnRCLEdBQUcsQ0FBQ0csTUFBSixDQUFXQyxZQUExQyxFQUF3RFQsSUFBeEQsQ0FBNkQsT0FBTztBQUFFRSxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQLENBQTdELENBQVA7QUFDRCxLQUZELE1BRU8sSUFBSUcsR0FBRyxDQUFDRyxNQUFKLENBQVdZLFNBQVgsSUFBd0JmLEdBQUcsQ0FBQ0csTUFBSixDQUFXYSxXQUF2QyxFQUFvRDtBQUN6RCxhQUFPdEIsZUFBZSxDQUNuQjZCLGFBREksQ0FDVXZCLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQURyQixFQUNnQ2YsR0FBRyxDQUFDRyxNQUFKLENBQVdhLFdBRDNDLEVBRUpyQixJQUZJLENBRUMsT0FBTztBQUFFRSxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQLENBRkQsQ0FBUDtBQUdEOztBQUNELFdBQU9ZLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUFFYixNQUFBQSxRQUFRLEVBQUU7QUFBWixLQUFoQixDQUFQO0FBQ0Q7O0FBRUQyQixFQUFBQSxZQUFZLENBQUN4QixHQUFELEVBQU07QUFDaEIsUUFBSUosSUFBSjs7QUFDQSxRQUFJSSxHQUFHLENBQUNHLE1BQUosQ0FBV0MsWUFBWCxJQUEyQkosR0FBRyxDQUFDQyxJQUFKLENBQVN3QixHQUF4QyxFQUE2QztBQUMzQzdCLE1BQUFBLElBQUksR0FBRyxFQUFQO0FBQ0FBLE1BQUFBLElBQUksQ0FBQ1EsWUFBTCxHQUFvQkosR0FBRyxDQUFDRyxNQUFKLENBQVdDLFlBQS9CO0FBQ0FSLE1BQUFBLElBQUksQ0FBQzZCLEdBQUwsR0FBV3pCLEdBQUcsQ0FBQ0MsSUFBSixDQUFTd0IsR0FBcEI7QUFDRCxLQUpELE1BSU8sSUFBSXpCLEdBQUcsQ0FBQ0csTUFBSixDQUFXWSxTQUFYLElBQXdCZixHQUFHLENBQUNHLE1BQUosQ0FBV2EsV0FBbkMsSUFBa0RoQixHQUFHLENBQUNDLElBQUosQ0FBU3dCLEdBQS9ELEVBQW9FO0FBQ3pFN0IsTUFBQUEsSUFBSSxHQUFHLEVBQVA7QUFDQUEsTUFBQUEsSUFBSSxDQUFDbUIsU0FBTCxHQUFpQmYsR0FBRyxDQUFDRyxNQUFKLENBQVdZLFNBQTVCO0FBQ0FuQixNQUFBQSxJQUFJLENBQUNvQixXQUFMLEdBQW1CaEIsR0FBRyxDQUFDRyxNQUFKLENBQVdhLFdBQTlCO0FBQ0FwQixNQUFBQSxJQUFJLENBQUM2QixHQUFMLEdBQVd6QixHQUFHLENBQUNDLElBQUosQ0FBU3dCLEdBQXBCO0FBQ0QsS0FMTSxNQUtBO0FBQ0wsWUFBTSxJQUFJbEIsWUFBTUMsS0FBVixDQUFnQixHQUFoQixFQUFxQiwwQkFBckIsQ0FBTjtBQUNEOztBQUNELFdBQU8sS0FBS1YsVUFBTCxDQUFnQkYsSUFBaEIsRUFBc0JJLEdBQUcsQ0FBQ1AsTUFBMUIsQ0FBUDtBQUNEOztBQUVEaUMsRUFBQUEsU0FBUyxDQUFDMUIsR0FBRCxFQUFNO0FBQ2IsUUFBSUMsSUFBSSxHQUFHRCxHQUFHLENBQUNDLElBQWY7O0FBQ0EsUUFBSUEsSUFBSSxDQUFDMEIsSUFBTCxJQUFhLFFBQWpCLEVBQTJCO0FBQ3pCLGFBQU8sS0FBS04sWUFBTCxDQUFrQnJCLEdBQWxCLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPLEtBQUt3QixZQUFMLENBQWtCeEIsR0FBbEIsQ0FBUDtBQUNEO0FBQ0Y7O0FBRUQ0QixFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQ0UsS0FERixFQUVFLGtCQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLN0Isa0JBQUwsQ0FBd0I4QixJQUF4QixDQUE2QixJQUE3QixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLEtBREYsRUFFRSxpQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2pCLGlCQUFMLENBQXVCa0IsSUFBdkIsQ0FBNEIsSUFBNUIsQ0FKRjtBQU1BLFNBQUtILEtBQUwsQ0FDRSxLQURGLEVBRUUsZ0NBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFLEtBQUs3QixrQkFBTCxDQUF3QjhCLElBQXhCLENBQTZCLElBQTdCLENBSkY7QUFNQSxTQUFLSCxLQUFMLENBQ0UsS0FERixFQUVFLHlDQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLakIsaUJBQUwsQ0FBdUJrQixJQUF2QixDQUE0QixJQUE1QixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxrQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxpQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLEtBREYsRUFFRSxnQ0FGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0wsU0FBTCxDQUFlTSxJQUFmLENBQW9CLElBQXBCLENBSkY7QUFNQSxTQUFLSCxLQUFMLENBQ0UsS0FERixFQUVFLHlDQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLTCxTQUFMLENBQWVNLElBQWYsQ0FBb0IsSUFBcEIsQ0FKRjtBQU1EOztBQXpJNEM7OztlQTRJaEMzQyxXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmV4cG9ydCBjbGFzcyBIb29rc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjcmVhdGVIb29rKGFIb29rLCBjb25maWcpIHtcbiAgICByZXR1cm4gY29uZmlnLmhvb2tzQ29udHJvbGxlci5jcmVhdGVIb29rKGFIb29rKS50aGVuKGhvb2sgPT4gKHsgcmVzcG9uc2U6IGhvb2sgfSkpO1xuICB9XG5cbiAgdXBkYXRlSG9vayhhSG9vaywgY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ob29rc0NvbnRyb2xsZXIudXBkYXRlSG9vayhhSG9vaykudGhlbihob29rID0+ICh7IHJlc3BvbnNlOiBob29rIH0pKTtcbiAgfVxuXG4gIGhhbmRsZVBvc3QocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlSG9vayhyZXEuYm9keSwgcmVxLmNvbmZpZyk7XG4gIH1cblxuICBoYW5kbGVHZXRGdW5jdGlvbnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbihmb3VuZEZ1bmN0aW9uID0+IHtcbiAgICAgICAgaWYgKCFmb3VuZEZ1bmN0aW9uKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgYG5vIGZ1bmN0aW9uIG5hbWVkOiAke3JlcS5wYXJhbXMuZnVuY3Rpb25OYW1lfSBpcyBkZWZpbmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZEZ1bmN0aW9uIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbnMoKS50aGVuKFxuICAgICAgZnVuY3Rpb25zID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IGZ1bmN0aW9ucyB8fCBbXSB9O1xuICAgICAgfSxcbiAgICAgIGVyciA9PiB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlR2V0VHJpZ2dlcnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gaG9va3NDb250cm9sbGVyXG4gICAgICAgIC5nZXRUcmlnZ2VyKHJlcS5wYXJhbXMuY2xhc3NOYW1lLCByZXEucGFyYW1zLnRyaWdnZXJOYW1lKVxuICAgICAgICAudGhlbihmb3VuZFRyaWdnZXIgPT4ge1xuICAgICAgICAgIGlmICghZm91bmRUcmlnZ2VyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgY2xhc3MgJHtyZXEucGFyYW1zLmNsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZFRyaWdnZXIgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBob29rc0NvbnRyb2xsZXIuZ2V0VHJpZ2dlcnMoKS50aGVuKHRyaWdnZXJzID0+ICh7IHJlc3BvbnNlOiB0cmlnZ2VycyB8fCBbXSB9KSk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5kZWxldGVGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xuICAgIH0gZWxzZSBpZiAocmVxLnBhcmFtcy5jbGFzc05hbWUgJiYgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlclxuICAgICAgICAuZGVsZXRlVHJpZ2dlcihyZXEucGFyYW1zLmNsYXNzTmFtZSwgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSlcbiAgICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHt9IH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiB7fSB9KTtcbiAgfVxuXG4gIGhhbmRsZVVwZGF0ZShyZXEpIHtcbiAgICB2YXIgaG9vaztcbiAgICBpZiAocmVxLnBhcmFtcy5mdW5jdGlvbk5hbWUgJiYgcmVxLmJvZHkudXJsKSB7XG4gICAgICBob29rID0ge307XG4gICAgICBob29rLmZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lICYmIHJlcS5ib2R5LnVybCkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5jbGFzc05hbWUgPSByZXEucGFyYW1zLmNsYXNzTmFtZTtcbiAgICAgIGhvb2sudHJpZ2dlck5hbWUgPSByZXEucGFyYW1zLnRyaWdnZXJOYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlSG9vayhob29rLCByZXEuY29uZmlnKTtcbiAgfVxuXG4gIGhhbmRsZVB1dChyZXEpIHtcbiAgICB2YXIgYm9keSA9IHJlcS5ib2R5O1xuICAgIGlmIChib2R5Ll9fb3AgPT0gJ0RlbGV0ZScpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRGdW5jdGlvbnMuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2VycycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRUcmlnZ2Vycy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldEZ1bmN0aW9ucy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzLzpjbGFzc05hbWUvOnRyaWdnZXJOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldFRyaWdnZXJzLmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQb3N0LmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZVBvc3QuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy9mdW5jdGlvbnMvOmZ1bmN0aW9uTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2Vycy86Y2xhc3NOYW1lLzp0cmlnZ2VyTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSG9va3NSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/IAPValidationRouter.js b/lib/Routers/IAPValidationRouter.js deleted file mode 100644 index f0ba814941..0000000000 --- a/lib/Routers/IAPValidationRouter.js +++ /dev/null @@ -1,136 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.IAPValidationRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const request = require('../request'); - -const rest = require('../rest'); - -// TODO move validation logic in IAPValidationController -const IAP_SANDBOX_URL = 'https://sandbox.itunes.apple.com/verifyReceipt'; -const IAP_PRODUCTION_URL = 'https://buy.itunes.apple.com/verifyReceipt'; -const APP_STORE_ERRORS = { - 21000: 'The App Store could not read the JSON object you provided.', - 21002: 'The data in the receipt-data property was malformed or missing.', - 21003: 'The receipt could not be authenticated.', - 21004: 'The shared secret you provided does not match the shared secret on file for your account.', - 21005: 'The receipt server is not currently available.', - 21006: 'This receipt is valid but the subscription has expired.', - 21007: 'This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.', - 21008: 'This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.' -}; - -function appStoreError(status) { - status = parseInt(status); - var errorString = APP_STORE_ERRORS[status] || 'unknown error.'; - return { - status: status, - error: errorString - }; -} - -function validateWithAppStore(url, receipt) { - return request({ - url: url, - method: 'POST', - body: { - 'receipt-data': receipt - }, - headers: { - 'Content-Type': 'application/json' - } - }).then(httpResponse => { - const body = httpResponse.data; - - if (body && body.status === 0) { - // No need to pass anything, status is OK - return; - } // receipt is from test and should go to test - - - throw body; - }); -} - -function getFileForProductIdentifier(productIdentifier, req) { - return rest.find(req.config, req.auth, '_Product', { - productIdentifier: productIdentifier - }, undefined, req.info.clientSDK, req.info.context).then(function (result) { - const products = result.results; - - if (!products || products.length != 1) { - // Error not found or too many - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - var download = products[0].download; - return Promise.resolve({ - response: download - }); - }); -} - -class IAPValidationRouter extends _PromiseRouter.default { - handleRequest(req) { - let receipt = req.body.receipt; - const productIdentifier = req.body.productIdentifier; - - if (!receipt || !productIdentifier) { - // TODO: Error, malformed request - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'missing receipt or productIdentifier'); - } // Transform the object if there - // otherwise assume it's in Base64 already - - - if (typeof receipt == 'object') { - if (receipt['__type'] == 'Bytes') { - receipt = receipt.base64; - } - } - - if (process.env.TESTING == '1' && req.body.bypassAppStoreValidation) { - return getFileForProductIdentifier(productIdentifier, req); - } - - function successCallback() { - return getFileForProductIdentifier(productIdentifier, req); - } - - function errorCallback(error) { - return Promise.resolve({ - response: appStoreError(error.status) - }); - } - - return validateWithAppStore(IAP_PRODUCTION_URL, receipt).then(() => { - return successCallback(); - }, error => { - if (error.status == 21007) { - return validateWithAppStore(IAP_SANDBOX_URL, receipt).then(() => { - return successCallback(); - }, error => { - return errorCallback(error); - }); - } - - return errorCallback(error); - }); - } - - mountRoutes() { - this.route('POST', '/validate_purchase', this.handleRequest); - } - -} - -exports.IAPValidationRouter = IAPValidationRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXIuanMiXSwibmFtZXMiOlsicmVxdWVzdCIsInJlcXVpcmUiLCJyZXN0IiwiSUFQX1NBTkRCT1hfVVJMIiwiSUFQX1BST0RVQ1RJT05fVVJMIiwiQVBQX1NUT1JFX0VSUk9SUyIsImFwcFN0b3JlRXJyb3IiLCJzdGF0dXMiLCJwYXJzZUludCIsImVycm9yU3RyaW5nIiwiZXJyb3IiLCJ2YWxpZGF0ZVdpdGhBcHBTdG9yZSIsInVybCIsInJlY2VpcHQiLCJtZXRob2QiLCJib2R5IiwiaGVhZGVycyIsInRoZW4iLCJodHRwUmVzcG9uc2UiLCJkYXRhIiwiZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyIiwicHJvZHVjdElkZW50aWZpZXIiLCJyZXEiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsInVuZGVmaW5lZCIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzdWx0IiwicHJvZHVjdHMiLCJyZXN1bHRzIiwibGVuZ3RoIiwiUGFyc2UiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJkb3dubG9hZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiLCJJQVBWYWxpZGF0aW9uUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJJTlZBTElEX0pTT04iLCJiYXNlNjQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsImJ5cGFzc0FwcFN0b3JlVmFsaWRhdGlvbiIsInN1Y2Nlc3NDYWxsYmFjayIsImVycm9yQ2FsbGJhY2siLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBR0E7Ozs7QUFGQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQXZCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLFNBQUQsQ0FBcEI7O0FBR0E7QUFDQSxNQUFNRSxlQUFlLEdBQUcsZ0RBQXhCO0FBQ0EsTUFB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O0FBbUJEOztBQUVEMEMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsb0JBQW5CLEVBQXlDLEtBQUtWLGFBQTlDO0FBQ0Q7O0FBckRvRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4uL3JlcXVlc3QnKTtcbmNvbnN0IHJlc3QgPSByZXF1aXJlKCcuLi9yZXN0Jyk7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8vIFRPRE8gbW92ZSB2YWxpZGF0aW9uIGxvZ2ljIGluIElBUFZhbGlkYXRpb25Db250cm9sbGVyXG5jb25zdCBJQVBfU0FOREJPWF9VUkwgPSAnaHR0cHM6Ly9zYW5kYm94Lml0dW5lcy5hcHBsZS5jb20vdmVyaWZ5UmVjZWlwdCc7XG5jb25zdCBJQVBfUFJPRFVDVElPTl9VUkwgPSAnaHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS92ZXJpZnlSZWNlaXB0JztcblxuY29uc3QgQVBQX1NUT1JFX0VSUk9SUyA9IHtcbiAgMjEwMDA6ICdUaGUgQXBwIFN0b3JlIGNvdWxkIG5vdCByZWFkIHRoZSBKU09OIG9iamVjdCB5b3UgcHJvdmlkZWQuJyxcbiAgMjEwMDI6ICdUaGUgZGF0YSBpbiB0aGUgcmVjZWlwdC1kYXRhIHByb3BlcnR5IHdhcyBtYWxmb3JtZWQgb3IgbWlzc2luZy4nLFxuICAyMTAwMzogJ1RoZSByZWNlaXB0IGNvdWxkIG5vdCBiZSBhdXRoZW50aWNhdGVkLicsXG4gIDIxMDA0OiAnVGhlIHNoYXJlZCBzZWNyZXQgeW91IHByb3ZpZGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaGFyZWQgc2VjcmV0IG9uIGZpbGUgZm9yIHlvdXIgYWNjb3VudC4nLFxuICAyMTAwNTogJ1RoZSByZWNlaXB0IHNlcnZlciBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS4nLFxuICAyMTAwNjogJ1RoaXMgcmVjZWlwdCBpcyB2YWxpZCBidXQgdGhlIHN1YnNjcmlwdGlvbiBoYXMgZXhwaXJlZC4nLFxuICAyMTAwNzogJ1RoaXMgcmVjZWlwdCBpcyBmcm9tIHRoZSB0ZXN0IGVudmlyb25tZW50LCBidXQgaXQgd2FzIHNlbnQgdG8gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQgZm9yIHZlcmlmaWNhdGlvbi4gU2VuZCBpdCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBpbnN0ZWFkLicsXG4gIDIxMDA4OiAnVGhpcyByZWNlaXB0IGlzIGZyb20gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQsIGJ1dCBpdCB3YXMgc2VudCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBmb3IgdmVyaWZpY2F0aW9uLiBTZW5kIGl0IHRvIHRoZSBwcm9kdWN0aW9uIGVudmlyb25tZW50IGluc3RlYWQuJyxcbn07XG5cbmZ1bmN0aW9uIGFwcFN0b3JlRXJyb3Ioc3RhdHVzKSB7XG4gIHN0YXR1cyA9IHBhcnNlSW50KHN0YXR1cyk7XG4gIHZhciBlcnJvclN0cmluZyA9IEFQUF9TVE9SRV9FUlJPUlNbc3RhdHVzXSB8fCAndW5rbm93biBlcnJvci4nO1xuICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cywgZXJyb3I6IGVycm9yU3RyaW5nIH07XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlV2l0aEFwcFN0b3JlKHVybCwgcmVjZWlwdCkge1xuICByZXR1cm4gcmVxdWVzdCh7XG4gICAgdXJsOiB1cmwsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgYm9keTogeyAncmVjZWlwdC1kYXRhJzogcmVjZWlwdCB9LFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfSxcbiAgfSkudGhlbihodHRwUmVzcG9uc2UgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBodHRwUmVzcG9uc2UuZGF0YTtcbiAgICBpZiAoYm9keSAmJiBib2R5LnN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gTm8gbmVlZCB0byBwYXNzIGFueXRoaW5nLCBzdGF0dXMgaXMgT0tcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gcmVjZWlwdCBpcyBmcm9tIHRlc3QgYW5kIHNob3VsZCBnbyB0byB0ZXN0XG4gICAgdGhyb3cgYm9keTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVGb3JQcm9kdWN0SWRlbnRpZmllcihwcm9kdWN0SWRlbnRpZmllciwgcmVxKSB7XG4gIHJldHVybiByZXN0XG4gICAgLmZpbmQoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX1Byb2R1Y3QnLFxuICAgICAgeyBwcm9kdWN0SWRlbnRpZmllcjogcHJvZHVjdElkZW50aWZpZXIgfSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgY29uc3QgcHJvZHVjdHMgPSByZXN1bHQucmVzdWx0cztcbiAgICAgIGlmICghcHJvZHVjdHMgfHwgcHJvZHVjdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgLy8gRXJyb3Igbm90IGZvdW5kIG9yIHRvbyBtYW55XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGRvd25sb2FkID0gcHJvZHVjdHNbMF0uZG93bmxvYWQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgcmVzcG9uc2U6IGRvd25sb2FkIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgSUFQVmFsaWRhdGlvblJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVSZXF1ZXN0KHJlcSkge1xuICAgIGxldCByZWNlaXB0ID0gcmVxLmJvZHkucmVjZWlwdDtcbiAgICBjb25zdCBwcm9kdWN0SWRlbnRpZmllciA9IHJlcS5ib2R5LnByb2R1Y3RJZGVudGlmaWVyO1xuXG4gICAgaWYgKCFyZWNlaXB0IHx8ICFwcm9kdWN0SWRlbnRpZmllcikge1xuICAgICAgLy8gVE9ETzogRXJyb3IsIG1hbGZvcm1lZCByZXF1ZXN0XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnbWlzc2luZyByZWNlaXB0IG9yIHByb2R1Y3RJZGVudGlmaWVyJyk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIHRoZSBvYmplY3QgaWYgdGhlcmVcbiAgICAvLyBvdGhlcndpc2UgYXNzdW1lIGl0J3MgaW4gQmFzZTY0IGFscmVhZHlcbiAgICBpZiAodHlwZW9mIHJlY2VpcHQgPT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChyZWNlaXB0WydfX3R5cGUnXSA9PSAnQnl0ZXMnKSB7XG4gICAgICAgIHJlY2VpcHQgPSByZWNlaXB0LmJhc2U2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyA9PSAnMScgJiYgcmVxLmJvZHkuYnlwYXNzQXBwU3RvcmVWYWxpZGF0aW9uKSB7XG4gICAgICByZXR1cm4gZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyKHByb2R1Y3RJZGVudGlmaWVyLCByZXEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Y2Nlc3NDYWxsYmFjaygpIHtcbiAgICAgIHJldHVybiBnZXRGaWxlRm9yUHJvZHVjdElkZW50aWZpZXIocHJvZHVjdElkZW50aWZpZXIsIHJlcSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JDYWxsYmFjayhlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBhcHBTdG9yZUVycm9yKGVycm9yLnN0YXR1cykgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlV2l0aEFwcFN0b3JlKElBUF9QUk9EVUNUSU9OX1VSTCwgcmVjZWlwdCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NDYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSAyMTAwNykge1xuICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVdpdGhBcHBTdG9yZShJQVBfU0FOREJPWF9VUkwsIHJlY2VpcHQpLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzQ2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvckNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92YWxpZGF0ZV9wdXJjaGFzZScsIHRoaXMuaGFuZGxlUmVxdWVzdCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/InstallationsRouter.js b/lib/Routers/InstallationsRouter.js deleted file mode 100644 index 62b677126a..0000000000 --- a/lib/Routers/InstallationsRouter.js +++ /dev/null @@ -1,57 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.InstallationsRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _middlewares = require("../middlewares"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// InstallationsRouter.js -class InstallationsRouter extends _ClassesRouter.default { - className() { - return '_Installation'; - } - - handleFind(req) { - const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); - - const options = _ClassesRouter.default.optionsFromBody(body); - - return _rest.default.find(req.config, req.auth, '_Installation', body.where, options, req.info.clientSDK, req.info.context).then(response => { - return { - response: response - }; - }); - } - - mountRoutes() { - this.route('GET', '/installations', req => { - return this.handleFind(req); - }); - this.route('GET', '/installations/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/installations', _middlewares.promiseEnsureIdempotency, req => { - return this.handleCreate(req); - }); - this.route('PUT', '/installations/:objectId', _middlewares.promiseEnsureIdempotency, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/installations/:objectId', req => { - return this.handleDelete(req); - }); - } - -} - -exports.InstallationsRouter = InstallationsRouter; -var _default = InstallationsRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0luc3RhbGxhdGlvbnNSb3V0ZXIuanMiXSwibmFtZXMiOlsiSW5zdGFsbGF0aW9uc1JvdXRlciIsIkNsYXNzZXNSb3V0ZXIiLCJjbGFzc05hbWUiLCJoYW5kbGVGaW5kIiwicmVxIiwiYm9keSIsIk9iamVjdCIsImFzc2lnbiIsIkpTT05Gcm9tUXVlcnkiLCJxdWVyeSIsIm9wdGlvbnMiLCJvcHRpb25zRnJvbUJvZHkiLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsImF1dGgiLCJ3aGVyZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUdldCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOztBQUNBOztBQUNBOzs7O0FBSkE7QUFNTyxNQUFNQSxtQkFBTixTQUFrQ0Msc0JBQWxDLENBQWdEO0FBQ3JEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLGVBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUNBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILGVBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBO0FBQVosT0FBUDtBQUNELEtBWkksQ0FBUDtBQWFEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixnQkFBbEIsRUFBb0NuQixHQUFHLElBQUk7QUFDekMsYUFBTyxLQUFLRCxVQUFMLENBQWdCQyxHQUFoQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsS0FBWCxFQUFrQiwwQkFBbEIsRUFBOENuQixHQUFHLElBQUk7QUFDbkQsYUFBTyxLQUFLb0IsU0FBTCxDQUFlcEIsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsTUFBWCxFQUFtQixnQkFBbkIsRUFBcUNFLHFDQUFyQyxFQUErRHJCLEdBQUcsSUFBSTtBQUNwRSxhQUFPLEtBQUtzQixZQUFMLENBQWtCdEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLbUIsS0FBTCxDQUFXLEtBQVgsRUFBa0IsMEJBQWxCLEVBQThDRSxxQ0FBOUMsRUFBd0VyQixHQUFHLElBQUk7QUFDN0UsYUFBTyxLQUFLdUIsWUFBTCxDQUFrQnZCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS21CLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLDBCQUFyQixFQUFpRG5CLEdBQUcsSUFBSTtBQUN0RCxhQUFPLEtBQUt3QixZQUFMLENBQWtCeEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF2Q29EOzs7ZUEwQ3hDSixtQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEluc3RhbGxhdGlvbnNSb3V0ZXIuanNcblxuaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IH0gZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgSW5zdGFsbGF0aW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfSW5zdGFsbGF0aW9uJztcbiAgfVxuXG4gIGhhbmRsZUZpbmQocmVxKSB7XG4gICAgY29uc3QgYm9keSA9IE9iamVjdC5hc3NpZ24ocmVxLmJvZHksIENsYXNzZXNSb3V0ZXIuSlNPTkZyb21RdWVyeShyZXEucXVlcnkpKTtcbiAgICBjb25zdCBvcHRpb25zID0gQ2xhc3Nlc1JvdXRlci5vcHRpb25zRnJvbUJvZHkoYm9keSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICBib2R5LndoZXJlLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvaW5zdGFsbGF0aW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVGaW5kKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9pbnN0YWxsYXRpb25zJywgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5LCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQ3JlYXRlKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvaW5zdGFsbGF0aW9ucy86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5zdGFsbGF0aW9uc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/LogsRouter.js b/lib/Routers/LogsRouter.js deleted file mode 100644 index 4399b717f5..0000000000 --- a/lib/Routers/LogsRouter.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LogsRouter = void 0; - -var _node = require("parse/node"); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class LogsRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/scriptlog', middleware.promiseEnforceMasterKeyAccess, this.validateRequest, req => { - return this.handleGET(req); - }); - } - - validateRequest(req) { - if (!req.config || !req.config.loggerController) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); - } - } // Returns a promise for a {response} object. - // query params: - // level (optional) Level of logging you want to query for (info || error) - // from (optional) Start time for the search. Defaults to 1 week ago. - // until (optional) End time for the search. Defaults to current time. - // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. - // size (optional) Number of rows returned by search. Defaults to 10 - // n same as size, overrides size if set - - - handleGET(req) { - const from = req.query.from; - const until = req.query.until; - let size = req.query.size; - - if (req.query.n) { - size = req.query.n; - } - - const order = req.query.order; - const level = req.query.level; - const options = { - from, - until, - size, - order, - level - }; - return req.config.loggerController.getLogs(options).then(result => { - return Promise.resolve({ - response: result - }); - }); - } - -} - -exports.LogsRouter = LogsRouter; -var _default = LogsRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0xvZ3NSb3V0ZXIuanMiXSwibmFtZXMiOlsiTG9nc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwidmFsaWRhdGVSZXF1ZXN0IiwicmVxIiwiaGFuZGxlR0VUIiwiY29uZmlnIiwibG9nZ2VyQ29udHJvbGxlciIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJmcm9tIiwicXVlcnkiLCJ1bnRpbCIsInNpemUiLCJuIiwib3JkZXIiLCJsZXZlbCIsIm9wdGlvbnMiLCJnZXRMb2dzIiwidGhlbiIsInJlc3VsdCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FDRSxLQURGLEVBRUUsWUFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0MsZUFKUCxFQUtFQyxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtDLFNBQUwsQ0FBZUQsR0FBZixDQUFQO0FBQ0QsS0FQSDtBQVNEOztBQUVERCxFQUFBQSxlQUFlLENBQUNDLEdBQUQsRUFBTTtBQUNuQixRQUFJLENBQUNBLEdBQUcsQ0FBQ0UsTUFBTCxJQUFlLENBQUNGLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBL0IsRUFBaUQ7QUFDL0MsWUFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEO0FBQ0YsR0FqQjJDLENBbUI1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQUwsRUFBQUEsU0FBUyxDQUFDRCxHQUFELEVBQU07QUFDYixVQUFNTyxJQUFJLEdBQUdQLEdBQUcsQ0FBQ1EsS0FBSixDQUFVRCxJQUF2QjtBQUNBLFVBQU1FLEtBQUssR0FBR1QsR0FBRyxDQUFDUSxLQUFKLENBQVVDLEtBQXhCO0FBQ0EsUUFBSUMsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUUsSUFBckI7O0FBQ0EsUUFBSVYsR0FBRyxDQUFDUSxLQUFKLENBQVVHLENBQWQsRUFBaUI7QUFDZkQsTUFBQUEsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUcsQ0FBakI7QUFDRDs7QUFFRCxVQUFNQyxLQUFLLEdBQUdaLEdBQUcsQ0FBQ1EsS0FBSixDQUFVSSxLQUF4QjtBQUNBLFVBQU1DLEtBQUssR0FBR2IsR0FBRyxDQUFDUSxLQUFKLENBQVVLLEtBQXhCO0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RQLE1BQUFBLElBRGM7QUFFZEUsTUFBQUEsS0FGYztBQUdkQyxNQUFBQSxJQUhjO0FBSWRFLE1BQUFBLEtBSmM7QUFLZEMsTUFBQUE7QUFMYyxLQUFoQjtBQVFBLFdBQU9iLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBWCxDQUE0QlksT0FBNUIsQ0FBb0NELE9BQXBDLEVBQTZDRSxJQUE3QyxDQUFrREMsTUFBTSxJQUFJO0FBQ2pFLGFBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUNyQkMsUUFBQUEsUUFBUSxFQUFFSDtBQURXLE9BQWhCLENBQVA7QUFHRCxLQUpNLENBQVA7QUFLRDs7QUFsRDJDOzs7ZUFxRC9CeEIsVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgTG9nc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3NjcmlwdGxvZycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy52YWxpZGF0ZVJlcXVlc3QsXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVHRVQocmVxKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVSZXF1ZXN0KHJlcSkge1xuICAgIGlmICghcmVxLmNvbmZpZyB8fCAhcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTG9nZ2VyIGFkYXB0ZXIgaXMgbm90IGF2YWlsYWJsZScpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZX0gb2JqZWN0LlxuICAvLyBxdWVyeSBwYXJhbXM6XG4gIC8vIGxldmVsIChvcHRpb25hbCkgTGV2ZWwgb2YgbG9nZ2luZyB5b3Ugd2FudCB0byBxdWVyeSBmb3IgKGluZm8gfHwgZXJyb3IpXG4gIC8vIGZyb20gKG9wdGlvbmFsKSBTdGFydCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byAxIHdlZWsgYWdvLlxuICAvLyB1bnRpbCAob3B0aW9uYWwpIEVuZCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byBjdXJyZW50IHRpbWUuXG4gIC8vIG9yZGVyIChvcHRpb25hbCkgRGlyZWN0aW9uIG9mIHJlc3VsdHMgcmV0dXJuZWQsIGVpdGhlciDigJxhc2PigJ0gb3Ig4oCcZGVzY+KAnS4gRGVmYXVsdHMgdG8g4oCcZGVzY+KAnS5cbiAgLy8gc2l6ZSAob3B0aW9uYWwpIE51bWJlciBvZiByb3dzIHJldHVybmVkIGJ5IHNlYXJjaC4gRGVmYXVsdHMgdG8gMTBcbiAgLy8gbiBzYW1lIGFzIHNpemUsIG92ZXJyaWRlcyBzaXplIGlmIHNldFxuICBoYW5kbGVHRVQocmVxKSB7XG4gICAgY29uc3QgZnJvbSA9IHJlcS5xdWVyeS5mcm9tO1xuICAgIGNvbnN0IHVudGlsID0gcmVxLnF1ZXJ5LnVudGlsO1xuICAgIGxldCBzaXplID0gcmVxLnF1ZXJ5LnNpemU7XG4gICAgaWYgKHJlcS5xdWVyeS5uKSB7XG4gICAgICBzaXplID0gcmVxLnF1ZXJ5Lm47XG4gICAgfVxuXG4gICAgY29uc3Qgb3JkZXIgPSByZXEucXVlcnkub3JkZXI7XG4gICAgY29uc3QgbGV2ZWwgPSByZXEucXVlcnkubGV2ZWw7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmdldExvZ3Mob3B0aW9ucykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgIHJlc3BvbnNlOiByZXN1bHQsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PublicAPIRouter.js b/lib/Routers/PublicAPIRouter.js deleted file mode 100644 index 1ee21b99b2..0000000000 --- a/lib/Routers/PublicAPIRouter.js +++ /dev/null @@ -1,322 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PublicAPIRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _express = _interopRequireDefault(require("express")); - -var _path = _interopRequireDefault(require("path")); - -var _fs = _interopRequireDefault(require("fs")); - -var _querystring = _interopRequireDefault(require("querystring")); - -var _node = require("parse/node"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const public_html = _path.default.resolve(__dirname, '../../public_html'); - -const views = _path.default.resolve(__dirname, '../../views'); - -class PublicAPIRouter extends _PromiseRouter.default { - verifyEmail(req) { - const { - username, - token: rawToken - } = req.query; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - const appId = req.params.appId; - - const config = _Config.default.get(appId); - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - if (!token || !username) { - return this.invalidLink(req); - } - - const userController = config.userController; - return userController.verifyEmail(username, token).then(() => { - const params = _querystring.default.stringify({ - username - }); - - return Promise.resolve({ - status: 302, - location: `${config.verifyEmailSuccessURL}?${params}` - }); - }, () => { - return this.invalidVerificationLink(req); - }); - } - - resendVerificationEmail(req) { - const username = req.body.username; - const appId = req.params.appId; - - const config = _Config.default.get(appId); - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - if (!username) { - return this.invalidLink(req); - } - - const userController = config.userController; - return userController.resendVerificationEmail(username).then(() => { - return Promise.resolve({ - status: 302, - location: `${config.linkSendSuccessURL}` - }); - }, () => { - return Promise.resolve({ - status: 302, - location: `${config.linkSendFailURL}` - }); - }); - } - - changePassword(req) { - return new Promise((resolve, reject) => { - const config = _Config.default.get(req.query.id); - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return resolve({ - status: 404, - text: 'Not found.' - }); - } // Should we keep the file in memory or leave like that? - - - _fs.default.readFile(_path.default.resolve(views, 'choose_password'), 'utf-8', (err, data) => { - if (err) { - return reject(err); - } - - data = data.replace('PARSE_SERVER_URL', `'${config.publicServerURL}'`); - resolve({ - text: data - }); - }); - }); - } - - requestResetPassword(req) { - const config = req.config; - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - const { - username, - token: rawToken - } = req.query; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if (!username || !token) { - return this.invalidLink(req); - } - - return config.userController.checkResetTokenValidity(username, token).then(() => { - const params = _querystring.default.stringify({ - token, - id: config.applicationId, - username, - app: config.appName - }); - - return Promise.resolve({ - status: 302, - location: `${config.choosePasswordURL}?${params}` - }); - }, () => { - return this.invalidLink(req); - }); - } - - resetPassword(req) { - const config = req.config; - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - const { - username, - new_password, - token: rawToken - } = req.body; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if ((!username || !token || !new_password) && req.xhr === false) { - return this.invalidLink(req); - } - - if (!username) { - throw new _node.Parse.Error(_node.Parse.Error.USERNAME_MISSING, 'Missing username'); - } - - if (!token) { - throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, 'Missing token'); - } - - if (!new_password) { - throw new _node.Parse.Error(_node.Parse.Error.PASSWORD_MISSING, 'Missing password'); - } - - return config.userController.updatePassword(username, token, new_password).then(() => { - return Promise.resolve({ - success: true - }); - }, err => { - return Promise.resolve({ - success: false, - err - }); - }).then(result => { - const params = _querystring.default.stringify({ - username: username, - token: token, - id: config.applicationId, - error: result.err, - app: config.appName - }); - - if (req.xhr) { - if (result.success) { - return Promise.resolve({ - status: 200, - response: 'Password successfully reset' - }); - } - - if (result.err) { - throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, `${result.err}`); - } - } - - const encodedUsername = encodeURIComponent(username); - const location = result.success ? `${config.passwordResetSuccessURL}?username=${encodedUsername}` : `${config.choosePasswordURL}?${params}`; - return Promise.resolve({ - status: 302, - location - }); - }); - } - - invalidLink(req) { - return Promise.resolve({ - status: 302, - location: req.config.invalidLinkURL - }); - } - - invalidVerificationLink(req) { - const config = req.config; - - if (req.query.username && req.params.appId) { - const params = _querystring.default.stringify({ - username: req.query.username, - appId: req.params.appId - }); - - return Promise.resolve({ - status: 302, - location: `${config.invalidVerificationLinkURL}?${params}` - }); - } else { - return this.invalidLink(req); - } - } - - missingPublicServerURL() { - return Promise.resolve({ - text: 'Not found.', - status: 404 - }); - } - - invalidRequest() { - const error = new Error(); - error.status = 403; - error.message = 'unauthorized'; - throw error; - } - - setConfig(req) { - req.config = _Config.default.get(req.params.appId); - return Promise.resolve(); - } - - mountRoutes() { - this.route('GET', '/apps/:appId/verify_email', req => { - this.setConfig(req); - }, req => { - return this.verifyEmail(req); - }); - this.route('POST', '/apps/:appId/resend_verification_email', req => { - this.setConfig(req); - }, req => { - return this.resendVerificationEmail(req); - }); - this.route('GET', '/apps/choose_password', req => { - return this.changePassword(req); - }); - this.route('POST', '/apps/:appId/request_password_reset', req => { - this.setConfig(req); - }, req => { - return this.resetPassword(req); - }); - this.route('GET', '/apps/:appId/request_password_reset', req => { - this.setConfig(req); - }, req => { - return this.requestResetPassword(req); - }); - } - - expressRouter() { - const router = _express.default.Router(); - - router.use('/apps', _express.default.static(public_html)); - router.use('/', super.expressRouter()); - return router; - } - -} - -exports.PublicAPIRouter = PublicAPIRouter; -var _default = PublicAPIRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1YmxpY0FQSVJvdXRlci5qcyJdLCJuYW1lcyI6WyJwdWJsaWNfaHRtbCIsInBhdGgiLCJyZXNvbHZlIiwiX19kaXJuYW1lIiwidmlld3MiLCJQdWJsaWNBUElSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwidmVyaWZ5RW1haWwiLCJyZXEiLCJ1c2VybmFtZSIsInRva2VuIiwicmF3VG9rZW4iLCJxdWVyeSIsInRvU3RyaW5nIiwiYXBwSWQiLCJwYXJhbXMiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJpbnZhbGlkUmVxdWVzdCIsInB1YmxpY1NlcnZlclVSTCIsIm1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwiLCJpbnZhbGlkTGluayIsInVzZXJDb250cm9sbGVyIiwidGhlbiIsInFzIiwic3RyaW5naWZ5IiwiUHJvbWlzZSIsInN0YXR1cyIsImxvY2F0aW9uIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImJvZHkiLCJsaW5rU2VuZFN1Y2Nlc3NVUkwiLCJsaW5rU2VuZEZhaWxVUkwiLCJjaGFuZ2VQYXNzd29yZCIsInJlamVjdCIsImlkIiwidGV4dCIsImZzIiwicmVhZEZpbGUiLCJlcnIiLCJkYXRhIiwicmVwbGFjZSIsInJlcXVlc3RSZXNldFBhc3N3b3JkIiwiY2hlY2tSZXNldFRva2VuVmFsaWRpdHkiLCJhcHBsaWNhdGlvbklkIiwiYXBwIiwiYXBwTmFtZSIsImNob29zZVBhc3N3b3JkVVJMIiwicmVzZXRQYXNzd29yZCIsIm5ld19wYXNzd29yZCIsInhociIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiT1RIRVJfQ0FVU0UiLCJQQVNTV09SRF9NSVNTSU5HIiwidXBkYXRlUGFzc3dvcmQiLCJzdWNjZXNzIiwicmVzdWx0IiwiZXJyb3IiLCJyZXNwb25zZSIsImVuY29kZWRVc2VybmFtZSIsImVuY29kZVVSSUNvbXBvbmVudCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwiaW52YWxpZExpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsIm1lc3NhZ2UiLCJzZXRDb25maWciLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiZXhwcmVzc1JvdXRlciIsInJvdXRlciIsImV4cHJlc3MiLCJSb3V0ZXIiLCJ1c2UiLCJzdGF0aWMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLFdBQVcsR0FBR0MsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLG1CQUF4QixDQUFwQjs7QUFDQSxNQUFNQyxLQUFLLEdBQUdILGNBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixhQUF4QixDQUFkOztBQUVPLE1BQU1FLGVBQU4sU0FBOEJDLHNCQUE5QixDQUE0QztBQUNqREMsRUFBQUEsV0FBVyxDQUFDQyxHQUFELEVBQU07QUFDZixVQUFNO0FBQUVDLE1BQUFBLFFBQUY7QUFBWUMsTUFBQUEsS0FBSyxFQUFFQztBQUFuQixRQUFnQ0gsR0FBRyxDQUFDSSxLQUExQztBQUNBLFVBQU1GLEtBQUssR0FBR0MsUUFBUSxJQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBaEMsR0FBMkNBLFFBQVEsQ0FBQ0UsUUFBVCxFQUEzQyxHQUFpRUYsUUFBL0U7QUFFQSxVQUFNRyxLQUFLLEdBQUdOLEdBQUcsQ0FBQ08sTUFBSixDQUFXRCxLQUF6Qjs7QUFDQSxVQUFNRSxNQUFNLEdBQUdDLGdCQUFPQyxHQUFQLENBQVdKLEtBQVgsQ0FBZjs7QUFFQSxRQUFJLENBQUNFLE1BQUwsRUFBYTtBQUNYLFdBQUtHLGNBQUw7QUFDRDs7QUFFRCxRQUFJLENBQUNILE1BQU0sQ0FBQ0ksZUFBWixFQUE2QjtBQUMzQixhQUFPLEtBQUtDLHNCQUFMLEVBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUNYLEtBQUQsSUFBVSxDQUFDRCxRQUFmLEVBQXlCO0FBQ3ZCLGFBQU8s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cnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBxcyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuXG5jb25zdCBwdWJsaWNfaHRtbCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi8uLi9wdWJsaWNfaHRtbCcpO1xuY29uc3Qgdmlld3MgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vLi4vdmlld3MnKTtcblxuZXhwb3J0IGNsYXNzIFB1YmxpY0FQSVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICB2ZXJpZnlFbWFpbChyZXEpIHtcbiAgICBjb25zdCB7IHVzZXJuYW1lLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5xdWVyeTtcbiAgICBjb25zdCB0b2tlbiA9IHJhd1Rva2VuICYmIHR5cGVvZiByYXdUb2tlbiAhPT0gJ3N0cmluZycgPyByYXdUb2tlbi50b1N0cmluZygpIDogcmF3VG9rZW47XG5cbiAgICBjb25zdCBhcHBJZCA9IHJlcS5wYXJhbXMuYXBwSWQ7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBJZCk7XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLnB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgcmV0dXJuIHRoaXMubWlzc2luZ1B1YmxpY1NlcnZlclVSTCgpO1xuICAgIH1cblxuICAgIGlmICghdG9rZW4gfHwgIXVzZXJuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci52ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7IHVzZXJuYW1lIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLnZlcmlmeUVtYWlsU3VjY2Vzc1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpIHtcbiAgICBjb25zdCB1c2VybmFtZSA9IHJlcS5ib2R5LnVzZXJuYW1lO1xuICAgIGNvbnN0IGFwcElkID0gcmVxLnBhcmFtcy5hcHBJZDtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KGFwcElkKTtcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyQ29udHJvbGxlciA9IGNvbmZpZy51c2VyQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5saW5rU2VuZFN1Y2Nlc3NVUkx9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmxpbmtTZW5kRmFpbFVSTH1gLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgY2hhbmdlUGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnF1ZXJ5LmlkKTtcblxuICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xuICAgICAgICAgIHN0YXR1czogNDA0LFxuICAgICAgICAgIHRleHQ6ICdOb3QgZm91bmQuJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBTaG91bGQgd2Uga2VlcCB0aGUgZmlsZSBpbiBtZW1vcnkgb3IgbGVhdmUgbGlrZSB0aGF0P1xuICAgICAgZnMucmVhZEZpbGUocGF0aC5yZXNvbHZlKHZpZXdzLCAnY2hvb3NlX3Bhc3N3b3JkJyksICd1dGYtOCcsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gZGF0YS5yZXBsYWNlKCdQQVJTRV9TRVJWRVJfVVJMJywgYCcke2NvbmZpZy5wdWJsaWNTZXJ2ZXJVUkx9J2ApO1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICB0ZXh0OiBkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmVxdWVzdFJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgdG9rZW46IHJhd1Rva2VuIH0gPSByZXEucXVlcnk7XG4gICAgY29uc3QgdG9rZW4gPSByYXdUb2tlbiAmJiB0eXBlb2YgcmF3VG9rZW4gIT09ICdzdHJpbmcnID8gcmF3VG9rZW4udG9TdHJpbmcoKSA6IHJhd1Rva2VuO1xuXG4gICAgaWYgKCF1c2VybmFtZSB8fCAhdG9rZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZy51c2VyQ29udHJvbGxlci5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgaWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgIGFwcDogY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmNob29zZVBhc3N3b3JkVVJMfT8ke3BhcmFtc31gLFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgbmV3X3Bhc3N3b3JkLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5ib2R5O1xuICAgIGNvbnN0IHRva2VuID0gcmF3VG9rZW4gJiYgdHlwZW9mIHJhd1Rva2VuICE9PSAnc3RyaW5nJyA/IHJhd1Rva2VuLnRvU3RyaW5nKCkgOiByYXdUb2tlbjtcblxuICAgIGlmICgoIXVzZXJuYW1lIHx8ICF0b2tlbiB8fCAhbmV3X3Bhc3N3b3JkKSAmJiByZXEueGhyID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBpZiAoIXVzZXJuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVVNFUk5BTUVfTUlTU0lORywgJ01pc3NpbmcgdXNlcm5hbWUnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsICdNaXNzaW5nIHRva2VuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFuZXdfcGFzc3dvcmQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAnTWlzc2luZyBwYXNzd29yZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25maWcudXNlckNvbnRyb2xsZXJcbiAgICAgIC51cGRhdGVQYXNzd29yZCh1c2VybmFtZSwgdG9rZW4sIG5ld19wYXNzd29yZClcbiAgICAgIC50aGVuKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdXNlcm5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHRva2VuOiB0b2tlbixcbiAgICAgICAgICBpZDogY29uZmlnLmFwcGxpY2F0aW9uSWQsXG4gICAgICAgICAgZXJyb3I6IHJlc3VsdC5lcnIsXG4gICAgICAgICAgYXBwOiBjb25maWcuYXBwTmFtZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcS54aHIpIHtcbiAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICAgICAgcmVzcG9uc2U6ICdQYXNzd29yZCBzdWNjZXNzZnVsbHkgcmVzZXQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXN1bHQuZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsIGAke3Jlc3VsdC5lcnJ9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW5jb2RlZFVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXJuYW1lKTtcbiAgICAgICAgY29uc3QgbG9jYXRpb24gPSByZXN1bHQuc3VjY2Vzc1xuICAgICAgICAgID8gYCR7Y29uZmlnLnBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMfT91c2VybmFtZT0ke2VuY29kZWRVc2VybmFtZX1gXG4gICAgICAgICAgOiBgJHtjb25maWcuY2hvb3NlUGFzc3dvcmRVUkx9PyR7cGFyYW1zfWA7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBpbnZhbGlkTGluayhyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHN0YXR1czogMzAyLFxuICAgICAgbG9jYXRpb246IHJlcS5jb25maWcuaW52YWxpZExpbmtVUkwsXG4gICAgfSk7XG4gIH1cblxuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICAgIGlmIChyZXEucXVlcnkudXNlcm5hbWUgJiYgcmVxLnBhcmFtcy5hcHBJZCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gcXMuc3RyaW5naWZ5KHtcbiAgICAgICAgdXNlcm5hbWU6IHJlcS5xdWVyeS51c2VybmFtZSxcbiAgICAgICAgYXBwSWQ6IHJlcS5wYXJhbXMuYXBwSWQsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5pbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cbiAgfVxuXG4gIG1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICB0ZXh0OiAnTm90IGZvdW5kLicsXG4gICAgICBzdGF0dXM6IDQwNCxcbiAgICB9KTtcbiAgfVxuXG4gIGludmFsaWRSZXF1ZXN0KCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSAndW5hdXRob3JpemVkJztcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHNldENvbmZpZyhyZXEpIHtcbiAgICByZXEuY29uZmlnID0gQ29uZmlnLmdldChyZXEucGFyYW1zLmFwcElkKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3ZlcmlmeV9lbWFpbCcsXG4gICAgICByZXEgPT4ge1xuICAgICAgICB0aGlzLnNldENvbmZpZyhyZXEpO1xuICAgICAgfSxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUVtYWlsKHJlcSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3Jlc2VuZF92ZXJpZmljYXRpb25fZW1haWwnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL2FwcHMvY2hvb3NlX3Bhc3N3b3JkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNoYW5nZVBhc3N3b3JkKHJlcSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9hcHBzLzphcHBJZC9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0JyxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3JlcXVlc3RfcGFzc3dvcmRfcmVzZXQnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0UmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBleHByZXNzUm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLnVzZSgnL2FwcHMnLCBleHByZXNzLnN0YXRpYyhwdWJsaWNfaHRtbCkpO1xuICAgIHJvdXRlci51c2UoJy8nLCBzdXBlci5leHByZXNzUm91dGVyKCkpO1xuICAgIHJldHVybiByb3V0ZXI7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVibGljQVBJUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PurgeRouter.js b/lib/Routers/PurgeRouter.js deleted file mode 100644 index 503d9eb543..0000000000 --- a/lib/Routers/PurgeRouter.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PurgeRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class PurgeRouter extends _PromiseRouter.default { - handlePurge(req) { - if (req.auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to purge a schema."); - } - - return req.config.database.purgeCollection(req.params.className).then(() => { - var cacheAdapter = req.config.cacheController; - - if (req.params.className == '_Session') { - cacheAdapter.user.clear(); - } else if (req.params.className == '_Role') { - cacheAdapter.role.clear(); - } - - return { - response: {} - }; - }).catch(error => { - if (!error || error && error.code === _node.default.Error.OBJECT_NOT_FOUND) { - return { - response: {} - }; - } - - throw error; - }); - } - - mountRoutes() { - this.route('DELETE', '/purge/:className', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handlePurge(req); - }); - } - -} - -exports.PurgeRouter = PurgeRouter; -var _default = PurgeRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1cmdlUm91dGVyLmpzIl0sIm5hbWVzIjpbIlB1cmdlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVB1cmdlIiwicmVxIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImNvbmZpZyIsImRhdGFiYXNlIiwicHVyZ2VDb2xsZWN0aW9uIiwicGFyYW1zIiwiY2xhc3NOYW1lIiwidGhlbiIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsInVzZXIiLCJjbGVhciIsInJvbGUiLCJyZXNwb25zZSIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiT0JKRUNUX05PVF9GT1VORCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ2YsUUFBSUEsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixzREFGSSxDQUFOO0FBSUQ7O0FBQ0QsV0FBT0wsR0FBRyxDQUFDTSxNQUFKLENBQVdDLFFBQVgsQ0FDSkMsZUFESSxDQUNZUixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FEdkIsRUFFSkMsSUFGSSxDQUVDLE1BQU07QUFDVixVQUFJQyxZQUFZLEdBQUdaLEdBQUcsQ0FBQ00sTUFBSixDQUFXTyxlQUE5Qjs7QUFDQSxVQUFJYixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixVQUE1QixFQUF3QztBQUN0Q0UsUUFBQUEsWUFBWSxDQUFDRSxJQUFiLENBQWtCQyxLQUFsQjtBQUNELE9BRkQsTUFFTyxJQUFJZixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixPQUE1QixFQUFxQztBQUMxQ0UsUUFBQUEsWUFBWSxDQUFDSSxJQUFiLENBQWtCRCxLQUFsQjtBQUNEOztBQUNELGFBQU87QUFBRUUsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVkksRUFXSkMsS0FYSSxDQVdFQyxLQUFLLElBQUk7QUFDZCxVQUFJLENBQUNBLEtBQUQsSUFBV0EsS0FBSyxJQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZWpCLGNBQU1DLEtBQU4sQ0FBWWlCLGdCQUFuRCxFQUFzRTtBQUNwRSxlQUFPO0FBQUVKLFVBQUFBLFFBQVEsRUFBRTtBQUFaLFNBQVA7QUFDRDs7QUFDRCxZQUFNRSxLQUFOO0FBQ0QsS0FoQkksQ0FBUDtBQWlCRDs7QUFFREcsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLFFBQVgsRUFBcUIsbUJBQXJCLEVBQTBDQyxVQUFVLENBQUNDLDZCQUFyRCxFQUFvRnpCLEdBQUcsSUFBSTtBQUN6RixhQUFPLEtBQUtELFdBQUwsQ0FBaUJDLEdBQWpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBL0I0Qzs7O2VBa0NoQ0gsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmV4cG9ydCBjbGFzcyBQdXJnZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVQdXJnZShyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBwdXJnZSBhIHNjaGVtYS5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5wdXJnZUNvbGxlY3Rpb24ocmVxLnBhcmFtcy5jbGFzc05hbWUpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHZhciBjYWNoZUFkYXB0ZXIgPSByZXEuY29uZmlnLmNhY2hlQ29udHJvbGxlcjtcbiAgICAgICAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5jbGVhcigpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfUm9sZScpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIucm9sZS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHt9IH07XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvcHVyZ2UvOmNsYXNzTmFtZScsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVQdXJnZShyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1cmdlUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PushRouter.js b/lib/Routers/PushRouter.js deleted file mode 100644 index f0b17383c3..0000000000 --- a/lib/Routers/PushRouter.js +++ /dev/null @@ -1,92 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -var _node = require("parse/node"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class PushRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('POST', '/push', middleware.promiseEnforceMasterKeyAccess, PushRouter.handlePOST); - } - - static handlePOST(req) { - if (req.auth.isReadOnly) { - throw new _node.Parse.Error(_node.Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to send push notifications."); - } - - const pushController = req.config.pushController; - - if (!pushController) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Push controller is not set'); - } - - const where = PushRouter.getQueryCondition(req); - let resolve; - const promise = new Promise(_resolve => { - resolve = _resolve; - }); - let pushStatusId; - pushController.sendPush(req.body, where, req.config, req.auth, objectId => { - pushStatusId = objectId; - resolve({ - headers: { - 'X-Parse-Push-Status-Id': pushStatusId - }, - response: { - result: true - } - }); - }).catch(err => { - req.config.loggerController.error(`_PushStatus ${pushStatusId}: error while sending push`, err); - }); - return promise; - } - /** - * Get query condition from the request body. - * @param {Object} req A request object - * @returns {Object} The query condition, the where field in a query api call - */ - - - static getQueryCondition(req) { - const body = req.body || {}; - const hasWhere = typeof body.where !== 'undefined'; - const hasChannels = typeof body.channels !== 'undefined'; - let where; - - if (hasWhere && hasChannels) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Channels and query can not be set at the same time.'); - } else if (hasWhere) { - where = body.where; - } else if (hasChannels) { - where = { - channels: { - $in: body.channels - } - }; - } else { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Sending a push requires either "channels" or a "where" query.'); - } - - return where; - } - -} - -exports.PushRouter = PushRouter; -var _default = PushRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1c2hSb3V0ZXIuanMiXSwibmFtZXMiOlsiUHVzaFJvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlUE9TVCIsInJlcSIsImF1dGgiLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJwdXNoQ29udHJvbGxlciIsImNvbmZpZyIsIlBVU0hfTUlTQ09ORklHVVJFRCIsIndoZXJlIiwiZ2V0UXVlcnlDb25kaXRpb24iLCJyZXNvbHZlIiwicHJvbWlzZSIsIlByb21pc2UiLCJfcmVzb2x2ZSIsInB1c2hTdGF0dXNJZCIsInNlbmRQdXNoIiwiYm9keSIsIm9iamVjdElkIiwiaGVhZGVycyIsInJlc3BvbnNlIiwicmVzdWx0IiwiY2F0Y2giLCJlcnIiLCJsb2dnZXJDb250cm9sbGVyIiwiZXJyb3IiLCJoYXNXaGVyZSIsImhhc0NoYW5uZWxzIiwiY2hhbm5lbHMiLCIkaW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLE9BQW5CLEVBQTRCQyxVQUFVLENBQUNDLDZCQUF2QyxFQUFzRUwsVUFBVSxDQUFDTSxVQUFqRjtBQUNEOztBQUVELFNBQU9BLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQXVCO0FBQ3JCLFFBQUlBLEdBQUcsQ0FBQ0MsSUFBSixDQUFTQyxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1DLGNBQWMsR0FBR04sR0FBRyxDQUFDTyxNQUFKLENBQVdELGNBQWxDOztBQUNBLFFBQUksQ0FBQ0EsY0FBTCxFQUFxQjtBQUNuQixZQUFNLElBQUlILFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUksa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0Q7O0FBRUQsVUFBTUMsS0FBSyxHQUFHaEIsVUFBVSxDQUFDaUIsaUJBQVgsQ0FBNkJWLEdBQTdCLENBQWQ7QUFDQSxRQUFJVyxPQUFKO0FBQ0EsVUFBTUMsT0FBTyxHQUFHLElBQUlDLE9BQUosQ0FBWUMsUUFBUSxJQUFJO0FBQ3RDSCxNQUFBQSxPQUFPLEdBQUdHLFFBQVY7QUFDRCxLQUZlLENBQWhCO0FBR0EsUUFBSUMsWUFBSjtBQUNBVCxJQUFBQSxjQUFjLENBQ1hVLFFBREgsQ0FDWWhCLEdBQUcsQ0FBQ2lCLElBRGhCLEVBQ3NCUixLQUR0QixFQUM2QlQsR0FBRyxDQUFDTyxNQURqQyxFQUN5Q1AsR0FBRyxDQUFDQyxJQUQ3QyxFQUNtRGlCLFFBQVEsSUFBSTtBQUMzREgsTUFBQUEsWUFBWSxHQUFHRyxRQUFmO0FBQ0FQLE1BQUFBLE9BQU8sQ0FBQztBQUNOUSxRQUFBQSxPQUFPLEVBQUU7QUFDUCxvQ0FBMEJKO0FBRG5CLFNBREg7QUFJTkssUUFBQUEsUUFBUSxFQUFFO0FBQ1JDLFVBQUFBLE1BQU0sRUFBRTtBQURBO0FBSkosT0FBRCxDQUFQO0FBUUQsS0FYSCxFQVlHQyxLQVpILENBWVNDLEdBQUcsSUFBSTtBQUNadkIsTUFBQUEsR0FBRyxDQUFDTyxNQUFKLENBQVdpQixnQkFBWCxDQUE0QkMsS0FBNUIsQ0FDRyxlQUFjVixZQUFhLDRCQUQ5QixFQUVFUSxHQUZGO0FBSUQsS0FqQkg7QUFrQkEsV0FBT1gsT0FBUDtBQUNEO0FBRUQ7Ozs7Ozs7QUFLQSxTQUFPRixpQkFBUCxDQUF5QlYsR0FBekIsRUFBOEI7QUFDNUIsVUFBTWlCLElBQUksR0FBR2pCLEdBQUcsQ0FBQ2lCLElBQUosSUFBWSxFQUF6QjtBQUNBLFVBQU1TLFFBQVEsR0FBRyxPQUFPVCxJQUFJLENBQUNSLEtBQVosS0FBc0IsV0FBdkM7QUFDQSxVQUFNa0IsV0FBVyxHQUFHLE9BQU9WLElBQUksQ0FBQ1csUUFBWixLQUF5QixXQUE3QztBQUVBLFFBQUluQixLQUFKOztBQUNBLFFBQUlpQixRQUFRLElBQUlDLFdBQWhCLEVBQTZCO0FBQzNCLFlBQU0sSUFBSXhCLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZSSxrQkFEUixFQUVKLHFEQUZJLENBQU47QUFJRCxLQUxELE1BS08sSUFBSWtCLFFBQUosRUFBYztBQUNuQmpCLE1BQUFBLEtBQUssR0FBR1EsSUFBSSxDQUFDUixLQUFiO0FBQ0QsS0FGTSxNQUVBLElBQUlrQixXQUFKLEVBQWlCO0FBQ3RCbEIsTUFBQUEsS0FBSyxHQUFHO0FBQ05tQixRQUFBQSxRQUFRLEVBQUU7QUFDUkMsVUFBQUEsR0FBRyxFQUFFWixJQUFJLENBQUNXO0FBREY7QUFESixPQUFSO0FBS0QsS0FOTSxNQU1BO0FBQ0wsWUFBTSxJQUFJekIsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlJLGtCQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFdBQU9DLEtBQVA7QUFDRDs7QUEzRTJDOzs7ZUE4RS9CaEIsVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuXG5leHBvcnQgY2xhc3MgUHVzaFJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9wdXNoJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgUHVzaFJvdXRlci5oYW5kbGVQT1NUKTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVQT1NUKHJlcSkge1xuICAgIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHNlbmQgcHVzaCBub3RpZmljYXRpb25zLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBwdXNoQ29udHJvbGxlciA9IHJlcS5jb25maWcucHVzaENvbnRyb2xsZXI7XG4gICAgaWYgKCFwdXNoQ29udHJvbGxlcikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCwgJ1B1c2ggY29udHJvbGxlciBpcyBub3Qgc2V0Jyk7XG4gICAgfVxuXG4gICAgY29uc3Qgd2hlcmUgPSBQdXNoUm91dGVyLmdldFF1ZXJ5Q29uZGl0aW9uKHJlcSk7XG4gICAgbGV0IHJlc29sdmU7XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKF9yZXNvbHZlID0+IHtcbiAgICAgIHJlc29sdmUgPSBfcmVzb2x2ZTtcbiAgICB9KTtcbiAgICBsZXQgcHVzaFN0YXR1c0lkO1xuICAgIHB1c2hDb250cm9sbGVyXG4gICAgICAuc2VuZFB1c2gocmVxLmJvZHksIHdoZXJlLCByZXEuY29uZmlnLCByZXEuYXV0aCwgb2JqZWN0SWQgPT4ge1xuICAgICAgICBwdXNoU3RhdHVzSWQgPSBvYmplY3RJZDtcbiAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ1gtUGFyc2UtUHVzaC1TdGF0dXMtSWQnOiBwdXNoU3RhdHVzSWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgcmVzdWx0OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIuZXJyb3IoXG4gICAgICAgICAgYF9QdXNoU3RhdHVzICR7cHVzaFN0YXR1c0lkfTogZXJyb3Igd2hpbGUgc2VuZGluZyBwdXNoYCxcbiAgICAgICAgICBlcnJcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBxdWVyeSBjb25kaXRpb24gZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIEEgcmVxdWVzdCBvYmplY3RcbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIHF1ZXJ5IGNvbmRpdGlvbiwgdGhlIHdoZXJlIGZpZWxkIGluIGEgcXVlcnkgYXBpIGNhbGxcbiAgICovXG4gIHN0YXRpYyBnZXRRdWVyeUNvbmRpdGlvbihyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gcmVxLmJvZHkgfHwge307XG4gICAgY29uc3QgaGFzV2hlcmUgPSB0eXBlb2YgYm9keS53aGVyZSAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgY29uc3QgaGFzQ2hhbm5lbHMgPSB0eXBlb2YgYm9keS5jaGFubmVscyAhPT0gJ3VuZGVmaW5lZCc7XG5cbiAgICBsZXQgd2hlcmU7XG4gICAgaWYgKGhhc1doZXJlICYmIGhhc0NoYW5uZWxzKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ0NoYW5uZWxzIGFuZCBxdWVyeSBjYW4gbm90IGJlIHNldCBhdCB0aGUgc2FtZSB0aW1lLidcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChoYXNXaGVyZSkge1xuICAgICAgd2hlcmUgPSBib2R5LndoZXJlO1xuICAgIH0gZWxzZSBpZiAoaGFzQ2hhbm5lbHMpIHtcbiAgICAgIHdoZXJlID0ge1xuICAgICAgICBjaGFubmVsczoge1xuICAgICAgICAgICRpbjogYm9keS5jaGFubmVscyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnU2VuZGluZyBhIHB1c2ggcmVxdWlyZXMgZWl0aGVyIFwiY2hhbm5lbHNcIiBvciBhIFwid2hlcmVcIiBxdWVyeS4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gd2hlcmU7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaFJvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/RolesRouter.js b/lib/Routers/RolesRouter.js deleted file mode 100644 index 10fd6e7942..0000000000 --- a/lib/Routers/RolesRouter.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.RolesRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class RolesRouter extends _ClassesRouter.default { - className() { - return '_Role'; - } - - mountRoutes() { - this.route('GET', '/roles', req => { - return this.handleFind(req); - }); - this.route('GET', '/roles/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/roles', req => { - return this.handleCreate(req); - }); - this.route('PUT', '/roles/:objectId', req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/roles/:objectId', req => { - return this.handleDelete(req); - }); - } - -} - -exports.RolesRouter = RolesRouter; -var _default = RolesRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1JvbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlJvbGVzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsIm1vdW50Um91dGVzIiwicm91dGUiLCJyZXEiLCJoYW5kbGVGaW5kIiwiaGFuZGxlR2V0IiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFNBQVMsR0FBRztBQUNWLFdBQU8sT0FBUDtBQUNEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixRQUFsQixFQUE0QkMsR0FBRyxJQUFJO0FBQ2pDLGFBQU8sS0FBS0MsVUFBTCxDQUFnQkQsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsS0FBWCxFQUFrQixrQkFBbEIsRUFBc0NDLEdBQUcsSUFBSTtBQUMzQyxhQUFPLEtBQUtFLFNBQUwsQ0FBZUYsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFFBQW5CLEVBQTZCQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRyxZQUFMLENBQWtCSCxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxLQUFYLEVBQWtCLGtCQUFsQixFQUFzQ0MsR0FBRyxJQUFJO0FBQzNDLGFBQU8sS0FBS0ksWUFBTCxDQUFrQkosR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsUUFBWCxFQUFxQixrQkFBckIsRUFBeUNDLEdBQUcsSUFBSTtBQUM5QyxhQUFPLEtBQUtLLFlBQUwsQ0FBa0JMLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBckI0Qzs7O2VBd0JoQ0wsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5cbmV4cG9ydCBjbGFzcyBSb2xlc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfUm9sZSc7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yb2xlcycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSb2xlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/SchemasRouter.js b/lib/Routers/SchemasRouter.js deleted file mode 100644 index 04681476df..0000000000 --- a/lib/Routers/SchemasRouter.js +++ /dev/null @@ -1,120 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SchemasRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// schemas.js -var Parse = require('parse/node').Parse, - SchemaController = require('../Controllers/SchemaController'); - -function classNameMismatchResponse(bodyClass, pathClass) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class name mismatch between ${bodyClass} and ${pathClass}.`); -} - -function getAllSchemas(req) { - return req.config.database.loadSchema({ - clearCache: true - }).then(schemaController => schemaController.getAllClasses(true)).then(schemas => ({ - response: { - results: schemas - } - })); -} - -function getOneSchema(req) { - const className = req.params.className; - return req.config.database.loadSchema({ - clearCache: true - }).then(schemaController => schemaController.getOneSchema(className, true)).then(schema => ({ - response: schema - })).catch(error => { - if (error === undefined) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); - } else { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); - } - }); -} - -function createSchema(req) { - if (req.auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); - } - - if (req.params.className && req.body.className) { - if (req.params.className != req.body.className) { - return classNameMismatchResponse(req.body.className, req.params.className); - } - } - - const className = req.params.className || req.body.className; - - if (!className) { - throw new Parse.Error(135, `POST ${req.path} needs a class name.`); - } - - return req.config.database.loadSchema({ - clearCache: true - }).then(schema => schema.addClassIfNotExists(className, req.body.fields, req.body.classLevelPermissions, req.body.indexes)).then(schema => ({ - response: schema - })); -} - -function modifySchema(req) { - if (req.auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); - } - - if (req.body.className && req.body.className != req.params.className) { - return classNameMismatchResponse(req.body.className, req.params.className); - } - - const submittedFields = req.body.fields || {}; - const className = req.params.className; - return req.config.database.loadSchema({ - clearCache: true - }).then(schema => schema.updateClass(className, submittedFields, req.body.classLevelPermissions, req.body.indexes, req.config.database)).then(result => ({ - response: result - })); -} - -const deleteSchema = req => { - if (req.auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); - } - - if (!SchemaController.classNameIsValid(req.params.className)) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, SchemaController.invalidClassNameMessage(req.params.className)); - } - - return req.config.database.deleteSchema(req.params.className).then(() => ({ - response: {} - })); -}; - -class SchemasRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/schemas', middleware.promiseEnforceMasterKeyAccess, getAllSchemas); - this.route('GET', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, getOneSchema); - this.route('POST', '/schemas', middleware.promiseEnforceMasterKeyAccess, createSchema); - this.route('POST', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, createSchema); - this.route('PUT', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, modifySchema); - this.route('DELETE', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, deleteSchema); - } - -} - -exports.SchemasRouter = SchemasRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1NjaGVtYXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZU1pc21hdGNoUmVzcG9uc2UiLCJib2R5Q2xhc3MiLCJwYXRoQ2xhc3MiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsImdldEFsbFNjaGVtYXMiLCJyZXEiLCJjb25maWciLCJkYXRhYmFzZSIsImxvYWRTY2hlbWEiLCJjbGVhckNhY2hlIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hcyIsInJlc3BvbnNlIiwicmVzdWx0cyIsImdldE9uZVNjaGVtYSIsImNsYXNzTmFtZSIsInBhcmFtcyIsInNjaGVtYSIsImNhdGNoIiwiZXJyb3IiLCJ1bmRlZmluZWQiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjcmVhdGVTY2hlbWEiLCJhdXRoIiwiaXNSZWFkT25seSIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwicGF0aCIsImFkZENsYXNzSWZOb3RFeGlzdHMiLCJmaWVsZHMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJpbmRleGVzIiwibW9kaWZ5U2NoZW1hIiwic3VibWl0dGVkRmllbGRzIiwidXBkYXRlQ2xhc3MiLCJyZXN1bHQiLCJkZWxldGVTY2hlbWEiLCJjbGFzc05hbWVJc1ZhbGlkIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJTY2hlbWFzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFLQTs7QUFDQTs7Ozs7Ozs7QUFOQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxnQkFBZ0IsR0FBR0Qs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QXdFMUMsYUFBeEU7QUFDQSxTQUFLd0MsS0FBTCxDQUNFLEtBREYsRUFFRSxxQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU5QixZQUpGO0FBTUEsU0FBSzRCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFVBQW5CLEVBQStCQyxVQUFVLENBQUNDLDZCQUExQyxFQUF5RXRCLFlBQXpFO0FBQ0EsU0FBS29CLEtBQUwsQ0FDRSxNQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFdEIsWUFKRjtBQU1BLFNBQUtvQixLQUFMLENBQ0UsS0FERixFQUVFLHFCQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRVosWUFKRjtBQU1BLFNBQUtVLEtBQUwsQ0FDRSxRQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFUixZQUpGO0FBTUQ7O0FBNUI4QyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNjaGVtYXMuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICBTY2hlbWFDb250cm9sbGVyID0gcmVxdWlyZSgnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xuXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5mdW5jdGlvbiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKGJvZHlDbGFzcywgcGF0aENsYXNzKSB7XG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgYENsYXNzIG5hbWUgbWlzbWF0Y2ggYmV0d2VlbiAke2JvZHlDbGFzc30gYW5kICR7cGF0aENsYXNzfS5gXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEFsbFNjaGVtYXMocmVxKSB7XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoeyBjbGVhckNhY2hlOiB0cnVlIH0pXG4gICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmdldEFsbENsYXNzZXModHJ1ZSkpXG4gICAgLnRoZW4oc2NoZW1hcyA9PiAoeyByZXNwb25zZTogeyByZXN1bHRzOiBzY2hlbWFzIH0gfSkpO1xufVxuXG5mdW5jdGlvbiBnZXRPbmVTY2hlbWEocmVxKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCB0cnVlKSlcbiAgICAudGhlbihzY2hlbWEgPT4gKHsgcmVzcG9uc2U6IHNjaGVtYSB9KSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yLicpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGNyZWF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lICYmIHJlcS5ib2R5LmNsYXNzTmFtZSkge1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAhPSByZXEuYm9keS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKHJlcS5ib2R5LmNsYXNzTmFtZSwgcmVxLnBhcmFtcy5jbGFzc05hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lIHx8IHJlcS5ib2R5LmNsYXNzTmFtZTtcbiAgaWYgKCFjbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM1LCBgUE9TVCAke3JlcS5wYXRofSBuZWVkcyBhIGNsYXNzIG5hbWUuYCk7XG4gIH1cblxuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYSA9PlxuICAgICAgc2NoZW1hLmFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgcmVxLmJvZHkuZmllbGRzLFxuICAgICAgICByZXEuYm9keS5jbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgIHJlcS5ib2R5LmluZGV4ZXNcbiAgICAgIClcbiAgICApXG4gICAgLnRoZW4oc2NoZW1hID0+ICh7IHJlc3BvbnNlOiBzY2hlbWEgfSkpO1xufVxuXG5mdW5jdGlvbiBtb2RpZnlTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHVwZGF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5ib2R5LmNsYXNzTmFtZSAmJiByZXEuYm9keS5jbGFzc05hbWUgIT0gcmVxLnBhcmFtcy5jbGFzc05hbWUpIHtcbiAgICByZXR1cm4gY2xhc3NOYW1lTWlzbWF0Y2hSZXNwb25zZShyZXEuYm9keS5jbGFzc05hbWUsIHJlcS5wYXJhbXMuY2xhc3NOYW1lKTtcbiAgfVxuXG4gIGNvbnN0IHN1Ym1pdHRlZEZpZWxkcyA9IHJlcS5ib2R5LmZpZWxkcyB8fCB7fTtcbiAgY29uc3QgY2xhc3NOYW1lID0gcmVxLnBhcmFtcy5jbGFzc05hbWU7XG5cbiAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAudGhlbihzY2hlbWEgPT5cbiAgICAgIHNjaGVtYS51cGRhdGVDbGFzcyhcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBzdWJtaXR0ZWRGaWVsZHMsXG4gICAgICAgIHJlcS5ib2R5LmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgcmVxLmJvZHkuaW5kZXhlcyxcbiAgICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgKVxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4gKHsgcmVzcG9uc2U6IHJlc3VsdCB9KSk7XG59XG5cbmNvbnN0IGRlbGV0ZVNjaGVtYSA9IHJlcSA9PiB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGRlbGV0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKCFTY2hlbWFDb250cm9sbGVyLmNsYXNzTmFtZUlzVmFsaWQocmVxLnBhcmFtcy5jbGFzc05hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgU2NoZW1hQ29udHJvbGxlci5pbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShyZXEucGFyYW1zLmNsYXNzTmFtZSlcbiAgICApO1xuICB9XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShyZXEucGFyYW1zLmNsYXNzTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xufTtcblxuZXhwb3J0IGNsYXNzIFNjaGVtYXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zY2hlbWFzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgZ2V0QWxsU2NoZW1hcyk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9zY2hlbWFzLzpjbGFzc05hbWUnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIGdldE9uZVNjaGVtYVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvc2NoZW1hcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGNyZWF0ZVNjaGVtYSk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBjcmVhdGVTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUFVUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBtb2RpZnlTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnREVMRVRFJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBkZWxldGVTY2hlbWFcbiAgICApO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/SessionsRouter.js b/lib/Routers/SessionsRouter.js deleted file mode 100644 index de4bdcd2e0..0000000000 --- a/lib/Routers/SessionsRouter.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.SessionsRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _Auth = _interopRequireDefault(require("../Auth")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class SessionsRouter extends _ClassesRouter.default { - className() { - return '_Session'; - } - - handleMe(req) { - // TODO: Verify correct behavior - if (!req.info || !req.info.sessionToken) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token required.'); - } - - return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { - sessionToken: req.info.sessionToken - }, undefined, req.info.clientSDK, req.info.context).then(response => { - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token not found.'); - } - - return { - response: response.results[0] - }; - }); - } - - handleUpdateToRevocableSession(req) { - const config = req.config; - const user = req.auth.user; // Issue #2720 - // Calling without a session token would result in a not found user - - if (!user) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'invalid session'); - } - - const { - sessionData, - createSession - } = _Auth.default.createSession(config, { - userId: user.id, - createdWith: { - action: 'upgrade' - }, - installationId: req.auth.installationId - }); - - return createSession().then(() => { - // delete the session token, use the db to skip beforeSave - return config.database.update('_User', { - objectId: user.id - }, { - sessionToken: { - __op: 'Delete' - } - }); - }).then(() => { - return Promise.resolve({ - response: sessionData - }); - }); - } - - mountRoutes() { - this.route('GET', '/sessions/me', req => { - return this.handleMe(req); - }); - this.route('GET', '/sessions', req => { - return this.handleFind(req); - }); - this.route('GET', '/sessions/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/sessions', req => { - return this.handleCreate(req); - }); - this.route('PUT', '/sessions/:objectId', req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/sessions/:objectId', req => { - return this.handleDelete(req); - }); - this.route('POST', '/upgradeToRevocableSession', req => { - return this.handleUpdateToRevocableSession(req); - }); - } - -} - -exports.SessionsRouter = SessionsRouter; -var _default = SessionsRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyLmpzIl0sIm5hbWVzIjpbIlNlc3Npb25zUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsImhhbmRsZU1lIiwicmVxIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsIkF1dGgiLCJtYXN0ZXIiLCJ1bmRlZmluZWQiLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0cyIsImxlbmd0aCIsImhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbiIsInVzZXIiLCJhdXRoIiwiT0JKRUNUX05PVF9GT1VORCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsImlkIiwiY3JlYXRlZFdpdGgiLCJhY3Rpb24iLCJpbnN0YWxsYXRpb25JZCIsImRhdGFiYXNlIiwidXBkYXRlIiwib2JqZWN0SWQiLCJfX29wIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsImhhbmRsZUdldCIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixTQUE2QkMsc0JBQTdCLENBQTJDO0FBQ2hEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFVBQVA7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxDQUFDQyxHQUFELEVBQU07QUFDWjtBQUNBLFFBQUksQ0FBQ0EsR0FBRyxDQUFDQyxJQUFMLElBQWEsQ0FBQ0QsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFlBQTNCLEVBQXlDO0FBQ3ZDLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxx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QUFJO0FBQ3JDLGFBQU8sS0FBS3VDLFlBQUwsQ0FBa0J2QyxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtvQyxLQUFMLENBQVcsS0FBWCxFQUFrQixxQkFBbEIsRUFBeUNwQyxHQUFHLElBQUk7QUFDOUMsYUFBTyxLQUFLd0MsWUFBTCxDQUFrQnhDLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS29DLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLHFCQUFyQixFQUE0Q3BDLEdBQUcsSUFBSTtBQUNqRCxhQUFPLEtBQUt5QyxZQUFMLENBQWtCekMsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLb0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsNEJBQW5CLEVBQWlEcEMsR0FBRyxJQUFJO0FBQ3RELGFBQU8sS0FBS2tCLDhCQUFMLENBQW9DbEIsR0FBcEMsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF0RitDOzs7ZUF5Rm5DSixjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IEF1dGggZnJvbSAnLi4vQXV0aCc7XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfU2Vzc2lvbic7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICAvLyBUT0RPOiBWZXJpZnkgY29ycmVjdCBiZWhhdmlvclxuICAgIGlmICghcmVxLmluZm8gfHwgIXJlcS5pbmZvLnNlc3Npb25Ub2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuOiByZXEuaW5mby5zZXNzaW9uVG9rZW4gfSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnU2Vzc2lvbiB0b2tlbiBub3QgZm91bmQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2UucmVzdWx0c1swXSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlVG9SZXZvY2FibGVTZXNzaW9uKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgdXNlciA9IHJlcS5hdXRoLnVzZXI7XG4gICAgLy8gSXNzdWUgIzI3MjBcbiAgICAvLyBDYWxsaW5nIHdpdGhvdXQgYSBzZXNzaW9uIHRva2VuIHdvdWxkIHJlc3VsdCBpbiBhIG5vdCBmb3VuZCB1c2VyXG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ2ludmFsaWQgc2Vzc2lvbicpO1xuICAgIH1cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24oY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIuaWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICd1cGdyYWRlJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmF1dGguaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGRlbGV0ZSB0aGUgc2Vzc2lvbiB0b2tlbiwgdXNlIHRoZSBkYiB0byBza2lwIGJlZm9yZVNhdmVcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvYmplY3RJZDogdXNlci5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyByZXNwb25zZTogc2Vzc2lvbkRhdGEgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvc2Vzc2lvbnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9zZXNzaW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91cGdyYWRlVG9SZXZvY2FibGVTZXNzaW9uJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbihyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNlc3Npb25zUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/UsersRouter.js b/lib/Routers/UsersRouter.js deleted file mode 100644 index e8a18d53f0..0000000000 --- a/lib/Routers/UsersRouter.js +++ /dev/null @@ -1,436 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.UsersRouter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _AccountLockout = _interopRequireDefault(require("../AccountLockout")); - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _Auth = _interopRequireDefault(require("../Auth")); - -var _password = _interopRequireDefault(require("../password")); - -var _triggers = require("../triggers"); - -var _middlewares = require("../middlewares"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -class UsersRouter extends _ClassesRouter.default { - className() { - return '_User'; - } - /** - * Removes all "_" prefixed properties from an object, except "__type" - * @param {Object} obj An object. - */ - - - static removeHiddenProperties(obj) { - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - // Regexp comes from Parse.Object.prototype.validate - if (key !== '__type' && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { - delete obj[key]; - } - } - } - } - /** - * Validates a password request in login and verifyPassword - * @param {Object} req The request - * @returns {Object} User object - * @private - */ - - - _authenticateUserFromRequest(req) { - return new Promise((resolve, reject) => { - // Use query parameters instead if provided in url - let payload = req.body; - - if (!payload.username && req.query && req.query.username || !payload.email && req.query && req.query.email) { - payload = req.query; - } - - const { - username, - email, - password - } = payload; // TODO: use the right error codes / descriptions. - - if (!username && !email) { - throw new _node.default.Error(_node.default.Error.USERNAME_MISSING, 'username/email is required.'); - } - - if (!password) { - throw new _node.default.Error(_node.default.Error.PASSWORD_MISSING, 'password is required.'); - } - - if (typeof password !== 'string' || email && typeof email !== 'string' || username && typeof username !== 'string') { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - - let user; - let isValidPassword = false; - let query; - - if (email && username) { - query = { - email, - username - }; - } else if (email) { - query = { - email - }; - } else { - query = { - $or: [{ - username - }, { - email: username - }] - }; - } - - return req.config.database.find('_User', query).then(results => { - if (!results.length) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - - if (results.length > 1) { - // corner case where user1 has username == user2 email - req.config.loggerController.warn("There is a user which email is the same as another user's username, logging in based on username"); - user = results.filter(user => user.username === username)[0]; - } else { - user = results[0]; - } - - return _password.default.compare(password, user.password); - }).then(correct => { - isValidPassword = correct; - const accountLockoutPolicy = new _AccountLockout.default(user, req.config); - return accountLockoutPolicy.handleLoginAttempt(isValidPassword); - }).then(() => { - if (!isValidPassword) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } // Ensure the user isn't locked out - // A locked out user won't be able to login - // To lock a user out, just set the ACL to `masterKey` only ({}). - // Empty ACL is OK - - - if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - - if (req.config.verifyUserEmails && req.config.preventLoginWithUnverifiedEmail && !user.emailVerified) { - throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); - } - - delete user.password; // Sometimes the authData still has null on that keys - // https://github.com/parse-community/parse-server/issues/935 - - if (user.authData) { - Object.keys(user.authData).forEach(provider => { - if (user.authData[provider] === null) { - delete user.authData[provider]; - } - }); - - if (Object.keys(user.authData).length == 0) { - delete user.authData; - } - } - - return resolve(user); - }).catch(error => { - return reject(error); - }); - }); - } - - handleMe(req) { - if (!req.info || !req.info.sessionToken) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - const sessionToken = req.info.sessionToken; - return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { - sessionToken - }, { - include: 'user' - }, req.info.clientSDK, req.info.context).then(response => { - if (!response.results || response.results.length == 0 || !response.results[0].user) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } else { - const user = response.results[0].user; // Send token back on the login, because SDKs expect that. - - user.sessionToken = sessionToken; // Remove hidden properties. - - UsersRouter.removeHiddenProperties(user); - return { - response: user - }; - } - }); - } - - async handleLogIn(req) { - const user = await this._authenticateUserFromRequest(req); // handle password expiry policy - - if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { - let changedAt = user._password_changed_at; - - if (!changedAt) { - // password was created before expiry policy was enabled. - // simply update _User object so that it will start enforcing from now - changedAt = new Date(); - req.config.database.update('_User', { - username: user.username - }, { - _password_changed_at: _node.default._encode(changedAt) - }); - } else { - // check whether the password has expired - if (changedAt.__type == 'Date') { - changedAt = new Date(changedAt.iso); - } // Calculate the expiry time. - - - const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge); - if (expiresAt < new Date()) // fail of current time is past password expiry time - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.'); - } - } // Remove hidden properties. - - - UsersRouter.removeHiddenProperties(user); - req.config.filesController.expandFilesInObject(req.config, user); // Before login trigger; throws if failure - - await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforeLogin, req.auth, _node.default.User.fromJSON(Object.assign({ - className: '_User' - }, user)), null, req.config); - - const { - sessionData, - createSession - } = _Auth.default.createSession(req.config, { - userId: user.objectId, - createdWith: { - action: 'login', - authProvider: 'password' - }, - installationId: req.info.installationId - }); - - user.sessionToken = sessionData.sessionToken; - await createSession(); - - const afterLoginUser = _node.default.User.fromJSON(Object.assign({ - className: '_User' - }, user)); - - (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogin, _objectSpread(_objectSpread({}, req.auth), {}, { - user: afterLoginUser - }), afterLoginUser, null, req.config); - return { - response: user - }; - } - - handleVerifyPassword(req) { - return this._authenticateUserFromRequest(req).then(user => { - // Remove hidden properties. - UsersRouter.removeHiddenProperties(user); - return { - response: user - }; - }).catch(error => { - throw error; - }); - } - - handleLogOut(req) { - const success = { - response: {} - }; - - if (req.info && req.info.sessionToken) { - return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { - sessionToken: req.info.sessionToken - }, undefined, req.info.clientSDK, req.info.context).then(records => { - if (records.results && records.results.length) { - return _rest.default.del(req.config, _Auth.default.master(req.config), '_Session', records.results[0].objectId, req.info.context).then(() => { - this._runAfterLogoutTrigger(req, records.results[0]); - - return Promise.resolve(success); - }); - } - - return Promise.resolve(success); - }); - } - - return Promise.resolve(success); - } - - _runAfterLogoutTrigger(req, session) { - // After logout trigger - (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogout, req.auth, _node.default.Session.fromJSON(Object.assign({ - className: '_Session' - }, session)), null, req.config); - } - - _throwOnBadEmailConfig(req) { - try { - _Config.default.validateEmailConfiguration({ - emailAdapter: req.config.userController.adapter, - appName: req.config.appName, - publicServerURL: req.config.publicServerURL, - emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration - }); - } catch (e) { - if (typeof e === 'string') { - // Maybe we need a Bad Configuration error, but the SDKs won't understand it. For now, Internal Server Error. - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.'); - } else { - throw e; - } - } - } - - handleResetRequest(req) { - this._throwOnBadEmailConfig(req); - - const { - email - } = req.body; - - if (!email) { - throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); - } - - if (typeof email !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); - } - - const userController = req.config.userController; - return userController.sendPasswordResetEmail(email).then(() => { - return Promise.resolve({ - response: {} - }); - }, err => { - if (err.code === _node.default.Error.OBJECT_NOT_FOUND) { - // Return success so that this endpoint can't - // be used to enumerate valid emails - return Promise.resolve({ - response: {} - }); - } else { - throw err; - } - }); - } - - handleVerificationEmailRequest(req) { - this._throwOnBadEmailConfig(req); - - const { - email - } = req.body; - - if (!email) { - throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); - } - - if (typeof email !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); - } - - return req.config.database.find('_User', { - email: email - }).then(results => { - if (!results.length || results.length < 1) { - throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); - } - - const user = results[0]; // remove password field, messes with saving on postgres - - delete user.password; - - if (user.emailVerified) { - throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`); - } - - const userController = req.config.userController; - return userController.regenerateEmailVerifyToken(user).then(() => { - userController.sendVerificationEmail(user); - return { - response: {} - }; - }); - }); - } - - mountRoutes() { - this.route('GET', '/users', req => { - return this.handleFind(req); - }); - this.route('POST', '/users', _middlewares.promiseEnsureIdempotency, req => { - return this.handleCreate(req); - }); - this.route('GET', '/users/me', req => { - return this.handleMe(req); - }); - this.route('GET', '/users/:objectId', req => { - return this.handleGet(req); - }); - this.route('PUT', '/users/:objectId', _middlewares.promiseEnsureIdempotency, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/users/:objectId', req => { - return this.handleDelete(req); - }); - this.route('GET', '/login', req => { - return this.handleLogIn(req); - }); - this.route('POST', '/login', req => { - return this.handleLogIn(req); - }); - this.route('POST', '/logout', req => { - return this.handleLogOut(req); - }); - this.route('POST', '/requestPasswordReset', req => { - return this.handleResetRequest(req); - }); - this.route('POST', '/verificationEmailRequest', req => { - return this.handleVerificationEmailRequest(req); - }); - this.route('GET', '/verifyPassword', req => { - return this.handleVerifyPassword(req); - }); - } - -} - -exports.UsersRouter = UsersRouter; -var _default = UsersRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1VzZXJzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlVzZXJzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsInJlbW92ZUhpZGRlblByb3BlcnRpZXMiLCJvYmoiLCJrZXkiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJ0ZXN0IiwiX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdCIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicGF5bG9hZCIsImJvZHkiLCJ1c2VybmFtZSIsInF1ZXJ5IiwiZW1haWwiLCJwYXNzd29yZCIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiUEFTU1dPUkRfTUlTU0lORyIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1c2VyIiwiaXNWYWxpZFBhc3N3b3JkIiwiJG9yIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2dnZXJDb250cm9sbGVyIiwid2FybiIsImZpbHRlciIsInBhc3N3b3JkQ3J5cHRvIiwiY29tcGFyZSIsImNvcnJlY3QiLCJhY2NvdW50TG9ja291dFBvbGljeSIsIkFjY291bnRMb2Nrb3V0IiwiaGFuZGxlTG9naW5BdHRlbXB0IiwiYXV0aCIsImlzTWFzdGVyIiwiQUNMIiwia2V5cyIsInZlcmlmeVVzZXJFbWFpbHMiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwiZW1haWxWZXJpZmllZCIsIkVNQUlMX05PVF9GT1VORCIsImF1dGhEYXRhIiwiZm9yRWFjaCIsInByb3ZpZGVyIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZU1lIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsInJlc3QiLCJBdXRoIiwibWFzdGVyIiwiaW5jbHVkZSIsImNsaWVudFNESyIsImNvbnRleHQiLCJyZXNwb25zZSIsImhhbmRsZUxvZ0luIiwicGFzc3dvcmRQb2xpY3kiLCJtYXhQYXNzd29yZEFnZSIsImNoYW5nZWRBdCIsIl9wYXNzd29yZF9jaGFuZ2VkX2F0IiwiRGF0ZSIsInVwZGF0ZSIsIl9lbmNvZGUiLCJfX3R5cGUiLCJpc28iLCJleHBpcmVzQXQiLCJnZXRUaW1lIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsIlRyaWdnZXJUeXBlcyIsImJlZm9yZUxvZ2luIiwiVXNlciIsImZyb21KU09OIiwiYXNzaWduIiwic2Vzc2lvbkRhdGEiLCJjcmVhdGVTZXNzaW9uIiwidXNlcklkIiwib2JqZWN0SWQiLCJjcmVhdGVkV2l0aCIsImFjdGlvbiIsImF1dGhQcm92aWRlciIsImluc3RhbGxhdGlvbklkIiwiYWZ0ZXJMb2dpblVzZXIiLCJhZnRlckxvZ2luIiwiaGFuZGxlVmVyaWZ5UGFzc3dvcmQiLCJoYW5kbGVMb2dPdXQiLCJzdWNjZXNzIiwidW5kZWZpbmVkIiwicmVjb3JkcyIsImRlbCIsIl9ydW5BZnRlckxvZ291dFRyaWdnZXIiLCJzZXNzaW9uIiwiYWZ0ZXJMb2dvdXQiLCJTZXNzaW9uIiwiX3Rocm93T25CYWRFbWFpbENvbmZpZyIsIkNvbmZpZyIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImhhbmRsZVJlc2V0UmVxdWVzdCIsIkVNQUlMX01JU1NJTkciLCJJTlZBTElEX0VNQUlMX0FERFJFU1MiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwiZXJyIiwiY29kZSIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCIsIk9USEVSX0NBVVNFIiwicmVnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW4iLCJzZW5kVmVyaWZpY2F0aW9uRW1haWwiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZUdldCIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7O0FBRU8sTUFBTUEsV0FBTixTQUEwQkMsc0JBQTFCLENBQXdDO0FBQzdDQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLE9BQVA7QUFDRDtBQUVEOzs7Ozs7QUFJQSxTQUFPQyxzQkFBUCxDQUE4QkMsR0FBOUIsRUFBbUM7QUFDakMsU0FBSyxJQUFJQyxHQUFULElBQWdCRCxHQUFoQixFQUFxQjtBQUNuQixVQUFJRSxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0wsR0FBckMsRUFBMENDLEdBQTFDLENBQUosRUFBb0Q7QUFDbEQ7QUFDQSxZQUFJQSxHQUFHLEtBQUssUUFBUixJQUFvQixDQUFDLDBCQUEwQkssSUFBMUIsQ0FBK0JMLEdBQS9CLENBQXpCLEVBQThEO0FBQzVELGlCQUFPRCxHQUFHLENBQUNDLEdBQUQsQ0FBVjtBQUNEO0FBQ0Y7QUFDRjtBQUNGO0FBRUQ7Ozs7Ozs7O0FBTUFNLEVBQUFBLDRCQUE0QixDQUFDQyxHQUFELEVBQU07QUFDaEMsV0FBTyxJQUFJQyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDO0FBQ0EsVUFBSUMsT0FBTyxHQUFHSixHQUFHLENBQUNLLElBQWxCOztBQUNBLFVBQ0csQ0FBQ0QsT0FBTyxDQUFDRSxRQUFULElBQXFCTixHQUFHLENBQUNPLEtBQXpCLElBQWtDUCxHQUFHLENBQUNPLEtBQUosQ0FBVUQsUUFBN0MsSUFDQyxDQUFDRixPQUFPLENBQUNJLEtBQVQsSUFBa0JSLEdBQUcsQ0FBQ08sS0FBdEIsSUFBK0JQLEdB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TCxDQUFrQnZGLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS3NILEtBQUwsQ0FBVyxNQUFYLEVBQW1CLHVCQUFuQixFQUE0Q3RILEdBQUcsSUFBSTtBQUNqRCxhQUFPLEtBQUsyRyxrQkFBTCxDQUF3QjNHLEdBQXhCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS3NILEtBQUwsQ0FBVyxNQUFYLEVBQW1CLDJCQUFuQixFQUFnRHRILEdBQUcsSUFBSTtBQUNyRCxhQUFPLEtBQUtpSCw4QkFBTCxDQUFvQ2pILEdBQXBDLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS3NILEtBQUwsQ0FBVyxLQUFYLEVBQWtCLGlCQUFsQixFQUFxQ3RILEdBQUcsSUFBSTtBQUMxQyxhQUFPLEtBQUtzRixvQkFBTCxDQUEwQnRGLEdBQTFCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBbGE0Qzs7O2VBcWFoQ1osVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRoZXNlIG1ldGhvZHMgaGFuZGxlIHRoZSBVc2VyLXJlbGF0ZWQgcm91dGVzLlxuXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgQWNjb3VudExvY2tvdXQgZnJvbSAnLi4vQWNjb3VudExvY2tvdXQnO1xuaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IEF1dGggZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgcGFzc3dvcmRDcnlwdG8gZnJvbSAnLi4vcGFzc3dvcmQnO1xuaW1wb3J0IHsgbWF5YmVSdW5UcmlnZ2VyLCBUeXBlcyBhcyBUcmlnZ2VyVHlwZXMgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kgfSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmV4cG9ydCBjbGFzcyBVc2Vyc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfVXNlcic7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgXCJfXCIgcHJlZml4ZWQgcHJvcGVydGllcyBmcm9tIGFuIG9iamVjdCwgZXhjZXB0IFwiX190eXBlXCJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iaiBBbiBvYmplY3QuXG4gICAqL1xuICBzdGF0aWMgcmVtb3ZlSGlkZGVuUHJvcGVydGllcyhvYmopIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAvLyBSZWdleHAgY29tZXMgZnJvbSBQYXJzZS5PYmplY3QucHJvdG90eXBlLnZhbGlkYXRlXG4gICAgICAgIGlmIChrZXkgIT09ICdfX3R5cGUnICYmICEvXltBLVphLXpdWzAtOUEtWmEtel9dKiQvLnRlc3Qoa2V5KSkge1xuICAgICAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBwYXNzd29yZCByZXF1ZXN0IGluIGxvZ2luIGFuZCB2ZXJpZnlQYXNzd29yZFxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFVzZXIgb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBVc2UgcXVlcnkgcGFyYW1ldGVycyBpbnN0ZWFkIGlmIHByb3ZpZGVkIGluIHVybFxuICAgICAgbGV0IHBheWxvYWQgPSByZXEuYm9keTtcbiAgICAgIGlmIChcbiAgICAgICAgKCFwYXlsb2FkLnVzZXJuYW1lICYmIHJlcS5xdWVyeSAmJiByZXEucXVlcnkudXNlcm5hbWUpIHx8XG4gICAgICAgICghcGF5bG9hZC5lbWFpbCAmJiByZXEucXVlcnkgJiYgcmVxLnF1ZXJ5LmVtYWlsKVxuICAgICAgKSB7XG4gICAgICAgIHBheWxvYWQgPSByZXEucXVlcnk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHVzZXJuYW1lLCBlbWFpbCwgcGFzc3dvcmQgfSA9IHBheWxvYWQ7XG5cbiAgICAgIC8vIFRPRE86IHVzZSB0aGUgcmlnaHQgZXJyb3IgY29kZXMgLyBkZXNjcmlwdGlvbnMuXG4gICAgICBpZiAoIXVzZXJuYW1lICYmICFlbWFpbCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVVNFUk5BTUVfTUlTU0lORywgJ3VzZXJuYW1lL2VtYWlsIGlzIHJlcXVpcmVkLicpO1xuICAgICAgfVxuICAgICAgaWYgKCFwYXNzd29yZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUEFTU1dPUkRfTUlTU0lORywgJ3Bhc3N3b3JkIGlzIHJlcXVpcmVkLicpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgcGFzc3dvcmQgIT09ICdzdHJpbmcnIHx8XG4gICAgICAgIChlbWFpbCAmJiB0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB8fFxuICAgICAgICAodXNlcm5hbWUgJiYgdHlwZW9mIHVzZXJuYW1lICE9PSAnc3RyaW5nJylcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICB9XG5cbiAgICAgIGxldCB1c2VyO1xuICAgICAgbGV0IGlzVmFsaWRQYXNzd29yZCA9IGZhbHNlO1xuICAgICAgbGV0IHF1ZXJ5O1xuICAgICAgaWYgKGVtYWlsICYmIHVzZXJuYW1lKSB7XG4gICAgICAgIHF1ZXJ5ID0geyBlbWFpbCwgdXNlcm5hbWUgfTtcbiAgICAgIH0gZWxzZSBpZiAoZW1haWwpIHtcbiAgICAgICAgcXVlcnkgPSB7IGVtYWlsIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeSA9IHsgJG9yOiBbeyB1c2VybmFtZSB9LCB7IGVtYWlsOiB1c2VybmFtZSB9XSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgLmZpbmQoJ19Vc2VyJywgcXVlcnkpXG4gICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAvLyBjb3JuZXIgY2FzZSB3aGVyZSB1c2VyMSBoYXMgdXNlcm5hbWUgPT0gdXNlcjIgZW1haWxcbiAgICAgICAgICAgIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlci53YXJuKFxuICAgICAgICAgICAgICBcIlRoZXJlIGlzIGEgdXNlciB3aGljaCBlbWFpbCBpcyB0aGUgc2FtZSBhcyBhbm90aGVyIHVzZXIncyB1c2VybmFtZSwgbG9nZ2luZyBpbiBiYXNlZCBvbiB1c2VybmFtZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdXNlciA9IHJlc3VsdHMuZmlsdGVyKHVzZXIgPT4gdXNlci51c2VybmFtZSA9PT0gdXNlcm5hbWUpWzBdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFzc3dvcmRDcnlwdG8uY29tcGFyZShwYXNzd29yZCwgdXNlci5wYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNvcnJlY3QgPT4ge1xuICAgICAgICAgIGlzVmFsaWRQYXNzd29yZCA9IGNvcnJlY3Q7XG4gICAgICAgICAgY29uc3QgYWNjb3VudExvY2tvdXRQb2xpY3kgPSBuZXcgQWNjb3VudExvY2tvdXQodXNlciwgcmVxLmNvbmZpZyk7XG4gICAgICAgICAgcmV0dXJuIGFjY291bnRMb2Nrb3V0UG9saWN5LmhhbmRsZUxvZ2luQXR0ZW1wdChpc1ZhbGlkUGFzc3dvcmQpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgaWYgKCFpc1ZhbGlkUGFzc3dvcmQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gRW5zdXJlIHRoZSB1c2VyIGlzbid0IGxvY2tlZCBvdXRcbiAgICAgICAgICAvLyBBIGxvY2tlZCBvdXQgdXNlciB3b24ndCBiZSBhYmxlIHRvIGxvZ2luXG4gICAgICAgICAgLy8gVG8gbG9jayBhIHVzZXIgb3V0LCBqdXN0IHNldCB0aGUgQUNMIHRvIGBtYXN0ZXJLZXlgIG9ubHkgICh7fSkuXG4gICAgICAgICAgLy8gRW1wdHkgQUNMIGlzIE9LXG4gICAgICAgICAgaWYgKCFyZXEuYXV0aC5pc01hc3RlciAmJiB1c2VyLkFDTCAmJiBPYmplY3Qua2V5cyh1c2VyLkFDTCkubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCB1c2VybmFtZS9wYXNzd29yZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVxLmNvbmZpZy52ZXJpZnlVc2VyRW1haWxzICYmXG4gICAgICAgICAgICByZXEuY29uZmlnLnByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWwgJiZcbiAgICAgICAgICAgICF1c2VyLmVtYWlsVmVyaWZpZWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsICdVc2VyIGVtYWlsIGlzIG5vdCB2ZXJpZmllZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWxldGUgdXNlci5wYXNzd29yZDtcblxuICAgICAgICAgIC8vIFNvbWV0aW1lcyB0aGUgYXV0aERhdGEgc3RpbGwgaGFzIG51bGwgb24gdGhhdCBrZXlzXG4gICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BhcnNlLWNvbW11bml0eS9wYXJzZS1zZXJ2ZXIvaXNzdWVzLzkzNVxuICAgICAgICAgIGlmICh1c2VyLmF1dGhEYXRhKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgICAgICAgaWYgKHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh1c2VyKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICBpZiAoIXJlcS5pbmZvIHx8ICFyZXEuaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2Vzc2lvblRva2VuID0gcmVxLmluZm8uc2Vzc2lvblRva2VuO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuIH0sXG4gICAgICAgIHsgaW5jbHVkZTogJ3VzZXInIH0sXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCB8fCAhcmVzcG9uc2UucmVzdWx0c1swXS51c2VyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXNwb25zZS5yZXN1bHRzWzBdLnVzZXI7XG4gICAgICAgICAgLy8gU2VuZCB0b2tlbiBiYWNrIG9uIHRoZSBsb2dpbiwgYmVjYXVzZSBTREtzIGV4cGVjdCB0aGF0LlxuICAgICAgICAgIHVzZXIuc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG5cbiAgICAgICAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUxvZ0luKHJlcSkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKTtcblxuICAgIC8vIGhhbmRsZSBwYXNzd29yZCBleHBpcnkgcG9saWN5XG4gICAgaWYgKHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgcmVxLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSkge1xuICAgICAgbGV0IGNoYW5nZWRBdCA9IHVzZXIuX3Bhc3N3b3JkX2NoYW5nZWRfYXQ7XG5cbiAgICAgIGlmICghY2hhbmdlZEF0KSB7XG4gICAgICAgIC8vIHBhc3N3b3JkIHdhcyBjcmVhdGVkIGJlZm9yZSBleHBpcnkgcG9saWN5IHdhcyBlbmFibGVkLlxuICAgICAgICAvLyBzaW1wbHkgdXBkYXRlIF9Vc2VyIG9iamVjdCBzbyB0aGF0IGl0IHdpbGwgc3RhcnQgZW5mb3JjaW5nIGZyb20gbm93XG4gICAgICAgIGNoYW5nZWRBdCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIHJlcS5jb25maWcuZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgeyB1c2VybmFtZTogdXNlci51c2VybmFtZSB9LFxuICAgICAgICAgIHsgX3Bhc3N3b3JkX2NoYW5nZWRfYXQ6IFBhcnNlLl9lbmNvZGUoY2hhbmdlZEF0KSB9XG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBwYXNzd29yZCBoYXMgZXhwaXJlZFxuICAgICAgICBpZiAoY2hhbmdlZEF0Ll9fdHlwZSA9PSAnRGF0ZScpIHtcbiAgICAgICAgICBjaGFuZ2VkQXQgPSBuZXcgRGF0ZShjaGFuZ2VkQXQuaXNvKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGV4cGlyeSB0aW1lLlxuICAgICAgICBjb25zdCBleHBpcmVzQXQgPSBuZXcgRGF0ZShcbiAgICAgICAgICBjaGFuZ2VkQXQuZ2V0VGltZSgpICsgODY0MDAwMDAgKiByZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlXG4gICAgICAgICk7XG4gICAgICAgIGlmIChleHBpcmVzQXQgPCBuZXcgRGF0ZSgpKVxuICAgICAgICAgIC8vIGZhaWwgb2YgY3VycmVudCB0aW1lIGlzIHBhc3QgcGFzc3dvcmQgZXhwaXJ5IHRpbWVcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICAgJ1lvdXIgcGFzc3dvcmQgaGFzIGV4cGlyZWQuIFBsZWFzZSByZXNldCB5b3VyIHBhc3N3b3JkLidcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgcmVxLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdChyZXEuY29uZmlnLCB1c2VyKTtcblxuICAgIC8vIEJlZm9yZSBsb2dpbiB0cmlnZ2VyOyB0aHJvd3MgaWYgZmFpbHVyZVxuICAgIGF3YWl0IG1heWJlUnVuVHJpZ2dlcihcbiAgICAgIFRyaWdnZXJUeXBlcy5iZWZvcmVMb2dpbixcbiAgICAgIHJlcS5hdXRoLFxuICAgICAgUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKSxcbiAgICAgIG51bGwsXG4gICAgICByZXEuY29uZmlnXG4gICAgKTtcblxuICAgIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IEF1dGguY3JlYXRlU2Vzc2lvbihyZXEuY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIub2JqZWN0SWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICdsb2dpbicsXG4gICAgICAgIGF1dGhQcm92aWRlcjogJ3Bhc3N3b3JkJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25EYXRhLnNlc3Npb25Ub2tlbjtcblxuICAgIGF3YWl0IGNyZWF0ZVNlc3Npb24oKTtcblxuICAgIGNvbnN0IGFmdGVyTG9naW5Vc2VyID0gUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKTtcbiAgICBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYWZ0ZXJMb2dpbixcbiAgICAgIHsgLi4ucmVxLmF1dGgsIHVzZXI6IGFmdGVyTG9naW5Vc2VyIH0sXG4gICAgICBhZnRlckxvZ2luVXNlcixcbiAgICAgIG51bGwsXG4gICAgICByZXEuY29uZmlnXG4gICAgKTtcblxuICAgIHJldHVybiB7IHJlc3BvbnNlOiB1c2VyIH07XG4gIH1cblxuICBoYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aGVudGljYXRlVXNlckZyb21SZXF1ZXN0KHJlcSlcbiAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXModXNlcik7XG5cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlTG9nT3V0KHJlcSkge1xuICAgIGNvbnN0IHN1Y2Nlc3MgPSB7IHJlc3BvbnNlOiB7fSB9O1xuICAgIGlmIChyZXEuaW5mbyAmJiByZXEuaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICAgIHJldHVybiByZXN0XG4gICAgICAgIC5maW5kKFxuICAgICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICAgJ19TZXNzaW9uJyxcbiAgICAgICAgICB7IHNlc3Npb25Ub2tlbjogcmVxLmluZm8uc2Vzc2lvblRva2VuIH0sXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICAgIClcbiAgICAgICAgLnRoZW4ocmVjb3JkcyA9PiB7XG4gICAgICAgICAgaWYgKHJlY29yZHMucmVzdWx0cyAmJiByZWNvcmRzLnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdFxuICAgICAgICAgICAgICAuZGVsKFxuICAgICAgICAgICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgICAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICAgICAgICAgJ19TZXNzaW9uJyxcbiAgICAgICAgICAgICAgICByZWNvcmRzLnJlc3VsdHNbMF0ub2JqZWN0SWQsXG4gICAgICAgICAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ydW5BZnRlckxvZ291dFRyaWdnZXIocmVxLCByZWNvcmRzLnJlc3VsdHNbMF0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc3VjY2Vzcyk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHN1Y2Nlc3MpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzdWNjZXNzKTtcbiAgfVxuXG4gIF9ydW5BZnRlckxvZ291dFRyaWdnZXIocmVxLCBzZXNzaW9uKSB7XG4gICAgLy8gQWZ0ZXIgbG9nb3V0IHRyaWdnZXJcbiAgICBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYWZ0ZXJMb2dvdXQsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIFBhcnNlLlNlc3Npb24uZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19TZXNzaW9uJyB9LCBzZXNzaW9uKSksXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG4gIH1cblxuICBfdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSkge1xuICAgIHRyeSB7XG4gICAgICBDb25maWcudmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgICAgICBlbWFpbEFkYXB0ZXI6IHJlcS5jb25maWcudXNlckNvbnRyb2xsZXIuYWRhcHRlcixcbiAgICAgICAgYXBwTmFtZTogcmVxLmNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBwdWJsaWNTZXJ2ZXJVUkw6IHJlcS5jb25maWcucHVibGljU2VydmVyVVJMLFxuICAgICAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjogcmVxLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmICh0eXBlb2YgZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gTWF5YmUgd2UgbmVlZCBhIEJhZCBDb25maWd1cmF0aW9uIGVycm9yLCBidXQgdGhlIFNES3Mgd29uJ3QgdW5kZXJzdGFuZCBpdC4gRm9yIG5vdywgSW50ZXJuYWwgU2VydmVyIEVycm9yLlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdBbiBhcHBOYW1lLCBwdWJsaWNTZXJ2ZXJVUkwsIGFuZCBlbWFpbEFkYXB0ZXIgYXJlIHJlcXVpcmVkIGZvciBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uIGZ1bmN0aW9uYWxpdHkuJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVSZXNldFJlcXVlc3QocmVxKSB7XG4gICAgdGhpcy5fdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSk7XG5cbiAgICBjb25zdCB7IGVtYWlsIH0gPSByZXEuYm9keTtcbiAgICBpZiAoIWVtYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTUlTU0lORywgJ3lvdSBtdXN0IHByb3ZpZGUgYW4gZW1haWwnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLFxuICAgICAgICAneW91IG11c3QgcHJvdmlkZSBhIHZhbGlkIGVtYWlsIHN0cmluZydcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlcjtcbiAgICByZXR1cm4gdXNlckNvbnRyb2xsZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAvLyBSZXR1cm4gc3VjY2VzcyBzbyB0aGF0IHRoaXMgZW5kcG9pbnQgY2FuJ3RcbiAgICAgICAgICAvLyBiZSB1c2VkIHRvIGVudW1lcmF0ZSB2YWxpZCBlbWFpbHNcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsICd5b3UgbXVzdCBwcm92aWRlIGFuIGVtYWlsJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUyxcbiAgICAgICAgJ3lvdSBtdXN0IHByb3ZpZGUgYSB2YWxpZCBlbWFpbCBzdHJpbmcnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBlbWFpbDogZW1haWwgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGggfHwgcmVzdWx0cy5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsIGBObyB1c2VyIGZvdW5kIHdpdGggZW1haWwgJHtlbWFpbH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuXG4gICAgICAvLyByZW1vdmUgcGFzc3dvcmQgZmllbGQsIG1lc3NlcyB3aXRoIHNhdmluZyBvbiBwb3N0Z3Jlc1xuICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgIGlmICh1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCBgRW1haWwgJHtlbWFpbH0gaXMgYWxyZWFkeSB2ZXJpZmllZC5gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgICAgcmV0dXJuIHVzZXJDb250cm9sbGVyLnJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKHVzZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICB1c2VyQ29udHJvbGxlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcik7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvdXNlcnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvdXNlcnMvOm9iamVjdElkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvbG9naW4nLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9sb2dpbicsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dJbihyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ291dCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dPdXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yZXF1ZXN0UGFzc3dvcmRSZXNldCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldFJlcXVlc3QocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92ZXJpZmljYXRpb25FbWFpbFJlcXVlc3QnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy92ZXJpZnlQYXNzd29yZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/StatusHandler.js b/lib/StatusHandler.js deleted file mode 100644 index 708d04b1b0..0000000000 --- a/lib/StatusHandler.js +++ /dev/null @@ -1,386 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.flatten = flatten; -exports.jobStatusHandler = jobStatusHandler; -exports.pushStatusHandler = pushStatusHandler; - -var _cryptoUtils = require("./cryptoUtils"); - -var _logger = require("./logger"); - -var _rest = _interopRequireDefault(require("./rest")); - -var _Auth = _interopRequireDefault(require("./Auth")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const PUSH_STATUS_COLLECTION = '_PushStatus'; -const JOB_STATUS_COLLECTION = '_JobStatus'; - -const incrementOp = function (object = {}, key, amount = 1) { - if (!object[key]) { - object[key] = { - __op: 'Increment', - amount: amount - }; - } else { - object[key].amount += amount; - } - - return object[key]; -}; - -function flatten(array) { - var flattened = []; - - for (var i = 0; i < array.length; i++) { - if (Array.isArray(array[i])) { - flattened = flattened.concat(flatten(array[i])); - } else { - flattened.push(array[i]); - } - } - - return flattened; -} - -function statusHandler(className, database) { - let lastPromise = Promise.resolve(); - - function create(object) { - lastPromise = lastPromise.then(() => { - return database.create(className, object).then(() => { - return Promise.resolve(object); - }); - }); - return lastPromise; - } - - function update(where, object) { - lastPromise = lastPromise.then(() => { - return database.update(className, where, object); - }); - return lastPromise; - } - - return Object.freeze({ - create, - update - }); -} - -function restStatusHandler(className, config) { - let lastPromise = Promise.resolve(); - - const auth = _Auth.default.master(config); - - function create(object) { - lastPromise = lastPromise.then(() => { - return _rest.default.create(config, auth, className, object).then(({ - response - }) => { - // merge the objects - return Promise.resolve(Object.assign({}, object, response)); - }); - }); - return lastPromise; - } - - function update(where, object) { - // TODO: when we have updateWhere, use that for proper interfacing - lastPromise = lastPromise.then(() => { - return _rest.default.update(config, auth, className, { - objectId: where.objectId - }, object).then(({ - response - }) => { - // merge the objects - return Promise.resolve(Object.assign({}, object, response)); - }); - }); - return lastPromise; - } - - return Object.freeze({ - create, - update - }); -} - -function jobStatusHandler(config) { - let jobStatus; - const objectId = (0, _cryptoUtils.newObjectId)(config.objectIdSize); - const database = config.database; - const handler = statusHandler(JOB_STATUS_COLLECTION, database); - - const setRunning = function (jobName, params) { - const now = new Date(); - jobStatus = { - objectId, - jobName, - params, - status: 'running', - source: 'api', - createdAt: now, - // lockdown! - ACL: {} - }; - return handler.create(jobStatus); - }; - - const setMessage = function (message) { - if (!message || typeof message !== 'string') { - return Promise.resolve(); - } - - return handler.update({ - objectId - }, { - message - }); - }; - - const setSucceeded = function (message) { - return setFinalStatus('succeeded', message); - }; - - const setFailed = function (message) { - return setFinalStatus('failed', message); - }; - - const setFinalStatus = function (status, message = undefined) { - const finishedAt = new Date(); - const update = { - status, - finishedAt - }; - - if (message && typeof message === 'string') { - update.message = message; - } - - if (message instanceof Error && typeof message.message === 'string') { - update.message = message.message; - } - - return handler.update({ - objectId - }, update); - }; - - return Object.freeze({ - setRunning, - setSucceeded, - setMessage, - setFailed - }); -} - -function pushStatusHandler(config, existingObjectId) { - let pushStatus; - const database = config.database; - const handler = restStatusHandler(PUSH_STATUS_COLLECTION, config); - let objectId = existingObjectId; - - const setInitial = function (body = {}, where, options = { - source: 'rest' - }) { - const now = new Date(); - let pushTime = now.toISOString(); - let status = 'pending'; - - if (Object.prototype.hasOwnProperty.call(body, 'push_time')) { - if (config.hasPushScheduledSupport) { - pushTime = body.push_time; - status = 'scheduled'; - } else { - _logger.logger.warn('Trying to schedule a push while server is not configured.'); - - _logger.logger.warn('Push will be sent immediately'); - } - } - - const data = body.data || {}; - const payloadString = JSON.stringify(data); - let pushHash; - - if (typeof data.alert === 'string') { - pushHash = (0, _cryptoUtils.md5Hash)(data.alert); - } else if (typeof data.alert === 'object') { - pushHash = (0, _cryptoUtils.md5Hash)(JSON.stringify(data.alert)); - } else { - pushHash = 'd41d8cd98f00b204e9800998ecf8427e'; - } - - const object = { - pushTime, - query: JSON.stringify(where), - payload: payloadString, - source: options.source, - title: options.title, - expiry: body.expiration_time, - expiration_interval: body.expiration_interval, - status: status, - numSent: 0, - pushHash, - // lockdown! - ACL: {} - }; - return handler.create(object).then(result => { - objectId = result.objectId; - pushStatus = { - objectId - }; - return Promise.resolve(pushStatus); - }); - }; - - const setRunning = function (batches) { - _logger.logger.verbose(`_PushStatus ${objectId}: sending push to installations with %d batches`, batches); - - return handler.update({ - status: 'pending', - objectId: objectId - }, { - status: 'running', - count: batches - }); - }; - - const trackSent = function (results, UTCOffset, cleanupInstallations = process.env.PARSE_SERVER_CLEANUP_INVALID_INSTALLATIONS) { - const update = { - numSent: 0, - numFailed: 0 - }; - const devicesToRemove = []; - - if (Array.isArray(results)) { - results = flatten(results); - results.reduce((memo, result) => { - // Cannot handle that - if (!result || !result.device || !result.device.deviceType) { - return memo; - } - - const deviceType = result.device.deviceType; - const key = result.transmitted ? `sentPerType.${deviceType}` : `failedPerType.${deviceType}`; - memo[key] = incrementOp(memo, key); - - if (typeof UTCOffset !== 'undefined') { - const offsetKey = result.transmitted ? `sentPerUTCOffset.${UTCOffset}` : `failedPerUTCOffset.${UTCOffset}`; - memo[offsetKey] = incrementOp(memo, offsetKey); - } - - if (result.transmitted) { - memo.numSent++; - } else { - if (result && result.response && result.response.error && result.device && result.device.deviceToken) { - const token = result.device.deviceToken; - const error = result.response.error; // GCM errors - - if (error === 'NotRegistered' || error === 'InvalidRegistration') { - devicesToRemove.push(token); - } // APNS errors - - - if (error === 'Unregistered' || error === 'BadDeviceToken') { - devicesToRemove.push(token); - } - } - - memo.numFailed++; - } - - return memo; - }, update); - } - - _logger.logger.verbose(`_PushStatus ${objectId}: sent push! %d success, %d failures`, update.numSent, update.numFailed); - - _logger.logger.verbose(`_PushStatus ${objectId}: needs cleanup`, { - devicesToRemove - }); - - ['numSent', 'numFailed'].forEach(key => { - if (update[key] > 0) { - update[key] = { - __op: 'Increment', - amount: update[key] - }; - } else { - delete update[key]; - } - }); - - if (devicesToRemove.length > 0 && cleanupInstallations) { - _logger.logger.info(`Removing device tokens on ${devicesToRemove.length} _Installations`); - - database.update('_Installation', { - deviceToken: { - $in: devicesToRemove - } - }, { - deviceToken: { - __op: 'Delete' - } - }, { - acl: undefined, - many: true - }); - } // indicate this batch is complete - - - incrementOp(update, 'count', -1); - return handler.update({ - objectId - }, update).then(res => { - if (res && res.count === 0) { - return this.complete(); - } - }); - }; - - const complete = function () { - return handler.update({ - objectId - }, { - status: 'succeeded', - count: { - __op: 'Delete' - } - }); - }; - - const fail = function (err) { - if (typeof err === 'string') { - err = { - message: err - }; - } - - const update = { - errorMessage: err, - status: 'failed' - }; - return handler.update({ - objectId - }, update); - }; - - const rval = { - setInitial, - setRunning, - trackSent, - complete, - fail - }; // define objectId to be dynamic - - Object.defineProperty(rval, 'objectId', { - get: () => objectId - }); - return Object.freeze(rval); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TdGF0dXNIYW5kbGVyLmpzIl0sIm5hbWVzIjpbIlBVU0hfU1RBVFVTX0NPTExFQ1RJT04iLCJKT0JfU1RBVFVTX0NPTExFQ1RJT04iLCJpbmNyZW1lbnRPcCIsIm9iamVjdCIsImtleSIsImFtb3VudCIsIl9fb3AiLCJmbGF0dGVuIiwiYXJyYXkiLCJmbGF0dGVuZWQiLCJpIiwibGVuZ3RoIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uY2F0IiwicHVzaCIsInN0YXR1c0hhbmRsZXIiLCJjbGFzc05hbWUiLCJkYXRhYmFzZSIsImxhc3RQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjcmVhdGUiLCJ0aGVuIiwidXBkYXRlIiwid2hlcmUiLCJPYmplY3QiLCJmcmVlemUiLCJyZXN0U3RhdHVzSGFuZGxlciIsImNvbmZpZyIsImF1dGgiLCJBdXRoIiwibWFzdGVyIiwicmVzdCIsInJlc3BvbnNlIiwiYXNzaWduIiwib2JqZWN0SWQiLCJqb2JTdGF0dXNIYW5kbGVyIiwiam9iU3RhdHVzIiwib2JqZWN0SWRTaXplIiwiaGFuZGxlciIsInNldFJ1bm5pbmciLCJqb2JOYW1lIiwicGFyYW1zIiwibm93IiwiRGF0ZSIsInN0YXR1cyIsInNvdXJjZSIsImNyZWF0ZWRBdCIsIkFDTCIsInNldE1lc3NhZ2UiLCJtZXNzYWdlIiwic2V0U3VjY2VlZGVkIiwic2V0RmluYWxTdGF0dXMiLCJzZXRGYWlsZWQiLCJ1bmRlZmluZWQiLCJmaW5pc2hlZEF0IiwiRXJyb3IiLCJwdXNoU3RhdHVzSGFuZGxlciIsImV4aXN0aW5nT2JqZWN0SWQiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsImJvZHkiLCJvcHRpb25zIiwicHVzaFRpbWUiLCJ0b0lTT1N0cmluZyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwicHVzaF90aW1lIiwibG9nZ2VyIiwid2FybiIsImRhdGEiLCJwYXlsb2FkU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1c2hIYXNoIiwiYWxlcnQiLCJxdWVyeSIsInBheWxvYWQiLCJ0aXRsZSIsImV4cGlyeSIsImV4cGlyYXRpb25fdGltZSIsImV4cGlyYXRpb25faW50ZXJ2YWwiLCJudW1TZW50IiwicmVzdWx0IiwiYmF0Y2hlcyIsInZlcmJvc2UiLCJjb3VudCIsInRyYWNrU2VudCIsInJlc3VsdHMiLCJVVENPZmZzZXQiLCJjbGVhbnVwSW5zdGFsbGF0aW9ucyIsInByb2Nlc3MiLCJlbnYiLCJQQVJTRV9TRVJWRVJfQ0xFQU5VUF9JTlZBTElEX0lOU1RBTExBVElPTlMiLCJudW1GYWlsZWQiLCJkZXZpY2VzVG9SZW1vdmUiLCJyZWR1Y2UiLCJtZW1vIiwiZGV2aWNlIiwiZGV2aWNlVHlwZSIsInRyYW5zbWl0dGVkIiwib2Zmc2V0S2V5IiwiZXJyb3IiLCJkZXZpY2VUb2tlbiIsInRva2VuIiwiZm9yRWFjaCIsImluZm8iLCIkaW4iLCJhY2wiLCJtYW55IiwicmVzIiwiY29tcGxldGUiLCJmYWlsIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicnZhbCIsImRlZmluZVByb3BlcnR5IiwiZ2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHNCQUFzQixHQUFHLGFBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsWUFBOUI7O0FBRUEsTUFBTUMsV0FBVyxHQUFHLFVBQVVDLE1BQU0sR0FBRyxFQUFuQixFQUF1QkMsR0FBdkIsRUFBNEJDLE1BQU0sR0FBRyxDQUFyQyxFQUF3QztBQUMxRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0MsR0FBRCxDQUFYLEVBQWtCO0FBQ2hCRCxJQUFBQSxNQUFNLENBQUNDLEdBQUQsQ0FBTixHQUFjO0FBQUVFLE1BQUFBLElBQUksRUFBRSxXQUFSO0FBQXFCRCxNQUFBQSxNQUFNLEVBQUVBO0FBQTdCLEtBQWQ7QUFDRCxHQUZELE1BRU87QUFDTEYsSUFBQUEsTUFBTSxDQUFDQyxHQUFELENBQU4s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QUFNOEYsSUFBSSxHQUFHO0FBQ1h6RCxJQUFBQSxVQURXO0FBRVhwQixJQUFBQSxVQUZXO0FBR1hpRCxJQUFBQSxTQUhXO0FBSVh3QixJQUFBQSxRQUpXO0FBS1hDLElBQUFBO0FBTFcsR0FBYixDQTNMMEQsQ0FtTTFEOztBQUNBekYsRUFBQUEsTUFBTSxDQUFDNkYsY0FBUCxDQUFzQkQsSUFBdEIsRUFBNEIsVUFBNUIsRUFBd0M7QUFDdENFLElBQUFBLEdBQUcsRUFBRSxNQUFNcEY7QUFEMkIsR0FBeEM7QUFJQSxTQUFPVixNQUFNLENBQUNDLE1BQVAsQ0FBYzJGLElBQWQsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWQ1SGFzaCwgbmV3T2JqZWN0SWQgfSBmcm9tICcuL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuL0F1dGgnO1xuXG5jb25zdCBQVVNIX1NUQVRVU19DT0xMRUNUSU9OID0gJ19QdXNoU3RhdHVzJztcbmNvbnN0IEpPQl9TVEFUVVNfQ09MTEVDVElPTiA9ICdfSm9iU3RhdHVzJztcblxuY29uc3QgaW5jcmVtZW50T3AgPSBmdW5jdGlvbiAob2JqZWN0ID0ge30sIGtleSwgYW1vdW50ID0gMSkge1xuICBpZiAoIW9iamVjdFtrZXldKSB7XG4gICAgb2JqZWN0W2tleV0gPSB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGFtb3VudCB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldLmFtb3VudCArPSBhbW91bnQ7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFtrZXldO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHtcbiAgdmFyIGZsYXR0ZW5lZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlbaV0pKSB7XG4gICAgICBmbGF0dGVuZWQgPSBmbGF0dGVuZWQuY29uY2F0KGZsYXR0ZW4oYXJyYXlbaV0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkLnB1c2goYXJyYXlbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmxhdHRlbmVkO1xufVxuXG5mdW5jdGlvbiBzdGF0dXNIYW5kbGVyKGNsYXNzTmFtZSwgZGF0YWJhc2UpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlKG9iamVjdCkge1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZGF0YWJhc2UuY3JlYXRlKGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxhc3RQcm9taXNlO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKHdoZXJlLCBvYmplY3QpIHtcbiAgICBsYXN0UHJvbWlzZSA9IGxhc3RQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIGRhdGFiYXNlLnVwZGF0ZShjbGFzc05hbWUsIHdoZXJlLCBvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBsYXN0UHJvbWlzZTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBjcmVhdGUsXG4gICAgdXBkYXRlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdFN0YXR1c0hhbmRsZXIoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIGNvbnN0IGF1dGggPSBBdXRoLm1hc3Rlcihjb25maWcpO1xuICBmdW5jdGlvbiBjcmVhdGUob2JqZWN0KSB7XG4gICAgbGFzdFByb21pc2UgPSBsYXN0UHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgLy8gbWVyZ2UgdGhlIG9iamVjdHNcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShPYmplY3QuYXNzaWduKHt9LCBvYmplY3QsIHJlc3BvbnNlKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUod2hlcmUsIG9iamVjdCkge1xuICAgIC8vIFRPRE86IHdoZW4gd2UgaGF2ZSB1cGRhdGVXaGVyZSwgdXNlIHRoYXQgZm9yIHByb3BlciBpbnRlcmZhY2luZ1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAudXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB7IG9iamVjdElkOiB3aGVyZS5vYmplY3RJZCB9LCBvYmplY3QpXG4gICAgICAgIC50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgb2JqZWN0c1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoT2JqZWN0LmFzc2lnbih7fSwgb2JqZWN0LCByZXNwb25zZSkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgY3JlYXRlLFxuICAgIHVwZGF0ZSxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBqb2JTdGF0dXNIYW5kbGVyKGNvbmZpZykge1xuICBsZXQgam9iU3RhdHVzO1xuICBjb25zdCBvYmplY3RJZCA9IG5ld09iamVjdElkKGNvbmZpZy5vYmplY3RJZFNpemUpO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHN0YXR1c0hhbmRsZXIoSk9CX1NUQVRVU19DT0xMRUNUSU9OLCBkYXRhYmFzZSk7XG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoam9iTmFtZSwgcGFyYW1zKSB7XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICBqb2JTdGF0dXMgPSB7XG4gICAgICBvYmplY3RJZCxcbiAgICAgIGpvYk5hbWUsXG4gICAgICBwYXJhbXMsXG4gICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgIHNvdXJjZTogJ2FwaScsXG4gICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgIC8vIGxvY2tkb3duIVxuICAgICAgQUNMOiB7fSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKGpvYlN0YXR1cyk7XG4gIH07XG5cbiAgY29uc3Qgc2V0TWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB7IG1lc3NhZ2UgfSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0U3VjY2VlZGVkID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gc2V0RmluYWxTdGF0dXMoJ3N1Y2NlZWRlZCcsIG1lc3NhZ2UpO1xuICB9O1xuXG4gIGNvbnN0IHNldEZhaWxlZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNldEZpbmFsU3RhdHVzKCdmYWlsZWQnLCBtZXNzYWdlKTtcbiAgfTtcblxuICBjb25zdCBzZXRGaW5hbFN0YXR1cyA9IGZ1bmN0aW9uIChzdGF0dXMsIG1lc3NhZ2UgPSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaW5pc2hlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB1cGRhdGUgPSB7IHN0YXR1cywgZmluaXNoZWRBdCB9O1xuICAgIGlmIChtZXNzYWdlICYmIHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgdXBkYXRlLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBtZXNzYWdlLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICB1cGRhdGUubWVzc2FnZSA9IG1lc3NhZ2UubWVzc2FnZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc2V0UnVubmluZyxcbiAgICBzZXRTdWNjZWVkZWQsXG4gICAgc2V0TWVzc2FnZSxcbiAgICBzZXRGYWlsZWQsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnLCBleGlzdGluZ09iamVjdElkKSB7XG4gIGxldCBwdXNoU3RhdHVzO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHJlc3RTdGF0dXNIYW5kbGVyKFBVU0hfU1RBVFVTX0NPTExFQ1RJT04sIGNvbmZpZyk7XG4gIGxldCBvYmplY3RJZCA9IGV4aXN0aW5nT2JqZWN0SWQ7XG4gIGNvbnN0IHNldEluaXRpYWwgPSBmdW5jdGlvbiAoYm9keSA9IHt9LCB3aGVyZSwgb3B0aW9ucyA9IHsgc291cmNlOiAncmVzdCcgfSkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IHB1c2hUaW1lID0gbm93LnRvSVNPU3RyaW5nKCk7XG4gICAgbGV0IHN0YXR1cyA9ICdwZW5kaW5nJztcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKSkge1xuICAgICAgaWYgKGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCkge1xuICAgICAgICBwdXNoVGltZSA9IGJvZHkucHVzaF90aW1lO1xuICAgICAgICBzdGF0dXMgPSAnc2NoZWR1bGVkJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdUcnlpbmcgdG8gc2NoZWR1bGUgYSBwdXNoIHdoaWxlIHNlcnZlciBpcyBub3QgY29uZmlndXJlZC4nKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1B1c2ggd2lsbCBiZSBzZW50IGltbWVkaWF0ZWx5Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YSB8fCB7fTtcbiAgICBjb25zdCBwYXlsb2FkU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgbGV0IHB1c2hIYXNoO1xuICAgIGlmICh0eXBlb2YgZGF0YS5hbGVydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHB1c2hIYXNoID0gbWQ1SGFzaChkYXRhLmFsZXJ0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLmFsZXJ0ID09PSAnb2JqZWN0Jykge1xuICAgICAgcHVzaEhhc2ggPSBtZDVIYXNoKEpTT04uc3RyaW5naWZ5KGRhdGEuYWxlcnQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEhhc2ggPSAnZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2UnO1xuICAgIH1cbiAgICBjb25zdCBvYmplY3QgPSB7XG4gICAgICBwdXNoVGltZSxcbiAgICAgIHF1ZXJ5OiBKU09OLnN0cmluZ2lmeSh3aGVyZSksXG4gICAgICBwYXlsb2FkOiBwYXlsb2FkU3RyaW5nLFxuICAgICAgc291cmNlOiBvcHRpb25zLnNvdXJjZSxcbiAgICAgIHRpdGxlOiBvcHRpb25zLnRpdGxlLFxuICAgICAgZXhwaXJ5OiBib2R5LmV4cGlyYXRpb25fdGltZSxcbiAgICAgIGV4cGlyYXRpb25faW50ZXJ2YWw6IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCxcbiAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgbnVtU2VudDogMCxcbiAgICAgIHB1c2hIYXNoLFxuICAgICAgLy8gbG9ja2Rvd24hXG4gICAgICBBQ0w6IHt9LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKG9iamVjdCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgb2JqZWN0SWQgPSByZXN1bHQub2JqZWN0SWQ7XG4gICAgICBwdXNoU3RhdHVzID0ge1xuICAgICAgICBvYmplY3RJZCxcbiAgICAgIH07XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHB1c2hTdGF0dXMpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoYmF0Y2hlcykge1xuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBzZW5kaW5nIHB1c2ggdG8gaW5zdGFsbGF0aW9ucyB3aXRoICVkIGJhdGNoZXNgLFxuICAgICAgYmF0Y2hlc1xuICAgICk7XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKFxuICAgICAge1xuICAgICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcbiAgICAgICAgb2JqZWN0SWQ6IG9iamVjdElkLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgIGNvdW50OiBiYXRjaGVzLFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgdHJhY2tTZW50ID0gZnVuY3Rpb24gKFxuICAgIHJlc3VsdHMsXG4gICAgVVRDT2Zmc2V0LFxuICAgIGNsZWFudXBJbnN0YWxsYXRpb25zID0gcHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0NMRUFOVVBfSU5WQUxJRF9JTlNUQUxMQVRJT05TXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAgIG51bVNlbnQ6IDAsXG4gICAgICBudW1GYWlsZWQ6IDAsXG4gICAgfTtcbiAgICBjb25zdCBkZXZpY2VzVG9SZW1vdmUgPSBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xuICAgICAgcmVzdWx0cyA9IGZsYXR0ZW4ocmVzdWx0cyk7XG4gICAgICByZXN1bHRzLnJlZHVjZSgobWVtbywgcmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIENhbm5vdCBoYW5kbGUgdGhhdFxuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LmRldmljZSB8fCAhcmVzdWx0LmRldmljZS5kZXZpY2VUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9IHJlc3VsdC5kZXZpY2UuZGV2aWNlVHlwZTtcbiAgICAgICAgY29uc3Qga2V5ID0gcmVzdWx0LnRyYW5zbWl0dGVkXG4gICAgICAgICAgPyBgc2VudFBlclR5cGUuJHtkZXZpY2VUeXBlfWBcbiAgICAgICAgICA6IGBmYWlsZWRQZXJUeXBlLiR7ZGV2aWNlVHlwZX1gO1xuICAgICAgICBtZW1vW2tleV0gPSBpbmNyZW1lbnRPcChtZW1vLCBrZXkpO1xuICAgICAgICBpZiAodHlwZW9mIFVUQ09mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCBvZmZzZXRLZXkgPSByZXN1bHQudHJhbnNtaXR0ZWRcbiAgICAgICAgICAgID8gYHNlbnRQZXJVVENPZmZzZXQuJHtVVENPZmZzZXR9YFxuICAgICAgICAgICAgOiBgZmFpbGVkUGVyVVRDT2Zmc2V0LiR7VVRDT2Zmc2V0fWA7XG4gICAgICAgICAgbWVtb1tvZmZzZXRLZXldID0gaW5jcmVtZW50T3AobWVtbywgb2Zmc2V0S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LnRyYW5zbWl0dGVkKSB7XG4gICAgICAgICAgbWVtby5udW1TZW50Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVzdWx0ICYmXG4gICAgICAgICAgICByZXN1bHQucmVzcG9uc2UgJiZcbiAgICAgICAgICAgIHJlc3VsdC5yZXNwb25zZS5lcnJvciAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZSAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZS5kZXZpY2VUb2tlblxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSByZXN1bHQuZGV2aWNlLmRldmljZVRva2VuO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQucmVzcG9uc2UuZXJyb3I7XG4gICAgICAgICAgICAvLyBHQ00gZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdOb3RSZWdpc3RlcmVkJyB8fCBlcnJvciA9PT0gJ0ludmFsaWRSZWdpc3RyYXRpb24nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFQTlMgZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdVbnJlZ2lzdGVyZWQnIHx8IGVycm9yID09PSAnQmFkRGV2aWNlVG9rZW4nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtby5udW1GYWlsZWQrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIHVwZGF0ZSk7XG4gICAgfVxuXG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IHNlbnQgcHVzaCEgJWQgc3VjY2VzcywgJWQgZmFpbHVyZXNgLFxuICAgICAgdXBkYXRlLm51bVNlbnQsXG4gICAgICB1cGRhdGUubnVtRmFpbGVkXG4gICAgKTtcbiAgICBsb2dnZXIudmVyYm9zZShgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IG5lZWRzIGNsZWFudXBgLCB7XG4gICAgICBkZXZpY2VzVG9SZW1vdmUsXG4gICAgfSk7XG4gICAgWydudW1TZW50JywgJ251bUZhaWxlZCddLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh1cGRhdGVba2V5XSA+IDApIHtcbiAgICAgICAgdXBkYXRlW2tleV0gPSB7XG4gICAgICAgICAgX19vcDogJ0luY3JlbWVudCcsXG4gICAgICAgICAgYW1vdW50OiB1cGRhdGVba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkZXZpY2VzVG9SZW1vdmUubGVuZ3RoID4gMCAmJiBjbGVhbnVwSW5zdGFsbGF0aW9ucykge1xuICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGRldmljZSB0b2tlbnMgb24gJHtkZXZpY2VzVG9SZW1vdmUubGVuZ3RofSBfSW5zdGFsbGF0aW9uc2ApO1xuICAgICAgZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgIHsgZGV2aWNlVG9rZW46IHsgJGluOiBkZXZpY2VzVG9SZW1vdmUgfSB9LFxuICAgICAgICB7IGRldmljZVRva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0gfSxcbiAgICAgICAge1xuICAgICAgICAgIGFjbDogdW5kZWZpbmVkLFxuICAgICAgICAgIG1hbnk6IHRydWUsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gaW5kaWNhdGUgdGhpcyBiYXRjaCBpcyBjb21wbGV0ZVxuICAgIGluY3JlbWVudE9wKHVwZGF0ZSwgJ2NvdW50JywgLTEpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5jb3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHsgb2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAnc3VjY2VlZGVkJyxcbiAgICAgICAgY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGZhaWwgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnIgPSB7IG1lc3NhZ2U6IGVyciB9O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBlcnJvck1lc3NhZ2U6IGVycixcbiAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB1cGRhdGUpO1xuICB9O1xuXG4gIGNvbnN0IHJ2YWwgPSB7XG4gICAgc2V0SW5pdGlhbCxcbiAgICBzZXRSdW5uaW5nLFxuICAgIHRyYWNrU2VudCxcbiAgICBjb21wbGV0ZSxcbiAgICBmYWlsLFxuICB9O1xuXG4gIC8vIGRlZmluZSBvYmplY3RJZCB0byBiZSBkeW5hbWljXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydmFsLCAnb2JqZWN0SWQnLCB7XG4gICAgZ2V0OiAoKSA9PiBvYmplY3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUocnZhbCk7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/TestUtils.js b/lib/TestUtils.js deleted file mode 100644 index 043a6dd202..0000000000 --- a/lib/TestUtils.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.destroyAllDataPermanently = destroyAllDataPermanently; - -var _cache = _interopRequireDefault(require("./cache")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Destroys all data in the database - * @param {boolean} fast set to true if it's ok to just drop objects and not indexes. - */ -function destroyAllDataPermanently(fast) { - if (!process.env.TESTING) { - throw 'Only supported in test environment'; - } - - return Promise.all(Object.keys(_cache.default.cache).map(appId => { - const app = _cache.default.get(appId); - - if (app.databaseController) { - return app.databaseController.deleteEverything(fast); - } else { - return Promise.resolve(); - } - })); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXN0VXRpbHMuanMiXSwibmFtZXMiOlsiZGVzdHJveUFsbERhdGFQZXJtYW5lbnRseSIsImZhc3QiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIlByb21pc2UiLCJhbGwiLCJPYmplY3QiLCJrZXlzIiwiQXBwQ2FjaGUiLCJjYWNoZSIsIm1hcCIsImFwcElkIiwiYXBwIiwiZ2V0IiwiZGF0YWJhc2VDb250cm9sbGVyIiwiZGVsZXRlRXZlcnl0aGluZyIsInJlc29sdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBOzs7O0FBSU8sU0FBU0EseUJBQVQsQ0FBbUNDLElBQW5DLEVBQXlDO0FBQzlDLE1BQUksQ0FBQ0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQWpCLEVBQTBCO0FBQ3hCLFVBQU0sb0NBQU47QUFDRDs7QUFDRCxTQUFPQyxPQUFPLENBQUNDLEdBQVIsQ0FDTEMsTUFBTSxDQUFDQyxJQUFQLENBQVlDLGVBQVNDLEtBQXJCLEVBQTRCQyxHQUE1QixDQUFnQ0MsS0FBSyxJQUFJO0FBQ3ZDLFVBQU1DLEdBQUcsR0FBR0osZUFBU0ssR0FBVCxDQUFhRixLQUFiLENBQVo7O0FBQ0EsUUFBSUMsR0FBRyxDQUFDRSxrQkFBUixFQUE0QjtBQUMxQixhQUFPRixHQUFHLENBQUNFLGtCQUFKLENBQXVCQyxnQkFBdkIsQ0FBd0NmLElBQXhDLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPSSxPQUFPLENBQUNZLE9BQVIsRUFBUDtBQUNEO0FBQ0YsR0FQRCxDQURLLENBQVA7QUFVRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcblxuLyoqXG4gKiBEZXN0cm95cyBhbGwgZGF0YSBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZHJvcCBvYmplY3RzIGFuZCBub3QgaW5kZXhlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lBbGxEYXRhUGVybWFuZW50bHkoZmFzdCkge1xuICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICB0aHJvdyAnT25seSBzdXBwb3J0ZWQgaW4gdGVzdCBlbnZpcm9ubWVudCc7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgIE9iamVjdC5rZXlzKEFwcENhY2hlLmNhY2hlKS5tYXAoYXBwSWQgPT4ge1xuICAgICAgY29uc3QgYXBwID0gQXBwQ2FjaGUuZ2V0KGFwcElkKTtcbiAgICAgIGlmIChhcHAuZGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBhcHAuZGF0YWJhc2VDb250cm9sbGVyLmRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSlcbiAgKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/batch.js b/lib/batch.js deleted file mode 100644 index 6572814078..0000000000 --- a/lib/batch.js +++ /dev/null @@ -1,132 +0,0 @@ -"use strict"; - -const Parse = require('parse/node').Parse; - -const url = require('url'); - -const path = require('path'); // These methods handle batch requests. - - -const batchPath = '/batch'; // Mounts a batch-handler onto a PromiseRouter. - -function mountOnto(router) { - router.route('POST', batchPath, req => { - return handleBatch(router, req); - }); -} - -function parseURL(URL) { - if (typeof URL === 'string') { - return url.parse(URL); - } - - return undefined; -} - -function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { - serverURL = serverURL ? parseURL(serverURL) : undefined; - publicServerURL = publicServerURL ? parseURL(publicServerURL) : undefined; - const apiPrefixLength = originalUrl.length - batchPath.length; - let apiPrefix = originalUrl.slice(0, apiPrefixLength); - - const makeRoutablePath = function (requestPath) { - // The routablePath is the path minus the api prefix - if (requestPath.slice(0, apiPrefix.length) != apiPrefix) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'cannot route batch path ' + requestPath); - } - - return path.posix.join('/', requestPath.slice(apiPrefix.length)); - }; - - if (serverURL && publicServerURL && serverURL.path != publicServerURL.path) { - const localPath = serverURL.path; - const publicPath = publicServerURL.path; // Override the api prefix - - apiPrefix = localPath; - return function (requestPath) { - // Build the new path by removing the public path - // and joining with the local path - const newPath = path.posix.join('/', localPath, '/', requestPath.slice(publicPath.length)); // Use the method for local routing - - return makeRoutablePath(newPath); - }; - } - - return makeRoutablePath; -} // Returns a promise for a {response} object. -// TODO: pass along auth correctly - - -function handleBatch(router, req) { - if (!Array.isArray(req.body.requests)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'requests must be an array'); - } // The batch paths are all from the root of our domain. - // That means they include the API prefix, that the API is mounted - // to. However, our promise router does not route the api prefix. So - // we need to figure out the API prefix, so that we can strip it - // from all the subrequests. - - - if (!req.originalUrl.endsWith(batchPath)) { - throw 'internal routing problem - expected url to end with batch'; - } - - const makeRoutablePath = makeBatchRoutingPathFunction(req.originalUrl, req.config.serverURL, req.config.publicServerURL); - let initialPromise = Promise.resolve(); - - if (req.body.transaction === true) { - initialPromise = req.config.database.createTransactionalSession(); - } - - return initialPromise.then(() => { - const promises = req.body.requests.map(restRequest => { - const routablePath = makeRoutablePath(restRequest.path); // Construct a request that we can send to a handler - - const request = { - body: restRequest.body, - config: req.config, - auth: req.auth, - info: req.info - }; - return router.tryRouteRequest(restRequest.method, routablePath, request).then(response => { - return { - success: response.response - }; - }, error => { - return { - error: { - code: error.code, - error: error.message - } - }; - }); - }); - return Promise.all(promises).then(results => { - if (req.body.transaction === true) { - if (results.find(result => typeof result.error === 'object')) { - return req.config.database.abortTransactionalSession().then(() => { - return Promise.reject({ - response: results - }); - }); - } else { - return req.config.database.commitTransactionalSession().then(() => { - return { - response: results - }; - }); - } - } else { - return { - response: results - }; - } - }); - }); -} - -module.exports = { - mountOnto, - makeBatchRoutingPathFunction -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9iYXRjaC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJwYXRoIiwiYmF0Y2hQYXRoIiwibW91bnRPbnRvIiwicm91dGVyIiwicm91dGUiLCJyZXEiLCJoYW5kbGVCYXRjaCIsInBhcnNlVVJMIiwiVVJMIiwicGFyc2UiLCJ1bmRlZmluZWQiLCJtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uIiwib3JpZ2luYWxVcmwiLCJzZXJ2ZXJVUkwiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJhcGlQcmVmaXhMZW5ndGgiLCJsZW5ndGgiLCJhcGlQcmVmaXgiLCJzbGljZSIsIm1ha2VSb3V0YWJsZVBhdGgiLCJyZXF1ZXN0UGF0aCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicG9zaXgiLCJqb2luIiwibG9jYWxQYXRoIiwicHVibGljUGF0aCIsIm5ld1BhdGgiLCJBcnJheSIsImlzQXJyYXkiLCJib2R5IiwicmVxdWVzdHMiLCJlbmRzV2l0aCIsImNvbmZpZyIsImluaXRpYWxQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0cmFuc2FjdGlvbiIsImRhdGFiYXNlIiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJ0aGVuIiwicHJvbWlzZXMiLCJtYXAiLCJyZXN0UmVxdWVzdCIsInJvdXRhYmxlUGF0aCIsInJlcXVlc3QiLCJhdXRoIiwiaW5mbyIsInRyeVJvdXRlUmVxdWVzdCIsIm1ldGhvZCIsInJlc3BvbnNlIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHRzIiwiZmluZCIsInJlc3VsdCIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFwQzs7QUFDQSxN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LEVBQUVNO0FBQVosU0FBUDtBQUNEO0FBQ0YsS0FkTSxDQUFQO0FBZUQsR0FyQ00sQ0FBUDtBQXNDRDs7QUFFRE0sTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Y3RCxFQUFBQSxTQURlO0FBRWZTLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbi8vIFRoZXNlIG1ldGhvZHMgaGFuZGxlIGJhdGNoIHJlcXVlc3RzLlxuY29uc3QgYmF0Y2hQYXRoID0gJy9iYXRjaCc7XG5cbi8vIE1vdW50cyBhIGJhdGNoLWhhbmRsZXIgb250byBhIFByb21pc2VSb3V0ZXIuXG5mdW5jdGlvbiBtb3VudE9udG8ocm91dGVyKSB7XG4gIHJvdXRlci5yb3V0ZSgnUE9TVCcsIGJhdGNoUGF0aCwgcmVxID0+IHtcbiAgICByZXR1cm4gaGFuZGxlQmF0Y2gocm91dGVyLCByZXEpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VVUkwoVVJMKSB7XG4gIGlmICh0eXBlb2YgVVJMID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB1cmwucGFyc2UoVVJMKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uKG9yaWdpbmFsVXJsLCBzZXJ2ZXJVUkwsIHB1YmxpY1NlcnZlclVSTCkge1xuICBzZXJ2ZXJVUkwgPSBzZXJ2ZXJVUkwgPyBwYXJzZVVSTChzZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuICBwdWJsaWNTZXJ2ZXJVUkwgPSBwdWJsaWNTZXJ2ZXJVUkwgPyBwYXJzZVVSTChwdWJsaWNTZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGFwaVByZWZpeExlbmd0aCA9IG9yaWdpbmFsVXJsLmxlbmd0aCAtIGJhdGNoUGF0aC5sZW5ndGg7XG4gIGxldCBhcGlQcmVmaXggPSBvcmlnaW5hbFVybC5zbGljZSgwLCBhcGlQcmVmaXhMZW5ndGgpO1xuXG4gIGNvbnN0IG1ha2VSb3V0YWJsZVBhdGggPSBmdW5jdGlvbiAocmVxdWVzdFBhdGgpIHtcbiAgICAvLyBUaGUgcm91dGFibGVQYXRoIGlzIHRoZSBwYXRoIG1pbnVzIHRoZSBhcGkgcHJlZml4XG4gICAgaWYgKHJlcXVlc3RQYXRoLnNsaWNlKDAsIGFwaVByZWZpeC5sZW5ndGgpICE9IGFwaVByZWZpeCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2Nhbm5vdCByb3V0ZSBiYXRjaCBwYXRoICcgKyByZXF1ZXN0UGF0aCk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLnBvc2l4LmpvaW4oJy8nLCByZXF1ZXN0UGF0aC5zbGljZShhcGlQcmVmaXgubGVuZ3RoKSk7XG4gIH07XG5cbiAgaWYgKHNlcnZlclVSTCAmJiBwdWJsaWNTZXJ2ZXJVUkwgJiYgc2VydmVyVVJMLnBhdGggIT0gcHVibGljU2VydmVyVVJMLnBhdGgpIHtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBzZXJ2ZXJVUkwucGF0aDtcbiAgICBjb25zdCBwdWJsaWNQYXRoID0gcHVibGljU2VydmVyVVJMLnBhdGg7XG4gICAgLy8gT3ZlcnJpZGUgdGhlIGFwaSBwcmVmaXhcbiAgICBhcGlQcmVmaXggPSBsb2NhbFBhdGg7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChyZXF1ZXN0UGF0aCkge1xuICAgICAgLy8gQnVpbGQgdGhlIG5ldyBwYXRoIGJ5IHJlbW92aW5nIHRoZSBwdWJsaWMgcGF0aFxuICAgICAgLy8gYW5kIGpvaW5pbmcgd2l0aCB0aGUgbG9jYWwgcGF0aFxuICAgICAgY29uc3QgbmV3UGF0aCA9IHBhdGgucG9zaXguam9pbignLycsIGxvY2FsUGF0aCwgJy8nLCByZXF1ZXN0UGF0aC5zbGljZShwdWJsaWNQYXRoLmxlbmd0aCkpO1xuICAgICAgLy8gVXNlIHRoZSBtZXRob2QgZm9yIGxvY2FsIHJvdXRpbmdcbiAgICAgIHJldHVybiBtYWtlUm91dGFibGVQYXRoKG5ld1BhdGgpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gbWFrZVJvdXRhYmxlUGF0aDtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlfSBvYmplY3QuXG4vLyBUT0RPOiBwYXNzIGFsb25nIGF1dGggY29ycmVjdGx5XG5mdW5jdGlvbiBoYW5kbGVCYXRjaChyb3V0ZXIsIHJlcSkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkocmVxLmJvZHkucmVxdWVzdHMpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ3JlcXVlc3RzIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgfVxuXG4gIC8vIFRoZSBiYXRjaCBwYXRocyBhcmUgYWxsIGZyb20gdGhlIHJvb3Qgb2Ygb3VyIGRvbWFpbi5cbiAgLy8gVGhhdCBtZWFucyB0aGV5IGluY2x1ZGUgdGhlIEFQSSBwcmVmaXgsIHRoYXQgdGhlIEFQSSBpcyBtb3VudGVkXG4gIC8vIHRvLiBIb3dldmVyLCBvdXIgcHJvbWlzZSByb3V0ZXIgZG9lcyBub3Qgcm91dGUgdGhlIGFwaSBwcmVmaXguIFNvXG4gIC8vIHdlIG5lZWQgdG8gZmlndXJlIG91dCB0aGUgQVBJIHByZWZpeCwgc28gdGhhdCB3ZSBjYW4gc3RyaXAgaXRcbiAgLy8gZnJvbSBhbGwgdGhlIHN1YnJlcXVlc3RzLlxuICBpZiAoIXJlcS5vcmlnaW5hbFVybC5lbmRzV2l0aChiYXRjaFBhdGgpKSB7XG4gICAgdGhyb3cgJ2ludGVybmFsIHJvdXRpbmcgcHJvYmxlbSAtIGV4cGVjdGVkIHVybCB0byBlbmQgd2l0aCBiYXRjaCc7XG4gIH1cblxuICBjb25zdCBtYWtlUm91dGFibGVQYXRoID0gbWFrZUJhdGNoUm91dGluZ1BhdGhGdW5jdGlvbihcbiAgICByZXEub3JpZ2luYWxVcmwsXG4gICAgcmVxLmNvbmZpZy5zZXJ2ZXJVUkwsXG4gICAgcmVxLmNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkxcbiAgKTtcblxuICBsZXQgaW5pdGlhbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgaWYgKHJlcS5ib2R5LnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgaW5pdGlhbFByb21pc2UgPSByZXEuY29uZmlnLmRhdGFiYXNlLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk7XG4gIH1cblxuICByZXR1cm4gaW5pdGlhbFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSByZXEuYm9keS5yZXF1ZXN0cy5tYXAocmVzdFJlcXVlc3QgPT4ge1xuICAgICAgY29uc3Qgcm91dGFibGVQYXRoID0gbWFrZVJvdXRhYmxlUGF0aChyZXN0UmVxdWVzdC5wYXRoKTtcblxuICAgICAgLy8gQ29uc3RydWN0IGEgcmVxdWVzdCB0aGF0IHdlIGNhbiBzZW5kIHRvIGEgaGFuZGxlclxuICAgICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgICAgYm9keTogcmVzdFJlcXVlc3QuYm9keSxcbiAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICBhdXRoOiByZXEuYXV0aCxcbiAgICAgICAgaW5mbzogcmVxLmluZm8sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gcm91dGVyLnRyeVJvdXRlUmVxdWVzdChyZXN0UmVxdWVzdC5tZXRob2QsIHJvdXRhYmxlUGF0aCwgcmVxdWVzdCkudGhlbihcbiAgICAgICAgcmVzcG9uc2UgPT4ge1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHJlc3BvbnNlLnJlc3BvbnNlIH07XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICByZXR1cm4geyBlcnJvcjogeyBjb2RlOiBlcnJvci5jb2RlLCBlcnJvcjogZXJyb3IubWVzc2FnZSB9IH07XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICBpZiAocmVxLmJvZHkudHJhbnNhY3Rpb24gPT09IHRydWUpIHtcbiAgICAgICAgaWYgKHJlc3VsdHMuZmluZChyZXN1bHQgPT4gdHlwZW9mIHJlc3VsdC5lcnJvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2UuYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHsgcmVzcG9uc2U6IHJlc3VsdHMgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2UuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXN1bHRzIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXN1bHRzIH07XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbW91bnRPbnRvLFxuICBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cache.js b/lib/cache.js deleted file mode 100644 index ddeda818f9..0000000000 --- a/lib/cache.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AppCache = void 0; - -var _InMemoryCache = require("./Adapters/Cache/InMemoryCache"); - -var AppCache = new _InMemoryCache.InMemoryCache({ - ttl: NaN -}); -exports.AppCache = AppCache; -var _default = AppCache; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jYWNoZS5qcyJdLCJuYW1lcyI6WyJBcHBDYWNoZSIsIkluTWVtb3J5Q2FjaGUiLCJ0dGwiLCJOYU4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFFTyxJQUFJQSxRQUFRLEdBQUcsSUFBSUMsNEJBQUosQ0FBa0I7QUFBRUMsRUFBQUEsR0FBRyxFQUFFQztBQUFQLENBQWxCLENBQWY7O2VBQ1FILFEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbk1lbW9yeUNhY2hlIH0gZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlJztcblxuZXhwb3J0IHZhciBBcHBDYWNoZSA9IG5ldyBJbk1lbW9yeUNhY2hlKHsgdHRsOiBOYU4gfSk7XG5leHBvcnQgZGVmYXVsdCBBcHBDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/definitions/parse-live-query-server.js b/lib/cli/definitions/parse-live-query-server.js deleted file mode 100644 index 2aac33fdba..0000000000 --- a/lib/cli/definitions/parse-live-query-server.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const LiveQueryServerOptions = require('../../Options/Definitions').LiveQueryServerOptions; - -var _default = LiveQueryServerOptions; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsInJlcXVpcmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxNQUFNQSxzQkFBc0IsR0FBR0MsT0FBTyxDQUFDLDJCQUFELENBQVAsQ0FDNUJELHNCQURIOztlQUVlQSxzQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IExpdmVRdWVyeVNlcnZlck9wdGlvbnMgPSByZXF1aXJlKCcuLi8uLi9PcHRpb25zL0RlZmluaXRpb25zJylcbiAgLkxpdmVRdWVyeVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/definitions/parse-server.js b/lib/cli/definitions/parse-server.js deleted file mode 100644 index c4089a0626..0000000000 --- a/lib/cli/definitions/parse-server.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const ParseServerDefinitions = require('../../Options/Definitions').ParseServerOptions; - -var _default = ParseServerDefinitions; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlU2VydmVyRGVmaW5pdGlvbnMiLCJyZXF1aXJlIiwiUGFyc2VTZXJ2ZXJPcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsc0JBQXNCLEdBQUdDLE9BQU8sQ0FBQywyQkFBRCxDQUFQLENBQzVCQyxrQkFESDs7ZUFFZUYsc0IiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBQYXJzZVNlcnZlckRlZmluaXRpb25zID0gcmVxdWlyZSgnLi4vLi4vT3B0aW9ucy9EZWZpbml0aW9ucycpXG4gIC5QYXJzZVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlckRlZmluaXRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/parse-live-query-server.js b/lib/cli/parse-live-query-server.js deleted file mode 100644 index 346727035d..0000000000 --- a/lib/cli/parse-live-query-server.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; - -var _parseLiveQueryServer = _interopRequireDefault(require("./definitions/parse-live-query-server")); - -var _runner = _interopRequireDefault(require("./utils/runner")); - -var _index = require("../index"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -(0, _runner.default)({ - definitions: _parseLiveQueryServer.default, - start: function (program, options, logOptions) { - logOptions(); - - _index.ParseServer.createLiveQueryServer(undefined, options); - } -}); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiZGVmaW5pdGlvbnMiLCJzdGFydCIsInByb2dyYW0iLCJvcHRpb25zIiwibG9nT3B0aW9ucyIsIlBhcnNlU2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOzs7O0FBRUEscUJBQU87QUFDTEEsRUFBQUEsV0FBVyxFQUFYQSw2QkFESztBQUVMQyxFQUFBQSxLQUFLLEVBQUUsVUFBVUMsT0FBVixFQUFtQkMsT0FBbkIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDQSxJQUFBQSxVQUFVOztBQUNWQyx1QkFBWUMscUJBQVosQ0FBa0NDLFNBQWxDLEVBQTZDSixPQUE3QztBQUNEO0FBTEksQ0FBUCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBkZWZpbml0aW9ucyBmcm9tICcuL2RlZmluaXRpb25zL3BhcnNlLWxpdmUtcXVlcnktc2VydmVyJztcbmltcG9ydCBydW5uZXIgZnJvbSAnLi91dGlscy9ydW5uZXInO1xuaW1wb3J0IHsgUGFyc2VTZXJ2ZXIgfSBmcm9tICcuLi9pbmRleCc7XG5cbnJ1bm5lcih7XG4gIGRlZmluaXRpb25zLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBsb2dPcHRpb25zKCk7XG4gICAgUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0sXG59KTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/parse-server.js b/lib/cli/parse-server.js deleted file mode 100755 index 188991e3fe..0000000000 --- a/lib/cli/parse-server.js +++ /dev/null @@ -1,111 +0,0 @@ -"use strict"; - -var _index = _interopRequireDefault(require("../index")); - -var _parseServer = _interopRequireDefault(require("./definitions/parse-server")); - -var _cluster = _interopRequireDefault(require("cluster")); - -var _os = _interopRequireDefault(require("os")); - -var _runner = _interopRequireDefault(require("./utils/runner")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/* eslint-disable no-console */ -const help = function () { - console.log(' Get Started guide:'); - console.log(''); - console.log(' Please have a look at the get started guide!'); - console.log(' http://docs.parseplatform.org/parse-server/guide/'); - console.log(''); - console.log(''); - console.log(' Usage with npm start'); - console.log(''); - console.log(' $ npm start -- path/to/config.json'); - console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(''); - console.log(''); - console.log(' Usage:'); - console.log(''); - console.log(' $ parse-server path/to/config.json'); - console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(''); -}; - -(0, _runner.default)({ - definitions: _parseServer.default, - help, - usage: '[options] ', - start: function (program, options, logOptions) { - if (!options.appId || !options.masterKey) { - program.outputHelp(); - console.error(''); - console.error('\u001b[31mERROR: appId and masterKey are required\u001b[0m'); - console.error(''); - process.exit(1); - } - - if (options['liveQuery.classNames']) { - options.liveQuery = options.liveQuery || {}; - options.liveQuery.classNames = options['liveQuery.classNames']; - delete options['liveQuery.classNames']; - } - - if (options['liveQuery.redisURL']) { - options.liveQuery = options.liveQuery || {}; - options.liveQuery.redisURL = options['liveQuery.redisURL']; - delete options['liveQuery.redisURL']; - } - - if (options['liveQuery.redisOptions']) { - options.liveQuery = options.liveQuery || {}; - options.liveQuery.redisOptions = options['liveQuery.redisOptions']; - delete options['liveQuery.redisOptions']; - } - - if (options.cluster) { - const numCPUs = typeof options.cluster === 'number' ? options.cluster : _os.default.cpus().length; - - if (_cluster.default.isMaster) { - logOptions(); - - for (let i = 0; i < numCPUs; i++) { - _cluster.default.fork(); - } - - _cluster.default.on('exit', (worker, code) => { - console.log(`worker ${worker.process.pid} died (${code})... Restarting`); - - _cluster.default.fork(); - }); - } else { - _index.default.start(options, () => { - printSuccessMessage(); - }); - } - } else { - _index.default.start(options, () => { - logOptions(); - console.log(''); - printSuccessMessage(); - }); - } - - function printSuccessMessage() { - console.log('[' + process.pid + '] parse-server running on ' + options.serverURL); - - if (options.mountGraphQL) { - console.log('[' + process.pid + '] GraphQL running on http://localhost:' + options.port + options.graphQLPath); - } - - if (options.mountPlayground) { - console.log('[' + process.pid + '] Playground running on http://localhost:' + options.port + options.playgroundPath); - } - } - } -}); -/* eslint-enable no-console */ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbImhlbHAiLCJjb25zb2xlIiwibG9nIiwiZGVmaW5pdGlvbnMiLCJ1c2FnZSIsInN0YXJ0IiwicHJvZ3JhbSIsIm9wdGlvbnMiLCJsb2dPcHRpb25zIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJvdXRwdXRIZWxwIiwiZXJyb3IiLCJwcm9jZXNzIiwiZXhpdCIsImxpdmVRdWVyeSIsImNsYXNzTmFtZXMiLCJyZWRpc1VSTCIsInJlZGlzT3B0aW9ucyIsImNsdXN0ZXIiLCJudW1DUFVzIiwib3MiLCJjcHVzIiwibGVuZ3RoIiwiaXNNYXN0ZXIiLCJpIiwiZm9yayIsIm9uIiwid29ya2VyIiwiY29kZSIsInBpZCIsIlBhcnNlU2VydmVyIiwicHJpbnRTdWNjZXNzTWVzc2FnZSIsInNlcnZlclVSTCIsIm1vdW50R3JhcGhRTCIsInBvcnQiLCJncmFwaFFMUGF0aCIsIm1vdW50UGxheWdyb3VuZCIsInBsYXlncm91bmRQYXRoIl0sIm1hcHBpbmdzIjoiOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBTEE7QUFPQSxNQUFNQSxJQUFJLEdBQUcsWUFBWTtBQUN2QkMsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksc0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxrREFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx1REFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxFQUFaO0FBQ0FELEVBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksd0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx3Q0FBWjtBQUNB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QUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLFVBQVMwQixNQUFNLENBQUNmLE9BQVAsQ0FBZWlCLEdBQUksVUFBU0QsSUFBSyxpQkFBdkQ7O0FBQ0FWLDJCQUFRTyxJQUFSO0FBQ0QsU0FIRDtBQUlELE9BVEQsTUFTTztBQUNMSyx1QkFBWTFCLEtBQVosQ0FBa0JFLE9BQWxCLEVBQTJCLE1BQU07QUFDL0J5QixVQUFBQSxtQkFBbUI7QUFDcEIsU0FGRDtBQUdEO0FBQ0YsS0FoQkQsTUFnQk87QUFDTEQscUJBQVkxQixLQUFaLENBQWtCRSxPQUFsQixFQUEyQixNQUFNO0FBQy9CQyxRQUFBQSxVQUFVO0FBQ1ZQLFFBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQThCLFFBQUFBLG1CQUFtQjtBQUNwQixPQUpEO0FBS0Q7O0FBRUQsYUFBU0EsbUJBQVQsR0FBK0I7QUFDN0IvQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxNQUFNVyxPQUFPLENBQUNpQixHQUFkLEdBQW9CLDRCQUFwQixHQUFtRHZCLE9BQU8sQ0FBQzBCLFNBQXZFOztBQUNBLFVBQUkxQixPQUFPLENBQUMyQixZQUFaLEVBQTBCO0FBQ3hCakMsUUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQ0UsTUFDRVcsT0FBTyxDQUFDaUIsR0FEVixHQUVFLHdDQUZGLEdBR0V2QixPQUFPLENBQUM0QixJQUhWLEdBSUU1QixPQUFPLENBQUM2QixXQUxaO0FBT0Q7O0FBQ0QsVUFBSTdCLE9BQU8sQ0FBQzhCLGVBQVosRUFBNkI7QUFDM0JwQyxRQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FDRSxNQUNFVyxPQUFPLENBQUNpQixHQURWLEdBRUUsMkNBRkYsR0FHRXZCLE9BQU8sQ0FBQzRCLElBSFYsR0FJRTVCLE9BQU8sQ0FBQytCLGNBTFo7QUFPRDtBQUNGO0FBQ0Y7QUExRUksQ0FBUDtBQTZFQSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCBQYXJzZVNlcnZlciBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQgZGVmaW5pdGlvbnMgZnJvbSAnLi9kZWZpbml0aW9ucy9wYXJzZS1zZXJ2ZXInO1xuaW1wb3J0IGNsdXN0ZXIgZnJvbSAnY2x1c3Rlcic7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHJ1bm5lciBmcm9tICcuL3V0aWxzL3J1bm5lcic7XG5cbmNvbnN0IGhlbHAgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCcgIEdldCBTdGFydGVkIGd1aWRlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgUGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSBnZXQgc3RhcnRlZCBndWlkZSEnKTtcbiAgY29uc29sZS5sb2coJyAgICBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvJyk7XG4gIGNvbnNvbGUubG9nKCcnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnICBVc2FnZSB3aXRoIG5wbSBzdGFydCcpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgbnBtIHN0YXJ0IC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgIFVzYWdlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgcGFyc2Utc2VydmVyIC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xufTtcblxucnVubmVyKHtcbiAgZGVmaW5pdGlvbnMsXG4gIGhlbHAsXG4gIHVzYWdlOiAnW29wdGlvbnNdIDxwYXRoL3RvL2NvbmZpZ3VyYXRpb24uanNvbj4nLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMuYXBwSWQgfHwgIW9wdGlvbnMubWFzdGVyS2V5KSB7XG4gICAgICBwcm9ncmFtLm91dHB1dEhlbHAoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJycpO1xuICAgICAgY29uc29sZS5lcnJvcignXFx1MDAxYlszMW1FUlJPUjogYXBwSWQgYW5kIG1hc3RlcktleSBhcmUgcmVxdWlyZWRcXHUwMDFiWzBtJyk7XG4gICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9uc1snbGl2ZVF1ZXJ5LmNsYXNzTmFtZXMnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LmNsYXNzTmFtZXMgPSBvcHRpb25zWydsaXZlUXVlcnkuY2xhc3NOYW1lcyddO1xuICAgICAgZGVsZXRlIG9wdGlvbnNbJ2xpdmVRdWVyeS5jbGFzc05hbWVzJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNVUkwnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LnJlZGlzVVJMID0gb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ10pIHtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5ID0gb3B0aW9ucy5saXZlUXVlcnkgfHwge307XG4gICAgICBvcHRpb25zLmxpdmVRdWVyeS5yZWRpc09wdGlvbnMgPSBvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzT3B0aW9ucyddO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmNsdXN0ZXIpIHtcbiAgICAgIGNvbnN0IG51bUNQVXMgPSB0eXBlb2Ygb3B0aW9ucy5jbHVzdGVyID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuY2x1c3RlciA6IG9zLmNwdXMoKS5sZW5ndGg7XG4gICAgICBpZiAoY2x1c3Rlci5pc01hc3Rlcikge1xuICAgICAgICBsb2dPcHRpb25zKCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ1BVczsgaSsrKSB7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2x1c3Rlci5vbignZXhpdCcsICh3b3JrZXIsIGNvZGUpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgd29ya2VyICR7d29ya2VyLnByb2Nlc3MucGlkfSBkaWVkICgke2NvZGV9KS4uLiBSZXN0YXJ0aW5nYCk7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2VTZXJ2ZXIuc3RhcnQob3B0aW9ucywgKCkgPT4ge1xuICAgICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIFBhcnNlU2VydmVyLnN0YXJ0KG9wdGlvbnMsICgpID0+IHtcbiAgICAgICAgbG9nT3B0aW9ucygpO1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByaW50U3VjY2Vzc01lc3NhZ2UoKSB7XG4gICAgICBjb25zb2xlLmxvZygnWycgKyBwcm9jZXNzLnBpZCArICddIHBhcnNlLXNlcnZlciBydW5uaW5nIG9uICcgKyBvcHRpb25zLnNlcnZlclVSTCk7XG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgJ1snICtcbiAgICAgICAgICAgIHByb2Nlc3MucGlkICtcbiAgICAgICAgICAgICddIEdyYXBoUUwgcnVubmluZyBvbiBodHRwOi8vbG9jYWxob3N0OicgK1xuICAgICAgICAgICAgb3B0aW9ucy5wb3J0ICtcbiAgICAgICAgICAgIG9wdGlvbnMuZ3JhcGhRTFBhdGhcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLm1vdW50UGxheWdyb3VuZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAnWycgK1xuICAgICAgICAgICAgcHJvY2Vzcy5waWQgK1xuICAgICAgICAgICAgJ10gUGxheWdyb3VuZCBydW5uaW5nIG9uIGh0dHA6Ly9sb2NhbGhvc3Q6JyArXG4gICAgICAgICAgICBvcHRpb25zLnBvcnQgK1xuICAgICAgICAgICAgb3B0aW9ucy5wbGF5Z3JvdW5kUGF0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbn0pO1xuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cli/utils/commander.js b/lib/cli/utils/commander.js deleted file mode 100644 index cff789e0ad..0000000000 --- a/lib/cli/utils/commander.js +++ /dev/null @@ -1,163 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _commander = require("commander"); - -var _path = _interopRequireDefault(require("path")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/* eslint-disable no-console */ -let _definitions; - -let _reverseDefinitions; - -let _defaults; - -_commander.Command.prototype.loadDefinitions = function (definitions) { - _definitions = definitions; - Object.keys(definitions).reduce((program, opt) => { - if (typeof definitions[opt] == 'object') { - const additionalOptions = definitions[opt]; - - if (additionalOptions.required === true) { - return program.option(`--${opt} <${opt}>`, additionalOptions.help, additionalOptions.action); - } else { - return program.option(`--${opt} [${opt}]`, additionalOptions.help, additionalOptions.action); - } - } - - return program.option(`--${opt} [${opt}]`); - }, this); - _reverseDefinitions = Object.keys(definitions).reduce((object, key) => { - let value = definitions[key]; - - if (typeof value == 'object') { - value = value.env; - } - - if (value) { - object[value] = key; - } - - return object; - }, {}); - _defaults = Object.keys(definitions).reduce((defs, opt) => { - if (_definitions[opt].default) { - defs[opt] = _definitions[opt].default; - } - - return defs; - }, {}); - /* istanbul ignore next */ - - this.on('--help', function () { - console.log(' Configure From Environment:'); - console.log(''); - Object.keys(_reverseDefinitions).forEach(key => { - console.log(` $ ${key}='${_reverseDefinitions[key]}'`); - }); - console.log(''); - }); -}; - -function parseEnvironment(env = {}) { - return Object.keys(_reverseDefinitions).reduce((options, key) => { - if (env[key]) { - const originalKey = _reverseDefinitions[key]; - - let action = option => option; - - if (typeof _definitions[originalKey] === 'object') { - action = _definitions[originalKey].action || action; - } - - options[_reverseDefinitions[key]] = action(env[key]); - } - - return options; - }, {}); -} - -function parseConfigFile(program) { - let options = {}; - - if (program.args.length > 0) { - let jsonPath = program.args[0]; - jsonPath = _path.default.resolve(jsonPath); - - const jsonConfig = require(jsonPath); - - if (jsonConfig.apps) { - if (jsonConfig.apps.length > 1) { - throw 'Multiple apps are not supported'; - } - - options = jsonConfig.apps[0]; - } else { - options = jsonConfig; - } - - Object.keys(options).forEach(key => { - const value = options[key]; - - if (!_definitions[key]) { - throw `error: unknown option ${key}`; - } - - const action = _definitions[key].action; - - if (action) { - options[key] = action(value); - } - }); - console.log(`Configuration loaded from ${jsonPath}`); - } - - return options; -} - -_commander.Command.prototype.setValuesIfNeeded = function (options) { - Object.keys(options).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(this, key)) { - this[key] = options[key]; - } - }); -}; - -_commander.Command.prototype._parse = _commander.Command.prototype.parse; - -_commander.Command.prototype.parse = function (args, env) { - this._parse(args); // Parse the environment first - - - const envOptions = parseEnvironment(env); - const fromFile = parseConfigFile(this); // Load the env if not passed from command line - - this.setValuesIfNeeded(envOptions); // Load from file to override - - this.setValuesIfNeeded(fromFile); // Last set the defaults - - this.setValuesIfNeeded(_defaults); -}; - -_commander.Command.prototype.getOptions = function () { - return Object.keys(_definitions).reduce((options, key) => { - if (typeof this[key] !== 'undefined') { - options[key] = this[key]; - } - - return options; - }, {}); -}; - -var _default = new _commander.Command(); -/* eslint-enable no-console */ - - -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvY29tbWFuZGVyLmpzIl0sIm5hbWVzIjpbIl9kZWZpbml0aW9ucyIsIl9yZXZlcnNlRGVmaW5pdGlvbnMiLCJfZGVmYXVsdHMiLCJDb21tYW5kIiwicHJvdG90eXBlIiwibG9hZERlZmluaXRpb25zIiwiZGVmaW5pdGlvbnMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwicHJvZ3JhbSIsIm9wdCIsImFkZGl0aW9uYWxPcHRpb25zIiwicmVxdWlyZWQiLCJvcHRpb24iLCJoZWxwIiwiYWN0aW9uIiwib2JqZWN0Iiwia2V5IiwidmFsdWUiLCJlbnYiLCJkZWZzIiwiZGVmYXVsdCIsIm9uIiwiY29uc29sZSIsImxvZyIsImZvckVhY2giLCJwYXJzZUVudmlyb25tZW50Iiwib3B0aW9ucyIsIm9yaWdpbmFsS2V5IiwicGFyc2VDb25maWdGaWxlIiwiYXJncyIsImxlbmd0aCIsImpzb25QYXRoIiwicGF0aCIsInJlc29sdmUiLCJqc29uQ29uZmlnIiwicmVxdWlyZSIsImFwcHMiLCJzZXRWYWx1ZXNJZk5lZWRlZCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9wYXJzZSIsInBhcnNlIiwiZW52T3B0aW9ucyIsImZyb21GaWxlIiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOzs7O0FBRkE7QUFHQSxJQUFJQSxZQUFKOztBQUNBLElBQUlDLG1CQUFKOztBQUNBLElBQUlDLFNBQUo7O0FBRUFDLG1CQUFRQyxTQUFSLENBQWtCQyxlQUFsQixHQUFvQyxVQUFTQyxXQUFULEVBQXNCO0FBQ3hETixFQUFBQSxZQUFZLEdBQUdNLFdBQWY7QUFFQUMsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVlGLFdBQVosRUFBeUJHLE1BQXpCLENBQWdDLENBQUNDLE9BQUQsRUFBVUMsR0FBVixLQUFrQjtBQUNoRCxRQUFJLE9BQU9MLFdBQVcsQ0FBQ0ssR0FBRCxDQUFsQixJQUEyQixRQUEvQixFQUF5QztB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UixDQUFrQjBDLFVBQWxCLEdBQStCLFlBQVc7QUFDeEMsU0FBT3ZDLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZUixZQUFaLEVBQTBCUyxNQUExQixDQUFpQyxDQUFDbUIsT0FBRCxFQUFVVixHQUFWLEtBQWtCO0FBQ3hELFFBQUksT0FBTyxLQUFLQSxHQUFMLENBQVAsS0FBcUIsV0FBekIsRUFBc0M7QUFDcENVLE1BQUFBLE9BQU8sQ0FBQ1YsR0FBRCxDQUFQLEdBQWUsS0FBS0EsR0FBTCxDQUFmO0FBQ0Q7O0FBQ0QsV0FBT1UsT0FBUDtBQUNELEdBTE0sRUFLSixFQUxJLENBQVA7QUFNRCxDQVBEOztlQVNlLElBQUl6QixrQkFBSixFO0FBQ2YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xubGV0IF9kZWZpbml0aW9ucztcbmxldCBfcmV2ZXJzZURlZmluaXRpb25zO1xubGV0IF9kZWZhdWx0cztcblxuQ29tbWFuZC5wcm90b3R5cGUubG9hZERlZmluaXRpb25zID0gZnVuY3Rpb24oZGVmaW5pdGlvbnMpIHtcbiAgX2RlZmluaXRpb25zID0gZGVmaW5pdGlvbnM7XG5cbiAgT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgocHJvZ3JhbSwgb3B0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBkZWZpbml0aW9uc1tvcHRdID09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IGRlZmluaXRpb25zW29wdF07XG4gICAgICBpZiAoYWRkaXRpb25hbE9wdGlvbnMucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIHByb2dyYW0ub3B0aW9uKFxuICAgICAgICAgIGAtLSR7b3B0fSA8JHtvcHR9PmAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuaGVscCxcbiAgICAgICAgICBhZGRpdGlvbmFsT3B0aW9ucy5hY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihcbiAgICAgICAgICBgLS0ke29wdH0gWyR7b3B0fV1gLFxuICAgICAgICAgIGFkZGl0aW9uYWxPcHRpb25zLmhlbHAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihgLS0ke29wdH0gWyR7b3B0fV1gKTtcbiAgfSwgdGhpcyk7XG5cbiAgX3JldmVyc2VEZWZpbml0aW9ucyA9IE9iamVjdC5rZXlzKGRlZmluaXRpb25zKS5yZWR1Y2UoKG9iamVjdCwga2V5KSA9PiB7XG4gICAgbGV0IHZhbHVlID0gZGVmaW5pdGlvbnNba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLmVudjtcbiAgICB9XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBvYmplY3RbdmFsdWVdID0ga2V5O1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LCB7fSk7XG5cbiAgX2RlZmF1bHRzID0gT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgoZGVmcywgb3B0KSA9PiB7XG4gICAgaWYgKF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQpIHtcbiAgICAgIGRlZnNbb3B0XSA9IF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQ7XG4gICAgfVxuICAgIHJldHVybiBkZWZzO1xuICB9LCB7fSk7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgdGhpcy5vbignLS1oZWxwJywgZnVuY3Rpb24oKSB7XG4gICAgY29uc29sZS5sb2coJyAgQ29uZmlndXJlIEZyb20gRW52aXJvbm1lbnQ6Jyk7XG4gICAgY29uc29sZS5sb2coJycpO1xuICAgIE9iamVjdC5rZXlzKF9yZXZlcnNlRGVmaW5pdGlvbnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGAgICAgJCAke2tleX09JyR7X3JldmVyc2VEZWZpbml0aW9uc1trZXldfSdgKTtcbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZygnJyk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gcGFyc2VFbnZpcm9ubWVudChlbnYgPSB7fSkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoX3JldmVyc2VEZWZpbml0aW9ucykucmVkdWNlKChvcHRpb25zLCBrZXkpID0+IHtcbiAgICBpZiAoZW52W2tleV0pIHtcbiAgICAgIGNvbnN0IG9yaWdpbmFsS2V5ID0gX3JldmVyc2VEZWZpbml0aW9uc1trZXldO1xuICAgICAgbGV0IGFjdGlvbiA9IG9wdGlvbiA9PiBvcHRpb247XG4gICAgICBpZiAodHlwZW9mIF9kZWZpbml0aW9uc1tvcmlnaW5hbEtleV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGFjdGlvbiA9IF9kZWZpbml0aW9uc1tvcmlnaW5hbEtleV0uYWN0aW9uIHx8IGFjdGlvbjtcbiAgICAgIH1cbiAgICAgIG9wdGlvbnNbX3JldmVyc2VEZWZpbml0aW9uc1trZXldXSA9IGFjdGlvbihlbnZba2V5XSk7XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9LCB7fSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlQ29uZmlnRmlsZShwcm9ncmFtKSB7XG4gIGxldCBvcHRpb25zID0ge307XG4gIGlmIChwcm9ncmFtLmFyZ3MubGVuZ3RoID4gMCkge1xuICAgIGxldCBqc29uUGF0aCA9IHByb2dyYW0uYXJnc1swXTtcbiAgICBqc29uUGF0aCA9IHBhdGgucmVzb2x2ZShqc29uUGF0aCk7XG4gICAgY29uc3QganNvbkNvbmZpZyA9IHJlcXVpcmUoanNvblBhdGgpO1xuICAgIGlmIChqc29uQ29uZmlnLmFwcHMpIHtcbiAgICAgIGlmIChqc29uQ29uZmlnLmFwcHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyAnTXVsdGlwbGUgYXBwcyBhcmUgbm90IHN1cHBvcnRlZCc7XG4gICAgICB9XG4gICAgICBvcHRpb25zID0ganNvbkNvbmZpZy5hcHBzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zID0ganNvbkNvbmZpZztcbiAgICB9XG4gICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW2tleV07XG4gICAgICBpZiAoIV9kZWZpbml0aW9uc1trZXldKSB7XG4gICAgICAgIHRocm93IGBlcnJvcjogdW5rbm93biBvcHRpb24gJHtrZXl9YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjdGlvbiA9IF9kZWZpbml0aW9uc1trZXldLmFjdGlvbjtcbiAgICAgIGlmIChhY3Rpb24pIHtcbiAgICAgICAgb3B0aW9uc1trZXldID0gYWN0aW9uKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zb2xlLmxvZyhgQ29uZmlndXJhdGlvbiBsb2FkZWQgZnJvbSAke2pzb25QYXRofWApO1xuICB9XG4gIHJldHVybiBvcHRpb25zO1xufVxuXG5Db21tYW5kLnByb3RvdHlwZS5zZXRWYWx1ZXNJZk5lZWRlZCA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsIGtleSkpIHtcbiAgICAgIHRoaXNba2V5XSA9IG9wdGlvbnNba2V5XTtcbiAgICB9XG4gIH0pO1xufTtcblxuQ29tbWFuZC5wcm90b3R5cGUuX3BhcnNlID0gQ29tbWFuZC5wcm90b3R5cGUucGFyc2U7XG5cbkNvbW1hbmQucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oYXJncywgZW52KSB7XG4gIHRoaXMuX3BhcnNlKGFyZ3MpO1xuICAvLyBQYXJzZSB0aGUgZW52aXJvbm1lbnQgZmlyc3RcbiAgY29uc3QgZW52T3B0aW9ucyA9IHBhcnNlRW52aXJvbm1lbnQoZW52KTtcbiAgY29uc3QgZnJvbUZpbGUgPSBwYXJzZUNvbmZpZ0ZpbGUodGhpcyk7XG4gIC8vIExvYWQgdGhlIGVudiBpZiBub3QgcGFzc2VkIGZyb20gY29tbWFuZCBsaW5lXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZW52T3B0aW9ucyk7XG4gIC8vIExvYWQgZnJvbSBmaWxlIHRvIG92ZXJyaWRlXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZnJvbUZpbGUpO1xuICAvLyBMYXN0IHNldCB0aGUgZGVmYXVsdHNcbiAgdGhpcy5zZXRWYWx1ZXNJZk5lZWRlZChfZGVmYXVsdHMpO1xufTtcblxuQ29tbWFuZC5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoX2RlZmluaXRpb25zKS5yZWR1Y2UoKG9wdGlvbnMsIGtleSkgPT4ge1xuICAgIGlmICh0eXBlb2YgdGhpc1trZXldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgb3B0aW9uc1trZXldID0gdGhpc1trZXldO1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfSwge30pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgbmV3IENvbW1hbmQoKTtcbi8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuIl19 \ No newline at end of file diff --git a/lib/cli/utils/runner.js b/lib/cli/utils/runner.js deleted file mode 100644 index 5725eaca43..0000000000 --- a/lib/cli/utils/runner.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = _default; - -var _commander = _interopRequireDefault(require("./commander")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function logStartupOptions(options) { - for (const key in options) { - let value = options[key]; - - if (key == 'masterKey') { - value = '***REDACTED***'; - } - - if (key == 'push' && options.verbose != true) { - value = '***REDACTED***'; - } - - if (typeof value === 'object') { - try { - value = JSON.stringify(value); - } catch (e) { - if (value && value.constructor && value.constructor.name) { - value = value.constructor.name; - } - } - } - /* eslint-disable no-console */ - - - console.log(`${key}: ${value}`); - /* eslint-enable no-console */ - } -} - -function _default({ - definitions, - help, - usage, - start -}) { - _commander.default.loadDefinitions(definitions); - - if (usage) { - _commander.default.usage(usage); - } - - if (help) { - _commander.default.on('--help', help); - } - - _commander.default.parse(process.argv, process.env); - - const options = _commander.default.getOptions(); - - start(_commander.default, options, function () { - logStartupOptions(options); - }); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvcnVubmVyLmpzIl0sIm5hbWVzIjpbImxvZ1N0YXJ0dXBPcHRpb25zIiwib3B0aW9ucyIsImtleSIsInZhbHVlIiwidmVyYm9zZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiY29uc29sZSIsImxvZyIsImRlZmluaXRpb25zIiwiaGVscCIsInVzYWdlIiwic3RhcnQiLCJwcm9ncmFtIiwibG9hZERlZmluaXRpb25zIiwib24iLCJwYXJzZSIsInByb2Nlc3MiLCJhcmd2IiwiZW52IiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsU0FBU0EsaUJBQVQsQ0FBMkJDLE9BQTNCLEVBQW9DO0FBQ2xDLE9BQUssTUFBTUMsR0FBWCxJQUFrQkQsT0FBbEIsRUFBMkI7QUFDekIsUUFBSUUsS0FBSyxHQUFHRixPQUFPLENBQUNDLEdBQUQsQ0FBbkI7O0FBQ0EsUUFBSUEsR0FBRyxJQUFJLFdBQVgsRUFBd0I7QUFDdEJDLE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUlELEdBQUcsSUFBSSxNQUFQLElBQWlCRCxPQUFPLENBQUNHLE9BQVIsSUFBbUIsSUFBeEMsRUFBOEM7QUFDNUNELE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUksT0FBT0EsS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUM3QixVQUFJO0FBQ0ZBLFFBQUFBLEtBQUssR0FBR0UsSUFBSSxDQUFDQyxTQUFMLENBQWVILEtBQWYsQ0FBUjtBQUNELE9BRkQsQ0FFRSxPQUFPSSxDQUFQLEVBQVU7QUFDVixZQUFJSixLQUFLLElBQUlBLEtBQUssQ0FBQ0ssV0FBZixJQUE4QkwsS0FBSyxDQUFDSyxXQUFOLENBQWtCQyxJQUFwRCxFQUEwRDtBQUN4RE4sVUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNLLFdBQU4sQ0FBa0JDLElBQTFCO0FBQ0Q7QUFDRjtBQUNGO0FBQ0Q7OztBQUNBQyxJQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxHQUFFVCxHQUFJLEtBQUlDLEtBQU0sRUFBN0I7QUFDQTtBQUNEO0FBQ0Y7O0FBRWMsa0JBQVM7QUFBRVMsRUFBQUEsV0FBRjtBQUFlQyxFQUFBQSxJQUFmO0FBQXFCQyxFQUFBQSxLQUFyQjtBQUE0QkMsRUFBQUE7QUFBNUIsQ0FBVCxFQUE4QztBQUMzREMscUJBQVFDLGVBQVIsQ0FBd0JMLFdBQXhCOztBQUNBLE1BQUlFLEtBQUosRUFBVztBQUNURSx1QkFBUUYsS0FBUixDQUFjQSxLQUFkO0FBQ0Q7O0FBQ0QsTUFBSUQsSUFBSixFQUFVO0FBQ1JHLHVCQUFRRSxFQUFSLENBQVcsUUFBWCxFQUFxQkwsSUFBckI7QUFDRDs7QUFDREcscUJBQVFHLEtBQVIsQ0FBY0MsT0FBTyxDQUFDQyxJQUF0QixFQUE0QkQsT0FBTyxDQUFDRSxHQUFwQzs7QUFFQSxRQUFNckIsT0FBTyxHQUFHZSxtQkFBUU8sVUFBUixFQUFoQjs7QUFDQVIsRUFBQUEsS0FBSyxDQUFDQyxrQkFBRCxFQUFVZixPQUFWLEVBQW1CLFlBQVc7QUFDakNELElBQUFBLGlCQUFpQixDQUFDQyxPQUFELENBQWpCO0FBQ0QsR0FGSSxDQUFMO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHJvZ3JhbSBmcm9tICcuL2NvbW1hbmRlcic7XG5cbmZ1bmN0aW9uIGxvZ1N0YXJ0dXBPcHRpb25zKG9wdGlvbnMpIHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucykge1xuICAgIGxldCB2YWx1ZSA9IG9wdGlvbnNba2V5XTtcbiAgICBpZiAoa2V5ID09ICdtYXN0ZXJLZXknKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmIChrZXkgPT0gJ3B1c2gnICYmIG9wdGlvbnMudmVyYm9zZSAhPSB0cnVlKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgIGNvbnNvbGUubG9nKGAke2tleX06ICR7dmFsdWV9YCk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oeyBkZWZpbml0aW9ucywgaGVscCwgdXNhZ2UsIHN0YXJ0IH0pIHtcbiAgcHJvZ3JhbS5sb2FkRGVmaW5pdGlvbnMoZGVmaW5pdGlvbnMpO1xuICBpZiAodXNhZ2UpIHtcbiAgICBwcm9ncmFtLnVzYWdlKHVzYWdlKTtcbiAgfVxuICBpZiAoaGVscCkge1xuICAgIHByb2dyYW0ub24oJy0taGVscCcsIGhlbHApO1xuICB9XG4gIHByb2dyYW0ucGFyc2UocHJvY2Vzcy5hcmd2LCBwcm9jZXNzLmVudik7XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHByb2dyYW0uZ2V0T3B0aW9ucygpO1xuICBzdGFydChwcm9ncmFtLCBvcHRpb25zLCBmdW5jdGlvbigpIHtcbiAgICBsb2dTdGFydHVwT3B0aW9ucyhvcHRpb25zKTtcbiAgfSk7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/cloud-code/HTTPResponse.js b/lib/cloud-code/HTTPResponse.js deleted file mode 100644 index 88c745095b..0000000000 --- a/lib/cloud-code/HTTPResponse.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -/** - * @typedef Parse.Cloud.HTTPResponse - * @property {Buffer} buffer The raw byte representation of the response body. Use this to receive binary data. See Buffer for more details. - * @property {Object} cookies The cookies sent by the server. The keys in this object are the names of the cookies. The values are Parse.Cloud.Cookie objects. - * @property {Object} data The parsed response body as a JavaScript object. This is only available when the response Content-Type is application/x-www-form-urlencoded or application/json. - * @property {Object} headers The headers sent by the server. The keys in this object are the names of the headers. We do not support multiple response headers with the same name. In the common case of Set-Cookie headers, please use the cookies field instead. - * @property {Number} status The status code. - * @property {String} text The raw text representation of the response body. - */ -class HTTPResponse { - constructor(response, body) { - let _text, _data; - - this.status = response.statusCode; - this.headers = response.headers || {}; - this.cookies = this.headers['set-cookie']; - - if (typeof body == 'string') { - _text = body; - } else if (Buffer.isBuffer(body)) { - this.buffer = body; - } else if (typeof body == 'object') { - _data = body; - } - - const getText = () => { - if (!_text && this.buffer) { - _text = this.buffer.toString('utf-8'); - } else if (!_text && _data) { - _text = JSON.stringify(_data); - } - - return _text; - }; - - const getData = () => { - if (!_data) { - try { - _data = JSON.parse(getText()); - } catch (e) { - /* */ - } - } - - return _data; - }; - - Object.defineProperty(this, 'body', { - get: () => { - return body; - } - }); - Object.defineProperty(this, 'text', { - enumerable: true, - get: getText - }); - Object.defineProperty(this, 'data', { - enumerable: true, - get: getData - }); - } - -} - -exports.default = HTTPResponse; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL0hUVFBSZXNwb25zZS5qcyJdLCJuYW1lcyI6WyJIVFRQUmVzcG9uc2UiLCJjb25zdHJ1Y3RvciIsInJlc3BvbnNlIiwiYm9keSIsIl90ZXh0IiwiX2RhdGEiLCJzdGF0dXMiLCJzdGF0dXNDb2RlIiwiaGVhZGVycyIsImNvb2tpZXMiLCJCdWZmZXIiLCJpc0J1ZmZlciIsImJ1ZmZlciIsImdldFRleHQiLCJ0b1N0cmluZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJnZXREYXRhIiwicGFyc2UiLCJlIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJlbnVtZXJhYmxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7Ozs7OztBQVNlLE1BQU1BLFlBQU4sQ0FBbUI7QUFDaENDLEVBQUFBLFdBQVcsQ0FBQ0MsUUFBRCxFQUFXQyxJQUFYLEVBQWlCO0FBQzFCLFFBQUlDLEtBQUosRUFBV0MsS0FBWDs7QUFDQSxTQUFLQyxNQUFMLEdBQWNKLFFBQVEsQ0FBQ0ssVUFBdkI7QUFDQSxTQUFLQyxPQUFMLEdBQWVOLFFBQVEsQ0FBQ00sT0FBVCxJQUFvQixFQUFuQztBQUNBLFNBQUtDLE9BQUwsR0FBZSxLQUFLRCxPQUFMLENBQWEsWUFBYixDQUFmOztBQUVBLFFBQUksT0FBT0wsSUFBUCxJQUFlLFFBQW5CLEVBQTZCO0FBQzNCQyxNQUFBQSxLQUFLLEdBQUdELElBQVI7QUFDRCxLQUZELE1BRU8sSUFBSU8sTUFBTSxDQUFDQyxRQUFQLENBQWdCUixJQUFoQixDQUFKLEVBQTJCO0FBQ2hDLFdBQUtTLE1BQUwsR0FBY1QsSUFBZDtBQUNELEtBRk0sTUFFQSxJQUFJLE9BQU9BLElBQVAsSUFBZSxRQUFuQixFQUE2QjtBQUNsQ0UsTUFBQUEsS0FBSyxHQUFHRixJQUFSO0FBQ0Q7O0FBRUQsVUFBTVUsT0FBTyxHQUFHLE1BQU07QUFDcEIsVUFBSSxDQUFDVCxLQUFELElBQVUsS0FBS1EsTUFBbkIsRUFBMkI7QUFDekJSLFFBQUFBLEtBQUssR0FBRyxLQUFLUSxNQUFMLENBQVlFLFFBQVosQ0FBcUIsT0FBckIsQ0FBUjtBQUNELE9BRkQsTUFFTyxJQUFJLENBQUNWLEtBQUQsSUFBVUMsS0FBZCxFQUFxQjtBQUMxQkQsUUFBQUEsS0FBSyxHQUFHVyxJQUFJLENBQUNDLFNBQUwsQ0FBZVgsS0FBZixDQUFSO0FBQ0Q7O0FBQ0QsYUFBT0QsS0FBUDtBQUNELEtBUEQ7O0FBU0EsVUFBTWEsT0FBTyxHQUFHLE1BQU07QUFDcEIsVUFBSSxDQUFDWixLQUFMLEVBQVk7QUFDVixZQUFJO0FBQ0ZBLFVBQUFBLEtBQUssR0FBR1UsSUFBSSxDQUFDRyxLQUFMLENBQVdMLE9BQU8sRUFBbEIsQ0FBUjtBQUNELFNBRkQsQ0FFRSxPQUFPTSxDQUFQLEVBQVU7QUFDVjtBQUNEO0FBQ0Y7O0FBQ0QsYUFBT2QsS0FBUDtBQUNELEtBVEQ7O0FBV0FlLElBQUFBLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixNQUE1QixFQUFvQztBQUNsQ0MsTUFBQUEsR0FBRyxFQUFFLE1BQU07QUFDVCxlQUFPbkIsSUFBUDtBQUNEO0FBSGlDLEtBQXBDO0FBTUFpQixJQUFBQSxNQUFNLENBQUNDLGNBQVAsQ0FBc0IsSUFBdEIsRUFBNEIsTUFBNUIsRUFBb0M7QUFDbENFLE1BQUFBLFVBQVUsRUFBRSxJQURzQjtBQUVsQ0QsTUFBQUEsR0FBRyxFQUFFVDtBQUY2QixLQUFwQztBQUtBTyxJQUFBQSxNQUFNLENBQUNDLGNBQVAsQ0FBc0IsSUFBdEIsRUFBNEIsTUFBNUIsRUFBb0M7QUFDbENFLE1BQUFBLFVBQVUsRUFBRSxJQURzQjtBQUVsQ0QsTUFBQUEsR0FBRyxFQUFFTDtBQUY2QixLQUFwQztBQUlEOztBQWxEK0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEB0eXBlZGVmIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZVxuICogQHByb3BlcnR5IHtCdWZmZXJ9IGJ1ZmZlciBUaGUgcmF3IGJ5dGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHJlc3BvbnNlIGJvZHkuIFVzZSB0aGlzIHRvIHJlY2VpdmUgYmluYXJ5IGRhdGEuIFNlZSBCdWZmZXIgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBjb29raWVzIFRoZSBjb29raWVzIHNlbnQgYnkgdGhlIHNlcnZlci4gVGhlIGtleXMgaW4gdGhpcyBvYmplY3QgYXJlIHRoZSBuYW1lcyBvZiB0aGUgY29va2llcy4gVGhlIHZhbHVlcyBhcmUgUGFyc2UuQ2xvdWQuQ29va2llIG9iamVjdHMuXG4gKiBAcHJvcGVydHkge09iamVjdH0gZGF0YSBUaGUgcGFyc2VkIHJlc3BvbnNlIGJvZHkgYXMgYSBKYXZhU2NyaXB0IG9iamVjdC4gVGhpcyBpcyBvbmx5IGF2YWlsYWJsZSB3aGVuIHRoZSByZXNwb25zZSBDb250ZW50LVR5cGUgaXMgYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIG9yIGFwcGxpY2F0aW9uL2pzb24uXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyBzZW50IGJ5IHRoZSBzZXJ2ZXIuIFRoZSBrZXlzIGluIHRoaXMgb2JqZWN0IGFyZSB0aGUgbmFtZXMgb2YgdGhlIGhlYWRlcnMuIFdlIGRvIG5vdCBzdXBwb3J0IG11bHRpcGxlIHJlc3BvbnNlIGhlYWRlcnMgd2l0aCB0aGUgc2FtZSBuYW1lLiBJbiB0aGUgY29tbW9uIGNhc2Ugb2YgU2V0LUNvb2tpZSBoZWFkZXJzLCBwbGVhc2UgdXNlIHRoZSBjb29raWVzIGZpZWxkIGluc3RlYWQuXG4gKiBAcHJvcGVydHkge051bWJlcn0gc3RhdHVzIFRoZSBzdGF0dXMgY29kZS5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB0ZXh0IFRoZSByYXcgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVzcG9uc2UgYm9keS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSFRUUFJlc3BvbnNlIHtcbiAgY29uc3RydWN0b3IocmVzcG9uc2UsIGJvZHkpIHtcbiAgICBsZXQgX3RleHQsIF9kYXRhO1xuICAgIHRoaXMuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzQ29kZTtcbiAgICB0aGlzLmhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzIHx8IHt9O1xuICAgIHRoaXMuY29va2llcyA9IHRoaXMuaGVhZGVyc1snc2V0LWNvb2tpZSddO1xuXG4gICAgaWYgKHR5cGVvZiBib2R5ID09ICdzdHJpbmcnKSB7XG4gICAgICBfdGV4dCA9IGJvZHk7XG4gICAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcbiAgICAgIHRoaXMuYnVmZmVyID0gYm9keTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBib2R5ID09ICdvYmplY3QnKSB7XG4gICAgICBfZGF0YSA9IGJvZHk7XG4gICAgfVxuXG4gICAgY29uc3QgZ2V0VGV4dCA9ICgpID0+IHtcbiAgICAgIGlmICghX3RleHQgJiYgdGhpcy5idWZmZXIpIHtcbiAgICAgICAgX3RleHQgPSB0aGlzLmJ1ZmZlci50b1N0cmluZygndXRmLTgnKTtcbiAgICAgIH0gZWxzZSBpZiAoIV90ZXh0ICYmIF9kYXRhKSB7XG4gICAgICAgIF90ZXh0ID0gSlNPTi5zdHJpbmdpZnkoX2RhdGEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIF90ZXh0O1xuICAgIH07XG5cbiAgICBjb25zdCBnZXREYXRhID0gKCkgPT4ge1xuICAgICAgaWYgKCFfZGF0YSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIF9kYXRhID0gSlNPTi5wYXJzZShnZXRUZXh0KCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLyogKi9cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIF9kYXRhO1xuICAgIH07XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2JvZHknLCB7XG4gICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0ZXh0Jywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZ2V0VGV4dCxcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZGF0YScsIHtcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGdldERhdGEsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/cloud-code/Parse.Cloud.js b/lib/cloud-code/Parse.Cloud.js deleted file mode 100644 index e81a930907..0000000000 --- a/lib/cloud-code/Parse.Cloud.js +++ /dev/null @@ -1,685 +0,0 @@ -"use strict"; - -var _node = require("parse/node"); - -var triggers = _interopRequireWildcard(require("../triggers")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function isParseObjectConstructor(object) { - return typeof object === 'function' && Object.prototype.hasOwnProperty.call(object, 'className'); -} - -function getClassName(parseClass) { - if (parseClass && parseClass.className) { - return parseClass.className; - } - - return parseClass; -} -/** @namespace - * @name Parse - * @description The Parse SDK. - * see [api docs](https://docs.parseplatform.org/js/api) and [guide](https://docs.parseplatform.org/js/guide) - */ - -/** @namespace - * @name Parse.Cloud - * @memberof Parse - * @description The Parse Cloud Code SDK. - */ - - -var ParseCloud = {}; -/** - * Defines a Cloud Function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.define('functionName', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.define('functionName', (request) => { - * // code here - * }, { ...validationObject }); - * ``` - * - * @static - * @memberof Parse.Cloud - * @param {String} name The name of the Cloud Function - * @param {Function} data The Cloud Function to register. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - -ParseCloud.define = function (functionName, handler, validationHandler) { - triggers.addFunction(functionName, handler, validationHandler, _node.Parse.applicationId); -}; -/** - * Defines a Background Job. - * - * **Available in Cloud Code only.** - * - * @method job - * @name Parse.Cloud.job - * @param {String} name The name of the Background Job - * @param {Function} func The Background Job to register. This function can be async should take a single parameters a {@link Parse.Cloud.JobRequest} - * - */ - - -ParseCloud.job = function (functionName, handler) { - triggers.addJob(functionName, handler, _node.Parse.applicationId); -}; -/** - * - * Registers a before save function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * - * ``` - * Parse.Cloud.beforeSave('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSave(Parse.User, (request) => { - * // code here - * }, { ...validationObject }) - * ``` - * - * @method beforeSave - * @name Parse.Cloud.beforeSave - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a save. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeSave = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeSave, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before delete function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.beforeDelete('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeDelete(Parse.User, (request) => { - * // code here - * }, { ...validationObject }) - *``` - * - * @method beforeDelete - * @name Parse.Cloud.beforeDelete - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before delete function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a delete. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeDelete = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeDelete, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * - * Registers the before login function. - * - * **Available in Cloud Code only.** - * - * This function provides further control - * in validating a login attempt. Specifically, - * it is triggered after a user enters - * correct credentials (or other valid authData), - * but prior to a session being generated. - * - * ``` - * Parse.Cloud.beforeLogin((request) => { - * // code here - * }) - * - * ``` - * - * @method beforeLogin - * @name Parse.Cloud.beforeLogin - * @param {Function} func The function to run before a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - */ - - -ParseCloud.beforeLogin = function (handler) { - let className = '_User'; - - if (typeof handler === 'string' || isParseObjectConstructor(handler)) { - // validation will occur downstream, this is to maintain internal - // code consistency with the other hook types. - className = getClassName(handler); - handler = arguments[1]; - } - - triggers.addTrigger(triggers.Types.beforeLogin, className, handler, _node.Parse.applicationId); -}; -/** - * - * Registers the after login function. - * - * **Available in Cloud Code only.** - * - * This function is triggered after a user logs in successfully, - * and after a _Session object has been created. - * - * ``` - * Parse.Cloud.afterLogin((request) => { - * // code here - * }); - * ``` - * - * @method afterLogin - * @name Parse.Cloud.afterLogin - * @param {Function} func The function to run after a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - */ - - -ParseCloud.afterLogin = function (handler) { - let className = '_User'; - - if (typeof handler === 'string' || isParseObjectConstructor(handler)) { - // validation will occur downstream, this is to maintain internal - // code consistency with the other hook types. - className = getClassName(handler); - handler = arguments[1]; - } - - triggers.addTrigger(triggers.Types.afterLogin, className, handler, _node.Parse.applicationId); -}; -/** - * - * Registers the after logout function. - * - * **Available in Cloud Code only.** - * - * This function is triggered after a user logs out. - * - * ``` - * Parse.Cloud.afterLogout((request) => { - * // code here - * }); - * ``` - * - * @method afterLogout - * @name Parse.Cloud.afterLogout - * @param {Function} func The function to run after a logout. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - */ - - -ParseCloud.afterLogout = function (handler) { - let className = '_Session'; - - if (typeof handler === 'string' || isParseObjectConstructor(handler)) { - // validation will occur downstream, this is to maintain internal - // code consistency with the other hook types. - className = getClassName(handler); - handler = arguments[1]; - } - - triggers.addTrigger(triggers.Types.afterLogout, className, handler, _node.Parse.applicationId); -}; -/** - * Registers an after save function. - * - * **Available in Cloud Code only.** - * - * If you want to use afterSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * - * ``` - * Parse.Cloud.afterSave('MyCustomClass', async function(request) { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterSave(Parse.User, async function(request) { - * // code here - * }, { ...validationObject }); - * ``` - * - * @method afterSave - * @name Parse.Cloud.afterSave - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run after a save. This function can be an async function and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterSave = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterSave, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after delete function. - * - * **Available in Cloud Code only.** - * - * If you want to use afterDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.afterDelete('MyCustomClass', async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterDelete(Parse.User, async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterDelete - * @name Parse.Cloud.afterDelete - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after delete function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run after a delete. This function can be async and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterDelete = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterDelete, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before find function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.beforeFind('MyCustomClass', async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeFind(Parse.User, async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeFind - * @name Parse.Cloud.beforeFind - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before find function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.BeforeFindRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.BeforeFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeFind = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeFind, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after find function. - * - * **Available in Cloud Code only.** - * - * If you want to use afterFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.afterFind('MyCustomClass', async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterFind(Parse.User, async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterFind - * @name Parse.Cloud.afterFind - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after find function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.AfterFindRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.AfterFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterFind = function (parseClass, handler, validationHandler) { - const className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterFind, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before save file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeSaveFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSaveFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeSaveFile - * @name Parse.Cloud.beforeSaveFile - * @param {Function} func The function to run before saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeSaveFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.beforeSaveFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after save file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterSaveFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterSaveFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterSaveFile - * @name Parse.Cloud.afterSaveFile - * @param {Function} func The function to run after saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterSaveFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.afterSaveFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before delete file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeDeleteFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeDeleteFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeDeleteFile - * @name Parse.Cloud.beforeDeleteFile - * @param {Function} func The function to run before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeDeleteFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.beforeDeleteFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after delete file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterDeleteFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterDeleteFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterDeleteFile - * @name Parse.Cloud.afterDeleteFile - * @param {Function} func The function to after before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterDeleteFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.afterDeleteFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before live query server connect function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeConnect(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeConnect(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeConnect - * @name Parse.Cloud.beforeConnect - * @param {Function} func The function to before connection is made. This function can be async and should take just one parameter, {@link Parse.Cloud.ConnectTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.ConnectTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeConnect = function (handler, validationHandler) { - triggers.addConnectTrigger(triggers.Types.beforeConnect, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before live query subscription function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeSubscribe for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.beforeSubscribe('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSubscribe(Parse.User, (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeSubscribe - * @name Parse.Cloud.beforeSubscribe - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before subscription function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a subscription. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeSubscribe = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeSubscribe, className, handler, _node.Parse.applicationId, validationHandler); -}; - -ParseCloud.onLiveQueryEvent = function (handler) { - triggers.addLiveQueryEventHandler(handler, _node.Parse.applicationId); -}; -/** - * Registers an after live query server event function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterLiveQueryEvent - * @name Parse.Cloud.afterLiveQueryEvent - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after live query event function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run after a live query event. This function can be async and should take one parameter, a {@link Parse.Cloud.LiveQueryEventTrigger}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.LiveQueryEventTrigger}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterLiveQueryEvent = function (parseClass, handler, validationHandler) { - const className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterEvent, className, handler, _node.Parse.applicationId, validationHandler); -}; - -ParseCloud._removeAllHooks = () => { - triggers._unregisterAll(); -}; - -ParseCloud.useMasterKey = () => { - // eslint-disable-next-line - console.warn('Parse.Cloud.useMasterKey is deprecated (and has no effect anymore) on parse-server, please refer to the cloud code migration notes: http://docs.parseplatform.org/parse-server/guide/#master-key-must-be-passed-explicitly'); -}; - -ParseCloud.httpRequest = require('./httpRequest'); -module.exports = ParseCloud; -/** - * @interface Parse.Cloud.TriggerRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.Object} object The object triggering the hook. - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) - * @property {Object} log The current logger inside Parse Server. - * @property {Parse.Object} original If set, the object, as currently stored. - */ - -/** - * @interface Parse.Cloud.FileTriggerRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.File} file The file that triggered the hook. - * @property {Integer} fileSize The size of the file in bytes. - * @property {Integer} contentLength The value from Content-Length header - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSaveFile`, `afterSaveFile`) - * @property {Object} log The current logger inside Parse Server. - */ - -/** - * @interface Parse.Cloud.ConnectTriggerRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} useMasterKey If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Integer} clients The number of clients connected. - * @property {Integer} subscriptions The number of subscriptions connected. - * @property {String} sessionToken If set, the session of the user that made the request. - */ - -/** - * @interface Parse.Cloud.LiveQueryEventTrigger - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} useMasterKey If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {String} sessionToken If set, the session of the user that made the request. - * @property {String} event The live query event that triggered the request. - * @property {Parse.Object} object The object triggering the hook. - * @property {Parse.Object} original If set, the object, as currently stored. - * @property {Integer} clients The number of clients connected. - * @property {Integer} subscriptions The number of subscriptions connected. - * @property {Boolean} sendEvent If the LiveQuery event should be sent to the client. Set to false to prevent LiveQuery from pushing to the client. - */ - -/** - * @interface Parse.Cloud.BeforeFindRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.Query} query The query triggering the hook. - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) - * @property {Object} log The current logger inside Parse Server. - * @property {Boolean} isGet wether the query a `get` or a `find` - */ - -/** - * @interface Parse.Cloud.AfterFindRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.Query} query The query triggering the hook. - * @property {Array} results The results the query yielded. - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) - * @property {Object} log The current logger inside Parse Server. - */ - -/** - * @interface Parse.Cloud.FunctionRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Object} params The params passed to the cloud function. - */ - -/** - * @interface Parse.Cloud.JobRequest - * @property {Object} params The params passed to the background job. - * @property {function} message If message is called with a string argument, will update the current message to be stored in the job status. - */ - -/** - * @interface Parse.Cloud.ValidatorObject - * @property {Boolean} requireUser whether the cloud trigger requires a user. - * @property {Boolean} requireMaster whether the cloud trigger requires a master key. - * @property {Boolean} validateMasterKey whether the validator should run if masterKey is provided. Defaults to false. - * @property {Boolean} skipWithMasterKey whether the cloud code function should be ignored using a masterKey. - * - * @property {Array|Object} requireUserKeys If set, keys required on request.user to make the request. - * @property {String} requireUserKeys.field If requireUserKeys is an object, name of field to validate on request user - * @property {Array|function|Any} requireUserKeys.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. - * @property {String} requireUserKeys.field.error custom error message if field is invalid. - * - * @property {Object|Array} fields if an array of strings, validator will look for keys in request.params, and throw if not provided. If Object, fields to validate. If the trigger is a cloud function, `request.params` will be validated, otherwise `request.object`. - * @property {String} fields.field name of field to validate. - * @property {String} fields.field.type expected type of data for field. - * @property {Boolean} fields.field.constant whether the field can be modified on the object. - * @property {Any} fields.field.default default value if field is `null`, or initial value `constant` is `true`. - * @property {Array|function|Any} fields.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. - * @property {String} fields.field.error custom error message if field is invalid. - */ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL1BhcnNlLkNsb3VkLmpzIl0sIm5hbWVzIjpbImlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvciIsIm9iamVjdCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImdldENsYXNzTmFtZSIsInBhcnNlQ2xhc3MiLCJjbGFzc05hbWUiLCJQYXJzZUNsb3VkIiwiZGVmaW5lIiwiZnVuY3Rpb25OYW1lIiwiaGFuZGxlciIsInZhbGlkYXRpb25IYW5kbGVyIiwidHJpZ2dlcnMiLCJhZGRGdW5jdGlvbiIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsImpvYiIsImFkZEpvYiIsImJlZm9yZVNhdmUiLCJhZGRUcmlnZ2VyIiwiVHlwZXMiLCJiZWZvcmVEZWxldGUiLCJiZWZvcmVMb2dpbiIsImFyZ3VtZW50cyIsImFmdGVyTG9naW4iLCJhZnRlckxvZ291dCIsImFmdGVyU2F2ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJlZm9yZVNhdmVGaWxlIiwiYWRkRmlsZVRyaWdnZXIiLCJhZnRlclNhdmVGaWxlIiwiYmVmb3JlRGVsZXRlRmlsZSIsImFmdGVyRGVsZXRlRmlsZSIsImJlZm9yZUNvbm5lY3QiLCJhZGRDb25uZWN0VHJpZ2dlciIsImJlZm9yZVN1YnNjcmliZSIsIm9uTGl2ZVF1ZXJ5RXZlbnQiLCJhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIiLCJhZnRlckxpdmVRdWVyeUV2ZW50IiwiYWZ0ZXJFdmVudCIsIl9yZW1vdmVBbGxIb29rcyIsIl91bnJlZ2lzdGVyQWxsIiwidXNlTWFzdGVyS2V5IiwiY29uc29sZSIsIndhcm4iLCJodHRwUmVxdWVzdCIsInJlcXVpcmUiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOzs7Ozs7QUFFQSxTQUFTQSx3QkFBVCxDQUFrQ0MsTUFBbEMsRUFBMEM7QUFDeEMsU0FBTyxPQUFPQSxNQUFQLEtB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QUMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCM0MsVUFBakI7QUFFQTs7Ozs7Ozs7Ozs7OztBQWFBOzs7Ozs7Ozs7Ozs7OztBQWNBOzs7Ozs7Ozs7O0FBVUE7Ozs7Ozs7Ozs7Ozs7O0FBY0E7Ozs7Ozs7Ozs7Ozs7QUFhQTs7Ozs7Ozs7Ozs7OztBQWFBOzs7Ozs7OztBQVFBOzs7Ozs7QUFNQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyB0cmlnZ2VycyBmcm9tICcuLi90cmlnZ2Vycyc7XG5cbmZ1bmN0aW9uIGlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvcihvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ2NsYXNzTmFtZScpO1xufVxuXG5mdW5jdGlvbiBnZXRDbGFzc05hbWUocGFyc2VDbGFzcykge1xuICBpZiAocGFyc2VDbGFzcyAmJiBwYXJzZUNsYXNzLmNsYXNzTmFtZSkge1xuICAgIHJldHVybiBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgfVxuICByZXR1cm4gcGFyc2VDbGFzcztcbn1cblxuLyoqIEBuYW1lc3BhY2VcbiAqIEBuYW1lIFBhcnNlXG4gKiBAZGVzY3JpcHRpb24gVGhlIFBhcnNlIFNESy5cbiAqICBzZWUgW2FwaSBkb2NzXShodHRwczovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvanMvYXBpKSBhbmQgW2d1aWRlXShodHRwczovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvanMvZ3VpZGUpXG4gKi9cblxuLyoqIEBuYW1lc3BhY2VcbiAqIEBuYW1lIFBhcnNlLkNsb3VkXG4gKiBAbWVtYmVyb2YgUGFyc2VcbiAqIEBkZXNjcmlwdGlvbiBUaGUgUGFyc2UgQ2xvdWQgQ29kZSBTREsuXG4gKi9cblxudmFyIFBhcnNlQ2xvdWQgPSB7fTtcbi8qKlxuICogRGVmaW5lcyBhIENsb3VkIEZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuZGVmaW5lKCdmdW5jdGlvbk5hbWUnLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5kZWZpbmUoJ2Z1bmN0aW9uTmFtZScsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICogYGBgXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlcm9mIFBhcnNlLkNsb3VkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgQ2xvdWQgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGRhdGEgVGhlIENsb3VkIEZ1bmN0aW9uIHRvIHJlZ2lzdGVyLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GdW5jdGlvblJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GdW5jdGlvblJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmRlZmluZSA9IGZ1bmN0aW9uIChmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKiBEZWZpbmVzIGEgQmFja2dyb3VuZCBKb2IuXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogQG1ldGhvZCBqb2JcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmpvYlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIEJhY2tncm91bmQgSm9iXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBCYWNrZ3JvdW5kIEpvYiB0byByZWdpc3Rlci4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgc2hvdWxkIHRha2UgYSBzaW5nbGUgcGFyYW1ldGVycyBhIHtAbGluayBQYXJzZS5DbG91ZC5Kb2JSZXF1ZXN0fVxuICpcbiAqL1xuUGFyc2VDbG91ZC5qb2IgPSBmdW5jdGlvbiAoZnVuY3Rpb25OYW1lLCBoYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEpvYihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIHNhdmUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZVNhdmUgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZSgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmUoUGFyc2UuVXNlciwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSlcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlU2F2ZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgc2F2ZSBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBzYXZlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH07XG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVTYXZlID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHZhciBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBkZWxldGUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZURlbGV0ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZSgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZShQYXJzZS5Vc2VyLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KVxuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZURlbGV0ZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBiZWZvcmUgZGVsZXRlIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIGRlbGV0ZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIsIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZURlbGV0ZSA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgdGhlIGJlZm9yZSBsb2dpbiBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHByb3ZpZGVzIGZ1cnRoZXIgY29udHJvbFxuICogaW4gdmFsaWRhdGluZyBhIGxvZ2luIGF0dGVtcHQuIFNwZWNpZmljYWxseSxcbiAqIGl0IGlzIHRyaWdnZXJlZCBhZnRlciBhIHVzZXIgZW50ZXJzXG4gKiBjb3JyZWN0IGNyZWRlbnRpYWxzIChvciBvdGhlciB2YWxpZCBhdXRoRGF0YSksXG4gKiBidXQgcHJpb3IgdG8gYSBzZXNzaW9uIGJlaW5nIGdlbmVyYXRlZC5cbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZUxvZ2luKChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSlcbiAqXG4gKiBgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZUxvZ2luXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVMb2dpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIGxvZ2luLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH07XG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlTG9naW4gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICBsZXQgY2xhc3NOYW1lID0gJ19Vc2VyJztcbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnc3RyaW5nJyB8fCBpc1BhcnNlT2JqZWN0Q29uc3RydWN0b3IoaGFuZGxlcikpIHtcbiAgICAvLyB2YWxpZGF0aW9uIHdpbGwgb2NjdXIgZG93bnN0cmVhbSwgdGhpcyBpcyB0byBtYWludGFpbiBpbnRlcm5hbFxuICAgIC8vIGNvZGUgY29uc2lzdGVuY3kgd2l0aCB0aGUgb3RoZXIgaG9vayB0eXBlcy5cbiAgICBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUoaGFuZGxlcik7XG4gICAgaGFuZGxlciA9IGFyZ3VtZW50c1sxXTtcbiAgfVxuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKHRyaWdnZXJzLlR5cGVzLmJlZm9yZUxvZ2luLCBjbGFzc05hbWUsIGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKlxuICogUmVnaXN0ZXJzIHRoZSBhZnRlciBsb2dpbiBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHRyaWdnZXJlZCBhZnRlciBhIHVzZXIgbG9ncyBpbiBzdWNjZXNzZnVsbHksXG4gKiBhbmQgYWZ0ZXIgYSBfU2Vzc2lvbiBvYmplY3QgaGFzIGJlZW4gY3JlYXRlZC5cbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyTG9naW4oKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJMb2dpblxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGFmdGVyIGEgbG9naW4uIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqL1xuUGFyc2VDbG91ZC5hZnRlckxvZ2luID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgbGV0IGNsYXNzTmFtZSA9ICdfVXNlcic7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycgfHwgaXNQYXJzZU9iamVjdENvbnN0cnVjdG9yKGhhbmRsZXIpKSB7XG4gICAgLy8gdmFsaWRhdGlvbiB3aWxsIG9jY3VyIGRvd25zdHJlYW0sIHRoaXMgaXMgdG8gbWFpbnRhaW4gaW50ZXJuYWxcbiAgICAvLyBjb2RlIGNvbnNpc3RlbmN5IHdpdGggdGhlIG90aGVyIGhvb2sgdHlwZXMuXG4gICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKGhhbmRsZXIpO1xuICAgIGhhbmRsZXIgPSBhcmd1bWVudHNbMV07XG4gIH1cbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcih0cmlnZ2Vycy5UeXBlcy5hZnRlckxvZ2luLCBjbGFzc05hbWUsIGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKlxuICogUmVnaXN0ZXJzIHRoZSBhZnRlciBsb2dvdXQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogVGhpcyBmdW5jdGlvbiBpcyB0cmlnZ2VyZWQgYWZ0ZXIgYSB1c2VyIGxvZ3Mgb3V0LlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dvdXQoKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJMb2dvdXRcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyTG9nb3V0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBsb2dvdXQuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqL1xuUGFyc2VDbG91ZC5hZnRlckxvZ291dCA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gIGxldCBjbGFzc05hbWUgPSAnX1Nlc3Npb24nO1xuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnIHx8IGlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvcihoYW5kbGVyKSkge1xuICAgIC8vIHZhbGlkYXRpb24gd2lsbCBvY2N1ciBkb3duc3RyZWFtLCB0aGlzIGlzIHRvIG1haW50YWluIGludGVybmFsXG4gICAgLy8gY29kZSBjb25zaXN0ZW5jeSB3aXRoIHRoZSBvdGhlciBob29rIHR5cGVzLlxuICAgIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShoYW5kbGVyKTtcbiAgICBoYW5kbGVyID0gYXJndW1lbnRzWzFdO1xuICB9XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIodHJpZ2dlcnMuVHlwZXMuYWZ0ZXJMb2dvdXQsIGNsYXNzTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBhZnRlciBzYXZlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBhZnRlclNhdmUgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgZnVuY3Rpb24ocmVxdWVzdCkge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlclNhdmUoUGFyc2UuVXNlciwgYXN5bmMgZnVuY3Rpb24ocmVxdWVzdCkge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJTYXZlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlclNhdmVcbiAqIEBwYXJhbSB7KFN0cmluZ3xQYXJzZS5PYmplY3QpfSBhcmcxIFRoZSBQYXJzZS5PYmplY3Qgc3ViY2xhc3MgdG8gcmVnaXN0ZXIgdGhlIGFmdGVyIHNhdmUgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBzYXZlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYWZ0ZXJTYXZlID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHZhciBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIGRlbGV0ZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYWZ0ZXJEZWxldGUgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZSgnTXlDdXN0b21DbGFzcycsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlKFBhcnNlLlVzZXIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyRGVsZXRlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgZGVsZXRlIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGFmdGVyIGEgZGVsZXRlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYWZ0ZXJEZWxldGUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckRlbGV0ZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBmaW5kIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBiZWZvcmVGaW5kIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRmluZCgnTXlDdXN0b21DbGFzcycsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZUZpbmQoUGFyc2UuVXNlciwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlRmluZFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlRmluZFxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYmVmb3JlIGZpbmQgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGEgZmluZC4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIGp1c3Qgb25lIHBhcmFtZXRlciwge0BsaW5rIFBhcnNlLkNsb3VkLkJlZm9yZUZpbmRSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuQmVmb3JlRmluZFJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZUZpbmQgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVGaW5kLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIGZpbmQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGFmdGVyRmluZCBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRmluZCgnTXlDdXN0b21DbGFzcycsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRmluZChQYXJzZS5Vc2VyLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlckZpbmRcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyRmluZFxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgZmluZCBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBmaW5kLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuQWZ0ZXJGaW5kUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkFmdGVyRmluZFJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyRmluZCA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBjb25zdCBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIHNhdmUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZVNhdmVGaWxlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVTYXZlRmlsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBzYXZpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVTYXZlRmlsZSA9IGZ1bmN0aW9uIChoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRGaWxlVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTYXZlRmlsZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIHNhdmUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyU2F2ZUZpbGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZUZpbGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBzYXZpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlclNhdmVGaWxlID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZpbGVUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyU2F2ZUZpbGUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBkZWxldGUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVEZWxldGVGaWxlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVEZWxldGVGaWxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGRlbGV0aW5nIGEgZmlsZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIGp1c3Qgb25lIHBhcmFtZXRlciwge0BsaW5rIFBhcnNlLkNsb3VkLkZpbGVUcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkZpbGVUcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlRGVsZXRlRmlsZSA9IGZ1bmN0aW9uIChoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRGaWxlVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVEZWxldGVGaWxlLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgZGVsZXRlIGZpbGUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJEZWxldGVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyRGVsZXRlRmlsZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJEZWxldGVGaWxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhZnRlciBiZWZvcmUgZGVsZXRpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlckRlbGV0ZUZpbGUgPSBmdW5jdGlvbiAoaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkRmlsZVRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJEZWxldGVGaWxlLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgbGl2ZSBxdWVyeSBzZXJ2ZXIgY29ubmVjdCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZUNvbm5lY3QoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlQ29ubmVjdChhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVDb25uZWN0XG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVDb25uZWN0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiZWZvcmUgY29ubmVjdGlvbiBpcyBtYWRlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuQ29ubmVjdFRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuQ29ubmVjdFRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVDb25uZWN0ID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZENvbm5lY3RUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUNvbm5lY3QsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBsaXZlIHF1ZXJ5IHN1YnNjcmlwdGlvbiBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYmVmb3JlU3Vic2NyaWJlIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU3Vic2NyaWJlKCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU3Vic2NyaWJlKFBhcnNlLlVzZXIsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZVN1YnNjcmliZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYmVmb3JlU3Vic2NyaWJlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBiZWZvcmUgc3Vic2NyaXB0aW9uIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIHN1YnNjcmlwdGlvbi4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIsIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZVN1YnNjcmliZSA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZVN1YnNjcmliZSxcbiAgICBjbGFzc05hbWUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG5QYXJzZUNsb3VkLm9uTGl2ZVF1ZXJ5RXZlbnQgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBhZnRlciBsaXZlIHF1ZXJ5IHNlcnZlciBldmVudCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyTGl2ZVF1ZXJ5RXZlbnQoJ015Q3VzdG9tQ2xhc3MnLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlckxpdmVRdWVyeUV2ZW50KCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJMaXZlUXVlcnlFdmVudFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJMaXZlUXVlcnlFdmVudFxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgbGl2ZSBxdWVyeSBldmVudCBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBhIGxpdmUgcXVlcnkgZXZlbnQuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyLCBhIHtAbGluayBQYXJzZS5DbG91ZC5MaXZlUXVlcnlFdmVudFRyaWdnZXJ9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5MaXZlUXVlcnlFdmVudFRyaWdnZXJ9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyTGl2ZVF1ZXJ5RXZlbnQgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgY29uc3QgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRXZlbnQsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuUGFyc2VDbG91ZC5fcmVtb3ZlQWxsSG9va3MgPSAoKSA9PiB7XG4gIHRyaWdnZXJzLl91bnJlZ2lzdGVyQWxsKCk7XG59O1xuXG5QYXJzZUNsb3VkLnVzZU1hc3RlcktleSA9ICgpID0+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIGNvbnNvbGUud2FybihcbiAgICAnUGFyc2UuQ2xvdWQudXNlTWFzdGVyS2V5IGlzIGRlcHJlY2F0ZWQgKGFuZCBoYXMgbm8gZWZmZWN0IGFueW1vcmUpIG9uIHBhcnNlLXNlcnZlciwgcGxlYXNlIHJlZmVyIHRvIHRoZSBjbG91ZCBjb2RlIG1pZ3JhdGlvbiBub3RlczogaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNtYXN0ZXIta2V5LW11c3QtYmUtcGFzc2VkLWV4cGxpY2l0bHknXG4gICk7XG59O1xuXG5QYXJzZUNsb3VkLmh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwUmVxdWVzdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhcnNlQ2xvdWQ7XG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuT2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlYCwgYGFmdGVyU2F2ZWAsIC4uLilcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKiBAcHJvcGVydHkge1BhcnNlLk9iamVjdH0gb3JpZ2luYWwgSWYgc2V0LCB0aGUgb2JqZWN0LCBhcyBjdXJyZW50bHkgc3RvcmVkLlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSBtYXN0ZXIgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1BhcnNlLkZpbGV9IGZpbGUgVGhlIGZpbGUgdGhhdCB0cmlnZ2VyZWQgdGhlIGhvb2suXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IGZpbGVTaXplIFRoZSBzaXplIG9mIHRoZSBmaWxlIGluIGJ5dGVzLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBjb250ZW50TGVuZ3RoIFRoZSB2YWx1ZSBmcm9tIENvbnRlbnQtTGVuZ3RoIGhlYWRlclxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlRmlsZWAsIGBhZnRlclNhdmVGaWxlYClcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLkNvbm5lY3RUcmlnZ2VyUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHVzZU1hc3RlcktleSBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY2xpZW50cyBUaGUgbnVtYmVyIG9mIGNsaWVudHMgY29ubmVjdGVkLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBzdWJzY3JpcHRpb25zIFRoZSBudW1iZXIgb2Ygc3Vic2NyaXB0aW9ucyBjb25uZWN0ZWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gc2Vzc2lvblRva2VuIElmIHNldCwgdGhlIHNlc3Npb24gb2YgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5MaXZlUXVlcnlFdmVudFRyaWdnZXJcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSB1c2VNYXN0ZXJLZXkgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gc2Vzc2lvblRva2VuIElmIHNldCwgdGhlIHNlc3Npb24gb2YgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGV2ZW50IFRoZSBsaXZlIHF1ZXJ5IGV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtQYXJzZS5PYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRyaWdnZXJpbmcgdGhlIGhvb2suXG4gKiBAcHJvcGVydHkge1BhcnNlLk9iamVjdH0gb3JpZ2luYWwgSWYgc2V0LCB0aGUgb2JqZWN0LCBhcyBjdXJyZW50bHkgc3RvcmVkLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBjbGllbnRzIFRoZSBudW1iZXIgb2YgY2xpZW50cyBjb25uZWN0ZWQuXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IHN1YnNjcmlwdGlvbnMgVGhlIG51bWJlciBvZiBzdWJzY3JpcHRpb25zIGNvbm5lY3RlZC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2VuZEV2ZW50IElmIHRoZSBMaXZlUXVlcnkgZXZlbnQgc2hvdWxkIGJlIHNlbnQgdG8gdGhlIGNsaWVudC4gU2V0IHRvIGZhbHNlIHRvIHByZXZlbnQgTGl2ZVF1ZXJ5IGZyb20gcHVzaGluZyB0byB0aGUgY2xpZW50LlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5CZWZvcmVGaW5kUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuUXVlcnl9IHF1ZXJ5IFRoZSBxdWVyeSB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlYCwgYGFmdGVyU2F2ZWAsIC4uLilcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGlzR2V0IHdldGhlciB0aGUgcXVlcnkgYSBgZ2V0YCBvciBhIGBmaW5kYFxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5BZnRlckZpbmRSZXF1ZXN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gbWFzdGVyIElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtQYXJzZS5RdWVyeX0gcXVlcnkgVGhlIHF1ZXJ5IHRyaWdnZXJpbmcgdGhlIGhvb2suXG4gKiBAcHJvcGVydHkge0FycmF5PFBhcnNlLk9iamVjdD59IHJlc3VsdHMgVGhlIHJlc3VsdHMgdGhlIHF1ZXJ5IHlpZWxkZWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaXAgVGhlIElQIGFkZHJlc3Mgb2YgdGhlIGNsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgb3JpZ2luYWwgSFRUUCBoZWFkZXJzIGZvciB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB0cmlnZ2VyTmFtZSBUaGUgbmFtZSBvZiB0aGUgdHJpZ2dlciAoYGJlZm9yZVNhdmVgLCBgYWZ0ZXJTYXZlYCwgLi4uKVxuICogQHByb3BlcnR5IHtPYmplY3R9IGxvZyBUaGUgY3VycmVudCBsb2dnZXIgaW5zaWRlIFBhcnNlIFNlcnZlci5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuRnVuY3Rpb25SZXF1ZXN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gbWFzdGVyIElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IHBhcmFtcyBUaGUgcGFyYW1zIHBhc3NlZCB0byB0aGUgY2xvdWQgZnVuY3Rpb24uXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLkpvYlJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhcmFtcyBwYXNzZWQgdG8gdGhlIGJhY2tncm91bmQgam9iLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gbWVzc2FnZSBJZiBtZXNzYWdlIGlzIGNhbGxlZCB3aXRoIGEgc3RyaW5nIGFyZ3VtZW50LCB3aWxsIHVwZGF0ZSB0aGUgY3VycmVudCBtZXNzYWdlIHRvIGJlIHN0b3JlZCBpbiB0aGUgam9iIHN0YXR1cy5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0XG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHJlcXVpcmVVc2VyIHdoZXRoZXIgdGhlIGNsb3VkIHRyaWdnZXIgcmVxdWlyZXMgYSB1c2VyLlxuICogQHByb3BlcnR5IHtCb29sZWFufSByZXF1aXJlTWFzdGVyIHdoZXRoZXIgdGhlIGNsb3VkIHRyaWdnZXIgcmVxdWlyZXMgYSBtYXN0ZXIga2V5LlxuICogQHByb3BlcnR5IHtCb29sZWFufSB2YWxpZGF0ZU1hc3RlcktleSB3aGV0aGVyIHRoZSB2YWxpZGF0b3Igc2hvdWxkIHJ1biBpZiBtYXN0ZXJLZXkgaXMgcHJvdmlkZWQuIERlZmF1bHRzIHRvIGZhbHNlLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBza2lwV2l0aE1hc3RlcktleSB3aGV0aGVyIHRoZSBjbG91ZCBjb2RlIGZ1bmN0aW9uIHNob3VsZCBiZSBpZ25vcmVkIHVzaW5nIGEgbWFzdGVyS2V5LlxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8U3RyaW5nPnxPYmplY3R9IHJlcXVpcmVVc2VyS2V5cyBJZiBzZXQsIGtleXMgcmVxdWlyZWQgb24gcmVxdWVzdC51c2VyIHRvIG1ha2UgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVxdWlyZVVzZXJLZXlzLmZpZWxkIElmIHJlcXVpcmVVc2VyS2V5cyBpcyBhbiBvYmplY3QsIG5hbWUgb2YgZmllbGQgdG8gdmFsaWRhdGUgb24gcmVxdWVzdCB1c2VyXG4gKiBAcHJvcGVydHkge0FycmF5fGZ1bmN0aW9ufEFueX0gcmVxdWlyZVVzZXJLZXlzLmZpZWxkLm9wdGlvbnMgYXJyYXkgb2Ygb3B0aW9ucyB0aGF0IHRoZSBmaWVsZCBjYW4gYmUsIGZ1bmN0aW9uIHRvIHZhbGlkYXRlIGZpZWxkLCBvciBzaW5nbGUgdmFsdWUuIFRocm93IGFuIGVycm9yIGlmIHZhbHVlIGlzIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVxdWlyZVVzZXJLZXlzLmZpZWxkLmVycm9yIGN1c3RvbSBlcnJvciBtZXNzYWdlIGlmIGZpZWxkIGlzIGludmFsaWQuXG4gKlxuICogQHByb3BlcnR5IHtPYmplY3R8QXJyYXk8U3RyaW5nPn0gZmllbGRzIGlmIGFuIGFycmF5IG9mIHN0cmluZ3MsIHZhbGlkYXRvciB3aWxsIGxvb2sgZm9yIGtleXMgaW4gcmVxdWVzdC5wYXJhbXMsIGFuZCB0aHJvdyBpZiBub3QgcHJvdmlkZWQuIElmIE9iamVjdCwgZmllbGRzIHRvIHZhbGlkYXRlLiBJZiB0aGUgdHJpZ2dlciBpcyBhIGNsb3VkIGZ1bmN0aW9uLCBgcmVxdWVzdC5wYXJhbXNgIHdpbGwgYmUgdmFsaWRhdGVkLCBvdGhlcndpc2UgYHJlcXVlc3Qub2JqZWN0YC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWVsZHMuZmllbGQgbmFtZSBvZiBmaWVsZCB0byB2YWxpZGF0ZS5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWVsZHMuZmllbGQudHlwZSBleHBlY3RlZCB0eXBlIG9mIGRhdGEgZm9yIGZpZWxkLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBmaWVsZHMuZmllbGQuY29uc3RhbnQgd2hldGhlciB0aGUgZmllbGQgY2FuIGJlIG1vZGlmaWVkIG9uIHRoZSBvYmplY3QuXG4gKiBAcHJvcGVydHkge0FueX0gZmllbGRzLmZpZWxkLmRlZmF1bHQgZGVmYXVsdCB2YWx1ZSBpZiBmaWVsZCBpcyBgbnVsbGAsIG9yIGluaXRpYWwgdmFsdWUgYGNvbnN0YW50YCBpcyBgdHJ1ZWAuXG4gKiBAcHJvcGVydHkge0FycmF5fGZ1bmN0aW9ufEFueX0gZmllbGRzLmZpZWxkLm9wdGlvbnMgYXJyYXkgb2Ygb3B0aW9ucyB0aGF0IHRoZSBmaWVsZCBjYW4gYmUsIGZ1bmN0aW9uIHRvIHZhbGlkYXRlIGZpZWxkLCBvciBzaW5nbGUgdmFsdWUuIFRocm93IGFuIGVycm9yIGlmIHZhbHVlIGlzIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZmllbGRzLmZpZWxkLmVycm9yIGN1c3RvbSBlcnJvciBtZXNzYWdlIGlmIGZpZWxkIGlzIGludmFsaWQuXG4gKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cloud-code/httpRequest.js b/lib/cloud-code/httpRequest.js deleted file mode 100644 index 32cf06eb38..0000000000 --- a/lib/cloud-code/httpRequest.js +++ /dev/null @@ -1,192 +0,0 @@ -"use strict"; - -var _HTTPResponse = _interopRequireDefault(require("./HTTPResponse")); - -var _querystring = _interopRequireDefault(require("querystring")); - -var _logger = _interopRequireDefault(require("../logger")); - -var _followRedirects = require("follow-redirects"); - -var _url = require("url"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const clients = { - 'http:': _followRedirects.http, - 'https:': _followRedirects.https -}; - -function makeCallback(resolve, reject) { - return function (response) { - const chunks = []; - response.on('data', chunk => { - chunks.push(chunk); - }); - response.on('end', () => { - const body = Buffer.concat(chunks); - const httpResponse = new _HTTPResponse.default(response, body); // Consider <200 && >= 400 as errors - - if (httpResponse.status < 200 || httpResponse.status >= 400) { - return reject(httpResponse); - } else { - return resolve(httpResponse); - } - }); - response.on('error', reject); - }; -} - -const encodeBody = function ({ - body, - headers = {} -}) { - if (typeof body !== 'object') { - return { - body, - headers - }; - } - - var contentTypeKeys = Object.keys(headers).filter(key => { - return key.match(/content-type/i) != null; - }); - - if (contentTypeKeys.length == 0) { - // no content type - // As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded - body = _querystring.default.stringify(body); - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } else { - /* istanbul ignore next */ - if (contentTypeKeys.length > 1) { - _logger.default.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.'); - } // There maybe many, we'll just take the 1st one - - - var contentType = contentTypeKeys[0]; - - if (headers[contentType].match(/application\/json/i)) { - body = JSON.stringify(body); - } else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) { - body = _querystring.default.stringify(body); - } - } - - return { - body, - headers - }; -}; -/** - * Makes an HTTP Request. - * - * **Available in Cloud Code only.** - * - * By default, Parse.Cloud.httpRequest does not follow redirects caused by HTTP 3xx response codes. You can use the followRedirects option in the {@link Parse.Cloud.HTTPOptions} object to change this behavior. - * - * Sample request: - * ``` - * Parse.Cloud.httpRequest({ - * url: 'http://www.parse.com/' - * }).then(function(httpResponse) { - * // success - * console.log(httpResponse.text); - * },function(httpResponse) { - * // error - * console.error('Request failed with response code ' + httpResponse.status); - * }); - * ``` - * - * @method httpRequest - * @name Parse.Cloud.httpRequest - * @param {Parse.Cloud.HTTPOptions} options The Parse.Cloud.HTTPOptions object that makes the request. - * @return {Promise} A promise that will be resolved with a {@link Parse.Cloud.HTTPResponse} object when the request completes. - */ - - -module.exports = function httpRequest(options) { - let url; - - try { - url = (0, _url.parse)(options.url); - } catch (e) { - return Promise.reject(e); - } - - options = Object.assign(options, encodeBody(options)); // support params options - - if (typeof options.params === 'object') { - options.qs = options.params; - } else if (typeof options.params === 'string') { - options.qs = _querystring.default.parse(options.params); - } - - const client = clients[url.protocol]; - - if (!client) { - return Promise.reject(`Unsupported protocol ${url.protocol}`); - } - - const requestOptions = { - method: options.method, - port: Number(url.port), - path: url.pathname, - hostname: url.hostname, - headers: options.headers, - encoding: null, - followRedirects: options.followRedirects === true - }; - - if (requestOptions.headers) { - Object.keys(requestOptions.headers).forEach(key => { - if (typeof requestOptions.headers[key] === 'undefined') { - delete requestOptions.headers[key]; - } - }); - } - - if (url.search) { - options.qs = Object.assign({}, options.qs, _querystring.default.parse(url.query)); - } - - if (url.auth) { - requestOptions.auth = url.auth; - } - - if (options.qs) { - requestOptions.path += `?${_querystring.default.stringify(options.qs)}`; - } - - if (options.agent) { - requestOptions.agent = options.agent; - } - - return new Promise((resolve, reject) => { - const req = client.request(requestOptions, makeCallback(resolve, reject, options)); - - if (options.body) { - req.write(options.body); - } - - req.on('error', error => { - reject(error); - }); - req.end(); - }); -}; -/** - * @typedef Parse.Cloud.HTTPOptions - * @property {String|Object} body The body of the request. If it is a JSON object, then the Content-Type set in the headers must be application/x-www-form-urlencoded or application/json. You can also set this to a {@link Buffer} object to send raw bytes. If you use a Buffer, you should also set the Content-Type header explicitly to describe what these bytes represent. - * @property {function} error The function that is called when the request fails. It will be passed a Parse.Cloud.HTTPResponse object. - * @property {Boolean} followRedirects Whether to follow redirects caused by HTTP 3xx responses. Defaults to false. - * @property {Object} headers The headers for the request. - * @property {String} method The method of the request. GET, POST, PUT, DELETE, HEAD, and OPTIONS are supported. Will default to GET if not specified. - * @property {String|Object} params The query portion of the url. You can pass a JSON object of key value pairs like params: {q : 'Sean Plott'} or a raw string like params:q=Sean Plott. - * @property {function} success The function that is called when the request successfully completes. It will be passed a Parse.Cloud.HTTPResponse object. - * @property {string} url The url to send the request to. - */ - - -module.exports.encodeBody = encodeBody; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0LmpzIl0sIm5hbWVzIjpbImNsaWVudHMiLCJodHRwIiwiaHR0cHMiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0IiwicmVzcG9uc2UiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsImJvZHkiLCJCdWZmZXIiLCJjb25jYXQiLCJodHRwUmVzcG9uc2UiLCJIVFRQUmVzcG9uc2UiLCJzdGF0dXMiLCJlbmNvZGVCb2R5IiwiaGVhZGVycyIsImNvbnRlbnRUeXBlS2V5cyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJtYXRjaCIsImxlbmd0aCIsInF1ZXJ5c3RyaW5nIiwic3RyaW5naWZ5IiwibG9nIiwiZXJyb3IiLCJjb250ZW50VHlwZSIsIkpTT04iLCJtb2R1bGUiLCJleHBvcnRzIiwiaHR0cFJlcXVlc3QiLCJvcHRpb25zIiwidXJsIiwiZSIsIlByb21pc2UiLCJhc3NpZ24iLCJwYXJhbXMiLCJxcyIsInBhcnNlIiwiY2xpZW50IiwicHJvdG9jb2wiLCJyZXF1ZXN0T3B0aW9ucyIsIm1ldGhvZCIsInBvcnQiLCJOdW1iZXIiLCJwYXRoIiwicGF0aG5hbWUiLCJob3N0bmFtZSIsImVuY29kaW5nIiwiZm9sbG93UmVkaXJlY3RzIiwiZm9yRWFjaCIsInNlYXJjaCIsInF1ZXJ5IiwiYXV0aCIsImFnZW50IiwicmVxIiwicmVxdWVzdCIsIndyaXRlIiwiZW5kIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2QsV0FBU0MscUJBREs7QUFFZCxZQUFVQztBQUZJLENBQWhCOztBQUtBLFNBQVNDLFlBQVQsQ0FBc0JDLE9BQXRCLEVBQStCQyxNQUEvQixFQUF1QztBQUNyQyxTQUFPLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsVUFBTUMsTUFBTSxHQUFHLEVBQWY7QUFDQUQsSUFBQUEsUUFBUSxD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bEI7QUFDRDs7QUFDRGdELElBQUFBLEdBQUcsQ0FBQ25ELEVBQUosQ0FBTyxPQUFQLEVBQWdCcUIsS0FBSyxJQUFJO0FBQ3ZCeEIsTUFBQUEsTUFBTSxDQUFDd0IsS0FBRCxDQUFOO0FBQ0QsS0FGRDtBQUdBOEIsSUFBQUEsR0FBRyxDQUFDRyxHQUFKO0FBQ0QsR0FUTSxDQUFQO0FBVUQsQ0F4REQ7QUEwREE7Ozs7Ozs7Ozs7Ozs7QUFZQTlCLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlaEIsVUFBZixHQUE0QkEsVUFBNUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSFRUUFJlc3BvbnNlIGZyb20gJy4vSFRUUFJlc3BvbnNlJztcbmltcG9ydCBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgbG9nIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBodHRwLCBodHRwcyB9IGZyb20gJ2ZvbGxvdy1yZWRpcmVjdHMnO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICd1cmwnO1xuXG5jb25zdCBjbGllbnRzID0ge1xuICAnaHR0cDonOiBodHRwLFxuICAnaHR0cHM6JzogaHR0cHMsXG59O1xuXG5mdW5jdGlvbiBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICByZXNwb25zZS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICB9KTtcbiAgICByZXNwb25zZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgY29uc3QgYm9keSA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZSA9IG5ldyBIVFRQUmVzcG9uc2UocmVzcG9uc2UsIGJvZHkpO1xuXG4gICAgICAvLyBDb25zaWRlciA8MjAwICYmID49IDQwMCBhcyBlcnJvcnNcbiAgICAgIGlmIChodHRwUmVzcG9uc2Uuc3RhdHVzIDwgMjAwIHx8IGh0dHBSZXNwb25zZS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoaHR0cFJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGh0dHBSZXNwb25zZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzcG9uc2Uub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfTtcbn1cblxuY29uc3QgZW5jb2RlQm9keSA9IGZ1bmN0aW9uICh7IGJvZHksIGhlYWRlcnMgPSB7fSB9KSB7XG4gIGlmICh0eXBlb2YgYm9keSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4geyBib2R5LCBoZWFkZXJzIH07XG4gIH1cbiAgdmFyIGNvbnRlbnRUeXBlS2V5cyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpLmZpbHRlcihrZXkgPT4ge1xuICAgIHJldHVybiBrZXkubWF0Y2goL2NvbnRlbnQtdHlwZS9pKSAhPSBudWxsO1xuICB9KTtcblxuICBpZiAoY29udGVudFR5cGVLZXlzLmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gbm8gY29udGVudCB0eXBlXG4gICAgLy8gIEFzIHBlciBodHRwczovL3BhcnNlLmNvbS9kb2NzL2Nsb3VkY29kZS9ndWlkZSNjbG91ZC1jb2RlLWFkdmFuY2VkLXNlbmRpbmctYS1wb3N0LXJlcXVlc3QgdGhlIGRlZmF1bHQgZW5jb2RpbmcgaXMgc3VwcG9zZWRseSB4LXd3dy1mb3JtLXVybGVuY29kZWRcblxuICAgIGJvZHkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoYm9keSk7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgfSBlbHNlIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmIChjb250ZW50VHlwZUtleXMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nLmVycm9yKCdQYXJzZS5DbG91ZC5odHRwUmVxdWVzdCcsICdtdWx0aXBsZSBjb250ZW50LXR5cGUgaGVhZGVycyBhcmUgc2V0LicpO1xuICAgIH1cbiAgICAvLyBUaGVyZSBtYXliZSBtYW55LCB3ZSdsbCBqdXN0IHRha2UgdGhlIDFzdCBvbmVcbiAgICB2YXIgY29udGVudFR5cGUgPSBjb250ZW50VHlwZUtleXNbMF07XG4gICAgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL2pzb24vaSkpIHtcbiAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShib2R5KTtcbiAgICB9IGVsc2UgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL3gtd3d3LWZvcm0tdXJsZW5jb2RlZC9pKSkge1xuICAgICAgYm9keSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShib2R5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgYm9keSwgaGVhZGVycyB9O1xufTtcblxuLyoqXG4gKiBNYWtlcyBhbiBIVFRQIFJlcXVlc3QuXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogQnkgZGVmYXVsdCwgUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3QgZG9lcyBub3QgZm9sbG93IHJlZGlyZWN0cyBjYXVzZWQgYnkgSFRUUCAzeHggcmVzcG9uc2UgY29kZXMuIFlvdSBjYW4gdXNlIHRoZSBmb2xsb3dSZWRpcmVjdHMgb3B0aW9uIGluIHRoZSB7QGxpbmsgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnN9IG9iamVjdCB0byBjaGFuZ2UgdGhpcyBiZWhhdmlvci5cbiAqXG4gKiBTYW1wbGUgcmVxdWVzdDpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3Qoe1xuICogICB1cmw6ICdodHRwOi8vd3d3LnBhcnNlLmNvbS8nXG4gKiB9KS50aGVuKGZ1bmN0aW9uKGh0dHBSZXNwb25zZSkge1xuICogICAvLyBzdWNjZXNzXG4gKiAgIGNvbnNvbGUubG9nKGh0dHBSZXNwb25zZS50ZXh0KTtcbiAqIH0sZnVuY3Rpb24oaHR0cFJlc3BvbnNlKSB7XG4gKiAgIC8vIGVycm9yXG4gKiAgIGNvbnNvbGUuZXJyb3IoJ1JlcXVlc3QgZmFpbGVkIHdpdGggcmVzcG9uc2UgY29kZSAnICsgaHR0cFJlc3BvbnNlLnN0YXR1cyk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgaHR0cFJlcXVlc3RcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmh0dHBSZXF1ZXN0XG4gKiBAcGFyYW0ge1BhcnNlLkNsb3VkLkhUVFBPcHRpb25zfSBvcHRpb25zIFRoZSBQYXJzZS5DbG91ZC5IVFRQT3B0aW9ucyBvYmplY3QgdGhhdCBtYWtlcyB0aGUgcmVxdWVzdC5cbiAqIEByZXR1cm4ge1Byb21pc2U8UGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlPn0gQSBwcm9taXNlIHRoYXQgd2lsbCBiZSByZXNvbHZlZCB3aXRoIGEge0BsaW5rIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZX0gb2JqZWN0IHdoZW4gdGhlIHJlcXVlc3QgY29tcGxldGVzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGh0dHBSZXF1ZXN0KG9wdGlvbnMpIHtcbiAgbGV0IHVybDtcbiAgdHJ5IHtcbiAgICB1cmwgPSBwYXJzZShvcHRpb25zLnVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XG4gIH1cbiAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgZW5jb2RlQm9keShvcHRpb25zKSk7XG4gIC8vIHN1cHBvcnQgcGFyYW1zIG9wdGlvbnNcbiAgaWYgKHR5cGVvZiBvcHRpb25zLnBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zLnFzID0gb3B0aW9ucy5wYXJhbXM7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMucGFyYW1zID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMucXMgPSBxdWVyeXN0cmluZy5wYXJzZShvcHRpb25zLnBhcmFtcyk7XG4gIH1cbiAgY29uc3QgY2xpZW50ID0gY2xpZW50c1t1cmwucHJvdG9jb2xdO1xuICBpZiAoIWNsaWVudCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJHt1cmwucHJvdG9jb2x9YCk7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgbWV0aG9kOiBvcHRpb25zLm1ldGhvZCxcbiAgICBwb3J0OiBOdW1iZXIodXJsLnBvcnQpLFxuICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICBlbmNvZGluZzogbnVsbCxcbiAgICBmb2xsb3dSZWRpcmVjdHM6IG9wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSB0cnVlLFxuICB9O1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xuICAgIE9iamVjdC5rZXlzKHJlcXVlc3RPcHRpb25zLmhlYWRlcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBkZWxldGUgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGlmICh1cmwuc2VhcmNoKSB7XG4gICAgb3B0aW9ucy5xcyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMucXMsIHF1ZXJ5c3RyaW5nLnBhcnNlKHVybC5xdWVyeSkpO1xuICB9XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIHJlcXVlc3RPcHRpb25zLmF1dGggPSB1cmwuYXV0aDtcbiAgfVxuICBpZiAob3B0aW9ucy5xcykge1xuICAgIHJlcXVlc3RPcHRpb25zLnBhdGggKz0gYD8ke3F1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvcHRpb25zLnFzKX1gO1xuICB9XG4gIGlmIChvcHRpb25zLmFnZW50KSB7XG4gICAgcmVxdWVzdE9wdGlvbnMuYWdlbnQgPSBvcHRpb25zLmFnZW50O1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gY2xpZW50LnJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG9wdGlvbnMpKTtcbiAgICBpZiAob3B0aW9ucy5ib2R5KSB7XG4gICAgICByZXEud3JpdGUob3B0aW9ucy5ib2R5KTtcbiAgICB9XG4gICAgcmVxLm9uKCdlcnJvcicsIGVycm9yID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gICAgcmVxLmVuZCgpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gYm9keSBUaGUgYm9keSBvZiB0aGUgcmVxdWVzdC4gSWYgaXQgaXMgYSBKU09OIG9iamVjdCwgdGhlbiB0aGUgQ29udGVudC1UeXBlIHNldCBpbiB0aGUgaGVhZGVycyBtdXN0IGJlIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCBvciBhcHBsaWNhdGlvbi9qc29uLiBZb3UgY2FuIGFsc28gc2V0IHRoaXMgdG8gYSB7QGxpbmsgQnVmZmVyfSBvYmplY3QgdG8gc2VuZCByYXcgYnl0ZXMuIElmIHlvdSB1c2UgYSBCdWZmZXIsIHlvdSBzaG91bGQgYWxzbyBzZXQgdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgZXhwbGljaXRseSB0byBkZXNjcmliZSB3aGF0IHRoZXNlIGJ5dGVzIHJlcHJlc2VudC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGVycm9yIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IGZhaWxzLiBJdCB3aWxsIGJlIHBhc3NlZCBhIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZSBvYmplY3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGZvbGxvd1JlZGlyZWN0cyBXaGV0aGVyIHRvIGZvbGxvdyByZWRpcmVjdHMgY2F1c2VkIGJ5IEhUVFAgM3h4IHJlc3BvbnNlcy4gRGVmYXVsdHMgdG8gZmFsc2UuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWV0aG9kIFRoZSBtZXRob2Qgb2YgdGhlIHJlcXVlc3QuIEdFVCwgUE9TVCwgUFVULCBERUxFVEUsIEhFQUQsIGFuZCBPUFRJT05TIGFyZSBzdXBwb3J0ZWQuIFdpbGwgZGVmYXVsdCB0byBHRVQgaWYgbm90IHNwZWNpZmllZC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gcGFyYW1zIFRoZSBxdWVyeSBwb3J0aW9uIG9mIHRoZSB1cmwuIFlvdSBjYW4gcGFzcyBhIEpTT04gb2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyBsaWtlIHBhcmFtczoge3EgOiAnU2VhbiBQbG90dCd9IG9yIGEgcmF3IHN0cmluZyBsaWtlIHBhcmFtczpxPVNlYW4gUGxvdHQuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzdWNjZXNzIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXMuIEl0IHdpbGwgYmUgcGFzc2VkIGEgUGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlIG9iamVjdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBzZW5kIHRoZSByZXF1ZXN0IHRvLlxuICovXG5cbm1vZHVsZS5leHBvcnRzLmVuY29kZUJvZHkgPSBlbmNvZGVCb2R5O1xuIl19 \ No newline at end of file diff --git a/lib/cryptoUtils.js b/lib/cryptoUtils.js deleted file mode 100644 index 5267fc1838..0000000000 --- a/lib/cryptoUtils.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.randomHexString = randomHexString; -exports.randomString = randomString; -exports.newObjectId = newObjectId; -exports.newToken = newToken; -exports.md5Hash = md5Hash; - -var _crypto = require("crypto"); - -// Returns a new random hex string of the given even size. -function randomHexString(size) { - if (size === 0) { - throw new Error('Zero-length randomHexString is useless.'); - } - - if (size % 2 !== 0) { - throw new Error('randomHexString size must be divisible by 2.'); - } - - return (0, _crypto.randomBytes)(size / 2).toString('hex'); -} // Returns a new random alphanumeric string of the given size. -// -// Note: to simplify implementation, the result has slight modulo bias, -// because chars length of 62 doesn't divide the number of all bytes -// (256) evenly. Such bias is acceptable for most cases when the output -// length is long enough and doesn't need to be uniform. - - -function randomString(size) { - if (size === 0) { - throw new Error('Zero-length randomString is useless.'); - } - - const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789'; - let objectId = ''; - const bytes = (0, _crypto.randomBytes)(size); - - for (let i = 0; i < bytes.length; ++i) { - objectId += chars[bytes.readUInt8(i) % chars.length]; - } - - return objectId; -} // Returns a new random alphanumeric string suitable for object ID. - - -function newObjectId(size = 10) { - return randomString(size); -} // Returns a new random hex string suitable for secure tokens. - - -function newToken() { - return randomHexString(32); -} - -function md5Hash(string) { - return (0, _crypto.createHash)('md5').update(string).digest('hex'); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jcnlwdG9VdGlscy5qcyJdLCJuYW1lcyI6WyJyYW5kb21IZXhTdHJpbmciLCJzaXplIiwiRXJyb3IiLCJ0b1N0cmluZyIsInJhbmRvbVN0cmluZyIsImNoYXJzIiwib2JqZWN0SWQiLCJieXRlcyIsImkiLCJsZW5ndGgiLCJyZWFkVUludDgiLCJuZXdPYmplY3RJZCIsIm5ld1Rva2VuIiwibWQ1SGFzaCIsInN0cmluZyIsInVwZGF0ZSIsImRpZ2VzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFFQTs7QUFFQTtBQUNPLFNBQVNBLGVBQVQsQ0FBeUJDLElBQXpCLEVBQStDO0FBQ3BELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUseUNBQVYsQ0FBTjtBQUNEOztBQUNELE1BQUlELElBQUksR0FBRyxDQUFQLEtBQWEsQ0FBakIsRUFBb0I7QUFDbEIsVUFBTSxJQUFJQyxLQUFKLENBQVUsOENBQVYsQ0FBTjtBQUNEOztBQUNELFNBQU8seUJBQVlELElBQUksR0FBRyxDQUFuQixFQUFzQkUsUUFBdEIsQ0FBK0IsS0FBL0IsQ0FBUDtBQUNELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNDLFlBQVQsQ0FBc0JILElBQXRCLEVBQTRDO0FBQ2pELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUsc0NBQVYsQ0FBTjtBQUNEOztBQUNELFFBQU1HLEtBQUssR0FBRywrQkFBK0IsNEJBQS9CLEdBQThELFlBQTVFO0FBQ0EsTUFBSUMsUUFBUSxHQUFHLEVBQWY7QUFDQSxRQUFNQyxLQUFLLEdBQUcseUJBQVlOLElBQVosQ0FBZDs7QUFDQSxPQUFLLElBQUlPLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdELEtBQUssQ0FBQ0UsTUFBMUIsRUFBa0MsRUFBRUQsQ0FBcEMsRUFBdUM7QUFDckNGLElBQUFBLFFBQVEsSUFBSUQsS0FBSyxDQUFDRSxLQUFLLENBQUNHLFNBQU4sQ0FBZ0JGLENBQWhCLElBQXFCSCxLQUFLLENBQUNJLE1BQTVCLENBQWpCO0FBQ0Q7O0FBQ0QsU0FBT0gsUUFBUDtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU0ssV0FBVCxDQUFxQlYsSUFBWSxHQUFHLEVBQXBDLEVBQWdEO0FBQ3JELFNBQU9HLFlBQVksQ0FBQ0gsSUFBRCxDQUFuQjtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU1csUUFBVCxHQUE0QjtBQUNqQyxTQUFPWixlQUFlLENBQUMsRUFBRCxDQUF0QjtBQUNEOztBQUVNLFNBQVNhLE9BQVQsQ0FBaUJDLE1BQWpCLEVBQXlDO0FBQzlDLFNBQU8sd0JBQVcsS0FBWCxFQUFrQkMsTUFBbEIsQ0FBeUJELE1BQXpCLEVBQWlDRSxNQUFqQyxDQUF3QyxLQUF4QyxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBAZmxvdyAqL1xuXG5pbXBvcnQgeyByYW5kb21CeXRlcywgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5cbi8vIFJldHVybnMgYSBuZXcgcmFuZG9tIGhleCBzdHJpbmcgb2YgdGhlIGdpdmVuIGV2ZW4gc2l6ZS5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21IZXhTdHJpbmcoc2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHNpemUgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1plcm8tbGVuZ3RoIHJhbmRvbUhleFN0cmluZyBpcyB1c2VsZXNzLicpO1xuICB9XG4gIGlmIChzaXplICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncmFuZG9tSGV4U3RyaW5nIHNpemUgbXVzdCBiZSBkaXZpc2libGUgYnkgMi4nKTtcbiAgfVxuICByZXR1cm4gcmFuZG9tQnl0ZXMoc2l6ZSAvIDIpLnRvU3RyaW5nKCdoZXgnKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBvZiB0aGUgZ2l2ZW4gc2l6ZS5cbi8vXG4vLyBOb3RlOiB0byBzaW1wbGlmeSBpbXBsZW1lbnRhdGlvbiwgdGhlIHJlc3VsdCBoYXMgc2xpZ2h0IG1vZHVsbyBiaWFzLFxuLy8gYmVjYXVzZSBjaGFycyBsZW5ndGggb2YgNjIgZG9lc24ndCBkaXZpZGUgdGhlIG51bWJlciBvZiBhbGwgYnl0ZXNcbi8vICgyNTYpIGV2ZW5seS4gU3VjaCBiaWFzIGlzIGFjY2VwdGFibGUgZm9yIG1vc3QgY2FzZXMgd2hlbiB0aGUgb3V0cHV0XG4vLyBsZW5ndGggaXMgbG9uZyBlbm91Z2ggYW5kIGRvZXNuJ3QgbmVlZCB0byBiZSB1bmlmb3JtLlxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAoc2l6ZSA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignWmVyby1sZW5ndGggcmFuZG9tU3RyaW5nIGlzIHVzZWxlc3MuJyk7XG4gIH1cbiAgY29uc3QgY2hhcnMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVonICsgJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JyArICcwMTIzNDU2Nzg5JztcbiAgbGV0IG9iamVjdElkID0gJyc7XG4gIGNvbnN0IGJ5dGVzID0gcmFuZG9tQnl0ZXMoc2l6ZSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHtcbiAgICBvYmplY3RJZCArPSBjaGFyc1tieXRlcy5yZWFkVUludDgoaSkgJSBjaGFycy5sZW5ndGhdO1xuICB9XG4gIHJldHVybiBvYmplY3RJZDtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBzdWl0YWJsZSBmb3Igb2JqZWN0IElELlxuZXhwb3J0IGZ1bmN0aW9uIG5ld09iamVjdElkKHNpemU6IG51bWJlciA9IDEwKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJhbmRvbVN0cmluZyhzaXplKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gaGV4IHN0cmluZyBzdWl0YWJsZSBmb3Igc2VjdXJlIHRva2Vucy5cbmV4cG9ydCBmdW5jdGlvbiBuZXdUb2tlbigpOiBzdHJpbmcge1xuICByZXR1cm4gcmFuZG9tSGV4U3RyaW5nKDMyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1kNUhhc2goc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKHN0cmluZykuZGlnZXN0KCdoZXgnKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/defaults.js b/lib/defaults.js deleted file mode 100644 index d824d3ba1d..0000000000 --- a/lib/defaults.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.DefaultMongoURI = exports.default = void 0; - -var _parsers = require("./Options/parsers"); - -const { - ParseServerOptions -} = require('./Options/Definitions'); - -const logsFolder = (() => { - let folder = './logs/'; - - if (typeof process !== 'undefined' && process.env.TESTING === '1') { - folder = './test_logs/'; - } - - if (process.env.PARSE_SERVER_LOGS_FOLDER) { - folder = (0, _parsers.nullParser)(process.env.PARSE_SERVER_LOGS_FOLDER); - } - - return folder; -})(); - -const { - verbose, - level -} = (() => { - const verbose = process.env.VERBOSE ? true : false; - return { - verbose, - level: verbose ? 'verbose' : undefined - }; -})(); - -const DefinitionDefaults = Object.keys(ParseServerOptions).reduce((memo, key) => { - const def = ParseServerOptions[key]; - - if (Object.prototype.hasOwnProperty.call(def, 'default')) { - memo[key] = def.default; - } - - return memo; -}, {}); -const computedDefaults = { - jsonLogs: process.env.JSON_LOGS || false, - logsFolder, - verbose, - level -}; - -var _default = Object.assign({}, DefinitionDefaults, computedDefaults); - -exports.default = _default; -const DefaultMongoURI = DefinitionDefaults.databaseURI; -exports.DefaultMongoURI = DefaultMongoURI; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZWZhdWx0cy5qcyJdLCJuYW1lcyI6WyJQYXJzZVNlcnZlck9wdGlvbnMiLCJyZXF1aXJlIiwibG9nc0ZvbGRlciIsImZvbGRlciIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwiUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSIiwidmVyYm9zZSIsImxldmVsIiwiVkVSQk9TRSIsInVuZGVmaW5lZCIsIkRlZmluaXRpb25EZWZhdWx0cyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJtZW1vIiwia2V5IiwiZGVmIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiZGVmYXVsdCIsImNvbXB1dGVkRGVmYXVsdHMiLCJqc29uTG9ncyIsIkpTT05fTE9HUyIsImFzc2lnbiIsIkRlZmF1bHRNb25nb1VSSSIsImRhdGFiYXNlVVJJIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQXlCQyxPQUFPLENBQUMsdUJBQUQsQ0FBdEM7O0FBQ0EsTUFBTUMsVUFBVSxHQUFHLENBQUMsTUFBTTtBQUN4QixNQUFJQyxNQUFNLEdBQUcsU0FBYjs7QUFDQSxNQUFJLE9BQU9DLE9BQVAsS0FBbUIsV0FBbkIsSUFBa0NBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLEtBQXdCLEdBQTlELEVBQW1FO0FBQ2pFSCxJQUFBQSxNQUFNLEdBQUcsY0FBVDtBQUNEOztBQUNELE1BQUlDLE9BQU8sQ0FBQ0MsR0FBUixDQUFZRSx3QkFBaEIsRUFBMEM7QUFDeENKLElBQUFBLE1BQU0sR0FBRyx5QkFBV0MsT0FBTyxDQUFDQyxHQUFSLENBQVlFLHdCQUF2QixDQUFUO0FBQ0Q7O0FBQ0QsU0FBT0osTUFBUDtBQUNELENBVGtCLEdBQW5COztBQVdBLE1BQU07QUFBRUssRUFBQUEsT0FBRjtBQUFXQyxFQUFBQTtBQUFYLElBQXFCLENBQUMsTUFBTTtBQUNoQyxRQUFNRCxPQUFPLEdBQUdKLE9BQU8sQ0FBQ0MsR0FBUixDQUFZSyxPQUFaLEdBQXNCLElBQXRCLEdBQTZCLEtBQTdDO0FBQ0EsU0FBTztBQUFFRixJQUFBQSxPQUFGO0FBQVdDLElBQUFBLEtBQUssRUFBRUQsT0FBTyxHQUFHLFNBQUgsR0FBZUc7QUFBeEMsR0FBUDtBQUNELENBSDBCLEdBQTNCOztBQUtBLE1BQU1DLGtCQUFrQixHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWWQsa0JBQVosRUFBZ0NlLE1BQWhDLENBQXVDLENBQUNDLElBQUQsRUFBT0MsR0FBUCxLQUFlO0FBQy9FLFFBQU1DLEdBQUcsR0FBR2xCLGtCQUFrQixDQUFDaUIsR0FBRCxDQUE5Qjs7QUFDQSxNQUFJSixNQUFNLENBQUNNLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0gsR0FBckMsRUFBMEMsU0FBMUMsQ0FBSixFQUEwRDtBQUN4REYsSUFBQUEsSUFBSSxDQUFDQyxHQUFELENBQUosR0FBWUMsR0FBRyxDQUFDSSxPQUFoQjtBQUNEOztBQUNELFNBQU9OLElBQVA7QUFDRCxDQU4wQixFQU14QixFQU53QixDQUEzQjtBQVFBLE1BQU1PLGdCQUFnQixHQUFHO0FBQ3ZCQyxFQUFBQSxRQUFRLEVBQUVwQixPQUFPLENBQUNDLEdBQVIsQ0FBWW9CLFNBQVosSUFBeUIsS0FEWjtBQUV2QnZCLEVBQUFBLFVBRnVCO0FBR3ZCTSxFQUFBQSxPQUh1QjtBQUl2QkMsRUFBQUE7QUFKdUIsQ0FBekI7O2VBT2VJLE1BQU0sQ0FBQ2EsTUFBUCxDQUFjLEVBQWQsRUFBa0JkLGtCQUFsQixFQUFzQ1csZ0JBQXRDLEM7OztBQUNSLE1BQU1JLGVBQWUsR0FBR2Ysa0JBQWtCLENBQUNnQixXQUEzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG51bGxQYXJzZXIgfSBmcm9tICcuL09wdGlvbnMvcGFyc2Vycyc7XG5jb25zdCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9ID0gcmVxdWlyZSgnLi9PcHRpb25zL0RlZmluaXRpb25zJyk7XG5jb25zdCBsb2dzRm9sZGVyID0gKCgpID0+IHtcbiAgbGV0IGZvbGRlciA9ICcuL2xvZ3MvJztcbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5URVNUSU5HID09PSAnMScpIHtcbiAgICBmb2xkZXIgPSAnLi90ZXN0X2xvZ3MvJztcbiAgfVxuICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSKSB7XG4gICAgZm9sZGVyID0gbnVsbFBhcnNlcihwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfTE9HU19GT0xERVIpO1xuICB9XG4gIHJldHVybiBmb2xkZXI7XG59KSgpO1xuXG5jb25zdCB7IHZlcmJvc2UsIGxldmVsIH0gPSAoKCkgPT4ge1xuICBjb25zdCB2ZXJib3NlID0gcHJvY2Vzcy5lbnYuVkVSQk9TRSA/IHRydWUgOiBmYWxzZTtcbiAgcmV0dXJuIHsgdmVyYm9zZSwgbGV2ZWw6IHZlcmJvc2UgPyAndmVyYm9zZScgOiB1bmRlZmluZWQgfTtcbn0pKCk7XG5cbmNvbnN0IERlZmluaXRpb25EZWZhdWx0cyA9IE9iamVjdC5rZXlzKFBhcnNlU2VydmVyT3B0aW9ucykucmVkdWNlKChtZW1vLCBrZXkpID0+IHtcbiAgY29uc3QgZGVmID0gUGFyc2VTZXJ2ZXJPcHRpb25zW2tleV07XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZGVmLCAnZGVmYXVsdCcpKSB7XG4gICAgbWVtb1trZXldID0gZGVmLmRlZmF1bHQ7XG4gIH1cbiAgcmV0dXJuIG1lbW87XG59LCB7fSk7XG5cbmNvbnN0IGNvbXB1dGVkRGVmYXVsdHMgPSB7XG4gIGpzb25Mb2dzOiBwcm9jZXNzLmVudi5KU09OX0xPR1MgfHwgZmFsc2UsXG4gIGxvZ3NGb2xkZXIsXG4gIHZlcmJvc2UsXG4gIGxldmVsLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgT2JqZWN0LmFzc2lnbih7fSwgRGVmaW5pdGlvbkRlZmF1bHRzLCBjb21wdXRlZERlZmF1bHRzKTtcbmV4cG9ydCBjb25zdCBEZWZhdWx0TW9uZ29VUkkgPSBEZWZpbml0aW9uRGVmYXVsdHMuZGF0YWJhc2VVUkk7XG4iXX0= \ No newline at end of file diff --git a/lib/deprecated.js b/lib/deprecated.js deleted file mode 100644 index ea008a18d6..0000000000 --- a/lib/deprecated.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.useExternal = useExternal; - -function useExternal(name, moduleName) { - return function () { - throw `${name} is not provided by parse-server anymore; please install ${moduleName}`; - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZXByZWNhdGVkLmpzIl0sIm5hbWVzIjpbInVzZUV4dGVybmFsIiwibmFtZSIsIm1vZHVsZU5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxTQUFTQSxXQUFULENBQXFCQyxJQUFyQixFQUEyQkMsVUFBM0IsRUFBdUM7QUFDNUMsU0FBTyxZQUFZO0FBQ2pCLFVBQU8sR0FBRUQsSUFBSyw0REFBMkRDLFVBQVcsRUFBcEY7QUFDRCxHQUZEO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gdXNlRXh0ZXJuYWwobmFtZSwgbW9kdWxlTmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IGAke25hbWV9IGlzIG5vdCBwcm92aWRlZCBieSBwYXJzZS1zZXJ2ZXIgYW55bW9yZTsgcGxlYXNlIGluc3RhbGwgJHttb2R1bGVOYW1lfWA7XG4gIH07XG59XG4iXX0= \ No newline at end of file diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index e34f529164..0000000000 --- a/lib/index.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "S3Adapter", { - enumerable: true, - get: function () { - return _s3FilesAdapter.default; - } -}); -Object.defineProperty(exports, "FileSystemAdapter", { - enumerable: true, - get: function () { - return _fsFilesAdapter.default; - } -}); -Object.defineProperty(exports, "InMemoryCacheAdapter", { - enumerable: true, - get: function () { - return _InMemoryCacheAdapter.default; - } -}); -Object.defineProperty(exports, "NullCacheAdapter", { - enumerable: true, - get: function () { - return _NullCacheAdapter.default; - } -}); -Object.defineProperty(exports, "RedisCacheAdapter", { - enumerable: true, - get: function () { - return _RedisCacheAdapter.default; - } -}); -Object.defineProperty(exports, "LRUCacheAdapter", { - enumerable: true, - get: function () { - return _LRUCache.default; - } -}); -Object.defineProperty(exports, "PushWorker", { - enumerable: true, - get: function () { - return _PushWorker.PushWorker; - } -}); -Object.defineProperty(exports, "ParseGraphQLServer", { - enumerable: true, - get: function () { - return _ParseGraphQLServer.ParseGraphQLServer; - } -}); -exports.TestUtils = exports.ParseServer = exports.GCSAdapter = exports.default = void 0; - -var _ParseServer2 = _interopRequireDefault(require("./ParseServer")); - -var _s3FilesAdapter = _interopRequireDefault(require("@parse/s3-files-adapter")); - -var _fsFilesAdapter = _interopRequireDefault(require("@parse/fs-files-adapter")); - -var _InMemoryCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/InMemoryCacheAdapter")); - -var _NullCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/NullCacheAdapter")); - -var _RedisCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/RedisCacheAdapter")); - -var _LRUCache = _interopRequireDefault(require("./Adapters/Cache/LRUCache.js")); - -var TestUtils = _interopRequireWildcard(require("./TestUtils")); - -exports.TestUtils = TestUtils; - -var _deprecated = require("./deprecated"); - -var _logger = require("./logger"); - -var _PushWorker = require("./Push/PushWorker"); - -var _Options = require("./Options"); - -var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Factory function -const _ParseServer = function (options) { - const server = new _ParseServer2.default(options); - return server.app; -}; // Mount the create liveQueryServer - - -exports.ParseServer = _ParseServer; -_ParseServer.createLiveQueryServer = _ParseServer2.default.createLiveQueryServer; -_ParseServer.start = _ParseServer2.default.start; -const GCSAdapter = (0, _deprecated.useExternal)('GCSAdapter', '@parse/gcs-files-adapter'); -exports.GCSAdapter = GCSAdapter; -Object.defineProperty(module.exports, 'logger', { - get: _logger.getLogger -}); -var _default = _ParseServer2.default; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJfUGFyc2VTZXJ2ZXIiLCJvcHRpb25zIiwic2VydmVyIiwiUGFyc2VTZXJ2ZXIiLCJhcHAiLCJjcmVhdGVMaXZlUXVlcnlTZXJ2ZXIiLCJzdGFydCIsIkdDU0FkYXB0ZXIiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsIm1vZHVsZSIsImV4cG9ydHMiLCJnZXQiLCJnZXRMb2dnZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHLFVBQVVDLE9BQVYsRUFBdUM7QUFDMUQsUUFBTUMsTUFBTSxHQUFHLElBQUlDLHFCQUFKLENBQWdCRixPQUFoQixDQUFmO0FBQ0EsU0FBT0MsTUFBTSxDQUFDRSxHQUFkO0FBQ0QsQ0FIRCxDLENBSUE7Ozs7QUFDQUosWUFBWSxDQUFDSyxxQkFBYixHQUFxQ0Ysc0JBQVlFLHFCQUFqRDtBQUNBTCxZQUFZLENBQUNNLEtBQWIsR0FBcUJILHNCQUFZRyxLQUFqQztBQUVBLE1BQU1DLFVBQVUsR0FBRyw2QkFBWSxZQUFaLEVBQTBCLDBCQUExQixDQUFuQjs7QUFFQUMsTUFBTSxDQUFDQyxjQUFQLENBQXNCQyxNQUFNLENBQUNDLE9BQTdCLEVBQXNDLFFBQXRDLEVBQWdEO0FBQzlDQyxFQUFBQSxHQUFHLEVBQUVDO0FBRHlDLENBQWhEO2VBSWVWLHFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlU2VydmVyIGZyb20gJy4vUGFyc2VTZXJ2ZXInO1xuaW1wb3J0IFMzQWRhcHRlciBmcm9tICdAcGFyc2UvczMtZmlsZXMtYWRhcHRlcic7XG5pbXBvcnQgRmlsZVN5c3RlbUFkYXB0ZXIgZnJvbSAnQHBhcnNlL2ZzLWZpbGVzLWFkYXB0ZXInO1xuaW1wb3J0IEluTWVtb3J5Q2FjaGVBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvQ2FjaGUvSW5NZW1vcnlDYWNoZUFkYXB0ZXInO1xuaW1wb3J0IE51bGxDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBSZWRpc0NhY2hlQWRhcHRlciBmcm9tICcuL0FkYXB0ZXJzL0NhY2hlL1JlZGlzQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBMUlVDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyc7XG5pbXBvcnQgKiBhcyBUZXN0VXRpbHMgZnJvbSAnLi9UZXN0VXRpbHMnO1xuaW1wb3J0IHsgdXNlRXh0ZXJuYWwgfSBmcm9tICcuL2RlcHJlY2F0ZWQnO1xuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgUHVzaFdvcmtlciB9IGZyb20gJy4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxTZXJ2ZXIgfSBmcm9tICcuL0dyYXBoUUwvUGFyc2VHcmFwaFFMU2VydmVyJztcblxuLy8gRmFjdG9yeSBmdW5jdGlvblxuY29uc3QgX1BhcnNlU2VydmVyID0gZnVuY3Rpb24gKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCBzZXJ2ZXIgPSBuZXcgUGFyc2VTZXJ2ZXIob3B0aW9ucyk7XG4gIHJldHVybiBzZXJ2ZXIuYXBwO1xufTtcbi8vIE1vdW50IHRoZSBjcmVhdGUgbGl2ZVF1ZXJ5U2VydmVyXG5fUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyID0gUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyO1xuX1BhcnNlU2VydmVyLnN0YXJ0ID0gUGFyc2VTZXJ2ZXIuc3RhcnQ7XG5cbmNvbnN0IEdDU0FkYXB0ZXIgPSB1c2VFeHRlcm5hbCgnR0NTQWRhcHRlcicsICdAcGFyc2UvZ2NzLWZpbGVzLWFkYXB0ZXInKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbmV4cG9ydCB7XG4gIFMzQWRhcHRlcixcbiAgR0NTQWRhcHRlcixcbiAgRmlsZVN5c3RlbUFkYXB0ZXIsXG4gIEluTWVtb3J5Q2FjaGVBZGFwdGVyLFxuICBOdWxsQ2FjaGVBZGFwdGVyLFxuICBSZWRpc0NhY2hlQWRhcHRlcixcbiAgTFJVQ2FjaGVBZGFwdGVyLFxuICBUZXN0VXRpbHMsXG4gIFB1c2hXb3JrZXIsXG4gIFBhcnNlR3JhcGhRTFNlcnZlcixcbiAgX1BhcnNlU2VydmVyIGFzIFBhcnNlU2VydmVyLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/logger.js b/lib/logger.js deleted file mode 100644 index bd58e6bce9..0000000000 --- a/lib/logger.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.setLogger = setLogger; -exports.getLogger = getLogger; - -var _defaults = _interopRequireDefault(require("./defaults")); - -var _WinstonLoggerAdapter = require("./Adapters/Logger/WinstonLoggerAdapter"); - -var _LoggerController = require("./Controllers/LoggerController"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Used for Separate Live Query Server -function defaultLogger() { - const options = { - logsFolder: _defaults.default.logsFolder, - jsonLogs: _defaults.default.jsonLogs, - verbose: _defaults.default.verbose, - silent: _defaults.default.silent - }; - const adapter = new _WinstonLoggerAdapter.WinstonLoggerAdapter(options); - return new _LoggerController.LoggerController(adapter, null, options); -} - -let logger = defaultLogger(); - -function setLogger(aLogger) { - logger = aLogger; -} - -function getLogger() { - return logger; -} // for: `import logger from './logger'` - - -Object.defineProperty(module.exports, 'default', { - get: getLogger -}); // for: `import { logger } from './logger'` - -Object.defineProperty(module.exports, 'logger', { - get: getLogger -}); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIuanMiXSwibmFtZXMiOlsiZGVmYXVsdExvZ2dlciIsIm9wdGlvbnMiLCJsb2dzRm9sZGVyIiwiZGVmYXVsdHMiLCJqc29uTG9ncyIsInZlcmJvc2UiLCJzaWxlbnQiLCJhZGFwdGVyIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJDb250cm9sbGVyIiwibG9nZ2VyIiwic2V0TG9nZ2VyIiwiYUxvZ2dlciIsImdldExvZ2dlciIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwibW9kdWxlIiwiZXhwb3J0cyIsImdldCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTtBQUNBLFNBQVNBLGFBQVQsR0FBeUI7QUFDdkIsUUFBTUMsT0FBTyxHQUFHO0FBQ2RDLElBQUFBLFVBQVUsRUFBRUMsa0JBQVNELFVBRFA7QUFFZEUsSUFBQUEsUUFBUSxFQUFFRCxrQkFBU0MsUUFGTDtBQUdkQyxJQUFBQSxPQUFPLEVBQUVGLGtCQUFTRSxPQUhKO0FBSWRDLElBQUFBLE1BQU0sRUFBRUgsa0JBQVNHO0FBSkgsR0FBaEI7QUFNQSxRQUFNQyxPQUFPLEdBQUcsSUFBSUMsMENBQUosQ0FBeUJQLE9BQXpCLENBQWhCO0FBQ0EsU0FBTyxJQUFJUSxrQ0FBSixDQUFxQkYsT0FBckIsRUFBOEIsSUFBOUIsRUFBb0NOLE9BQXBDLENBQVA7QUFDRDs7QUFFRCxJQUFJUyxNQUFNLEdBQUdWLGFBQWEsRUFBMUI7O0FBRU8sU0FBU1csU0FBVCxDQUFtQkMsT0FBbkIsRUFBNEI7QUFDakNGLEVBQUFBLE1BQU0sR0FBR0UsT0FBVDtBQUNEOztBQUVNLFNBQVNDLFNBQVQsR0FBcUI7QUFDMUIsU0FBT0gsTUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0FJLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxTQUF0QyxFQUFpRDtBQUMvQ0MsRUFBQUEsR0FBRyxFQUFFTDtBQUQwQyxDQUFqRCxFLENBSUE7O0FBQ0FDLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxRQUF0QyxFQUFnRDtBQUM5Q0MsRUFBQUEsR0FBRyxFQUFFTDtBQUR5QyxDQUFoRCIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCB7IFdpbnN0b25Mb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vQ29udHJvbGxlcnMvTG9nZ2VyQ29udHJvbGxlcic7XG5cbi8vIFVzZWQgZm9yIFNlcGFyYXRlIExpdmUgUXVlcnkgU2VydmVyXG5mdW5jdGlvbiBkZWZhdWx0TG9nZ2VyKCkge1xuICBjb25zdCBvcHRpb25zID0ge1xuICAgIGxvZ3NGb2xkZXI6IGRlZmF1bHRzLmxvZ3NGb2xkZXIsXG4gICAganNvbkxvZ3M6IGRlZmF1bHRzLmpzb25Mb2dzLFxuICAgIHZlcmJvc2U6IGRlZmF1bHRzLnZlcmJvc2UsXG4gICAgc2lsZW50OiBkZWZhdWx0cy5zaWxlbnQsXG4gIH07XG4gIGNvbnN0IGFkYXB0ZXIgPSBuZXcgV2luc3RvbkxvZ2dlckFkYXB0ZXIob3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihhZGFwdGVyLCBudWxsLCBvcHRpb25zKTtcbn1cblxubGV0IGxvZ2dlciA9IGRlZmF1bHRMb2dnZXIoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihhTG9nZ2VyKSB7XG4gIGxvZ2dlciA9IGFMb2dnZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2dnZXIoKSB7XG4gIHJldHVybiBsb2dnZXI7XG59XG5cbi8vIGZvcjogYGltcG9ydCBsb2dnZXIgZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnZGVmYXVsdCcsIHtcbiAgZ2V0OiBnZXRMb2dnZXIsXG59KTtcblxuLy8gZm9yOiBgaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuIl19 \ No newline at end of file diff --git a/lib/middlewares.js b/lib/middlewares.js deleted file mode 100644 index c7d89304d0..0000000000 --- a/lib/middlewares.js +++ /dev/null @@ -1,492 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.handleParseHeaders = handleParseHeaders; -exports.allowCrossDomain = allowCrossDomain; -exports.allowMethodOverride = allowMethodOverride; -exports.handleParseErrors = handleParseErrors; -exports.enforceMasterKeyAccess = enforceMasterKeyAccess; -exports.promiseEnforceMasterKeyAccess = promiseEnforceMasterKeyAccess; -exports.promiseEnsureIdempotency = promiseEnsureIdempotency; -exports.DEFAULT_ALLOWED_HEADERS = void 0; - -var _cache = _interopRequireDefault(require("./cache")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _Auth = _interopRequireDefault(require("./Auth")); - -var _Config = _interopRequireDefault(require("./Config")); - -var _ClientSDK = _interopRequireDefault(require("./ClientSDK")); - -var _logger = _interopRequireDefault(require("./logger")); - -var _rest = _interopRequireDefault(require("./rest")); - -var _MongoStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Mongo/MongoStorageAdapter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control'; -exports.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS; - -const getMountForRequest = function (req) { - const mountPathLength = req.originalUrl.length - req.url.length; - const mountPath = req.originalUrl.slice(0, mountPathLength); - return req.protocol + '://' + req.get('host') + mountPath; -}; // Checks that the request is authorized for this app and checks user -// auth too. -// The bodyparser should run before this middleware. -// Adds info to the request: -// req.config - the Config for this app -// req.auth - the Auth for this request - - -function handleParseHeaders(req, res, next) { - var mount = getMountForRequest(req); - var info = { - appId: req.get('X-Parse-Application-Id'), - sessionToken: req.get('X-Parse-Session-Token'), - masterKey: req.get('X-Parse-Master-Key'), - installationId: req.get('X-Parse-Installation-Id'), - clientKey: req.get('X-Parse-Client-Key'), - javascriptKey: req.get('X-Parse-Javascript-Key'), - dotNetKey: req.get('X-Parse-Windows-Key'), - restAPIKey: req.get('X-Parse-REST-API-Key'), - clientVersion: req.get('X-Parse-Client-Version'), - context: {} - }; - var basicAuth = httpAuth(req); - - if (basicAuth) { - var basicAuthAppId = basicAuth.appId; - - if (_cache.default.get(basicAuthAppId)) { - info.appId = basicAuthAppId; - info.masterKey = basicAuth.masterKey || info.masterKey; - info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey; - } - } - - if (req.body) { - // Unity SDK sends a _noBody key which needs to be removed. - // Unclear at this point if action needs to be taken. - delete req.body._noBody; - } - - var fileViaJSON = false; - - if (!info.appId || !_cache.default.get(info.appId)) { - // See if we can find the app id on the body. - if (req.body instanceof Buffer) { - // The only chance to find the app id is if this is a file - // upload that actually is a JSON body. So try to parse it. - // https://github.com/parse-community/parse-server/issues/6589 - // It is also possible that the client is trying to upload a file but forgot - // to provide x-parse-app-id in header and parse a binary file will fail - try { - req.body = JSON.parse(req.body); - } catch (e) { - return invalidRequest(req, res); - } - - fileViaJSON = true; - } - - if (req.body) { - delete req.body._RevocableSession; - } - - if (req.body && req.body._ApplicationId && _cache.default.get(req.body._ApplicationId) && (!info.masterKey || _cache.default.get(req.body._ApplicationId).masterKey === info.masterKey)) { - info.appId = req.body._ApplicationId; - info.javascriptKey = req.body._JavaScriptKey || ''; - delete req.body._ApplicationId; - delete req.body._JavaScriptKey; // TODO: test that the REST API formats generated by the other - // SDKs are handled ok - - if (req.body._ClientVersion) { - info.clientVersion = req.body._ClientVersion; - delete req.body._ClientVersion; - } - - if (req.body._InstallationId) { - info.installationId = req.body._InstallationId; - delete req.body._InstallationId; - } - - if (req.body._SessionToken) { - info.sessionToken = req.body._SessionToken; - delete req.body._SessionToken; - } - - if (req.body._MasterKey) { - info.masterKey = req.body._MasterKey; - delete req.body._MasterKey; - } - - if (req.body._context && req.body._context instanceof Object) { - info.context = req.body._context; - delete req.body._context; - } - - if (req.body._ContentType) { - req.headers['content-type'] = req.body._ContentType; - delete req.body._ContentType; - } - } else { - return invalidRequest(req, res); - } - } - - if (info.sessionToken && typeof info.sessionToken !== 'string') { - info.sessionToken = info.sessionToken.toString(); - } - - if (info.clientVersion) { - info.clientSDK = _ClientSDK.default.fromString(info.clientVersion); - } - - if (fileViaJSON) { - req.fileData = req.body.fileData; // We need to repopulate req.body with a buffer - - var base64 = req.body.base64; - req.body = Buffer.from(base64, 'base64'); - } - - const clientIp = getClientIp(req); - info.app = _cache.default.get(info.appId); - req.config = _Config.default.get(info.appId, mount); - req.config.headers = req.headers || {}; - req.config.ip = clientIp; - req.info = info; - - if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(clientIp) === -1) { - return invalidRequest(req, res); - } - - var isMaster = info.masterKey === req.config.masterKey; - - if (isMaster) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: true - }); - next(); - return; - } - - var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey; - - if (typeof req.config.readOnlyMasterKey != 'undefined' && req.config.readOnlyMasterKey && isReadOnlyMaster) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: true, - isReadOnly: true - }); - next(); - return; - } // Client keys are not required in parse-server, but if any have been configured in the server, validate them - // to preserve original behavior. - - - const keys = ['clientKey', 'javascriptKey', 'dotNetKey', 'restAPIKey']; - const oneKeyConfigured = keys.some(function (key) { - return req.config[key] !== undefined; - }); - const oneKeyMatches = keys.some(function (key) { - return req.config[key] !== undefined && info[key] === req.config[key]; - }); - - if (oneKeyConfigured && !oneKeyMatches) { - return invalidRequest(req, res); - } - - if (req.url == '/login') { - delete info.sessionToken; - } - - if (req.userFromJWT) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: false, - user: req.userFromJWT - }); - next(); - return; - } - - if (!info.sessionToken) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: false - }); - next(); - return; - } - - return Promise.resolve().then(() => { - // handle the upgradeToRevocableSession path on it's own - if (info.sessionToken && req.url === '/upgradeToRevocableSession' && info.sessionToken.indexOf('r:') != 0) { - return _Auth.default.getAuthForLegacySessionToken({ - config: req.config, - installationId: info.installationId, - sessionToken: info.sessionToken - }); - } else { - return _Auth.default.getAuthForSessionToken({ - config: req.config, - installationId: info.installationId, - sessionToken: info.sessionToken - }); - } - }).then(auth => { - if (auth) { - req.auth = auth; - next(); - } - }).catch(error => { - if (error instanceof _node.default.Error) { - next(error); - return; - } else { - // TODO: Determine the correct error scenario. - req.config.loggerController.error('error getting auth for sessionToken', error); - throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error); - } - }); -} - -function getClientIp(req) { - if (req.headers['x-forwarded-for']) { - // try to get from x-forwared-for if it set (behind reverse proxy) - return req.headers['x-forwarded-for'].split(',')[0]; - } else if (req.connection && req.connection.remoteAddress) { - // no proxy, try getting from connection.remoteAddress - return req.connection.remoteAddress; - } else if (req.socket) { - // try to get it from req.socket - return req.socket.remoteAddress; - } else if (req.connection && req.connection.socket) { - // try to get it form the connection.socket - return req.connection.socket.remoteAddress; - } else { - // if non above, fallback. - return req.ip; - } -} - -function httpAuth(req) { - if (!(req.req || req).headers.authorization) return; - var header = (req.req || req).headers.authorization; - var appId, masterKey, javascriptKey; // parse header - - var authPrefix = 'basic '; - var match = header.toLowerCase().indexOf(authPrefix); - - if (match == 0) { - var encodedAuth = header.substring(authPrefix.length, header.length); - var credentials = decodeBase64(encodedAuth).split(':'); - - if (credentials.length == 2) { - appId = credentials[0]; - var key = credentials[1]; - var jsKeyPrefix = 'javascript-key='; - var matchKey = key.indexOf(jsKeyPrefix); - - if (matchKey == 0) { - javascriptKey = key.substring(jsKeyPrefix.length, key.length); - } else { - masterKey = key; - } - } - } - - return { - appId: appId, - masterKey: masterKey, - javascriptKey: javascriptKey - }; -} - -function decodeBase64(str) { - return Buffer.from(str, 'base64').toString(); -} - -function allowCrossDomain(appId) { - return (req, res, next) => { - const config = _Config.default.get(appId, getMountForRequest(req)); - - let allowHeaders = DEFAULT_ALLOWED_HEADERS; - - if (config && config.allowHeaders) { - allowHeaders += `, ${config.allowHeaders.join(', ')}`; - } - - const allowOrigin = config && config.allowOrigin || '*'; - res.header('Access-Control-Allow-Origin', allowOrigin); - res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); - res.header('Access-Control-Allow-Headers', allowHeaders); - res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id'); // intercept OPTIONS method - - if ('OPTIONS' == req.method) { - res.sendStatus(200); - } else { - next(); - } - }; -} - -function allowMethodOverride(req, res, next) { - if (req.method === 'POST' && req.body._method) { - req.originalMethod = req.method; - req.method = req.body._method; - delete req.body._method; - } - - next(); -} - -function handleParseErrors(err, req, res, next) { - const log = req.config && req.config.loggerController || _logger.default; - - if (err instanceof _node.default.Error) { - if (req.config && req.config.enableExpressErrorHandler) { - return next(err); - } - - let httpStatus; // TODO: fill out this mapping - - switch (err.code) { - case _node.default.Error.INTERNAL_SERVER_ERROR: - httpStatus = 500; - break; - - case _node.default.Error.OBJECT_NOT_FOUND: - httpStatus = 404; - break; - - default: - httpStatus = 400; - } - - res.status(httpStatus); - res.json({ - code: err.code, - error: err.message - }); - log.error('Parse error: ', err); - } else if (err.status && err.message) { - res.status(err.status); - res.json({ - error: err.message - }); - - if (!(process && process.env.TESTING)) { - next(err); - } - } else { - log.error('Uncaught internal server error.', err, err.stack); - res.status(500); - res.json({ - code: _node.default.Error.INTERNAL_SERVER_ERROR, - message: 'Internal server error.' - }); - - if (!(process && process.env.TESTING)) { - next(err); - } - } -} - -function enforceMasterKeyAccess(req, res, next) { - if (!req.auth.isMaster) { - res.status(403); - res.end('{"error":"unauthorized: master key is required"}'); - return; - } - - next(); -} - -function promiseEnforceMasterKeyAccess(request) { - if (!request.auth.isMaster) { - const error = new Error(); - error.status = 403; - error.message = 'unauthorized: master key is required'; - throw error; - } - - return Promise.resolve(); -} -/** - * Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID - * in the request header. If a request has no request ID, it is executed anyway. - * @param {*} req The request to evaluate. - * @returns Promise<{}> - */ - - -function promiseEnsureIdempotency(req) { - // Enable feature only for MongoDB - if (!(req.config.database.adapter instanceof _MongoStorageAdapter.default)) { - return Promise.resolve(); - } // Get parameters - - - const config = req.config; - const requestId = ((req || {}).headers || {})['x-parse-request-id']; - const { - paths, - ttl - } = config.idempotencyOptions; - - if (!requestId || !config.idempotencyOptions) { - return Promise.resolve(); - } // Request path may contain trailing slashes, depending on the original request, so remove - // leading and trailing slashes to make it easier to specify paths in the configuration - - - const reqPath = req.path.replace(/^\/|\/$/, ''); // Determine whether idempotency is enabled for current request path - - let match = false; - - for (const path of paths) { - // Assume one wants a path to always match from the beginning to prevent any mistakes - const regex = new RegExp(path.charAt(0) === '^' ? path : '^' + path); - - if (reqPath.match(regex)) { - match = true; - break; - } - } - - if (!match) { - return Promise.resolve(); - } // Try to store request - - - const expiryDate = new Date(new Date().setSeconds(new Date().getSeconds() + ttl)); - return _rest.default.create(config, _Auth.default.master(config), '_Idempotency', { - reqId: requestId, - expire: _node.default._encode(expiryDate) - }).catch(e => { - if (e.code == _node.default.Error.DUPLICATE_VALUE) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_REQUEST, 'Duplicate request'); - } - - throw e; - }); -} - -function invalidRequest(req, res) { - res.status(403); - res.end('{"error":"unauthorized"}'); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlcy5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0FMTE9XRURfSEVBREVSUyIsImdldE1vdW50Rm9yUmVxdWVzdCIsInJlcSIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJwcm90b2NvbCIsImdldCIsImhhbmRsZVBhcnNlSGVhZGVycyIsInJlcyIsIm5leHQiLCJtb3VudCIsImluZm8iLCJhcHBJZCIsInNlc3Npb25Ub2tlbiIsIm1hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiY29udGV4dCIsImJhc2ljQXV0aCIsImh0dHBBdXRoIiwiYmFzaWNBdXRoQXBwSWQiLCJBcHBDYWNoZSIsImJvZHkiLCJfbm9Cb2R5IiwiZmlsZVZpYUpTT04iLCJCdWZmZXIiLCJKU09OIiwicGFyc2UiLCJlIiwiaW52YWxpZFJlcXVlc3QiLCJfUmV2b2NhYmxlU2Vzc2lvbiIsIl9BcHBsaWNhdGlvbklkIiwiX0phdmFTY3JpcHRLZXkiLCJfQ2xpZW50VmVyc2lvbiIsIl9JbnN0YWxsYXRpb25JZCIsIl9TZXNzaW9uVG9rZW4iLCJfTWFzdGVyS2V5IiwiX2NvbnRleHQiLCJPYmplY3QiLCJfQ29udGVudFR5cGUiLCJoZWFkZXJzIiwidG9TdHJpbmciLCJjbGllbnRTREsiLCJDbGllbnRTREsiLCJmcm9tU3RyaW5nIiwiZmlsZURhdGEiLCJiYXNlNjQiLCJmcm9tIiwiY2xpZW50SXAiLCJnZXRDbGllbnRJcCIsImFwcCIsImNvbmZpZyIsIkNvbmZpZyIsImlwIiwibWFzdGVyS2V5SXBzIiwiaW5kZXhPZiIsImlzTWFzdGVyIiwiYXV0aCIsIkF1dGgiLCJpc1JlYWRPbmx5TWFzdGVyIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJpc1JlYWRPbmx5Iiwia2V5cyIsIm9uZUtleUNvbmZpZ3VyZWQiLCJzb21lIiwia2V5IiwidW5kZWZpbmVkIiwib25lS2V5TWF0Y2hlcyIsInVzZXJGcm9tSldUIiwidXNlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4iLCJnZXRBdXRoRm9yU2Vzc2lvblRva2VuIiwiY2F0Y2giLCJlcnJvciIsIlBhcnNlIiwiRXJyb3IiLCJsb2dnZXJDb250cm9sbGVyIiwiVU5LTk9XTl9FUlJPUiIsInNwbGl0IiwiY29ubmVjdGlvbiIsInJlbW90ZUFkZHJlc3MiLCJzb2NrZXQiLCJhdXRob3JpemF0aW9uIiwiaGVhZGVyIiwiYXV0aFByZWZpeCIsIm1hdGNoIiwidG9Mb3dlckNhc2UiLCJlbmNvZGVkQXV0aCIsInN1YnN0cmluZyIsImNyZWRlbnRpYWxzIiwiZGVjb2RlQmFzZTY0IiwianNLZXlQcmVmaXgiLCJtYXRjaEtleSIsInN0ciIsImFsbG93Q3Jvc3NEb21haW4iLCJhbGxvd0hlYWRlcnMiLCJqb2luIiwiYWxsb3dPcmlnaW4iLCJtZXRob2QiLCJzZW5kU3RhdHVzIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsIl9tZXRob2QiLCJvcmlnaW5hbE1ldGhvZCIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZXJyIiwibG9nIiwiZGVmYXVsdExvZ2dlciIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJodHRwU3RhdHVzIiwiY29kZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJzdGF0dXMiLCJqc29uIiwibWVzc2FnZSIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwic3RhY2siLCJlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiZW5kIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXF1ZXN0IiwicHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IiwiZGF0YWJhc2UiLCJhZGFwdGVyIiwiTW9uZ29TdG9yYWdlQWRhcHRlciIsInJlcXVlc3RJZCIsInBhdGhzIiwidHRsIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwicmVxUGF0aCIsInBhdGgiLCJyZXBsYWNlIiwicmVnZXgiLCJSZWdFeHAiLCJjaGFyQXQiLCJleHBpcnlEYXRlIiwiRGF0ZSIsInNldFNlY29uZHMiLCJnZXRTZWNvbmRzIiwicmVzdCIsImNyZWF0ZSIsIm1hc3RlciIsInJlcUlkIiwiZXhwaXJlIiwiX2VuY29kZSIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsdUJBQXVCLEdBQ2xDLCtPQURLOzs7QUFHUCxNQUFNQyxrQkFBa0IsR0FBRyxVQUFVQyxHQUFWLEVBQWU7QUFDeEMsUUFBTUMsZUFBZSxHQUFHRCxHQUFHLENBQUNFLFdBQUosQ0FBZ0JDLE1BQWhCLEdBQXlCSCxHQUFHLENBQUNJLEdBQUosQ0FBUUQsTUFBekQ7QUFDQSxRQUFNRSxTQUFTLEdBQUdMLEdBQUcsQ0FBQ0UsV0FBSixDQUFnQkksS0FBaEIsQ0FBc0IsQ0FBdEIsRUFBeUJMLGVBQXpCLENBQWxCO0FBQ0EsU0FBT0QsR0FBRyxDQUFDTyxRQUFKLEdBQWUsS0FBZixHQUF1QlAsR0FBRyxDQUFDUSxHQUFKLENBQVEsTUFBUixDQUF2QixHQUF5Q0gsU0FBaEQ7QUFDRCxDQUpELEMsQ0FNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNJLGtCQUFULENBQTRCVCxHQUE1QixFQUFpQ1UsR0FBakMsRUFBc0NDLElBQXRDLEVBQTRDO0FBQ2pELE1BQUlDLEtBQUssR0FBR2Isa0JBQWtCLENBQUNDLEdBQUQsQ0FBOUI7QUFFQSxNQUFJYSxJQUFJLEdBQUc7QUFDVEMsSUFBQUEsS0FBSyxFQUFFZCxHQUFHLENBQUNRLEdBQUosQ0FBUSx3QkFBUixDQURFO0FBRVRPLElBQUFBLFlBQVksRUFBRWYsR0FBRyxDQUFDUSxH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aGUnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGF1dGggZnJvbSAnLi9BdXRoJztcbmltcG9ydCBDb25maWcgZnJvbSAnLi9Db25maWcnO1xuaW1wb3J0IENsaWVudFNESyBmcm9tICcuL0NsaWVudFNESyc7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuL3Jlc3QnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXInO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9BTExPV0VEX0hFQURFUlMgPVxuICAnWC1QYXJzZS1NYXN0ZXItS2V5LCBYLVBhcnNlLVJFU1QtQVBJLUtleSwgWC1QYXJzZS1KYXZhc2NyaXB0LUtleSwgWC1QYXJzZS1BcHBsaWNhdGlvbi1JZCwgWC1QYXJzZS1DbGllbnQtVmVyc2lvbiwgWC1QYXJzZS1TZXNzaW9uLVRva2VuLCBYLVJlcXVlc3RlZC1XaXRoLCBYLVBhcnNlLVJldm9jYWJsZS1TZXNzaW9uLCBYLVBhcnNlLVJlcXVlc3QtSWQsIENvbnRlbnQtVHlwZSwgUHJhZ21hLCBDYWNoZS1Db250cm9sJztcblxuY29uc3QgZ2V0TW91bnRGb3JSZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcSkge1xuICBjb25zdCBtb3VudFBhdGhMZW5ndGggPSByZXEub3JpZ2luYWxVcmwubGVuZ3RoIC0gcmVxLnVybC5sZW5ndGg7XG4gIGNvbnN0IG1vdW50UGF0aCA9IHJlcS5vcmlnaW5hbFVybC5zbGljZSgwLCBtb3VudFBhdGhMZW5ndGgpO1xuICByZXR1cm4gcmVxLnByb3RvY29sICsgJzovLycgKyByZXEuZ2V0KCdob3N0JykgKyBtb3VudFBhdGg7XG59O1xuXG4vLyBDaGVja3MgdGhhdCB0aGUgcmVxdWVzdCBpcyBhdXRob3JpemVkIGZvciB0aGlzIGFwcCBhbmQgY2hlY2tzIHVzZXJcbi8vIGF1dGggdG9vLlxuLy8gVGhlIGJvZHlwYXJzZXIgc2hvdWxkIHJ1biBiZWZvcmUgdGhpcyBtaWRkbGV3YXJlLlxuLy8gQWRkcyBpbmZvIHRvIHRoZSByZXF1ZXN0OlxuLy8gcmVxLmNvbmZpZyAtIHRoZSBDb25maWcgZm9yIHRoaXMgYXBwXG4vLyByZXEuYXV0aCAtIHRoZSBBdXRoIGZvciB0aGlzIHJlcXVlc3RcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXJzZUhlYWRlcnMocmVxLCByZXMsIG5leHQpIHtcbiAgdmFyIG1vdW50ID0gZ2V0TW91bnRGb3JSZXF1ZXN0KHJlcSk7XG5cbiAgdmFyIGluZm8gPSB7XG4gICAgYXBwSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnKSxcbiAgICBzZXNzaW9uVG9rZW46IHJlcS5nZXQoJ1gtUGFyc2UtU2Vzc2lvbi1Ub2tlbicpLFxuICAgIG1hc3RlcktleTogcmVxLmdldCgnWC1QYXJzZS1NYXN0ZXItS2V5JyksXG4gICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtSW5zdGFsbGF0aW9uLUlkJyksXG4gICAgY2xpZW50S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1LZXknKSxcbiAgICBqYXZhc2NyaXB0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUphdmFzY3JpcHQtS2V5JyksXG4gICAgZG90TmV0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLVdpbmRvd3MtS2V5JyksXG4gICAgcmVzdEFQSUtleTogcmVxLmdldCgnWC1QYXJzZS1SRVNULUFQSS1LZXknKSxcbiAgICBjbGllbnRWZXJzaW9uOiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1WZXJzaW9uJyksXG4gICAgY29udGV4dDoge30sXG4gIH07XG5cbiAgdmFyIGJhc2ljQXV0aCA9IGh0dHBBdXRoKHJlcSk7XG5cbiAgaWYgKGJhc2ljQXV0aCkge1xuICAgIHZhciBiYXNpY0F1dGhBcHBJZCA9IGJhc2ljQXV0aC5hcHBJZDtcbiAgICBpZiAoQXBwQ2FjaGUuZ2V0KGJhc2ljQXV0aEFwcElkKSkge1xuICAgICAgaW5mby5hcHBJZCA9IGJhc2ljQXV0aEFwcElkO1xuICAgICAgaW5mby5tYXN0ZXJLZXkgPSBiYXNpY0F1dGgubWFzdGVyS2V5IHx8IGluZm8ubWFzdGVyS2V5O1xuICAgICAgaW5mby5qYXZhc2NyaXB0S2V5ID0gYmFzaWNBdXRoLmphdmFzY3JpcHRLZXkgfHwgaW5mby5qYXZhc2NyaXB0S2V5O1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXEuYm9keSkge1xuICAgIC8vIFVuaXR5IFNESyBzZW5kcyBhIF9ub0JvZHkga2V5IHdoaWNoIG5lZWRzIHRvIGJlIHJlbW92ZWQuXG4gICAgLy8gVW5jbGVhciBhdCB0aGlzIHBvaW50IGlmIGFjdGlvbiBuZWVkcyB0byBiZSB0YWtlbi5cbiAgICBkZWxldGUgcmVxLmJvZHkuX25vQm9keTtcbiAgfVxuXG4gIHZhciBmaWxlVmlhSlNPTiA9IGZhbHNlO1xuXG4gIGlmICghaW5mby5hcHBJZCB8fCAhQXBwQ2FjaGUuZ2V0KGluZm8uYXBwSWQpKSB7XG4gICAgLy8gU2VlIGlmIHdlIGNhbiBmaW5kIHRoZSBhcHAgaWQgb24gdGhlIGJvZHkuXG4gICAgaWYgKHJlcS5ib2R5IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAvLyBUaGUgb25seSBjaGFuY2UgdG8gZmluZCB0aGUgYXBwIGlkIGlzIGlmIHRoaXMgaXMgYSBmaWxlXG4gICAgICAvLyB1cGxvYWQgdGhhdCBhY3R1YWxseSBpcyBhIEpTT04gYm9keS4gU28gdHJ5IHRvIHBhcnNlIGl0LlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BhcnNlLWNvbW11bml0eS9wYXJzZS1zZXJ2ZXIvaXNzdWVzLzY1ODlcbiAgICAgIC8vIEl0IGlzIGFsc28gcG9zc2libGUgdGhhdCB0aGUgY2xpZW50IGlzIHRyeWluZyB0byB1cGxvYWQgYSBmaWxlIGJ1dCBmb3Jnb3RcbiAgICAgIC8vIHRvIHByb3ZpZGUgeC1wYXJzZS1hcHAtaWQgaW4gaGVhZGVyIGFuZCBwYXJzZSBhIGJpbmFyeSBmaWxlIHdpbGwgZmFpbFxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVxLmJvZHkgPSBKU09OLnBhcnNlKHJlcS5ib2R5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgICAgIH1cbiAgICAgIGZpbGVWaWFKU09OID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocmVxLmJvZHkpIHtcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fUmV2b2NhYmxlU2Vzc2lvbjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICByZXEuYm9keSAmJlxuICAgICAgcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQgJiZcbiAgICAgIEFwcENhY2hlLmdldChyZXEuYm9keS5fQXBwbGljYXRpb25JZCkgJiZcbiAgICAgICghaW5mby5tYXN0ZXJLZXkgfHwgQXBwQ2FjaGUuZ2V0KHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkKS5tYXN0ZXJLZXkgPT09IGluZm8ubWFzdGVyS2V5KVxuICAgICkge1xuICAgICAgaW5mby5hcHBJZCA9IHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkO1xuICAgICAgaW5mby5qYXZhc2NyaXB0S2V5ID0gcmVxLmJvZHkuX0phdmFTY3JpcHRLZXkgfHwgJyc7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQ7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX0phdmFTY3JpcHRLZXk7XG4gICAgICAvLyBUT0RPOiB0ZXN0IHRoYXQgdGhlIFJFU1QgQVBJIGZvcm1hdHMgZ2VuZXJhdGVkIGJ5IHRoZSBvdGhlclxuICAgICAgLy8gU0RLcyBhcmUgaGFuZGxlZCBva1xuICAgICAgaWYgKHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uKSB7XG4gICAgICAgIGluZm8uY2xpZW50VmVyc2lvbiA9IHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0NsaWVudFZlcnNpb247XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX0luc3RhbGxhdGlvbklkKSB7XG4gICAgICAgIGluZm8uaW5zdGFsbGF0aW9uSWQgPSByZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQ7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQ7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX1Nlc3Npb25Ub2tlbikge1xuICAgICAgICBpbmZvLnNlc3Npb25Ub2tlbiA9IHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW47XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fU2Vzc2lvblRva2VuO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9NYXN0ZXJLZXkpIHtcbiAgICAgICAgaW5mby5tYXN0ZXJLZXkgPSByZXEuYm9keS5fTWFzdGVyS2V5O1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX01hc3RlcktleTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fY29udGV4dCAmJiByZXEuYm9keS5fY29udGV4dCBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICBpbmZvLmNvbnRleHQgPSByZXEuYm9keS5fY29udGV4dDtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9jb250ZXh0O1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9Db250ZW50VHlwZSkge1xuICAgICAgICByZXEuaGVhZGVyc1snY29udGVudC10eXBlJ10gPSByZXEuYm9keS5fQ29udGVudFR5cGU7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fQ29udGVudFR5cGU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZm8uc2Vzc2lvblRva2VuICYmIHR5cGVvZiBpbmZvLnNlc3Npb25Ub2tlbiAhPT0gJ3N0cmluZycpIHtcbiAgICBpbmZvLnNlc3Npb25Ub2tlbiA9IGluZm8uc2Vzc2lvblRva2VuLnRvU3RyaW5nKCk7XG4gIH1cblxuICBpZiAoaW5mby5jbGllbnRWZXJzaW9uKSB7XG4gICAgaW5mby5jbGllbnRTREsgPSBDbGllbnRTREsuZnJvbVN0cmluZyhpbmZvLmNsaWVudFZlcnNpb24pO1xuICB9XG5cbiAgaWYgKGZpbGVWaWFKU09OKSB7XG4gICAgcmVxLmZpbGVEYXRhID0gcmVxLmJvZHkuZmlsZURhdGE7XG4gICAgLy8gV2UgbmVlZCB0byByZXBvcHVsYXRlIHJlcS5ib2R5IHdpdGggYSBidWZmZXJcbiAgICB2YXIgYmFzZTY0ID0gcmVxLmJvZHkuYmFzZTY0O1xuICAgIHJlcS5ib2R5ID0gQnVmZmVyLmZyb20oYmFzZTY0LCAnYmFzZTY0Jyk7XG4gIH1cblxuICBjb25zdCBjbGllbnRJcCA9IGdldENsaWVudElwKHJlcSk7XG5cbiAgaW5mby5hcHAgPSBBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCk7XG4gIHJlcS5jb25maWcgPSBDb25maWcuZ2V0KGluZm8uYXBwSWQsIG1vdW50KTtcbiAgcmVxLmNvbmZpZy5oZWFkZXJzID0gcmVxLmhlYWRlcnMgfHwge307XG4gIHJlcS5jb25maWcuaXAgPSBjbGllbnRJcDtcbiAgcmVxLmluZm8gPSBpbmZvO1xuXG4gIGlmIChcbiAgICBpbmZvLm1hc3RlcktleSAmJlxuICAgIHJlcS5jb25maWcubWFzdGVyS2V5SXBzICYmXG4gICAgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMubGVuZ3RoICE9PSAwICYmXG4gICAgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMuaW5kZXhPZihjbGllbnRJcCkgPT09IC0xXG4gICkge1xuICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gIH1cblxuICB2YXIgaXNNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gcmVxLmNvbmZpZy5tYXN0ZXJLZXk7XG5cbiAgaWYgKGlzTWFzdGVyKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IHRydWUsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBpc1JlYWRPbmx5TWFzdGVyID0gaW5mby5tYXN0ZXJLZXkgPT09IHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXk7XG4gIGlmIChcbiAgICB0eXBlb2YgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAhPSAndW5kZWZpbmVkJyAmJlxuICAgIHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXkgJiZcbiAgICBpc1JlYWRPbmx5TWFzdGVyXG4gICkge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiB0cnVlLFxuICAgICAgaXNSZWFkT25seTogdHJ1ZSxcbiAgICB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQ2xpZW50IGtleXMgYXJlIG5vdCByZXF1aXJlZCBpbiBwYXJzZS1zZXJ2ZXIsIGJ1dCBpZiBhbnkgaGF2ZSBiZWVuIGNvbmZpZ3VyZWQgaW4gdGhlIHNlcnZlciwgdmFsaWRhdGUgdGhlbVxuICAvLyAgdG8gcHJlc2VydmUgb3JpZ2luYWwgYmVoYXZpb3IuXG4gIGNvbnN0IGtleXMgPSBbJ2NsaWVudEtleScsICdqYXZhc2NyaXB0S2V5JywgJ2RvdE5ldEtleScsICdyZXN0QVBJS2V5J107XG4gIGNvbnN0IG9uZUtleUNvbmZpZ3VyZWQgPSBrZXlzLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZDtcbiAgfSk7XG4gIGNvbnN0IG9uZUtleU1hdGNoZXMgPSBrZXlzLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZCAmJiBpbmZvW2tleV0gPT09IHJlcS5jb25maWdba2V5XTtcbiAgfSk7XG5cbiAgaWYgKG9uZUtleUNvbmZpZ3VyZWQgJiYgIW9uZUtleU1hdGNoZXMpIHtcbiAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICB9XG5cbiAgaWYgKHJlcS51cmwgPT0gJy9sb2dpbicpIHtcbiAgICBkZWxldGUgaW5mby5zZXNzaW9uVG9rZW47XG4gIH1cblxuICBpZiAocmVxLnVzZXJGcm9tSldUKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgdXNlcjogcmVxLnVzZXJGcm9tSldULFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIWluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyBoYW5kbGUgdGhlIHVwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24gcGF0aCBvbiBpdCdzIG93blxuICAgICAgaWYgKFxuICAgICAgICBpbmZvLnNlc3Npb25Ub2tlbiAmJlxuICAgICAgICByZXEudXJsID09PSAnL3VwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24nICYmXG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuLmluZGV4T2YoJ3I6JykgIT0gMFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBhdXRoLmdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4oe1xuICAgICAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICBzZXNzaW9uVG9rZW46IGluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhdXRoLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICBzZXNzaW9uVG9rZW46IGluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKGF1dGggPT4ge1xuICAgICAgaWYgKGF1dGgpIHtcbiAgICAgICAgcmVxLmF1dGggPSBhdXRoO1xuICAgICAgICBuZXh0KCk7XG4gICAgICB9XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgICAgbmV4dChlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IERldGVybWluZSB0aGUgY29ycmVjdCBlcnJvciBzY2VuYXJpby5cbiAgICAgICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmVycm9yKCdlcnJvciBnZXR0aW5nIGF1dGggZm9yIHNlc3Npb25Ub2tlbicsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVOS05PV05fRVJST1IsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50SXAocmVxKSB7XG4gIGlmIChyZXEuaGVhZGVyc1sneC1mb3J3YXJkZWQtZm9yJ10pIHtcbiAgICAvLyB0cnkgdG8gZ2V0IGZyb20geC1mb3J3YXJlZC1mb3IgaWYgaXQgc2V0IChiZWhpbmQgcmV2ZXJzZSBwcm94eSlcbiAgICByZXR1cm4gcmVxLmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddLnNwbGl0KCcsJylbMF07XG4gIH0gZWxzZSBpZiAocmVxLmNvbm5lY3Rpb24gJiYgcmVxLmNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzcykge1xuICAgIC8vIG5vIHByb3h5LCB0cnkgZ2V0dGluZyBmcm9tIGNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzc1xuICAgIHJldHVybiByZXEuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzO1xuICB9IGVsc2UgaWYgKHJlcS5zb2NrZXQpIHtcbiAgICAvLyB0cnkgdG8gZ2V0IGl0IGZyb20gcmVxLnNvY2tldFxuICAgIHJldHVybiByZXEuc29ja2V0LnJlbW90ZUFkZHJlc3M7XG4gIH0gZWxzZSBpZiAocmVxLmNvbm5lY3Rpb24gJiYgcmVxLmNvbm5lY3Rpb24uc29ja2V0KSB7XG4gICAgLy8gdHJ5IHRvIGdldCBpdCBmb3JtIHRoZSBjb25uZWN0aW9uLnNvY2tldFxuICAgIHJldHVybiByZXEuY29ubmVjdGlvbi5zb2NrZXQucmVtb3RlQWRkcmVzcztcbiAgfSBlbHNlIHtcbiAgICAvLyBpZiBub24gYWJvdmUsIGZhbGxiYWNrLlxuICAgIHJldHVybiByZXEuaXA7XG4gIH1cbn1cblxuZnVuY3Rpb24gaHR0cEF1dGgocmVxKSB7XG4gIGlmICghKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb24pIHJldHVybjtcblxuICB2YXIgaGVhZGVyID0gKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG4gIHZhciBhcHBJZCwgbWFzdGVyS2V5LCBqYXZhc2NyaXB0S2V5O1xuXG4gIC8vIHBhcnNlIGhlYWRlclxuICB2YXIgYXV0aFByZWZpeCA9ICdiYXNpYyAnO1xuXG4gIHZhciBtYXRjaCA9IGhlYWRlci50b0xvd2VyQ2FzZSgpLmluZGV4T2YoYXV0aFByZWZpeCk7XG5cbiAgaWYgKG1hdGNoID09IDApIHtcbiAgICB2YXIgZW5jb2RlZEF1dGggPSBoZWFkZXIuc3Vic3RyaW5nKGF1dGhQcmVmaXgubGVuZ3RoLCBoZWFkZXIubGVuZ3RoKTtcbiAgICB2YXIgY3JlZGVudGlhbHMgPSBkZWNvZGVCYXNlNjQoZW5jb2RlZEF1dGgpLnNwbGl0KCc6Jyk7XG5cbiAgICBpZiAoY3JlZGVudGlhbHMubGVuZ3RoID09IDIpIHtcbiAgICAgIGFwcElkID0gY3JlZGVudGlhbHNbMF07XG4gICAgICB2YXIga2V5ID0gY3JlZGVudGlhbHNbMV07XG5cbiAgICAgIHZhciBqc0tleVByZWZpeCA9ICdqYXZhc2NyaXB0LWtleT0nO1xuXG4gICAgICB2YXIgbWF0Y2hLZXkgPSBrZXkuaW5kZXhPZihqc0tleVByZWZpeCk7XG4gICAgICBpZiAobWF0Y2hLZXkgPT0gMCkge1xuICAgICAgICBqYXZhc2NyaXB0S2V5ID0ga2V5LnN1YnN0cmluZyhqc0tleVByZWZpeC5sZW5ndGgsIGtleS5sZW5ndGgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFzdGVyS2V5ID0ga2V5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFwcElkOiBhcHBJZCwgbWFzdGVyS2V5OiBtYXN0ZXJLZXksIGphdmFzY3JpcHRLZXk6IGphdmFzY3JpcHRLZXkgfTtcbn1cblxuZnVuY3Rpb24gZGVjb2RlQmFzZTY0KHN0cikge1xuICByZXR1cm4gQnVmZmVyLmZyb20oc3RyLCAnYmFzZTY0JykudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93Q3Jvc3NEb21haW4oYXBwSWQpIHtcbiAgcmV0dXJuIChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwSWQsIGdldE1vdW50Rm9yUmVxdWVzdChyZXEpKTtcbiAgICBsZXQgYWxsb3dIZWFkZXJzID0gREVGQVVMVF9BTExPV0VEX0hFQURFUlM7XG4gICAgaWYgKGNvbmZpZyAmJiBjb25maWcuYWxsb3dIZWFkZXJzKSB7XG4gICAgICBhbGxvd0hlYWRlcnMgKz0gYCwgJHtjb25maWcuYWxsb3dIZWFkZXJzLmpvaW4oJywgJyl9YDtcbiAgICB9XG4gICAgY29uc3QgYWxsb3dPcmlnaW4gPSAoY29uZmlnICYmIGNvbmZpZy5hbGxvd09yaWdpbikgfHwgJyonO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsIGFsbG93T3JpZ2luKTtcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCxQVVQsUE9TVCxERUxFVEUsT1BUSU9OUycpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLCBhbGxvd0hlYWRlcnMpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUV4cG9zZS1IZWFkZXJzJywgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCwgWC1QYXJzZS1QdXNoLVN0YXR1cy1JZCcpO1xuICAgIC8vIGludGVyY2VwdCBPUFRJT05TIG1ldGhvZFxuICAgIGlmICgnT1BUSU9OUycgPT0gcmVxLm1ldGhvZCkge1xuICAgICAgcmVzLnNlbmRTdGF0dXMoMjAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93TWV0aG9kT3ZlcnJpZGUocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiByZXEuYm9keS5fbWV0aG9kKSB7XG4gICAgcmVxLm9yaWdpbmFsTWV0aG9kID0gcmVxLm1ldGhvZDtcbiAgICByZXEubWV0aG9kID0gcmVxLmJvZHkuX21ldGhvZDtcbiAgICBkZWxldGUgcmVxLmJvZHkuX21ldGhvZDtcbiAgfVxuICBuZXh0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXJzZUVycm9ycyhlcnIsIHJlcSwgcmVzLCBuZXh0KSB7XG4gIGNvbnN0IGxvZyA9IChyZXEuY29uZmlnICYmIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcikgfHwgZGVmYXVsdExvZ2dlcjtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgaWYgKHJlcS5jb25maWcgJiYgcmVxLmNvbmZpZy5lbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnIpO1xuICAgIH1cbiAgICBsZXQgaHR0cFN0YXR1cztcbiAgICAvLyBUT0RPOiBmaWxsIG91dCB0aGlzIG1hcHBpbmdcbiAgICBzd2l0Y2ggKGVyci5jb2RlKSB7XG4gICAgICBjYXNlIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDUwMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQ6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA0MDQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDQwMDtcbiAgICB9XG4gICAgcmVzLnN0YXR1cyhodHRwU3RhdHVzKTtcbiAgICByZXMuanNvbih7IGNvZGU6IGVyci5jb2RlLCBlcnJvcjogZXJyLm1lc3NhZ2UgfSk7XG4gICAgbG9nLmVycm9yKCdQYXJzZSBlcnJvcjogJywgZXJyKTtcbiAgfSBlbHNlIGlmIChlcnIuc3RhdHVzICYmIGVyci5tZXNzYWdlKSB7XG4gICAgcmVzLnN0YXR1cyhlcnIuc3RhdHVzKTtcbiAgICByZXMuanNvbih7IGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBpZiAoIShwcm9jZXNzICYmIHByb2Nlc3MuZW52LlRFU1RJTkcpKSB7XG4gICAgICBuZXh0KGVycik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxvZy5lcnJvcignVW5jYXVnaHQgaW50ZXJuYWwgc2VydmVyIGVycm9yLicsIGVyciwgZXJyLnN0YWNrKTtcbiAgICByZXMuc3RhdHVzKDUwMCk7XG4gICAgcmVzLmpzb24oe1xuICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgbWVzc2FnZTogJ0ludGVybmFsIHNlcnZlciBlcnJvci4nLFxuICAgIH0pO1xuICAgIGlmICghKHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYuVEVTVElORykpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKCFyZXEuYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcy5zdGF0dXMoNDAzKTtcbiAgICByZXMuZW5kKCd7XCJlcnJvclwiOlwidW5hdXRob3JpemVkOiBtYXN0ZXIga2V5IGlzIHJlcXVpcmVkXCJ9Jyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIG5leHQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzKHJlcXVlc3QpIHtcbiAgaWYgKCFyZXF1ZXN0LmF1dGguaXNNYXN0ZXIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLnN0YXR1cyA9IDQwMztcbiAgICBlcnJvci5tZXNzYWdlID0gJ3VuYXV0aG9yaXplZDogbWFzdGVyIGtleSBpcyByZXF1aXJlZCc7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vKipcbiAqIERlZHVwbGljYXRlcyBhIHJlcXVlc3QgdG8gZW5zdXJlIGlkZW1wb3RlbmN5LiBEdXBsaWNhdGVzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSByZXF1ZXN0IElEXG4gKiBpbiB0aGUgcmVxdWVzdCBoZWFkZXIuIElmIGEgcmVxdWVzdCBoYXMgbm8gcmVxdWVzdCBJRCwgaXQgaXMgZXhlY3V0ZWQgYW55d2F5LlxuICogQHBhcmFtIHsqfSByZXEgVGhlIHJlcXVlc3QgdG8gZXZhbHVhdGUuXG4gKiBAcmV0dXJucyBQcm9taXNlPHt9PlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5KHJlcSkge1xuICAvLyBFbmFibGUgZmVhdHVyZSBvbmx5IGZvciBNb25nb0RCXG4gIGlmICghKHJlcS5jb25maWcuZGF0YWJhc2UuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXIpKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIEdldCBwYXJhbWV0ZXJzXG4gIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gIGNvbnN0IHJlcXVlc3RJZCA9ICgocmVxIHx8IHt9KS5oZWFkZXJzIHx8IHt9KVsneC1wYXJzZS1yZXF1ZXN0LWlkJ107XG4gIGNvbnN0IHsgcGF0aHMsIHR0bCB9ID0gY29uZmlnLmlkZW1wb3RlbmN5T3B0aW9ucztcbiAgaWYgKCFyZXF1ZXN0SWQgfHwgIWNvbmZpZy5pZGVtcG90ZW5jeU9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gUmVxdWVzdCBwYXRoIG1heSBjb250YWluIHRyYWlsaW5nIHNsYXNoZXMsIGRlcGVuZGluZyBvbiB0aGUgb3JpZ2luYWwgcmVxdWVzdCwgc28gcmVtb3ZlXG4gIC8vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgdG8gbWFrZSBpdCBlYXNpZXIgdG8gc3BlY2lmeSBwYXRocyBpbiB0aGUgY29uZmlndXJhdGlvblxuICBjb25zdCByZXFQYXRoID0gcmVxLnBhdGgucmVwbGFjZSgvXlxcL3xcXC8kLywgJycpO1xuICAvLyBEZXRlcm1pbmUgd2hldGhlciBpZGVtcG90ZW5jeSBpcyBlbmFibGVkIGZvciBjdXJyZW50IHJlcXVlc3QgcGF0aFxuICBsZXQgbWF0Y2ggPSBmYWxzZTtcbiAgZm9yIChjb25zdCBwYXRoIG9mIHBhdGhzKSB7XG4gICAgLy8gQXNzdW1lIG9uZSB3YW50cyBhIHBhdGggdG8gYWx3YXlzIG1hdGNoIGZyb20gdGhlIGJlZ2lubmluZyB0byBwcmV2ZW50IGFueSBtaXN0YWtlc1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChwYXRoLmNoYXJBdCgwKSA9PT0gJ14nID8gcGF0aCA6ICdeJyArIHBhdGgpO1xuICAgIGlmIChyZXFQYXRoLm1hdGNoKHJlZ2V4KSkge1xuICAgICAgbWF0Y2ggPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gVHJ5IHRvIHN0b3JlIHJlcXVlc3RcbiAgY29uc3QgZXhwaXJ5RGF0ZSA9IG5ldyBEYXRlKG5ldyBEYXRlKCkuc2V0U2Vjb25kcyhuZXcgRGF0ZSgpLmdldFNlY29uZHMoKSArIHR0bCkpO1xuICByZXR1cm4gcmVzdFxuICAgIC5jcmVhdGUoY29uZmlnLCBhdXRoLm1hc3Rlcihjb25maWcpLCAnX0lkZW1wb3RlbmN5Jywge1xuICAgICAgcmVxSWQ6IHJlcXVlc3RJZCxcbiAgICAgIGV4cGlyZTogUGFyc2UuX2VuY29kZShleHBpcnlEYXRlKSxcbiAgICB9KVxuICAgIC5jYXRjaChlID0+IHtcbiAgICAgIGlmIChlLmNvZGUgPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5EVVBMSUNBVEVfUkVRVUVTVCwgJ0R1cGxpY2F0ZSByZXF1ZXN0Jyk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcykge1xuICByZXMuc3RhdHVzKDQwMyk7XG4gIHJlcy5lbmQoJ3tcImVycm9yXCI6XCJ1bmF1dGhvcml6ZWRcIn0nKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/password.js b/lib/password.js deleted file mode 100644 index 6091ae5d2d..0000000000 --- a/lib/password.js +++ /dev/null @@ -1,38 +0,0 @@ -"use strict"; - -// Tools for encrypting and decrypting passwords. -// Basically promise-friendly wrappers for bcrypt. -var bcrypt = require('bcryptjs'); - -try { - const _bcrypt = require('@node-rs/bcrypt'); - - bcrypt = { - hash: _bcrypt.hash, - compare: _bcrypt.verify - }; -} catch (e) { - /* */ -} // Returns a promise for a hashed password string. - - -function hash(password) { - return bcrypt.hash(password, 10); -} // Returns a promise for whether this password compares to equal this -// hashed password. - - -function compare(password, hashedPassword) { - // Cannot bcrypt compare when one is undefined - if (!password || !hashedPassword) { - return Promise.resolve(false); - } - - return bcrypt.compare(password, hashedPassword); -} - -module.exports = { - hash: hash, - compare: compare -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXNzd29yZC5qcyJdLCJuYW1lcyI6WyJiY3J5cHQiLCJyZXF1aXJlIiwiX2JjcnlwdCIsImhhc2giLCJjb21wYXJlIiwidmVyaWZ5IiwiZSIsInBhc3N3b3JkIiwiaGFzaGVkUGFzc3dvcmQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBLElBQUlBLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBcEI7O0FBRUEsSUFBSTtBQUNGLFFBQU1DLE9BQU8sR0FBR0QsT0FBTyxDQUFDLGlCQUFELENBQXZCOztBQUNBRCxFQUFBQSxNQUFNLEdBQUc7QUFDUEcsSUFBQUEsSUFBSSxFQUFFRCxPQUFPLENBQUNDLElBRFA7QUFFUEMsSUFBQUEsT0FBTyxFQUFFRixPQUFPLENBQUNHO0FBRlYsR0FBVDtBQUlELENBTkQsQ0FNRSxPQUFPQyxDQUFQLEVBQVU7QUFDVjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0gsSUFBVCxDQUFjSSxRQUFkLEVBQXdCO0FBQ3RCLFNBQU9QLE1BQU0sQ0FBQ0csSUFBUCxDQUFZSSxRQUFaLEVBQXNCLEVBQXRCLENBQVA7QUFDRCxDLENBRUQ7QUFDQTs7O0FBQ0EsU0FBU0gsT0FBVCxDQUFpQkcsUUFBakIsRUFBMkJDLGNBQTNCLEVBQTJDO0FBQ3pDO0FBQ0EsTUFBSSxDQUFDRCxRQUFELElBQWEsQ0FBQ0MsY0FBbEIsRUFBa0M7QUFDaEMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEtBQWhCLENBQVA7QUFDRDs7QUFDRCxTQUFPVixNQUFNLENBQUNJLE9BQVAsQ0FBZUcsUUFBZixFQUF5QkMsY0FBekIsQ0FBUDtBQUNEOztBQUVERyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlQsRUFBQUEsSUFBSSxFQUFFQSxJQURTO0FBRWZDLEVBQUFBLE9BQU8sRUFBRUE7QUFGTSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRvb2xzIGZvciBlbmNyeXB0aW5nIGFuZCBkZWNyeXB0aW5nIHBhc3N3b3Jkcy5cbi8vIEJhc2ljYWxseSBwcm9taXNlLWZyaWVuZGx5IHdyYXBwZXJzIGZvciBiY3J5cHQuXG52YXIgYmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0anMnKTtcblxudHJ5IHtcbiAgY29uc3QgX2JjcnlwdCA9IHJlcXVpcmUoJ0Bub2RlLXJzL2JjcnlwdCcpO1xuICBiY3J5cHQgPSB7XG4gICAgaGFzaDogX2JjcnlwdC5oYXNoLFxuICAgIGNvbXBhcmU6IF9iY3J5cHQudmVyaWZ5LFxuICB9O1xufSBjYXRjaCAoZSkge1xuICAvKiAqL1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBoYXNoZWQgcGFzc3dvcmQgc3RyaW5nLlxuZnVuY3Rpb24gaGFzaChwYXNzd29yZCkge1xuICByZXR1cm4gYmNyeXB0Lmhhc2gocGFzc3dvcmQsIDEwKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgdGhpcyBwYXNzd29yZCBjb21wYXJlcyB0byBlcXVhbCB0aGlzXG4vLyBoYXNoZWQgcGFzc3dvcmQuXG5mdW5jdGlvbiBjb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCkge1xuICAvLyBDYW5ub3QgYmNyeXB0IGNvbXBhcmUgd2hlbiBvbmUgaXMgdW5kZWZpbmVkXG4gIGlmICghcGFzc3dvcmQgfHwgIWhhc2hlZFBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYXNoOiBoYXNoLFxuICBjb21wYXJlOiBjb21wYXJlLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/request.js b/lib/request.js deleted file mode 100644 index 47dae80852..0000000000 --- a/lib/request.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; - -module.exports = require('./cloud-code/httpRequest'); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LmpzIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJyZXF1aXJlIl0sIm1hcHBpbmdzIjoiOztBQUFBQSxNQUFNLENBQUNDLE9BQVAsR0FBaUJDLE9BQU8sQ0FBQywwQkFBRCxDQUF4QiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0Jyk7XG4iXX0= \ No newline at end of file diff --git a/lib/requiredParameter.js b/lib/requiredParameter.js deleted file mode 100644 index 2a657ca91b..0000000000 --- a/lib/requiredParameter.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _default = errorMessage => { - throw errorMessage; -}; - -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1aXJlZFBhcmFtZXRlci5qcyJdLCJuYW1lcyI6WyJlcnJvck1lc3NhZ2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7ZUFDZ0JBLFlBQUQsSUFBK0I7QUFDNUMsUUFBTUEsWUFBTjtBQUNELEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQGZsb3cgKi9cbmV4cG9ydCBkZWZhdWx0IChlcnJvck1lc3NhZ2U6IHN0cmluZyk6IGFueSA9PiB7XG4gIHRocm93IGVycm9yTWVzc2FnZTtcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/rest.js b/lib/rest.js deleted file mode 100644 index f5c9fa9ce5..0000000000 --- a/lib/rest.js +++ /dev/null @@ -1,208 +0,0 @@ -"use strict"; - -// This file contains helpers for running operations in REST format. -// The goal is that handlers that explicitly handle an express route -// should just be shallow wrappers around things in this file, but -// these functions should not explicitly depend on the request -// object. -// This means that one of these handlers can support multiple -// routes. That's useful for the routes that do really similar -// things. -var Parse = require('parse/node').Parse; - -var RestQuery = require('./RestQuery'); - -var RestWrite = require('./RestWrite'); - -var triggers = require('./triggers'); - -function checkTriggers(className, config, types) { - return types.some(triggerType => { - return triggers.getTrigger(className, triggers.Types[triggerType], config.applicationId); - }); -} - -function checkLiveQuery(className, config) { - return config.liveQueryController && config.liveQueryController.hasLiveQuery(className); -} // Returns a promise for an object with optional keys 'results' and 'count'. - - -function find(config, auth, className, restWhere, restOptions, clientSDK, context) { - enforceRoleSecurity('find', className, auth); - return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context).then(result => { - restWhere = result.restWhere || restWhere; - restOptions = result.restOptions || restOptions; - const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); - return query.execute(); - }); -} // get is just like find but only queries an objectId. - - -const get = (config, auth, className, objectId, restOptions, clientSDK, context) => { - var restWhere = { - objectId - }; - enforceRoleSecurity('get', className, auth); - return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context, true).then(result => { - restWhere = result.restWhere || restWhere; - restOptions = result.restOptions || restOptions; - const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); - return query.execute(); - }); -}; // Returns a promise that doesn't resolve to any useful value. - - -function del(config, auth, className, objectId, context) { - if (typeof objectId !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad objectId'); - } - - if (className === '_User' && auth.isUnauthenticated()) { - throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth to delete user'); - } - - enforceRoleSecurity('delete', className, auth); - let inflatedObject; - let schemaController; - return Promise.resolve().then(() => { - const hasTriggers = checkTriggers(className, config, ['beforeDelete', 'afterDelete']); - const hasLiveQuery = checkLiveQuery(className, config); - - if (hasTriggers || hasLiveQuery || className == '_Session') { - return new RestQuery(config, auth, className, { - objectId - }).execute({ - op: 'delete' - }).then(response => { - if (response && response.results && response.results.length) { - const firstResult = response.results[0]; - firstResult.className = className; - - if (className === '_Session' && !auth.isMaster) { - if (!auth.user || firstResult.user.objectId !== auth.user.id) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - } - - var cacheAdapter = config.cacheController; - cacheAdapter.user.del(firstResult.sessionToken); - inflatedObject = Parse.Object.fromJSON(firstResult); - return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config, context); - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.'); - }); - } - - return Promise.resolve({}); - }).then(() => { - if (!auth.isMaster) { - return auth.getUserRoles(); - } else { - return; - } - }).then(() => config.database.loadSchema()).then(s => { - schemaController = s; - const options = {}; - - if (!auth.isMaster) { - options.acl = ['*']; - - if (auth.user) { - options.acl.push(auth.user.id); - options.acl = options.acl.concat(auth.userRoles); - } - } - - return config.database.destroy(className, { - objectId: objectId - }, options, schemaController); - }).then(() => { - // Notify LiveQuery server if possible - const perms = schemaController.getClassLevelPermissions(className); - config.liveQueryController.onAfterDelete(className, inflatedObject, null, perms); - return triggers.maybeRunTrigger(triggers.Types.afterDelete, auth, inflatedObject, null, config, context); - }).catch(error => { - handleSessionMissingError(error, className, auth); - }); -} // Returns a promise for a {response, status, location} object. - - -function create(config, auth, className, restObject, clientSDK, context) { - enforceRoleSecurity('create', className, auth); - var write = new RestWrite(config, auth, className, null, restObject, null, clientSDK, context); - return write.execute(); -} // Returns a promise that contains the fields of the update that the -// REST API is supposed to return. -// Usually, this is just updatedAt. - - -function update(config, auth, className, restWhere, restObject, clientSDK, context) { - enforceRoleSecurity('update', className, auth); - return Promise.resolve().then(() => { - const hasTriggers = checkTriggers(className, config, ['beforeSave', 'afterSave']); - const hasLiveQuery = checkLiveQuery(className, config); - - if (hasTriggers || hasLiveQuery) { - // Do not use find, as it runs the before finds - return new RestQuery(config, auth, className, restWhere, undefined, undefined, false).execute({ - op: 'update' - }); - } - - return Promise.resolve({}); - }).then(({ - results - }) => { - var originalRestObject; - - if (results && results.length) { - originalRestObject = results[0]; - } - - return new RestWrite(config, auth, className, restWhere, restObject, originalRestObject, clientSDK, context, 'update').execute(); - }).catch(error => { - handleSessionMissingError(error, className, auth); - }); -} - -function handleSessionMissingError(error, className, auth) { - // If we're trying to update a user without / with bad session token - if (className === '_User' && error.code === Parse.Error.OBJECT_NOT_FOUND && !auth.isMaster) { - throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth.'); - } - - throw error; -} - -const classesWithMasterOnlyAccess = ['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_JobSchedule', '_Idempotency']; // Disallowing access to the _Role collection except by master key - -function enforceRoleSecurity(method, className, auth) { - if (className === '_Installation' && !auth.isMaster) { - if (method === 'delete' || method === 'find') { - const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } - } //all volatileClasses are masterKey only - - - if (classesWithMasterOnlyAccess.indexOf(className) >= 0 && !auth.isMaster) { - const error = `Clients aren't allowed to perform the ${method} operation on the ${className} collection.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } // readOnly masterKey is not allowed - - - if (auth.isReadOnly && (method === 'delete' || method === 'create' || method === 'update')) { - const error = `read-only masterKey isn't allowed to perform the ${method} operation.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } -} - -module.exports = { - create, - del, - find, - get, - update -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXN0LmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlJlc3RXcml0ZSIsInRyaWdnZXJzIiwiY2hlY2tUcmlnZ2VycyIsImNsYXNzTmFtZSIsImNvbmZpZyIsInR5cGVzIiwic29tZSIsInRyaWdnZXJUeXBlIiwiZ2V0VHJpZ2dlciIsIlR5cGVzIiwiYXBwbGljYXRpb25JZCIsImNoZWNrTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsImhhc0xpdmVRdWVyeSIsImZpbmQiLCJhdXRoIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiZW5mb3JjZVJvbGVTZWN1cml0eSIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwiYmVmb3JlRmluZCIsInRoZW4iLCJyZXN1bHQiLCJxdWVyeSIsImV4ZWN1dGUiLCJnZXQiLCJvYmplY3RJZCIsImRlbCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJTRVNTSU9OX01JU1NJTkciLCJpbmZsYXRlZE9iamVjdCIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwicmVzb2x2ZSIsImhhc1RyaWdnZXJzIiwib3AiLCJyZXNwb25zZSIsInJlc3VsdHMiLCJsZW5ndGgiLCJmaXJzdFJlc3VsdCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVDb250cm9sbGVyIiwic2Vzc2lvblRva2VuIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJtYXliZVJ1blRyaWdnZXIiLCJiZWZvcmVEZWxldGUiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0VXNlclJvbGVzIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwicyIsIm9wdGlvbnMiLCJhY2wiLCJwdXNoIiwiY29uY2F0IiwidXNlclJvbGVzIiwiZGVzdHJveSIsInBlcm1zIiwiZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwib25BZnRlckRlbGV0ZSIsImFmdGVyRGVsZXRlIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IiLCJjcmVhdGUiLCJyZXN0T2JqZWN0Iiwid3JpdGUiLCJ1cGRhdGUiLCJ1bmRlZmluZWQiLCJvcmlnaW5hbFJlc3RPYmplY3QiLCJjb2RlIiwiY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzIiwibWV0aG9kIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImluZGV4T2YiLCJpc1JlYWRPbmx5IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxJQUFJRSxTQUFTLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBQXZCOztBQUNBLElBQUlFLFNBQVMsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBdkI7O0FBQ0EsSUFBSUcsUUFBUSxHQUFHSCxPQUFPLENBQUMsWUFBRCxDQUF0Qjs7QUFFQSxTQUFTSSxhQUFULENBQXVCQyxTQUF2QixFQUFrQ0MsTUFBbEMsRUFBMENDLEtBQTFDLEVBQWlEO0FBQy9DLFNBQU9BLEtBQUssQ0FBQ0MsSUFBTixDQUFXQyxXQUFXLElBQUk7QUFDL0IsV0FBT04sUUFBUSxDQUFDTyxVQUFULENBQW9CTCxTQUFwQixFQUErQkYsUUFBUSxDQUFDUSxLQUFULENBQWVGLFdBQWYsQ0FBL0IsRUFBNERILE1BQU0sQ0FBQ00sYUFBbkUsQ0FBUDtBQUNELEdBRk0sQ0FBUDtBQUdEOztBQUVELFNBQVNDLGNBQVQsQ0FBd0JSLFNBQXhCLEVBQW1DQyxNQUFuQyxFQUEyQztBQUN6QyxTQUFPQSxNQUFNLENBQUNRLG1CQUFQLElBQThCUixNQUFNLENBQUNRLG1CQUFQLENBQTJCQyxZQUEzQixDQUF3Q1YsU0FBeEMsQ0FBckM7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNXLElBQVQsQ0FBY1YsTUFBZCxFQUFzQlcsSUFBdEIsRUFBNEJaLFNBQTVCLEVBQXVDYSxTQUF2QyxFQUFrREMsV0FBbEQsRUFBK0RDLFNBQS9ELEVBQTBFQyxPQUExRSxFQUFtRjtBQUNqRkMsRUFBQUEsbUJBQW1CLENBQUMsTUFBRCxFQUFTakIsU0FBVCxFQUFvQlksSUFBcEIsQ0FBbkI7QUFDQSxTQUFPZCxRQUFRLENBQ1pvQixvQkFESSxDQUVIcEIsUUFBUSxDQUFDUSxLQUFULENBQWVhLFVBRlosRUFHSG5CLFNBSEcsRUFJSGEsU0FKRyxFQUtIQyxXQUxHLEVBTUhiLE1BTkcsRUFPSFcsSUFQRyxFQVFISSxPQVJHLEVBVUpJLElBVkksQ0FVQ0MsTUFBTSxJQUFJO0FBQ2RSLElBQUFBLFNBQVMsR0FBR1EsTUFBTSxDQUFDUixTQUFQLElBQW9CQSxTQUFoQztBQUNBQyxJQUFBQSxXQUFXLEdBQUdPLE1BQU0sQ0FBQ1AsV0FBUCxJQUFzQkEsV0FBcEM7QUFDQSxVQUFNUSxLQUFLLEdBQUcsSUFBSTFCLFNBQUosQ0FBY0ssTUFBZCxFQUFzQlcsSUFBdEIsRUFBNEJaLFNBQTVCLEVBQXVDYSxTQUF2QyxFQUFrREMsV0FBbEQsRUFBK0RDLFNBQS9ELENBQWQ7QUFDQSxXQUFPTyxLQUFLLENBQUNDLE9BQU4sRUFBUDtBQUNELEdBZkksQ0FBUDtBQWdCRCxDLENBRUQ7OztBQUNBLE1BQU1DLEdBQUcsR0FBRyxDQUFDdkIsTUFBRCxFQUFTVyxJQUFULEVBQWVaLFNBQWYsRUFBMEJ5QixRQUExQixFQUFvQ1gsV0FBcEMsRUFBaURDLFNBQWpELEVBQTREQyxPQUE1RCxLQUF3RTtBQUNsRixNQUFJSCxTQUFTLEdBQUc7QUFBRVksSUFBQUE7QUFBRixHQUFoQjtBQUNBUixFQUFBQSxtQkFBbUIsQ0FBQyxLQUFELEVBQVFqQixTQUFSLEVBQW1CWSxJQUFuQixDQUFuQjtBQUNBLFNBQU9kLFFBQVEsQ0FDWm9CLG9CQURJLENBRUhwQixRQUFRLENBQUNRLEtBQVQsQ0FBZWEsVUFGWixFQUdIbkIsU0FIRyxFQUlIYSxTQUpHLEVBS0hDLFdBTEcsRUFNSGIsTUFORyxFQU9IVyxJQVBHLEVBUUhJLE9BUkcsRUFTSCxJQVRHLEVBV0pJLElBWEksQ0FXQ0MsTUFBTSxJQUFJO0FBQ2RSLElBQUFBLFNBQVMsR0FBR1EsTUFBTSxDQUFDUixTQUFQLElBQW9CQSxTQUFoQztBQUNBQyxJQUFBQSxXQUFXLEdBQUdPLE1BQU0sQ0FBQ1AsV0FBUCxJQUFzQkEsV0FBcEM7QUFDQSxVQUFNUSxLQUFLLEdBQUcsSUFBSTFCLFNBQUosQ0FBY0ssTUFBZCxFQUFzQlcsSUFBdEIsRUFBNEJaLFNBQTVCLEVBQXVDYSxTQUF2QyxFQUFrREMsV0FBbEQsRUFBK0RDLFNBQS9ELENBQWQ7QUFDQSxXQUFPTyxLQUFLLENBQUNDLE9BQU4sRUFBUDtBQUNELEdBaEJJLENBQVA7QUFpQkQsQ0FwQkQsQyxDQXNCQTs7O0FBQ0EsU0FBU0csR0FBVCxDQUFhekIsTUFBYixFQUFxQlcsSUFBckIsRUFBMkJaLFNBQTNCLEVBQXNDeUIsUUFBdEMsRUFBZ0RULE9BQWhELEVBQXlEO0FBQ3ZELE1BQUksT0FBT1MsUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUNoQyxVQUFNLElBQUkvQixLQUFLLENBQUNpQyxLQUFWLENBQWdCakMsS0FBSyxDQUFDaUMsS0FBTixDQUFZQyxZQUE1QixFQUEwQyxjQUExQyxDQUFOO0FBQ0Q7O0FBRUQsTUFBSTVCLFNBQVMsS0FBSyxPQUFkLElBQXlCWSxJQUFJLENBQUNpQixpQkFBTCxFQUE3QixFQUF1RDtBQUNyRCxVQUFNLElBQUluQyxLQUFLLENBQUNpQyxLQUFWLENBQWdCakMsS0FBSyxDQUFDaUMsS0FBTixDQUFZRyxlQUE1QixFQUE2QyxrQ0FBN0MsQ0FBTjtBQUNEOztBQUVEYixFQUFBQSxtQkFBbUIsQ0FBQyxRQUFELEVBQVdqQixTQUFYLEVBQXNCWSxJQUF0QixDQUFuQjtBQUVBLE1BQUltQixjQUFKO0FBQ0EsTUFBSUMsZ0JBQUo7QUFFQSxTQUFPQyxPQUFPLENBQUNDLE9BQVIsR0FDSmQsSUFESSxDQUNDLE1BQU07QUFDVixVQUFNZSxXQUFXLEdBQUdwQyxhQUFhLENBQUNDLFNBQUQsRUFBWUMsTUFBWixFQUFvQixDQUFDLGNBQUQsRUFBaUIsYUFBakIsQ0FBcEIsQ0FBakM7QUFDQSxVQUFNUyxZQUFZLEdBQUdGLGNBQWMsQ0FBQ1IsU0FBRCxFQUFZQyxNQUFaLENBQW5DOztBQUNBLFFBQUlrQyxXQUFXLElBQUl6QixZQUFmLElBQStCVixTQUFTLElBQUksVUFBaEQsRUFBNEQ7QUFDMUQsYUFBTyxJQUFJSixTQUFKLENBQWNLLE1BQWQsRUFBc0JXLElBQXRCLEVBQTRCWixTQUE1QixFQUF1QztBQUFFeUIsUUFBQUE7QUFBRixPQUF2QyxFQUNKRixPQURJLENBQ0k7QUFBRWEsUUFBQUEsRUFBRSxFQUFFO0FBQU4sT0FESixFQUVKaEIsSUFGSSxDQUVDaUIsUUFBUSxJQUFJO0FBQ2hCLFlBQUlBLFFBQVEsSUFBSUEsUUFBUSxDQUFDQyxPQUFyQixJQUFnQ0QsUUFBUSxDQUFDQyxPQUFULENBQWlCQyxNQUFyRCxFQUE2RDtBQUMzRCxnQkFBTUMsV0FBVyxHQUFHSCxRQUFRLENBQUNDLE9BQVQsQ0FBaUIsQ0FBakIsQ0FBcEI7QUFDQUUsVUFBQUEsV0FBVyxDQUFDeEMsU0FBWixHQUF3QkEsU0FBeEI7O0FBQ0EsY0FBSUEsU0FBUyxLQUFLLFVBQWQsSUFBNEIsQ0FBQ1ksSUFBSSxDQUFDNkIsUUFBdEMsRUFBZ0Q7QUFDOUMsZ0JBQUksQ0FBQzdCLElBQUksQ0FBQzhCLElBQU4sSUFBY0YsV0FBVyxDQUFDRSxJQUFaLENBQWlCakIsUUFBakIsS0FBOEJiLElBQUksQ0FBQzhCLElBQUwsQ0FBVUMsRUFBMUQsRUFBOEQ7QUFDNUQsb0JBQU0sSUFBSWpELEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlpQixxQkFBNUIsRUFBbUQsdUJBQW5ELENBQU47QUFDRDtBQUNGOztBQUNELGNBQUlDLFlBQVksR0FBRzVDLE1BQU0sQ0FBQzZDLGVBQTFCO0FBQ0FELFVBQUFBLFlBQVksQ0FBQ0gsSUFBYixDQUFrQmhCLEdBQWxCLENBQXNCYyxXQUFXLENBQUNPLFlBQWxDO0FBQ0FoQixVQUFBQSxjQUFjLEdBQUdyQyxLQUFLLENBQUNzRCxNQUFOLENBQWFDLFFBQWIsQ0FBc0JULFdBQXRCLENBQWpCO0FBQ0EsaUJBQU8xQyxRQUFRLENBQUNvRCxlQUFULENBQ0xwRCxRQUFRLENBQUNRLEtBQVQsQ0FBZTZDLFlBRFYsRUFFTHZDLElBRkssRUFHTG1CLGNBSEssRUFJTCxJQUpLLEVBS0w5QixNQUxLLEVBTUxlLE9BTkssQ0FBUDtBQVFEOztBQUNELGNBQU0sSUFBSXRCLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVl5QixnQkFBNUIsRUFBOEMsOEJBQTlDLENBQU47QUFDRCxPQXhCSSxDQUFQO0FBeUJEOztBQUNELFdBQU9uQixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNELEdBaENJLEVBaUNKZCxJQWpDSSxDQWlDQyxNQUFNO0FBQ1YsUUFBSSxDQUFDUixJQUFJLENBQUM2QixRQUFWLEVBQW9CO0FBQ2xCLGFBQU83QixJQUFJLENBQUN5QyxZQUFMLEVBQVA7QUFDRCxLQUZELE1BRU87QUFDTDtBQUNEO0FBQ0YsR0F2Q0ksRUF3Q0pqQyxJQXhDSSxDQXdDQyxNQUFNbkIsTUFBTSxDQUFDcUQsUUFBUCxDQUFnQkMsVUFBaEIsRUF4Q1AsRUF5Q0puQyxJQXpDSSxDQXlDQ29DLENBQUMsSUFBSTtBQUNUeEIsSUFBQUEsZ0JBQWdCLEdBQUd3QixDQUFuQjtBQUNBLFVBQU1DLE9BQU8sR0FBRyxFQUFoQjs7QUFDQSxRQUFJLENBQUM3QyxJQUFJLENBQUM2QixRQUFWLEVBQW9CO0FBQ2xCZ0IsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLEdBQWMsQ0FBQyxHQUFELENBQWQ7O0FBQ0EsVUFBSTlDLElBQUksQ0FBQzhCLElBQVQsRUFBZTtBQUNiZSxRQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsSUFBWixDQUFpQi9DLElBQUksQ0FBQzhCLElBQUwsQ0FBVUMsRUFBM0I7QUFDQWMsUUFBQUEsT0FBTyxDQUFDQyxHQUFSLEdBQWNELE9BQU8sQ0FBQ0MsR0FBUixDQUFZRSxNQUFaLENBQW1CaEQsSUFBSSxDQUFDaUQsU0FBeEIsQ0FBZDtBQUNEO0FBQ0Y7O0FBRUQsV0FBTzVELE1BQU0sQ0FBQ3FELFFBQVAsQ0FBZ0JRLE9BQWhCLENBQ0w5RCxTQURLLEVBRUw7QUFDRXlCLE1BQUFBLFFBQVEsRUFBRUE7QUFEWixLQUZLLEVBS0xnQyxPQUxLLEVBTUx6QixnQkFOSyxDQUFQO0FBUUQsR0E1REksRUE2REpaLElBN0RJLENBNkRDLE1BQU07QUFDVjtBQUNBLFVBQU0yQyxLQUFLLEdBQUcvQixnQkFBZ0IsQ0FBQ2dDLHdCQUFqQixDQUEwQ2hFLFNBQTFDLENBQWQ7QUFDQUMsSUFBQUEsTUFBTSxDQUFDUSxtQkFBUCxDQUEyQndELGFBQTNCLENBQXlDakUsU0FBekMsRUFBb0QrQixjQUFwRCxFQUFvRSxJQUFwRSxFQUEwRWdDLEtBQTFFO0FBQ0EsV0FBT2pFLFFBQVEsQ0FBQ29ELGVBQVQsQ0FDTHBELFFBQVEsQ0FBQ1EsS0FBVCxDQUFlNEQsV0FEVixFQUVMdEQsSUFGSyxFQUdMbUIsY0FISyxFQUlMLElBSkssRUFLTDlCLE1BTEssRUFNTGUsT0FOSyxDQUFQO0FBUUQsR0F6RUksRUEwRUptRCxLQTFFSSxDQTBFRUMsS0FBSyxJQUFJO0FBQ2RDLElBQUFBLHlCQUF5QixDQUFDRCxLQUFELEVBQVFwRSxTQUFSLEVBQW1CWSxJQUFuQixDQUF6QjtBQUNELEdBNUVJLENBQVA7QUE2RUQsQyxDQUVEOzs7QUFDQSxTQUFTMEQsTUFBVCxDQUFnQnJFLE1BQWhCLEVBQXdCVyxJQUF4QixFQUE4QlosU0FBOUIsRUFBeUN1RSxVQUF6QyxFQUFxRHhELFNBQXJELEVBQWdFQyxPQUFoRSxFQUF5RTtBQUN2RUMsRUFBQUEsbUJBQW1CLENBQUMsUUFBRCxFQUFXakIsU0FBWCxFQUFzQlksSUFBdEIsQ0FBbkI7QUFDQSxNQUFJNEQsS0FBSyxHQUFHLElBQUkzRSxTQUFKLENBQWNJLE1BQWQsRUFBc0JXLElBQXRCLEVBQTRCWixTQUE1QixFQUF1QyxJQUF2QyxFQUE2Q3VFLFVBQTdDLEVBQXlELElBQXpELEVBQStEeEQsU0FBL0QsRUFBMEVDLE9BQTFFLENBQVo7QUFDQSxTQUFPd0QsS0FBSyxDQUFDakQsT0FBTixFQUFQO0FBQ0QsQyxDQUVEO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBU2tELE1BQVQsQ0FBZ0J4RSxNQUFoQixFQUF3QlcsSUFBeEIsRUFBOEJaLFNBQTlCLEVBQXlDYSxTQUF6QyxFQUFvRDBELFVBQXBELEVBQWdFeEQsU0FBaEUsRUFBMkVDLE9BQTNFLEVBQW9GO0FBQ2xGQyxFQUFBQSxtQkFBbUIsQ0FBQyxRQUFELEVBQVdqQixTQUFYLEVBQXNCWSxJQUF0QixDQUFuQjtBQUVBLFNBQU9xQixPQUFPLENBQUNDLE9BQVIsR0FDSmQsSUFESSxDQUNDLE1BQU07QUFDVixVQUFNZSxXQUFXLEdBQUdwQyxhQUFhLENBQUNDLFNBQUQsRUFBWUMsTUFBWixFQUFvQixDQUFDLFlBQUQsRUFBZSxXQUFmLENBQXBCLENBQWpDO0FBQ0EsVUFBTVMsWUFBWSxHQUFHRixjQUFjLENBQUNSLFNBQUQsRUFBWUMsTUFBWixDQUFuQzs7QUFDQSxRQUFJa0MsV0FBVyxJQUFJekIsWUFBbkIsRUFBaUM7QUFDL0I7QUFDQSxhQUFPLElBQUlkLFNBQUosQ0FDTEssTUFESyxFQUVMVyxJQUZLLEVBR0xaLFNBSEssRUFJTGEsU0FKSyxFQUtMNkQsU0FMSyxFQU1MQSxTQU5LLEVBT0wsS0FQSyxFQVFMbkQsT0FSSyxDQVFHO0FBQ1JhLFFBQUFBLEVBQUUsRUFBRTtBQURJLE9BUkgsQ0FBUDtBQVdEOztBQUNELFdBQU9ILE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0QsR0FuQkksRUFvQkpkLElBcEJJLENBb0JDLENBQUM7QUFBRWtCLElBQUFBO0FBQUYsR0FBRCxLQUFpQjtBQUNyQixRQUFJcUMsa0JBQUo7O0FBQ0EsUUFBSXJDLE9BQU8sSUFBSUEsT0FBTyxDQUFDQyxNQUF2QixFQUErQjtBQUM3Qm9DLE1BQUFBLGtCQUFrQixHQUFHckMsT0FBTyxDQUFDLENBQUQsQ0FBNUI7QUFDRDs7QUFDRCxXQUFPLElBQUl6QyxTQUFKLENBQ0xJLE1BREssRUFFTFcsSUFGSyxFQUdMWixTQUhLLEVBSUxhLFNBSkssRUFLTDBELFVBTEssRUFNTEksa0JBTkssRUFPTDVELFNBUEssRUFRTEMsT0FSSyxFQVNMLFFBVEssRUFVTE8sT0FWSyxFQUFQO0FBV0QsR0FwQ0ksRUFxQ0o0QyxLQXJDSSxDQXFDRUMsS0FBSyxJQUFJO0FBQ2RDLElBQUFBLHlCQUF5QixDQUFDRCxLQUFELEVBQVFwRSxTQUFSLEVBQW1CWSxJQUFuQixDQUF6QjtBQUNELEdBdkNJLENBQVA7QUF3Q0Q7O0FBRUQsU0FBU3lELHlCQUFULENBQW1DRCxLQUFuQyxFQUEwQ3BFLFNBQTFDLEVBQXFEWSxJQUFyRCxFQUEyRDtBQUN6RDtBQUNBLE1BQUlaLFNBQVMsS0FBSyxPQUFkLElBQXlCb0UsS0FBSyxDQUFDUSxJQUFOLEtBQWVsRixLQUFLLENBQUNpQyxLQUFOLENBQVl5QixnQkFBcEQsSUFBd0UsQ0FBQ3hDLElBQUksQ0FBQzZCLFFBQWxGLEVBQTRGO0FBQzFGLFVBQU0sSUFBSS9DLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlHLGVBQTVCLEVBQTZDLG9CQUE3QyxDQUFOO0FBQ0Q7O0FBQ0QsUUFBTXNDLEtBQU47QUFDRDs7QUFFRCxNQUFNUywyQkFBMkIsR0FBRyxDQUNsQyxZQURrQyxFQUVsQyxhQUZrQyxFQUdsQyxRQUhrQyxFQUlsQyxlQUprQyxFQUtsQyxjQUxrQyxFQU1sQyxjQU5rQyxDQUFwQyxDLENBUUE7O0FBQ0EsU0FBUzVELG1CQUFULENBQTZCNkQsTUFBN0IsRUFBcUM5RSxTQUFyQyxFQUFnRFksSUFBaEQsRUFBc0Q7QUFDcEQsTUFBSVosU0FBUyxLQUFLLGVBQWQsSUFBaUMsQ0FBQ1ksSUFBSSxDQUFDNkIsUUFBM0MsRUFBcUQ7QUFDbkQsUUFBSXFDLE1BQU0sS0FBSyxRQUFYLElBQXVCQSxNQUFNLEtBQUssTUFBdEMsRUFBOEM7QUFDNUMsWUFBTVYsS0FBSyxHQUFJLHlDQUF3Q1UsTUFBTyw0Q0FBOUQ7QUFDQSxZQUFNLElBQUlwRixLQUFLLENBQUNpQyxLQUFWLENBQWdCakMsS0FBSyxDQUFDaUMsS0FBTixDQUFZb0QsbUJBQTVCLEVBQWlEWCxLQUFqRCxDQUFOO0FBQ0Q7QUFDRixHQU5tRCxDQVFwRDs7O0FBQ0EsTUFBSVMsMkJBQTJCLENBQUNHLE9BQTVCLENBQW9DaEYsU0FBcEMsS0FBa0QsQ0FBbEQsSUFBdUQsQ0FBQ1ksSUFBSSxDQUFDNkIsUUFBakUsRUFBMkU7QUFDekUsVUFBTTJCLEtBQUssR0FBSSx5Q0FBd0NVLE1BQU8scUJBQW9COUUsU0FBVSxjQUE1RjtBQUNBLFVBQU0sSUFBSU4sS0FBSyxDQUFDaUMsS0FBVixDQUFnQmpDLEtBQUssQ0FBQ2lDLEtBQU4sQ0FBWW9ELG1CQUE1QixFQUFpRFgsS0FBakQsQ0FBTjtBQUNELEdBWm1ELENBY3BEOzs7QUFDQSxNQUFJeEQsSUFBSSxDQUFDcUUsVUFBTCxLQUFvQkgsTUFBTSxLQUFLLFFBQVgsSUFBdUJBLE1BQU0sS0FBSyxRQUFsQyxJQUE4Q0EsTUFBTSxLQUFLLFFBQTdFLENBQUosRUFBNEY7QUFDMUYsVUFBTVYsS0FBSyxHQUFJLG9EQUFtRFUsTUFBTyxhQUF6RTtBQUNBLFVBQU0sSUFBSXBGLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlvRCxtQkFBNUIsRUFBaURYLEtBQWpELENBQU47QUFDRDtBQUNGOztBQUVEYyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmIsRUFBQUEsTUFEZTtBQUVmNUMsRUFBQUEsR0FGZTtBQUdmZixFQUFBQSxJQUhlO0FBSWZhLEVBQUFBLEdBSmU7QUFLZmlELEVBQUFBO0FBTGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGlzIGZpbGUgY29udGFpbnMgaGVscGVycyBmb3IgcnVubmluZyBvcGVyYXRpb25zIGluIFJFU1QgZm9ybWF0LlxuLy8gVGhlIGdvYWwgaXMgdGhhdCBoYW5kbGVycyB0aGF0IGV4cGxpY2l0bHkgaGFuZGxlIGFuIGV4cHJlc3Mgcm91dGVcbi8vIHNob3VsZCBqdXN0IGJlIHNoYWxsb3cgd3JhcHBlcnMgYXJvdW5kIHRoaW5ncyBpbiB0aGlzIGZpbGUsIGJ1dFxuLy8gdGhlc2UgZnVuY3Rpb25zIHNob3VsZCBub3QgZXhwbGljaXRseSBkZXBlbmQgb24gdGhlIHJlcXVlc3Rcbi8vIG9iamVjdC5cbi8vIFRoaXMgbWVhbnMgdGhhdCBvbmUgb2YgdGhlc2UgaGFuZGxlcnMgY2FuIHN1cHBvcnQgbXVsdGlwbGVcbi8vIHJvdXRlcy4gVGhhdCdzIHVzZWZ1bCBmb3IgdGhlIHJvdXRlcyB0aGF0IGRvIHJlYWxseSBzaW1pbGFyXG4vLyB0aGluZ3MuXG5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxudmFyIFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG52YXIgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcbnZhciB0cmlnZ2VycyA9IHJlcXVpcmUoJy4vdHJpZ2dlcnMnKTtcblxuZnVuY3Rpb24gY2hlY2tUcmlnZ2VycyhjbGFzc05hbWUsIGNvbmZpZywgdHlwZXMpIHtcbiAgcmV0dXJuIHR5cGVzLnNvbWUodHJpZ2dlclR5cGUgPT4ge1xuICAgIHJldHVybiB0cmlnZ2Vycy5nZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXNbdHJpZ2dlclR5cGVdLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjaGVja0xpdmVRdWVyeShjbGFzc05hbWUsIGNvbmZpZykge1xuICByZXR1cm4gY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIgJiYgY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIuaGFzTGl2ZVF1ZXJ5KGNsYXNzTmFtZSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhbiBvYmplY3Qgd2l0aCBvcHRpb25hbCBrZXlzICdyZXN1bHRzJyBhbmQgJ2NvdW50Jy5cbmZ1bmN0aW9uIGZpbmQoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNsaWVudFNESywgY29udGV4dCkge1xuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCdmaW5kJywgY2xhc3NOYW1lLCBhdXRoKTtcbiAgcmV0dXJuIHRyaWdnZXJzXG4gICAgLm1heWJlUnVuUXVlcnlUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRmluZCxcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgY29uZmlnLFxuICAgICAgYXV0aCxcbiAgICAgIGNvbnRleHRcbiAgICApXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIHJlc3RXaGVyZSA9IHJlc3VsdC5yZXN0V2hlcmUgfHwgcmVzdFdoZXJlO1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN1bHQucmVzdE9wdGlvbnMgfHwgcmVzdE9wdGlvbnM7XG4gICAgICBjb25zdCBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNsaWVudFNESyk7XG4gICAgICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpO1xuICAgIH0pO1xufVxuXG4vLyBnZXQgaXMganVzdCBsaWtlIGZpbmQgYnV0IG9ubHkgcXVlcmllcyBhbiBvYmplY3RJZC5cbmNvbnN0IGdldCA9IChjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0SWQsIHJlc3RPcHRpb25zLCBjbGllbnRTREssIGNvbnRleHQpID0+IHtcbiAgdmFyIHJlc3RXaGVyZSA9IHsgb2JqZWN0SWQgfTtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnZ2V0JywgY2xhc3NOYW1lLCBhdXRoKTtcbiAgcmV0dXJuIHRyaWdnZXJzXG4gICAgLm1heWJlUnVuUXVlcnlUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRmluZCxcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgY29uZmlnLFxuICAgICAgYXV0aCxcbiAgICAgIGNvbnRleHQsXG4gICAgICB0cnVlXG4gICAgKVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICByZXN0V2hlcmUgPSByZXN1bHQucmVzdFdoZXJlIHx8IHJlc3RXaGVyZTtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdWx0LnJlc3RPcHRpb25zIHx8IHJlc3RPcHRpb25zO1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREspO1xuICAgICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICB9KTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZG9lc24ndCByZXNvbHZlIHRvIGFueSB1c2VmdWwgdmFsdWUuXG5mdW5jdGlvbiBkZWwoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2Ygb2JqZWN0SWQgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBvYmplY3RJZCcpO1xuICB9XG5cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiBhdXRoLmlzVW5hdXRoZW50aWNhdGVkKCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0VTU0lPTl9NSVNTSU5HLCAnSW5zdWZmaWNpZW50IGF1dGggdG8gZGVsZXRlIHVzZXInKTtcbiAgfVxuXG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2RlbGV0ZScsIGNsYXNzTmFtZSwgYXV0aCk7XG5cbiAgbGV0IGluZmxhdGVkT2JqZWN0O1xuICBsZXQgc2NoZW1hQ29udHJvbGxlcjtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBoYXNUcmlnZ2VycyA9IGNoZWNrVHJpZ2dlcnMoY2xhc3NOYW1lLCBjb25maWcsIFsnYmVmb3JlRGVsZXRlJywgJ2FmdGVyRGVsZXRlJ10pO1xuICAgICAgY29uc3QgaGFzTGl2ZVF1ZXJ5ID0gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpO1xuICAgICAgaWYgKGhhc1RyaWdnZXJzIHx8IGhhc0xpdmVRdWVyeSB8fCBjbGFzc05hbWUgPT0gJ19TZXNzaW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3RRdWVyeShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgeyBvYmplY3RJZCB9KVxuICAgICAgICAgIC5leGVjdXRlKHsgb3A6ICdkZWxldGUnIH0pXG4gICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnJlc3VsdHMgJiYgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZmlyc3RSZXN1bHQgPSByZXNwb25zZS5yZXN1bHRzWzBdO1xuICAgICAgICAgICAgICBmaXJzdFJlc3VsdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfU2Vzc2lvbicgJiYgIWF1dGguaXNNYXN0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWF1dGgudXNlciB8fCBmaXJzdFJlc3VsdC51c2VyLm9iamVjdElkICE9PSBhdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIGNhY2hlQWRhcHRlciA9IGNvbmZpZy5jYWNoZUNvbnRyb2xsZXI7XG4gICAgICAgICAgICAgIGNhY2hlQWRhcHRlci51c2VyLmRlbChmaXJzdFJlc3VsdC5zZXNzaW9uVG9rZW4pO1xuICAgICAgICAgICAgICBpbmZsYXRlZE9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihmaXJzdFJlc3VsdCk7XG4gICAgICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgICAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRGVsZXRlLFxuICAgICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgICAgaW5mbGF0ZWRPYmplY3QsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kIGZvciBkZWxldGUuJyk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGlmICghYXV0aC5pc01hc3Rlcikge1xuICAgICAgICByZXR1cm4gYXV0aC5nZXRVc2VyUm9sZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9KVxuICAgIC50aGVuKCgpID0+IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKCkpXG4gICAgLnRoZW4ocyA9PiB7XG4gICAgICBzY2hlbWFDb250cm9sbGVyID0gcztcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICAgIGlmICghYXV0aC5pc01hc3Rlcikge1xuICAgICAgICBvcHRpb25zLmFjbCA9IFsnKiddO1xuICAgICAgICBpZiAoYXV0aC51c2VyKSB7XG4gICAgICAgICAgb3B0aW9ucy5hY2wucHVzaChhdXRoLnVzZXIuaWQpO1xuICAgICAgICAgIG9wdGlvbnMuYWNsID0gb3B0aW9ucy5hY2wuY29uY2F0KGF1dGgudXNlclJvbGVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29uZmlnLmRhdGFiYXNlLmRlc3Ryb3koXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAge1xuICAgICAgICAgIG9iamVjdElkOiBvYmplY3RJZCxcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgc2NoZW1hQ29udHJvbGxlclxuICAgICAgKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIE5vdGlmeSBMaXZlUXVlcnkgc2VydmVyIGlmIHBvc3NpYmxlXG4gICAgICBjb25zdCBwZXJtcyA9IHNjaGVtYUNvbnRyb2xsZXIuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSk7XG4gICAgICBjb25maWcubGl2ZVF1ZXJ5Q29udHJvbGxlci5vbkFmdGVyRGVsZXRlKGNsYXNzTmFtZSwgaW5mbGF0ZWRPYmplY3QsIG51bGwsIHBlcm1zKTtcbiAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlLFxuICAgICAgICBhdXRoLFxuICAgICAgICBpbmZsYXRlZE9iamVjdCxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBjb250ZXh0XG4gICAgICApO1xuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIGhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IoZXJyb3IsIGNsYXNzTmFtZSwgYXV0aCk7XG4gICAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZSwgc3RhdHVzLCBsb2NhdGlvbn0gb2JqZWN0LlxuZnVuY3Rpb24gY3JlYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0T2JqZWN0LCBjbGllbnRTREssIGNvbnRleHQpIHtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnY3JlYXRlJywgY2xhc3NOYW1lLCBhdXRoKTtcbiAgdmFyIHdyaXRlID0gbmV3IFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgbnVsbCwgcmVzdE9iamVjdCwgbnVsbCwgY2xpZW50U0RLLCBjb250ZXh0KTtcbiAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBjb250YWlucyB0aGUgZmllbGRzIG9mIHRoZSB1cGRhdGUgdGhhdCB0aGVcbi8vIFJFU1QgQVBJIGlzIHN1cHBvc2VkIHRvIHJldHVybi5cbi8vIFVzdWFsbHksIHRoaXMgaXMganVzdCB1cGRhdGVkQXQuXG5mdW5jdGlvbiB1cGRhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9iamVjdCwgY2xpZW50U0RLLCBjb250ZXh0KSB7XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ3VwZGF0ZScsIGNsYXNzTmFtZSwgYXV0aCk7XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgaGFzVHJpZ2dlcnMgPSBjaGVja1RyaWdnZXJzKGNsYXNzTmFtZSwgY29uZmlnLCBbJ2JlZm9yZVNhdmUnLCAnYWZ0ZXJTYXZlJ10pO1xuICAgICAgY29uc3QgaGFzTGl2ZVF1ZXJ5ID0gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpO1xuICAgICAgaWYgKGhhc1RyaWdnZXJzIHx8IGhhc0xpdmVRdWVyeSkge1xuICAgICAgICAvLyBEbyBub3QgdXNlIGZpbmQsIGFzIGl0IHJ1bnMgdGhlIGJlZm9yZSBmaW5kc1xuICAgICAgICByZXR1cm4gbmV3IFJlc3RRdWVyeShcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgZmFsc2VcbiAgICAgICAgKS5leGVjdXRlKHtcbiAgICAgICAgICBvcDogJ3VwZGF0ZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoeyByZXN1bHRzIH0pID0+IHtcbiAgICAgIHZhciBvcmlnaW5hbFJlc3RPYmplY3Q7XG4gICAgICBpZiAocmVzdWx0cyAmJiByZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICBvcmlnaW5hbFJlc3RPYmplY3QgPSByZXN1bHRzWzBdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSZXN0V3JpdGUoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgIHJlc3RPYmplY3QsXG4gICAgICAgIG9yaWdpbmFsUmVzdE9iamVjdCxcbiAgICAgICAgY2xpZW50U0RLLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICAndXBkYXRlJ1xuICAgICAgKS5leGVjdXRlKCk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKSB7XG4gIC8vIElmIHdlJ3JlIHRyeWluZyB0byB1cGRhdGUgYSB1c2VyIHdpdGhvdXQgLyB3aXRoIGJhZCBzZXNzaW9uIHRva2VuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCAmJiAhYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5TRVNTSU9OX01JU1NJTkcsICdJbnN1ZmZpY2llbnQgYXV0aC4nKTtcbiAgfVxuICB0aHJvdyBlcnJvcjtcbn1cblxuY29uc3QgY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzID0gW1xuICAnX0pvYlN0YXR1cycsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSG9va3MnLFxuICAnX0dsb2JhbENvbmZpZycsXG4gICdfSm9iU2NoZWR1bGUnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl07XG4vLyBEaXNhbGxvd2luZyBhY2Nlc3MgdG8gdGhlIF9Sb2xlIGNvbGxlY3Rpb24gZXhjZXB0IGJ5IG1hc3RlciBrZXlcbmZ1bmN0aW9uIGVuZm9yY2VSb2xlU2VjdXJpdHkobWV0aG9kLCBjbGFzc05hbWUsIGF1dGgpIHtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19JbnN0YWxsYXRpb24nICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScgfHwgbWV0aG9kID09PSAnZmluZCcpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYENsaWVudHMgYXJlbid0IGFsbG93ZWQgdG8gcGVyZm9ybSB0aGUgJHttZXRob2R9IG9wZXJhdGlvbiBvbiB0aGUgaW5zdGFsbGF0aW9uIGNvbGxlY3Rpb24uYDtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLy9hbGwgdm9sYXRpbGVDbGFzc2VzIGFyZSBtYXN0ZXJLZXkgb25seVxuICBpZiAoY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzLmluZGV4T2YoY2xhc3NOYW1lKSA+PSAwICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgQ2xpZW50cyBhcmVuJ3QgYWxsb3dlZCB0byBwZXJmb3JtIHRoZSAke21ldGhvZH0gb3BlcmF0aW9uIG9uIHRoZSAke2NsYXNzTmFtZX0gY29sbGVjdGlvbi5gO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gIH1cblxuICAvLyByZWFkT25seSBtYXN0ZXJLZXkgaXMgbm90IGFsbG93ZWRcbiAgaWYgKGF1dGguaXNSZWFkT25seSAmJiAobWV0aG9kID09PSAnZGVsZXRlJyB8fCBtZXRob2QgPT09ICdjcmVhdGUnIHx8IG1ldGhvZCA9PT0gJ3VwZGF0ZScpKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgcmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHBlcmZvcm0gdGhlICR7bWV0aG9kfSBvcGVyYXRpb24uYDtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTiwgZXJyb3IpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGUsXG4gIGRlbCxcbiAgZmluZCxcbiAgZ2V0LFxuICB1cGRhdGUsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/triggers.js b/lib/triggers.js deleted file mode 100644 index 7283aae253..0000000000 --- a/lib/triggers.js +++ /dev/null @@ -1,1040 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.addFunction = addFunction; -exports.addJob = addJob; -exports.addTrigger = addTrigger; -exports.addFileTrigger = addFileTrigger; -exports.addConnectTrigger = addConnectTrigger; -exports.addLiveQueryEventHandler = addLiveQueryEventHandler; -exports.removeFunction = removeFunction; -exports.removeTrigger = removeTrigger; -exports._unregisterAll = _unregisterAll; -exports.getTrigger = getTrigger; -exports.getFileTrigger = getFileTrigger; -exports.triggerExists = triggerExists; -exports.getFunction = getFunction; -exports.getFunctionNames = getFunctionNames; -exports.getJob = getJob; -exports.getJobs = getJobs; -exports.getValidator = getValidator; -exports.getRequestObject = getRequestObject; -exports.getRequestQueryObject = getRequestQueryObject; -exports.getResponseObject = getResponseObject; -exports.maybeRunAfterFindTrigger = maybeRunAfterFindTrigger; -exports.maybeRunQueryTrigger = maybeRunQueryTrigger; -exports.resolveError = resolveError; -exports.maybeRunValidator = maybeRunValidator; -exports.maybeRunTrigger = maybeRunTrigger; -exports.inflate = inflate; -exports.runLiveQueryEventHandlers = runLiveQueryEventHandlers; -exports.getRequestFileObject = getRequestFileObject; -exports.maybeRunFileTrigger = maybeRunFileTrigger; -exports.maybeRunConnectTrigger = maybeRunConnectTrigger; -exports.maybeRunSubscribeTrigger = maybeRunSubscribeTrigger; -exports.maybeRunAfterEventTrigger = maybeRunAfterEventTrigger; -exports.Types = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _logger = require("./logger"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const Types = { - beforeLogin: 'beforeLogin', - afterLogin: 'afterLogin', - afterLogout: 'afterLogout', - beforeSave: 'beforeSave', - afterSave: 'afterSave', - beforeDelete: 'beforeDelete', - afterDelete: 'afterDelete', - beforeFind: 'beforeFind', - afterFind: 'afterFind', - beforeSaveFile: 'beforeSaveFile', - afterSaveFile: 'afterSaveFile', - beforeDeleteFile: 'beforeDeleteFile', - afterDeleteFile: 'afterDeleteFile', - beforeConnect: 'beforeConnect', - beforeSubscribe: 'beforeSubscribe', - afterEvent: 'afterEvent' -}; -exports.Types = Types; -const FileClassName = '@File'; -const ConnectClassName = '@Connect'; - -const baseStore = function () { - const Validators = Object.keys(Types).reduce(function (base, key) { - base[key] = {}; - return base; - }, {}); - const Functions = {}; - const Jobs = {}; - const LiveQuery = []; - const Triggers = Object.keys(Types).reduce(function (base, key) { - base[key] = {}; - return base; - }, {}); - return Object.freeze({ - Functions, - Jobs, - Validators, - Triggers, - LiveQuery - }); -}; - -function validateClassNameForTriggers(className, type) { - if (type == Types.beforeSave && className === '_PushStatus') { - // _PushStatus uses undocumented nested key increment ops - // allowing beforeSave would mess up the objects big time - // TODO: Allow proper documented way of using nested increment ops - throw 'Only afterSave is allowed on _PushStatus'; - } - - if ((type === Types.beforeLogin || type === Types.afterLogin) && className !== '_User') { - // TODO: check if upstream code will handle `Error` instance rather - // than this anti-pattern of throwing strings - throw 'Only the _User class is allowed for the beforeLogin and afterLogin triggers'; - } - - if (type === Types.afterLogout && className !== '_Session') { - // TODO: check if upstream code will handle `Error` instance rather - // than this anti-pattern of throwing strings - throw 'Only the _Session class is allowed for the afterLogout trigger.'; - } - - if (className === '_Session' && type !== Types.afterLogout) { - // TODO: check if upstream code will handle `Error` instance rather - // than this anti-pattern of throwing strings - throw 'Only the afterLogout trigger is allowed for the _Session class.'; - } - - return className; -} - -const _triggerStore = {}; -const Category = { - Functions: 'Functions', - Validators: 'Validators', - Jobs: 'Jobs', - Triggers: 'Triggers' -}; - -function getStore(category, name, applicationId) { - const path = name.split('.'); - path.splice(-1); // remove last component - - applicationId = applicationId || _node.default.applicationId; - _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); - let store = _triggerStore[applicationId][category]; - - for (const component of path) { - store = store[component]; - - if (!store) { - return undefined; - } - } - - return store; -} - -function add(category, name, handler, applicationId) { - const lastComponent = name.split('.').splice(-1); - const store = getStore(category, name, applicationId); - - if (store[lastComponent]) { - _logger.logger.warn(`Warning: Duplicate cloud functions exist for ${lastComponent}. Only the last one will be used and the others will be ignored.`); - } - - store[lastComponent] = handler; -} - -function remove(category, name, applicationId) { - const lastComponent = name.split('.').splice(-1); - const store = getStore(category, name, applicationId); - delete store[lastComponent]; -} - -function get(category, name, applicationId) { - const lastComponent = name.split('.').splice(-1); - const store = getStore(category, name, applicationId); - return store[lastComponent]; -} - -function addFunction(functionName, handler, validationHandler, applicationId) { - add(Category.Functions, functionName, handler, applicationId); - add(Category.Validators, functionName, validationHandler, applicationId); -} - -function addJob(jobName, handler, applicationId) { - add(Category.Jobs, jobName, handler, applicationId); -} - -function addTrigger(type, className, handler, applicationId, validationHandler) { - validateClassNameForTriggers(className, type); - add(Category.Triggers, `${type}.${className}`, handler, applicationId); - add(Category.Validators, `${type}.${className}`, validationHandler, applicationId); -} - -function addFileTrigger(type, handler, applicationId, validationHandler) { - add(Category.Triggers, `${type}.${FileClassName}`, handler, applicationId); - add(Category.Validators, `${type}.${FileClassName}`, validationHandler, applicationId); -} - -function addConnectTrigger(type, handler, applicationId, validationHandler) { - add(Category.Triggers, `${type}.${ConnectClassName}`, handler, applicationId); - add(Category.Validators, `${type}.${ConnectClassName}`, validationHandler, applicationId); -} - -function addLiveQueryEventHandler(handler, applicationId) { - applicationId = applicationId || _node.default.applicationId; - _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); - - _triggerStore[applicationId].LiveQuery.push(handler); -} - -function removeFunction(functionName, applicationId) { - remove(Category.Functions, functionName, applicationId); -} - -function removeTrigger(type, className, applicationId) { - remove(Category.Triggers, `${type}.${className}`, applicationId); -} - -function _unregisterAll() { - Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]); -} - -function getTrigger(className, triggerType, applicationId) { - if (!applicationId) { - throw 'Missing ApplicationID'; - } - - return get(Category.Triggers, `${triggerType}.${className}`, applicationId); -} - -function getFileTrigger(type, applicationId) { - return getTrigger(FileClassName, type, applicationId); -} - -function triggerExists(className, type, applicationId) { - return getTrigger(className, type, applicationId) != undefined; -} - -function getFunction(functionName, applicationId) { - return get(Category.Functions, functionName, applicationId); -} - -function getFunctionNames(applicationId) { - const store = _triggerStore[applicationId] && _triggerStore[applicationId][Category.Functions] || {}; - const functionNames = []; - - const extractFunctionNames = (namespace, store) => { - Object.keys(store).forEach(name => { - const value = store[name]; - - if (namespace) { - name = `${namespace}.${name}`; - } - - if (typeof value === 'function') { - functionNames.push(name); - } else { - extractFunctionNames(name, value); - } - }); - }; - - extractFunctionNames(null, store); - return functionNames; -} - -function getJob(jobName, applicationId) { - return get(Category.Jobs, jobName, applicationId); -} - -function getJobs(applicationId) { - var manager = _triggerStore[applicationId]; - - if (manager && manager.Jobs) { - return manager.Jobs; - } - - return undefined; -} - -function getValidator(functionName, applicationId) { - return get(Category.Validators, functionName, applicationId); -} - -function getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context) { - const request = { - triggerName: triggerType, - object: parseObject, - master: false, - log: config.loggerController, - headers: config.headers, - ip: config.ip - }; - - if (originalParseObject) { - request.original = originalParseObject; - } - - if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) { - // Set a copy of the context on the request object. - request.context = Object.assign({}, context); - } - - if (!auth) { - return request; - } - - if (auth.isMaster) { - request['master'] = true; - } - - if (auth.user) { - request['user'] = auth.user; - } - - if (auth.installationId) { - request['installationId'] = auth.installationId; - } - - return request; -} - -function getRequestQueryObject(triggerType, auth, query, count, config, context, isGet) { - isGet = !!isGet; - var request = { - triggerName: triggerType, - query, - master: false, - count, - log: config.loggerController, - isGet, - headers: config.headers, - ip: config.ip, - context: context || {} - }; - - if (!auth) { - return request; - } - - if (auth.isMaster) { - request['master'] = true; - } - - if (auth.user) { - request['user'] = auth.user; - } - - if (auth.installationId) { - request['installationId'] = auth.installationId; - } - - return request; -} // Creates the response object, and uses the request object to pass data -// The API will call this with REST API formatted objects, this will -// transform them to Parse.Object instances expected by Cloud Code. -// Any changes made to the object in a beforeSave will be included. - - -function getResponseObject(request, resolve, reject) { - return { - success: function (response) { - if (request.triggerName === Types.afterFind) { - if (!response) { - response = request.objects; - } - - response = response.map(object => { - return object.toJSON(); - }); - return resolve(response); - } // Use the JSON response - - - if (response && typeof response === 'object' && !request.object.equals(response) && request.triggerName === Types.beforeSave) { - return resolve(response); - } - - if (response && typeof response === 'object' && request.triggerName === Types.afterSave) { - return resolve(response); - } - - if (request.triggerName === Types.afterSave) { - return resolve(); - } - - response = {}; - - if (request.triggerName === Types.beforeSave) { - response['object'] = request.object._getSaveJSON(); - } - - return resolve(response); - }, - error: function (error) { - const e = resolveError(error, { - code: _node.default.Error.SCRIPT_FAILED, - message: 'Script failed. Unknown error.' - }); - reject(e); - } - }; -} - -function userIdForLog(auth) { - return auth && auth.user ? auth.user.id : undefined; -} - -function logTriggerAfterHook(triggerType, className, input, auth) { - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); - - _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, { - className, - triggerType, - user: userIdForLog(auth) - }); -} - -function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) { - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); - - const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result)); - - _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { - className, - triggerType, - user: userIdForLog(auth) - }); -} - -function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) { - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); - - _logger.logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, { - className, - triggerType, - error, - user: userIdForLog(auth) - }); -} - -function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config, query) { - return new Promise((resolve, reject) => { - const trigger = getTrigger(className, triggerType, config.applicationId); - - if (!trigger) { - return resolve(); - } - - const request = getRequestObject(triggerType, auth, null, null, config); - - if (query) { - request.query = query; - } - - const { - success, - error - } = getResponseObject(request, object => { - resolve(object); - }, error => { - reject(error); - }); - logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth); - request.objects = objects.map(object => { - //setting the class name to transform into parse object - object.className = className; - return _node.default.Object.fromJSON(object); - }); - return Promise.resolve().then(() => { - return maybeRunValidator(request, `${triggerType}.${className}`); - }).then(() => { - if (request.skipWithMasterKey) { - return request.objects; - } - - const response = trigger(request); - - if (response && typeof response.then === 'function') { - return response.then(results => { - if (!results) { - throw new _node.default.Error(_node.default.Error.SCRIPT_FAILED, 'AfterFind expect results to be returned in the promise'); - } - - return results; - }); - } - - return response; - }).then(success, error); - }).then(results => { - logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth); - return results; - }); -} - -function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, context, isGet) { - const trigger = getTrigger(className, triggerType, config.applicationId); - - if (!trigger) { - return Promise.resolve({ - restWhere, - restOptions - }); - } - - const json = Object.assign({}, restOptions); - json.where = restWhere; - const parseQuery = new _node.default.Query(className); - parseQuery.withJSON(json); - let count = false; - - if (restOptions) { - count = !!restOptions.count; - } - - const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, context, isGet); - return Promise.resolve().then(() => { - return maybeRunValidator(requestObject, `${triggerType}.${className}`); - }).then(() => { - if (requestObject.skipWithMasterKey) { - return requestObject.query; - } - - return trigger(requestObject); - }).then(result => { - let queryResult = parseQuery; - - if (result && result instanceof _node.default.Query) { - queryResult = result; - } - - const jsonQuery = queryResult.toJSON(); - - if (jsonQuery.where) { - restWhere = jsonQuery.where; - } - - if (jsonQuery.limit) { - restOptions = restOptions || {}; - restOptions.limit = jsonQuery.limit; - } - - if (jsonQuery.skip) { - restOptions = restOptions || {}; - restOptions.skip = jsonQuery.skip; - } - - if (jsonQuery.include) { - restOptions = restOptions || {}; - restOptions.include = jsonQuery.include; - } - - if (jsonQuery.excludeKeys) { - restOptions = restOptions || {}; - restOptions.excludeKeys = jsonQuery.excludeKeys; - } - - if (jsonQuery.explain) { - restOptions = restOptions || {}; - restOptions.explain = jsonQuery.explain; - } - - if (jsonQuery.keys) { - restOptions = restOptions || {}; - restOptions.keys = jsonQuery.keys; - } - - if (jsonQuery.order) { - restOptions = restOptions || {}; - restOptions.order = jsonQuery.order; - } - - if (jsonQuery.hint) { - restOptions = restOptions || {}; - restOptions.hint = jsonQuery.hint; - } - - if (requestObject.readPreference) { - restOptions = restOptions || {}; - restOptions.readPreference = requestObject.readPreference; - } - - if (requestObject.includeReadPreference) { - restOptions = restOptions || {}; - restOptions.includeReadPreference = requestObject.includeReadPreference; - } - - if (requestObject.subqueryReadPreference) { - restOptions = restOptions || {}; - restOptions.subqueryReadPreference = requestObject.subqueryReadPreference; - } - - return { - restWhere, - restOptions - }; - }, err => { - const error = resolveError(err, { - code: _node.default.Error.SCRIPT_FAILED, - message: 'Script failed. Unknown error.' - }); - throw error; - }); -} - -function resolveError(message, defaultOpts) { - if (!defaultOpts) { - defaultOpts = {}; - } - - if (!message) { - return new _node.default.Error(defaultOpts.code || _node.default.Error.SCRIPT_FAILED, defaultOpts.message || 'Script failed.'); - } - - if (message instanceof _node.default.Error) { - return message; - } - - const code = defaultOpts.code || _node.default.Error.SCRIPT_FAILED; // If it's an error, mark it as a script failed - - if (typeof message === 'string') { - return new _node.default.Error(code, message); - } - - const error = new _node.default.Error(code, message.message || message); - - if (message instanceof Error) { - error.stack = message.stack; - } - - return error; -} - -function maybeRunValidator(request, functionName) { - const theValidator = getValidator(functionName, _node.default.applicationId); - - if (!theValidator) { - return; - } - - if (typeof theValidator === 'object' && theValidator.skipWithMasterKey && request.master) { - request.skipWithMasterKey = true; - } - - return new Promise((resolve, reject) => { - return Promise.resolve().then(() => { - return typeof theValidator === 'object' ? builtInTriggerValidator(theValidator, request) : theValidator(request); - }).then(() => { - resolve(); - }).catch(e => { - const error = resolveError(e, { - code: _node.default.Error.VALIDATION_ERROR, - message: 'Validation failed.' - }); - reject(error); - }); - }); -} - -function builtInTriggerValidator(options, request) { - if (request.master && !options.validateMasterKey) { - return; - } - - let reqUser = request.user; - - if (!reqUser && request.object && request.object.className === '_User' && !request.object.existed()) { - reqUser = request.object; - } - - if (options.requireUser && !reqUser) { - throw 'Validation failed. Please login to continue.'; - } - - if (options.requireMaster && !request.master) { - throw 'Validation failed. Master key is required to complete this request.'; - } - - let params = request.params || {}; - - if (request.object) { - params = request.object.toJSON(); - } - - const requiredParam = key => { - const value = params[key]; - - if (value == null) { - throw `Validation failed. Please specify data for ${key}.`; - } - }; - - const validateOptions = (opt, key, val) => { - let opts = opt.options; - - if (typeof opts === 'function') { - try { - const result = opts(val); - - if (!result && result != null) { - throw opt.error || `Validation failed. Invalid value for ${key}.`; - } - } catch (e) { - if (!e) { - throw opt.error || `Validation failed. Invalid value for ${key}.`; - } - - throw opt.error || e.message || e; - } - - return; - } - - if (!Array.isArray(opts)) { - opts = [opt.options]; - } - - if (!opts.includes(val)) { - throw opt.error || `Validation failed. Invalid option for ${key}. Expected: ${opts.join(', ')}`; - } - }; - - const getType = fn => { - const match = fn && fn.toString().match(/^\s*function (\w+)/); - return (match ? match[1] : '').toLowerCase(); - }; - - if (Array.isArray(options.fields)) { - for (const key of options.fields) { - requiredParam(key); - } - } else { - for (const key in options.fields) { - const opt = options.fields[key]; - let val = params[key]; - - if (typeof opt === 'string') { - requiredParam(opt); - } - - if (typeof opt === 'object') { - if (opt.default != null && val == null) { - val = opt.default; - params[key] = val; - - if (request.object) { - request.object.set(key, val); - } - } - - if (opt.constant && request.object) { - if (request.original) { - request.object.set(key, request.original.get(key)); - } else if (opt.default != null) { - request.object.set(key, opt.default); - } - } - - if (opt.required) { - requiredParam(key); - } - - if (opt.type) { - const type = getType(opt.type); - - if (type == 'array' && !Array.isArray(val)) { - throw `Validation failed. Invalid type for ${key}. Expected: array`; - } else if (typeof val !== type) { - throw `Validation failed. Invalid type for ${key}. Expected: ${type}`; - } - } - - if (opt.options) { - validateOptions(opt, key, val); - } - } - } - } - - const userKeys = options.requireUserKeys || []; - - if (Array.isArray(userKeys)) { - for (const key of userKeys) { - if (!reqUser) { - throw 'Please login to make this request.'; - } - - if (reqUser.get(key) == null) { - throw `Validation failed. Please set data for ${key} on your account.`; - } - } - } else if (typeof userKeys === 'object') { - for (const key in options.requireUserKeys) { - const opt = options.requireUserKeys[key]; - - if (opt.options) { - validateOptions(opt, key, reqUser.get(key)); - } - } - } -} // To be used as part of the promise chain when saving/deleting an object -// Will resolve successfully if no trigger is configured -// Resolves to an object, empty or containing an object key. A beforeSave -// trigger will set the object key to the rest format object to save. -// originalParseObject is optional, we only need that for before/afterSave functions - - -function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config, context) { - if (!parseObject) { - return Promise.resolve({}); - } - - return new Promise(function (resolve, reject) { - var trigger = getTrigger(parseObject.className, triggerType, config.applicationId); - if (!trigger) return resolve(); - var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context); - var { - success, - error - } = getResponseObject(request, object => { - logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth); - - if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) { - Object.assign(context, request.context); - } - - resolve(object); - }, error => { - logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error); - reject(error); - }); // AfterSave and afterDelete triggers can return a promise, which if they - // do, needs to be resolved before this promise is resolved, - // so trigger execution is synced with RestWrite.execute() call. - // If triggers do not return a promise, they can run async code parallel - // to the RestWrite.execute() call. - - return Promise.resolve().then(() => { - return maybeRunValidator(request, `${triggerType}.${parseObject.className}`); - }).then(() => { - if (request.skipWithMasterKey) { - return Promise.resolve(); - } - - const promise = trigger(request); - - if (triggerType === Types.afterSave || triggerType === Types.afterDelete || triggerType === Types.afterLogin) { - logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth); - } // beforeSave is expected to return null (nothing) - - - if (triggerType === Types.beforeSave) { - if (promise && typeof promise.then === 'function') { - return promise.then(response => { - // response.object may come from express routing before hook - if (response && response.object) { - return response; - } - - return null; - }); - } - - return null; - } - - return promise; - }).then(success, error); - }); -} // Converts a REST-format object to a Parse.Object -// data is either className or an object - - -function inflate(data, restObject) { - var copy = typeof data == 'object' ? data : { - className: data - }; - - for (var key in restObject) { - copy[key] = restObject[key]; - } - - return _node.default.Object.fromJSON(copy); -} - -function runLiveQueryEventHandlers(data, applicationId = _node.default.applicationId) { - if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) { - return; - } - - _triggerStore[applicationId].LiveQuery.forEach(handler => handler(data)); -} - -function getRequestFileObject(triggerType, auth, fileObject, config) { - const request = _objectSpread(_objectSpread({}, fileObject), {}, { - triggerName: triggerType, - master: false, - log: config.loggerController, - headers: config.headers, - ip: config.ip - }); - - if (!auth) { - return request; - } - - if (auth.isMaster) { - request['master'] = true; - } - - if (auth.user) { - request['user'] = auth.user; - } - - if (auth.installationId) { - request['installationId'] = auth.installationId; - } - - return request; -} - -async function maybeRunFileTrigger(triggerType, fileObject, config, auth) { - const fileTrigger = getFileTrigger(triggerType, config.applicationId); - - if (typeof fileTrigger === 'function') { - try { - const request = getRequestFileObject(triggerType, auth, fileObject, config); - await maybeRunValidator(request, `${triggerType}.${FileClassName}`); - - if (request.skipWithMasterKey) { - return fileObject; - } - - const result = await fileTrigger(request); - logTriggerSuccessBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { - fileSize: fileObject.fileSize - }), result, auth); - return result || fileObject; - } catch (error) { - logTriggerErrorBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { - fileSize: fileObject.fileSize - }), auth, error); - throw error; - } - } - - return fileObject; -} - -async function maybeRunConnectTrigger(triggerType, request) { - const trigger = getTrigger(ConnectClassName, triggerType, _node.default.applicationId); - - if (!trigger) { - return; - } - - request.user = await userForSessionToken(request.sessionToken); - await maybeRunValidator(request, `${triggerType}.${ConnectClassName}`); - - if (request.skipWithMasterKey) { - return; - } - - return trigger(request); -} - -async function maybeRunSubscribeTrigger(triggerType, className, request) { - const trigger = getTrigger(className, triggerType, _node.default.applicationId); - - if (!trigger) { - return; - } - - const parseQuery = new _node.default.Query(className); - parseQuery.withJSON(request.query); - request.query = parseQuery; - request.user = await userForSessionToken(request.sessionToken); - await maybeRunValidator(request, `${triggerType}.${className}`); - - if (request.skipWithMasterKey) { - return; - } - - await trigger(request); - const query = request.query.toJSON(); - - if (query.keys) { - query.fields = query.keys.split(','); - } - - request.query = query; -} - -async function maybeRunAfterEventTrigger(triggerType, className, request) { - const trigger = getTrigger(className, triggerType, _node.default.applicationId); - - if (!trigger) { - return; - } - - if (request.object) { - request.object = _node.default.Object.fromJSON(request.object); - } - - if (request.original) { - request.original = _node.default.Object.fromJSON(request.original); - } - - request.user = await userForSessionToken(request.sessionToken); - await maybeRunValidator(request, `${triggerType}.${className}`); - - if (request.skipWithMasterKey) { - return; - } - - return trigger(request); -} - -async function userForSessionToken(sessionToken) { - if (!sessionToken) { - return; - } - - const q = new _node.default.Query('_Session'); - q.equalTo('sessionToken', sessionToken); - const session = await q.first({ - useMasterKey: true - }); - - if (!session) { - return; - } - - const user = session.get('user'); - - if (!user) { - return; - } - - await user.fetch({ - useMasterKey: true - }); - return user; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJuYW1lcyI6WyJUeXBlcyIsImJlZm9yZUxvZ2luIiwiYWZ0ZXJMb2dpbiIsImFmdGVyTG9nb3V0IiwiYmVmb3JlU2F2ZSIsImFmdGVyU2F2ZSIsImJlZm9yZURlbGV0ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJlZm9yZVNhdmVGaWxlIiwiYWZ0ZXJTYXZlRmlsZSIsImJlZm9yZURlbGV0ZUZpbGUiLCJhZnRlckRlbGV0ZUZpbGUiLCJiZWZvcmVDb25uZWN0IiwiYmVmb3JlU3Vic2NyaWJlIiwiYWZ0ZXJFdmVudCIsIkZpbGVDbGFzc05hbWUiLCJDb25uZWN0Q2xhc3NOYW1lIiwiYmFzZVN0b3JlIiwiVmFsaWRhdG9ycyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJiYXNlIiwia2V5IiwiRnVuY3Rpb25zIiwiSm9icyIsIkxpdmVRdWVyeSIsIlRyaWdnZXJzIiwiZnJlZXplIiwidmFsaWRhdGVDbGFzc05hbWVGb3JUcmlnZ2VycyIsImNsYXNzTmFtZSIsInR5cGUiLCJfdHJpZ2dlclN0b3JlIiwiQ2F0ZWdvcnkiLCJnZXRTdG9yZSIsImNhdGVnb3J5IiwibmFtZSIsImFwcGxpY2F0aW9uSWQiLCJwYXRoIiwic3BsaXQiLCJzcGxpY2UiLCJQYXJzZSIsInN0b3JlIiwiY29tcG9uZW50IiwidW5kZWZpbmVkIiwiYWRkIiwiaGFuZGxlciIsImxhc3RDb21wb25lbnQiLCJsb2dnZXIiLCJ3YXJuIiwicmVtb3ZlIiwiZ2V0IiwiYWRkRnVuY3Rpb24iLCJmdW5jdGlvbk5hbWUiLCJ2YWxpZGF0aW9uSGFuZGxlciIsImFkZEpvYiIsImpvYk5hbWUiLCJhZGRUcmlnZ2VyIiwiYWRkRmlsZVRyaWdnZXIiLCJhZGRDb25uZWN0VHJpZ2dlciIsImFkZExpdmVRdWVyeUV2ZW50SGFuZGxlciIsInB1c2giLCJyZW1vdmVGdW5jdGlvbiIsInJlbW92ZVRyaWdnZXIiLCJfdW5yZWdpc3RlckFsbCIsImZvckVhY2giLCJhcHBJZCIsImdldFRyaWdnZXIiLCJ0cmlnZ2VyVHlwZSIsImdldEZpbGVUcmlnZ2VyIiwidHJpZ2dlckV4aXN0cyIsImdldEZ1bmN0aW9uIiwiZ2V0RnVuY3Rpb25OYW1lcyIsImZ1bmN0aW9uTmFtZXMiLCJleHRyYWN0RnVuY3Rpb25OYW1lcyIsIm5hbWVzcGFjZSIsInZhbHVlIiwiZ2V0Sm9iIiwiZ2V0Sm9icyIsIm1hbmFnZXIiLCJnZXRWYWxpZGF0b3IiLCJnZXRSZXF1ZXN0T2JqZWN0IiwiYXV0aCIsInBhcnNlT2JqZWN0Iiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImNvbmZpZyIsImNvbnRleHQiLCJyZXF1ZXN0IiwidHJpZ2dlck5hbWUiLCJvYmplY3QiLCJtYXN0ZXIiLCJsb2ciLCJsb2dnZXJDb250cm9sbGVyIiwiaGVhZGVycyIsImlwIiwib3JpZ2luYWwiLCJhc3NpZ24iLCJpc01hc3RlciIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsImdldFJlcXVlc3RRdWVyeU9iamVjdCIsInF1ZXJ5IiwiY291bnQiLCJpc0dldCIsImdldFJlc3BvbnNlT2JqZWN0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJ0b0pTT04iLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJlcnJvciIsImUiLCJyZXNvbHZlRXJyb3IiLCJjb2RlIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwibWVzc2FnZSIsInVzZXJJZEZvckxvZyIsImlkIiwibG9nVHJpZ2dlckFmdGVySG9vayIsImlucHV0IiwiY2xlYW5JbnB1dCIsInRydW5jYXRlTG9nTWVzc2FnZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJpbmZvIiwibG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rIiwicmVzdWx0IiwiY2xlYW5SZXN1bHQiLCJsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiUHJvbWlzZSIsInRyaWdnZXIiLCJmcm9tSlNPTiIsInRoZW4iLCJtYXliZVJ1blZhbGlkYXRvciIsInNraXBXaXRoTWFzdGVyS2V5IiwicmVzdWx0cyIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJqc29uIiwid2hlcmUiLCJwYXJzZVF1ZXJ5IiwiUXVlcnkiLCJ3aXRoSlNPTiIsInJlcXVlc3RPYmplY3QiLCJxdWVyeVJlc3VsdCIsImpzb25RdWVyeSIsImxpbWl0Iiwic2tpcCIsImluY2x1ZGUiLCJleGNsdWRlS2V5cyIsImV4cGxhaW4iLCJvcmRlciIsImhpbnQiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJlcnIiLCJkZWZhdWx0T3B0cyIsInN0YWNrIiwidGhlVmFsaWRhdG9yIiwiYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IiLCJjYXRjaCIsIlZBTElEQVRJT05fRVJST1IiLCJvcHRpb25zIiwidmFsaWRhdGVNYXN0ZXJLZXkiLCJyZXFVc2VyIiwiZXhpc3RlZCIsInJlcXVpcmVVc2VyIiwicmVxdWlyZU1hc3RlciIsInBhcmFtcyIsInJlcXVpcmVkUGFyYW0iLCJ2YWxpZGF0ZU9wdGlvbnMiLCJvcHQiLCJ2YWwiLCJvcHRzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZXMiLCJqb2luIiwiZ2V0VHlwZSIsImZuIiwibWF0Y2giLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiZmllbGRzIiwiZGVmYXVsdCIsInNldCIsImNvbnN0YW50IiwicmVxdWlyZWQiLCJ1c2VyS2V5cyIsInJlcXVpcmVVc2VyS2V5cyIsIm1heWJlUnVuVHJpZ2dlciIsInByb21pc2UiLCJpbmZsYXRlIiwiZGF0YSIsInJlc3RPYmplY3QiLCJjb3B5IiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsImdldFJlcXVlc3RGaWxlT2JqZWN0IiwiZmlsZU9iamVjdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJmaWxlVHJpZ2dlciIsImZpbGUiLCJmaWxlU2l6ZSIsIm1heWJlUnVuQ29ubmVjdFRyaWdnZXIiLCJ1c2VyRm9yU2Vzc2lvblRva2VuIiwic2Vzc2lvblRva2VuIiwibWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyIiwibWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlciIsInEiLCJlcXVhbFRvIiwic2Vzc2lvbiIsImZpcnN0IiwidXNlTWFzdGVyS2V5IiwiZmV0Y2giXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBOztBQUNBOzs7Ozs7Ozs7O0FBRU8sTUFBTUEsS0FBSyxHQUFHO0FBQ25CQyxFQUFBQSxXQUFXLEVBQUUsYUFETTtBQUVuQkMsRUFBQUEsVUFBVSxFQUFFLFlBRk87QUFHbkJDLEVBQUFBLFdBQVcsRUFBRSxhQUhNO0FBSW5CQyxFQUFBQSxVQUFVLEVBQUUsWUFKTztBQUtuQkMsRUFBQUEsU0FBUyxFQUFFLFdBTFE7QUFNbkJDLEVBQUFBLFlBQVksRUFBRSxjQU5LO0FBT25CQyxFQUFBQSxXQUFXLEVBQUUsYUFQTTtBQVFuQkMsRUFBQUEsVUFBVSxFQUFFLFlBUk87QUFTbkJDLEVBQUFBLFNBQVMsRUFBRSxXQVRRO0FBVW5CQyxFQUFBQSxjQUFjLEVBQUUsZ0JBVkc7QUFXbkJDLEVBQUFBLGFBQWEsRUFBRSxlQVhJO0FBWW5CQyxFQUFBQSxnQkFBZ0IsRUFBRSxrQkFaQztBQWFuQkMsRUFBQUEsZUFBZSxFQUFFLGlCQWJFO0FBY25CQyxFQUFBQSxhQUFhLEVBQUUsZUFkSTtBQWVuQkMsRUFBQUEsZUFBZSxFQUFFLGlCQWZFO0FBZ0JuQkMsRUFBQUEsVUFBVSxFQUFFO0FBaEJPLENBQWQ7O0FBbUJQLE1BQU1DLGFBQWEsR0FBRyxPQUF0QjtBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFVBQXpCOztBQUVBLE1BQU1DLFNBQVMsR0FBRyxZQUFZO0FBQzVCLFFBQU1DLFVBQVUsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVl0QixLQUFaLEVBQW1CdUIsTUFBbkIsQ0FBMEIsVUFBVUMs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QUFZLEVBQUU7QUFBaEIsR0FBWCxDQUFOO0FBQ0EsU0FBTzFILElBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRyaWdnZXJzLmpzXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBjb25zdCBUeXBlcyA9IHtcbiAgYmVmb3JlTG9naW46ICdiZWZvcmVMb2dpbicsXG4gIGFmdGVyTG9naW46ICdhZnRlckxvZ2luJyxcbiAgYWZ0ZXJMb2dvdXQ6ICdhZnRlckxvZ291dCcsXG4gIGJlZm9yZVNhdmU6ICdiZWZvcmVTYXZlJyxcbiAgYWZ0ZXJTYXZlOiAnYWZ0ZXJTYXZlJyxcbiAgYmVmb3JlRGVsZXRlOiAnYmVmb3JlRGVsZXRlJyxcbiAgYWZ0ZXJEZWxldGU6ICdhZnRlckRlbGV0ZScsXG4gIGJlZm9yZUZpbmQ6ICdiZWZvcmVGaW5kJyxcbiAgYWZ0ZXJGaW5kOiAnYWZ0ZXJGaW5kJyxcbiAgYmVmb3JlU2F2ZUZpbGU6ICdiZWZvcmVTYXZlRmlsZScsXG4gIGFmdGVyU2F2ZUZpbGU6ICdhZnRlclNhdmVGaWxlJyxcbiAgYmVmb3JlRGVsZXRlRmlsZTogJ2JlZm9yZURlbGV0ZUZpbGUnLFxuICBhZnRlckRlbGV0ZUZpbGU6ICdhZnRlckRlbGV0ZUZpbGUnLFxuICBiZWZvcmVDb25uZWN0OiAnYmVmb3JlQ29ubmVjdCcsXG4gIGJlZm9yZVN1YnNjcmliZTogJ2JlZm9yZVN1YnNjcmliZScsXG4gIGFmdGVyRXZlbnQ6ICdhZnRlckV2ZW50Jyxcbn07XG5cbmNvbnN0IEZpbGVDbGFzc05hbWUgPSAnQEZpbGUnO1xuY29uc3QgQ29ubmVjdENsYXNzTmFtZSA9ICdAQ29ubmVjdCc7XG5cbmNvbnN0IGJhc2VTdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgVmFsaWRhdG9ycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG4gIGNvbnN0IEZ1bmN0aW9ucyA9IHt9O1xuICBjb25zdCBKb2JzID0ge307XG4gIGNvbnN0IExpdmVRdWVyeSA9IFtdO1xuICBjb25zdCBUcmlnZ2VycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIEZ1bmN0aW9ucyxcbiAgICBKb2JzLFxuICAgIFZhbGlkYXRvcnMsXG4gICAgVHJpZ2dlcnMsXG4gICAgTGl2ZVF1ZXJ5LFxuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMoY2xhc3NOYW1lLCB0eXBlKSB7XG4gIGlmICh0eXBlID09IFR5cGVzLmJlZm9yZVNhdmUgJiYgY2xhc3NOYW1lID09PSAnX1B1c2hTdGF0dXMnKSB7XG4gICAgLy8gX1B1c2hTdGF0dXMgdXNlcyB1bmRvY3VtZW50ZWQgbmVzdGVkIGtleSBpbmNyZW1lbnQgb3BzXG4gICAgLy8gYWxsb3dpbmcgYmVmb3JlU2F2ZSB3b3VsZCBtZXNzIHVwIHRoZSBvYmplY3RzIGJpZyB0aW1lXG4gICAgLy8gVE9ETzogQWxsb3cgcHJvcGVyIGRvY3VtZW50ZWQgd2F5IG9mIHVzaW5nIG5lc3RlZCBpbmNyZW1lbnQgb3BzXG4gICAgdGhyb3cgJ09ubHkgYWZ0ZXJTYXZlIGlzIGFsbG93ZWQgb24gX1B1c2hTdGF0dXMnO1xuICB9XG4gIGlmICgodHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHwgdHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbikgJiYgY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBfVXNlciBjbGFzcyBpcyBhbGxvd2VkIGZvciB0aGUgYmVmb3JlTG9naW4gYW5kIGFmdGVyTG9naW4gdHJpZ2dlcnMnO1xuICB9XG4gIGlmICh0eXBlID09PSBUeXBlcy5hZnRlckxvZ291dCAmJiBjbGFzc05hbWUgIT09ICdfU2Vzc2lvbicpIHtcbiAgICAvLyBUT0RPOiBjaGVjayBpZiB1cHN0cmVhbSBjb2RlIHdpbGwgaGFuZGxlIGBFcnJvcmAgaW5zdGFuY2UgcmF0aGVyXG4gICAgLy8gdGhhbiB0aGlzIGFudGktcGF0dGVybiBvZiB0aHJvd2luZyBzdHJpbmdzXG4gICAgdGhyb3cgJ09ubHkgdGhlIF9TZXNzaW9uIGNsYXNzIGlzIGFsbG93ZWQgZm9yIHRoZSBhZnRlckxvZ291dCB0cmlnZ2VyLic7XG4gIH1cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19TZXNzaW9uJyAmJiB0eXBlICE9PSBUeXBlcy5hZnRlckxvZ291dCkge1xuICAgIC8vIFRPRE86IGNoZWNrIGlmIHVwc3RyZWFtIGNvZGUgd2lsbCBoYW5kbGUgYEVycm9yYCBpbnN0YW5jZSByYXRoZXJcbiAgICAvLyB0aGFuIHRoaXMgYW50aS1wYXR0ZXJuIG9mIHRocm93aW5nIHN0cmluZ3NcbiAgICB0aHJvdyAnT25seSB0aGUgYWZ0ZXJMb2dvdXQgdHJpZ2dlciBpcyBhbGxvd2VkIGZvciB0aGUgX1Nlc3Npb24gY2xhc3MuJztcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuXG5jb25zdCBfdHJpZ2dlclN0b3JlID0ge307XG5cbmNvbnN0IENhdGVnb3J5ID0ge1xuICBGdW5jdGlvbnM6ICdGdW5jdGlvbnMnLFxuICBWYWxpZGF0b3JzOiAnVmFsaWRhdG9ycycsXG4gIEpvYnM6ICdKb2JzJyxcbiAgVHJpZ2dlcnM6ICdUcmlnZ2VycycsXG59O1xuXG5mdW5jdGlvbiBnZXRTdG9yZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBwYXRoID0gbmFtZS5zcGxpdCgnLicpO1xuICBwYXRoLnNwbGljZSgtMSk7IC8vIHJlbW92ZSBsYXN0IGNvbXBvbmVudFxuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgbGV0IHN0b3JlID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVtjYXRlZ29yeV07XG4gIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgpIHtcbiAgICBzdG9yZSA9IHN0b3JlW2NvbXBvbmVudF07XG4gICAgaWYgKCFzdG9yZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0b3JlO1xufVxuXG5mdW5jdGlvbiBhZGQoY2F0ZWdvcnksIG5hbWUsIGhhbmRsZXIsIGFwcGxpY2F0aW9uSWQpIHtcbiAgY29uc3QgbGFzdENvbXBvbmVudCA9IG5hbWUuc3BsaXQoJy4nKS5zcGxpY2UoLTEpO1xuICBjb25zdCBzdG9yZSA9IGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgaWYgKHN0b3JlW2xhc3RDb21wb25lbnRdKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgV2FybmluZzogRHVwbGljYXRlIGNsb3VkIGZ1bmN0aW9ucyBleGlzdCBmb3IgJHtsYXN0Q29tcG9uZW50fS4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSB1c2VkIGFuZCB0aGUgb3RoZXJzIHdpbGwgYmUgaWdub3JlZC5gXG4gICAgKTtcbiAgfVxuICBzdG9yZVtsYXN0Q29tcG9uZW50XSA9IGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICBkZWxldGUgc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmZ1bmN0aW9uIGdldChjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICByZXR1cm4gc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5GdW5jdGlvbnMsIGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEpvYihqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyaWdnZXIodHlwZSwgY2xhc3NOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFkZChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHlwZX0uJHtjbGFzc05hbWV9YCwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGaWxlVHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb25uZWN0VHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZW1vdmUoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmVtb3ZlKENhdGVnb3J5LlRyaWdnZXJzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF91bnJlZ2lzdGVyQWxsKCkge1xuICBPYmplY3Qua2V5cyhfdHJpZ2dlclN0b3JlKS5mb3JFYWNoKGFwcElkID0+IGRlbGV0ZSBfdHJpZ2dlclN0b3JlW2FwcElkXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFhcHBsaWNhdGlvbklkKSB7XG4gICAgdGhyb3cgJ01pc3NpbmcgQXBwbGljYXRpb25JRCc7XG4gIH1cbiAgcmV0dXJuIGdldChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWAsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZVRyaWdnZXIodHlwZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0VHJpZ2dlcihGaWxlQ2xhc3NOYW1lLCB0eXBlLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXJFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgYXBwbGljYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHlwZSwgYXBwbGljYXRpb25JZCkgIT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb24oZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHJldHVybiBnZXQoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lcyhhcHBsaWNhdGlvbklkKSB7XG4gIGNvbnN0IHN0b3JlID1cbiAgICAoX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSAmJiBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdW0NhdGVnb3J5LkZ1bmN0aW9uc10pIHx8IHt9O1xuICBjb25zdCBmdW5jdGlvbk5hbWVzID0gW107XG4gIGNvbnN0IGV4dHJhY3RGdW5jdGlvbk5hbWVzID0gKG5hbWVzcGFjZSwgc3RvcmUpID0+IHtcbiAgICBPYmplY3Qua2V5cyhzdG9yZSkuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3RvcmVbbmFtZV07XG4gICAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICAgIG5hbWUgPSBgJHtuYW1lc3BhY2V9LiR7bmFtZX1gO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmdW5jdGlvbk5hbWVzLnB1c2gobmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHRyYWN0RnVuY3Rpb25OYW1lcyhuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIGV4dHJhY3RGdW5jdGlvbk5hbWVzKG51bGwsIHN0b3JlKTtcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRKb2Ioam9iTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LkpvYnMsIGpvYk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9icyhhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9icztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LlZhbGlkYXRvcnMsIGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0T2JqZWN0KFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIG9iamVjdDogcGFyc2VPYmplY3QsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gIH07XG5cbiAgaWYgKG9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICByZXF1ZXN0Lm9yaWdpbmFsID0gb3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgfVxuXG4gIGlmIChcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlRGVsZXRlIHx8XG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlXG4gICkge1xuICAgIC8vIFNldCBhIGNvcHkgb2YgdGhlIGNvbnRleHQgb24gdGhlIHJlcXVlc3Qgb2JqZWN0LlxuICAgIHJlcXVlc3QuY29udGV4dCA9IE9iamVjdC5hc3NpZ24oe30sIGNvbnRleHQpO1xuICB9XG5cbiAgaWYgKCFhdXRoKSB7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cbiAgaWYgKGF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXF1ZXN0WydtYXN0ZXInXSA9IHRydWU7XG4gIH1cbiAgaWYgKGF1dGgudXNlcikge1xuICAgIHJlcXVlc3RbJ3VzZXInXSA9IGF1dGgudXNlcjtcbiAgfVxuICBpZiAoYXV0aC5pbnN0YWxsYXRpb25JZCkge1xuICAgIHJlcXVlc3RbJ2luc3RhbGxhdGlvbklkJ10gPSBhdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdFF1ZXJ5T2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBxdWVyeSwgY291bnQsIGNvbmZpZywgY29udGV4dCwgaXNHZXQpIHtcbiAgaXNHZXQgPSAhIWlzR2V0O1xuXG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyVHlwZSxcbiAgICBxdWVyeSxcbiAgICBtYXN0ZXI6IGZhbHNlLFxuICAgIGNvdW50LFxuICAgIGxvZzogY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgaXNHZXQsXG4gICAgaGVhZGVyczogY29uZmlnLmhlYWRlcnMsXG4gICAgaXA6IGNvbmZpZy5pcCxcbiAgICBjb250ZXh0OiBjb250ZXh0IHx8IHt9LFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuLy8gQ3JlYXRlcyB0aGUgcmVzcG9uc2Ugb2JqZWN0LCBhbmQgdXNlcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gcGFzcyBkYXRhXG4vLyBUaGUgQVBJIHdpbGwgY2FsbCB0aGlzIHdpdGggUkVTVCBBUEkgZm9ybWF0dGVkIG9iamVjdHMsIHRoaXMgd2lsbFxuLy8gdHJhbnNmb3JtIHRoZW0gdG8gUGFyc2UuT2JqZWN0IGluc3RhbmNlcyBleHBlY3RlZCBieSBDbG91ZCBDb2RlLlxuLy8gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgb2JqZWN0IGluIGEgYmVmb3JlU2F2ZSB3aWxsIGJlIGluY2x1ZGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyRmluZCkge1xuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgcmVzcG9uc2UgPSByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0LnRvSlNPTigpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHRoZSBKU09OIHJlc3BvbnNlXG4gICAgICBpZiAoXG4gICAgICAgIHJlc3BvbnNlICYmXG4gICAgICAgIHR5cGVvZiByZXNwb25zZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIXJlcXVlc3Qub2JqZWN0LmVxdWFscyhyZXNwb25zZSkgJiZcbiAgICAgICAgcmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXNwb25zZSAmJiB0eXBlb2YgcmVzcG9uc2UgPT09ICdvYmplY3QnICYmIHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyU2F2ZSkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmJlZm9yZVNhdmUpIHtcbiAgICAgICAgcmVzcG9uc2VbJ29iamVjdCddID0gcmVxdWVzdC5vYmplY3QuX2dldFNhdmVKU09OKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgfSxcbiAgICBlcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBjb25zdCBlID0gcmVzb2x2ZUVycm9yKGVycm9yLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgIG1lc3NhZ2U6ICdTY3JpcHQgZmFpbGVkLiBVbmtub3duIGVycm9yLicsXG4gICAgICB9KTtcbiAgICAgIHJlamVjdChlKTtcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiB1c2VySWRGb3JMb2coYXV0aCkge1xuICByZXR1cm4gYXV0aCAmJiBhdXRoLnVzZXIgPyBhdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgpIHtcbiAgY29uc3QgY2xlYW5JbnB1dCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKTtcbiAgbG9nZ2VyLmluZm8oXG4gICAgYCR7dHJpZ2dlclR5cGV9IHRyaWdnZXJlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKFxuICAgICAgYXV0aFxuICAgICl9OlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1gLFxuICAgIHtcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgdXNlcjogdXNlcklkRm9yTG9nKGF1dGgpLFxuICAgIH1cbiAgKTtcbn1cblxuZnVuY3Rpb24gbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIGlucHV0LCByZXN1bHQsIGF1dGgpIHtcbiAgY29uc3QgY2xlYW5JbnB1dCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKTtcbiAgY29uc3QgY2xlYW5SZXN1bHQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICBsb2dnZXIuaW5mbyhcbiAgICBgJHt0cmlnZ2VyVHlwZX0gdHJpZ2dlcmVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIGlucHV0LCBhdXRoLCBlcnJvcikge1xuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXIuZXJyb3IoXG4gICAgYCR7dHJpZ2dlclR5cGV9IGZhaWxlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKFxuICAgICAgYXV0aFxuICAgICl9OlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gLFxuICAgIHtcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgZXJyb3IsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyKHRyaWdnZXJUeXBlLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdHMsIGNvbmZpZywgcXVlcnkpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgbnVsbCwgbnVsbCwgY29uZmlnKTtcbiAgICBpZiAocXVlcnkpIHtcbiAgICAgIHJlcXVlc3QucXVlcnkgPSBxdWVyeTtcbiAgICB9XG4gICAgY29uc3QgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgb2JqZWN0ID0+IHtcbiAgICAgICAgcmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICApO1xuICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCAnQWZ0ZXJGaW5kJywgSlNPTi5zdHJpbmdpZnkob2JqZWN0cyksIGF1dGgpO1xuICAgIHJlcXVlc3Qub2JqZWN0cyA9IG9iamVjdHMubWFwKG9iamVjdCA9PiB7XG4gICAgICAvL3NldHRpbmcgdGhlIGNsYXNzIG5hbWUgdG8gdHJhbnNmb3JtIGludG8gcGFyc2Ugb2JqZWN0XG4gICAgICBvYmplY3QuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgICAgcmV0dXJuIFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgICByZXR1cm4gcmVxdWVzdC5vYmplY3RzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gdHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgICAgaWYgKHJlc3BvbnNlICYmIHR5cGVvZiByZXNwb25zZS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgICAgICAgICAgJ0FmdGVyRmluZCBleHBlY3QgcmVzdWx0cyB0byBiZSByZXR1cm5lZCBpbiB0aGUgcHJvbWlzZSdcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gIH0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgbG9nVHJpZ2dlckFmdGVySG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBKU09OLnN0cmluZ2lmeShyZXN1bHRzKSwgYXV0aCk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5RdWVyeVRyaWdnZXIoXG4gIHRyaWdnZXJUeXBlLFxuICBjbGFzc05hbWUsXG4gIHJlc3RXaGVyZSxcbiAgcmVzdE9wdGlvbnMsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgY29udGV4dCxcbiAgaXNHZXRcbikge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgcmVzdFdoZXJlLFxuICAgICAgcmVzdE9wdGlvbnMsXG4gICAgfSk7XG4gIH1cbiAgY29uc3QganNvbiA9IE9iamVjdC5hc3NpZ24oe30sIHJlc3RPcHRpb25zKTtcbiAganNvbi53aGVyZSA9IHJlc3RXaGVyZTtcblxuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gIHBhcnNlUXVlcnkud2l0aEpTT04oanNvbik7XG5cbiAgbGV0IGNvdW50ID0gZmFsc2U7XG4gIGlmIChyZXN0T3B0aW9ucykge1xuICAgIGNvdW50ID0gISFyZXN0T3B0aW9ucy5jb3VudDtcbiAgfVxuICBjb25zdCByZXF1ZXN0T2JqZWN0ID0gZ2V0UmVxdWVzdFF1ZXJ5T2JqZWN0KFxuICAgIHRyaWdnZXJUeXBlLFxuICAgIGF1dGgsXG4gICAgcGFyc2VRdWVyeSxcbiAgICBjb3VudCxcbiAgICBjb25maWcsXG4gICAgY29udGV4dCxcbiAgICBpc0dldFxuICApO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdE9iamVjdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHJlcXVlc3RPYmplY3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3RPYmplY3QucXVlcnk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJpZ2dlcihyZXF1ZXN0T2JqZWN0KTtcbiAgICB9KVxuICAgIC50aGVuKFxuICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgbGV0IHF1ZXJ5UmVzdWx0ID0gcGFyc2VRdWVyeTtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgICAgICAgIHF1ZXJ5UmVzdWx0ID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGpzb25RdWVyeSA9IHF1ZXJ5UmVzdWx0LnRvSlNPTigpO1xuICAgICAgICBpZiAoanNvblF1ZXJ5LndoZXJlKSB7XG4gICAgICAgICAgcmVzdFdoZXJlID0ganNvblF1ZXJ5LndoZXJlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkubGltaXQpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmxpbWl0ID0ganNvblF1ZXJ5LmxpbWl0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuc2tpcCkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuc2tpcCA9IGpzb25RdWVyeS5za2lwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuaW5jbHVkZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZSA9IGpzb25RdWVyeS5pbmNsdWRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuZXhjbHVkZUtleXMpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmV4Y2x1ZGVLZXlzID0ganNvblF1ZXJ5LmV4Y2x1ZGVLZXlzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuZXhwbGFpbikge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuZXhwbGFpbiA9IGpzb25RdWVyeS5leHBsYWluO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkua2V5cykge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMua2V5cyA9IGpzb25RdWVyeS5rZXlzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkub3JkZXIpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLm9yZGVyID0ganNvblF1ZXJ5Lm9yZGVyO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uUXVlcnkuaGludCkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuaGludCA9IGpzb25RdWVyeS5oaW50O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LnJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlcXVlc3RPYmplY3QucmVhZFByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3RPYmplY3QuaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSByZXF1ZXN0T2JqZWN0LmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9iamVjdC5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICB9O1xuICAgICAgfSxcbiAgICAgIGVyciA9PiB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGVyciwge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgICAgbWVzc2FnZTogJ1NjcmlwdCBmYWlsZWQuIFVua25vd24gZXJyb3IuJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRXJyb3IobWVzc2FnZSwgZGVmYXVsdE9wdHMpIHtcbiAgaWYgKCFkZWZhdWx0T3B0cykge1xuICAgIGRlZmF1bHRPcHRzID0ge307XG4gIH1cbiAgaWYgKCFtZXNzYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIGRlZmF1bHRPcHRzLmNvZGUgfHwgUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgIGRlZmF1bHRPcHRzLm1lc3NhZ2UgfHwgJ1NjcmlwdCBmYWlsZWQuJ1xuICAgICk7XG4gIH1cbiAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgIHJldHVybiBtZXNzYWdlO1xuICB9XG5cbiAgY29uc3QgY29kZSA9IGRlZmF1bHRPcHRzLmNvZGUgfHwgUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRDtcbiAgLy8gSWYgaXQncyBhbiBlcnJvciwgbWFyayBpdCBhcyBhIHNjcmlwdCBmYWlsZWRcbiAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoY29kZSwgbWVzc2FnZSk7XG4gIH1cbiAgY29uc3QgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoY29kZSwgbWVzc2FnZS5tZXNzYWdlIHx8IG1lc3NhZ2UpO1xuICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgZXJyb3Iuc3RhY2sgPSBtZXNzYWdlLnN0YWNrO1xuICB9XG4gIHJldHVybiBlcnJvcjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBmdW5jdGlvbk5hbWUpIHtcbiAgY29uc3QgdGhlVmFsaWRhdG9yID0gZ2V0VmFsaWRhdG9yKGZ1bmN0aW9uTmFtZSwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdGhlVmFsaWRhdG9yKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICh0eXBlb2YgdGhlVmFsaWRhdG9yID09PSAnb2JqZWN0JyAmJiB0aGVWYWxpZGF0b3Iuc2tpcFdpdGhNYXN0ZXJLZXkgJiYgcmVxdWVzdC5tYXN0ZXIpIHtcbiAgICByZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5ID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHRoZVZhbGlkYXRvciA9PT0gJ29iamVjdCdcbiAgICAgICAgICA/IGJ1aWx0SW5UcmlnZ2VyVmFsaWRhdG9yKHRoZVZhbGlkYXRvciwgcmVxdWVzdClcbiAgICAgICAgICA6IHRoZVZhbGlkYXRvcihyZXF1ZXN0KTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZSA9PiB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGUsIHtcbiAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLFxuICAgICAgICAgIG1lc3NhZ2U6ICdWYWxpZGF0aW9uIGZhaWxlZC4nLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICB9KTtcbn1cbmZ1bmN0aW9uIGJ1aWx0SW5UcmlnZ2VyVmFsaWRhdG9yKG9wdGlvbnMsIHJlcXVlc3QpIHtcbiAgaWYgKHJlcXVlc3QubWFzdGVyICYmICFvcHRpb25zLnZhbGlkYXRlTWFzdGVyS2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCByZXFVc2VyID0gcmVxdWVzdC51c2VyO1xuICBpZiAoXG4gICAgIXJlcVVzZXIgJiZcbiAgICByZXF1ZXN0Lm9iamVjdCAmJlxuICAgIHJlcXVlc3Qub2JqZWN0LmNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJlxuICAgICFyZXF1ZXN0Lm9iamVjdC5leGlzdGVkKClcbiAgKSB7XG4gICAgcmVxVXNlciA9IHJlcXVlc3Qub2JqZWN0O1xuICB9XG4gIGlmIChvcHRpb25zLnJlcXVpcmVVc2VyICYmICFyZXFVc2VyKSB7XG4gICAgdGhyb3cgJ1ZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2UgbG9naW4gdG8gY29udGludWUuJztcbiAgfVxuICBpZiAob3B0aW9ucy5yZXF1aXJlTWFzdGVyICYmICFyZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHRocm93ICdWYWxpZGF0aW9uIGZhaWxlZC4gTWFzdGVyIGtleSBpcyByZXF1aXJlZCB0byBjb21wbGV0ZSB0aGlzIHJlcXVlc3QuJztcbiAgfVxuICBsZXQgcGFyYW1zID0gcmVxdWVzdC5wYXJhbXMgfHwge307XG4gIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgIHBhcmFtcyA9IHJlcXVlc3Qub2JqZWN0LnRvSlNPTigpO1xuICB9XG4gIGNvbnN0IHJlcXVpcmVkUGFyYW0gPSBrZXkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyYW1zW2tleV07XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gUGxlYXNlIHNwZWNpZnkgZGF0YSBmb3IgJHtrZXl9LmA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHZhbGlkYXRlT3B0aW9ucyA9IChvcHQsIGtleSwgdmFsKSA9PiB7XG4gICAgbGV0IG9wdHMgPSBvcHQub3B0aW9ucztcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdHModmFsKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgcmVzdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWUpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBlLm1lc3NhZ2UgfHwgZTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICBvcHRzID0gW29wdC5vcHRpb25zXTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdHMuaW5jbHVkZXModmFsKSkge1xuICAgICAgdGhyb3cgKFxuICAgICAgICBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIG9wdGlvbiBmb3IgJHtrZXl9LiBFeHBlY3RlZDogJHtvcHRzLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZ2V0VHlwZSA9IGZuID0+IHtcbiAgICBjb25zdCBtYXRjaCA9IGZuICYmIGZuLnRvU3RyaW5nKCkubWF0Y2goL15cXHMqZnVuY3Rpb24gKFxcdyspLyk7XG4gICAgcmV0dXJuIChtYXRjaCA/IG1hdGNoWzFdIDogJycpLnRvTG93ZXJDYXNlKCk7XG4gIH07XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZmllbGRzKSkge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIG9wdGlvbnMuZmllbGRzKSB7XG4gICAgICByZXF1aXJlZFBhcmFtKGtleSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMuZmllbGRzKSB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zLmZpZWxkc1trZXldO1xuICAgICAgbGV0IHZhbCA9IHBhcmFtc1trZXldO1xuICAgICAgaWYgKHR5cGVvZiBvcHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlcXVpcmVkUGFyYW0ob3B0KTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAob3B0LmRlZmF1bHQgIT0gbnVsbCAmJiB2YWwgPT0gbnVsbCkge1xuICAgICAgICAgIHZhbCA9IG9wdC5kZWZhdWx0O1xuICAgICAgICAgIHBhcmFtc1trZXldID0gdmFsO1xuICAgICAgICAgIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgICAgICAgICAgcmVxdWVzdC5vYmplY3Quc2V0KGtleSwgdmFsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdC5jb25zdGFudCAmJiByZXF1ZXN0Lm9iamVjdCkge1xuICAgICAgICAgIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgICAgICAgICByZXF1ZXN0Lm9iamVjdC5zZXQoa2V5LCByZXF1ZXN0Lm9yaWdpbmFsLmdldChrZXkpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG9wdC5kZWZhdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qub2JqZWN0LnNldChrZXksIG9wdC5kZWZhdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdC5yZXF1aXJlZCkge1xuICAgICAgICAgIHJlcXVpcmVkUGFyYW0oa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LnR5cGUpIHtcbiAgICAgICAgICBjb25zdCB0eXBlID0gZ2V0VHlwZShvcHQudHlwZSk7XG4gICAgICAgICAgaWYgKHR5cGUgPT0gJ2FycmF5JyAmJiAhQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdHlwZSBmb3IgJHtrZXl9LiBFeHBlY3RlZDogYXJyYXlgO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbCAhPT0gdHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHR5cGUgZm9yICR7a2V5fS4gRXhwZWN0ZWQ6ICR7dHlwZX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0Lm9wdGlvbnMpIHtcbiAgICAgICAgICB2YWxpZGF0ZU9wdGlvbnMob3B0LCBrZXksIHZhbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3QgdXNlcktleXMgPSBvcHRpb25zLnJlcXVpcmVVc2VyS2V5cyB8fCBbXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkodXNlcktleXMpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgdXNlcktleXMpIHtcbiAgICAgIGlmICghcmVxVXNlcikge1xuICAgICAgICB0aHJvdyAnUGxlYXNlIGxvZ2luIHRvIG1ha2UgdGhpcyByZXF1ZXN0Lic7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXFVc2VyLmdldChrZXkpID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2Ugc2V0IGRhdGEgZm9yICR7a2V5fSBvbiB5b3VyIGFjY291bnQuYDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHVzZXJLZXlzID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzKSB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zLnJlcXVpcmVVc2VyS2V5c1trZXldO1xuICAgICAgaWYgKG9wdC5vcHRpb25zKSB7XG4gICAgICAgIHZhbGlkYXRlT3B0aW9ucyhvcHQsIGtleSwgcmVxVXNlci5nZXQoa2V5KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIFRvIGJlIHVzZWQgYXMgcGFydCBvZiB0aGUgcHJvbWlzZSBjaGFpbiB3aGVuIHNhdmluZy9kZWxldGluZyBhbiBvYmplY3Rcbi8vIFdpbGwgcmVzb2x2ZSBzdWNjZXNzZnVsbHkgaWYgbm8gdHJpZ2dlciBpcyBjb25maWd1cmVkXG4vLyBSZXNvbHZlcyB0byBhbiBvYmplY3QsIGVtcHR5IG9yIGNvbnRhaW5pbmcgYW4gb2JqZWN0IGtleS4gQSBiZWZvcmVTYXZlXG4vLyB0cmlnZ2VyIHdpbGwgc2V0IHRoZSBvYmplY3Qga2V5IHRvIHRoZSByZXN0IGZvcm1hdCBvYmplY3QgdG8gc2F2ZS5cbi8vIG9yaWdpbmFsUGFyc2VPYmplY3QgaXMgb3B0aW9uYWwsIHdlIG9ubHkgbmVlZCB0aGF0IGZvciBiZWZvcmUvYWZ0ZXJTYXZlIGZ1bmN0aW9uc1xuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVHJpZ2dlcihcbiAgdHJpZ2dlclR5cGUsXG4gIGF1dGgsXG4gIHBhcnNlT2JqZWN0LFxuICBvcmlnaW5hbFBhcnNlT2JqZWN0LFxuICBjb25maWcsXG4gIGNvbnRleHRcbikge1xuICBpZiAoIXBhcnNlT2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgdHJpZ2dlciA9IGdldFRyaWdnZXIocGFyc2VPYmplY3QuY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghdHJpZ2dlcikgcmV0dXJuIHJlc29sdmUoKTtcbiAgICB2YXIgcmVxdWVzdCA9IGdldFJlcXVlc3RPYmplY3QoXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGF1dGgsXG4gICAgICBwYXJzZU9iamVjdCxcbiAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICBjb25maWcsXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgICB2YXIgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgb2JqZWN0ID0+IHtcbiAgICAgICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKFxuICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC50b0pTT04oKSxcbiAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgYXV0aFxuICAgICAgICApO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZVNhdmUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZURlbGV0ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckRlbGV0ZVxuICAgICAgICApIHtcbiAgICAgICAgICBPYmplY3QuYXNzaWduKGNvbnRleHQsIHJlcXVlc3QuY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgbG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayhcbiAgICAgICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgICAgcGFyc2VPYmplY3QudG9KU09OKCksXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBBZnRlclNhdmUgYW5kIGFmdGVyRGVsZXRlIHRyaWdnZXJzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCBpZiB0aGV5XG4gICAgLy8gZG8sIG5lZWRzIHRvIGJlIHJlc29sdmVkIGJlZm9yZSB0aGlzIHByb21pc2UgaXMgcmVzb2x2ZWQsXG4gICAgLy8gc28gdHJpZ2dlciBleGVjdXRpb24gaXMgc3luY2VkIHdpdGggUmVzdFdyaXRlLmV4ZWN1dGUoKSBjYWxsLlxuICAgIC8vIElmIHRyaWdnZXJzIGRvIG5vdCByZXR1cm4gYSBwcm9taXNlLCB0aGV5IGNhbiBydW4gYXN5bmMgY29kZSBwYXJhbGxlbFxuICAgIC8vIHRvIHRoZSBSZXN0V3JpdGUuZXhlY3V0ZSgpIGNhbGwuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtwYXJzZU9iamVjdC5jbGFzc05hbWV9YCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9taXNlID0gdHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJEZWxldGUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpblxuICAgICAgICApIHtcbiAgICAgICAgICBsb2dUcmlnZ2VyQWZ0ZXJIb29rKHRyaWdnZXJUeXBlLCBwYXJzZU9iamVjdC5jbGFzc05hbWUsIHBhcnNlT2JqZWN0LnRvSlNPTigpLCBhdXRoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBiZWZvcmVTYXZlIGlzIGV4cGVjdGVkIHRvIHJldHVybiBudWxsIChub3RoaW5nKVxuICAgICAgICBpZiAodHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZVNhdmUpIHtcbiAgICAgICAgICBpZiAocHJvbWlzZSAmJiB0eXBlb2YgcHJvbWlzZS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgLy8gcmVzcG9uc2Uub2JqZWN0IG1heSBjb21lIGZyb20gZXhwcmVzcyByb3V0aW5nIGJlZm9yZSBob29rXG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5vYmplY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gIH0pO1xufVxuXG4vLyBDb252ZXJ0cyBhIFJFU1QtZm9ybWF0IG9iamVjdCB0byBhIFBhcnNlLk9iamVjdFxuLy8gZGF0YSBpcyBlaXRoZXIgY2xhc3NOYW1lIG9yIGFuIG9iamVjdFxuZXhwb3J0IGZ1bmN0aW9uIGluZmxhdGUoZGF0YSwgcmVzdE9iamVjdCkge1xuICB2YXIgY29weSA9IHR5cGVvZiBkYXRhID09ICdvYmplY3QnID8gZGF0YSA6IHsgY2xhc3NOYW1lOiBkYXRhIH07XG4gIGZvciAodmFyIGtleSBpbiByZXN0T2JqZWN0KSB7XG4gICAgY29weVtrZXldID0gcmVzdE9iamVjdFtrZXldO1xuICB9XG4gIHJldHVybiBQYXJzZS5PYmplY3QuZnJvbUpTT04oY29weSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKGRhdGEsIGFwcGxpY2F0aW9uSWQgPSBQYXJzZS5hcHBsaWNhdGlvbklkKSB7XG4gIGlmICghX3RyaWdnZXJTdG9yZSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkuZm9yRWFjaChoYW5kbGVyID0+IGhhbmRsZXIoZGF0YSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdEZpbGVPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIGZpbGVPYmplY3QsIGNvbmZpZykge1xuICBjb25zdCByZXF1ZXN0ID0ge1xuICAgIC4uLmZpbGVPYmplY3QsXG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuRmlsZVRyaWdnZXIodHJpZ2dlclR5cGUsIGZpbGVPYmplY3QsIGNvbmZpZywgYXV0aCkge1xuICBjb25zdCBmaWxlVHJpZ2dlciA9IGdldEZpbGVUcmlnZ2VyKHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIGlmICh0eXBlb2YgZmlsZVRyaWdnZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGdldFJlcXVlc3RGaWxlT2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBmaWxlT2JqZWN0LCBjb25maWcpO1xuICAgICAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7RmlsZUNsYXNzTmFtZX1gKTtcbiAgICAgIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgIHJldHVybiBmaWxlT2JqZWN0O1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmlsZVRyaWdnZXIocmVxdWVzdCk7XG4gICAgICBsb2dUcmlnZ2VyU3VjY2Vzc0JlZm9yZUhvb2soXG4gICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAnUGFyc2UuRmlsZScsXG4gICAgICAgIHsgLi4uZmlsZU9iamVjdC5maWxlLnRvSlNPTigpLCBmaWxlU2l6ZTogZmlsZU9iamVjdC5maWxlU2l6ZSB9LFxuICAgICAgICByZXN1bHQsXG4gICAgICAgIGF1dGhcbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzdWx0IHx8IGZpbGVPYmplY3Q7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2soXG4gICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAnUGFyc2UuRmlsZScsXG4gICAgICAgIHsgLi4uZmlsZU9iamVjdC5maWxlLnRvSlNPTigpLCBmaWxlU2l6ZTogZmlsZU9iamVjdC5maWxlU2l6ZSB9LFxuICAgICAgICBhdXRoLFxuICAgICAgICBlcnJvclxuICAgICAgKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmlsZU9iamVjdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuQ29ubmVjdFRyaWdnZXIodHJpZ2dlclR5cGUsIHJlcXVlc3QpIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoQ29ubmVjdENsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmVxdWVzdC51c2VyID0gYXdhaXQgdXNlckZvclNlc3Npb25Ub2tlbihyZXF1ZXN0LnNlc3Npb25Ub2tlbik7XG4gIGF3YWl0IG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke0Nvbm5lY3RDbGFzc05hbWV9YCk7XG4gIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiB0cmlnZ2VyKHJlcXVlc3QpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIHJlcXVlc3QpIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gIHBhcnNlUXVlcnkud2l0aEpTT04ocmVxdWVzdC5xdWVyeSk7XG4gIHJlcXVlc3QucXVlcnkgPSBwYXJzZVF1ZXJ5O1xuICByZXF1ZXN0LnVzZXIgPSBhd2FpdCB1c2VyRm9yU2Vzc2lvblRva2VuKHJlcXVlc3Quc2Vzc2lvblRva2VuKTtcbiAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgIHJldHVybjtcbiAgfVxuICBhd2FpdCB0cmlnZ2VyKHJlcXVlc3QpO1xuICBjb25zdCBxdWVyeSA9IHJlcXVlc3QucXVlcnkudG9KU09OKCk7XG4gIGlmIChxdWVyeS5rZXlzKSB7XG4gICAgcXVlcnkuZmllbGRzID0gcXVlcnkua2V5cy5zcGxpdCgnLCcpO1xuICB9XG4gIHJlcXVlc3QucXVlcnkgPSBxdWVyeTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuQWZ0ZXJFdmVudFRyaWdnZXIodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgcmVxdWVzdCkge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgIHJlcXVlc3Qub2JqZWN0ID0gUGFyc2UuT2JqZWN0LmZyb21KU09OKHJlcXVlc3Qub2JqZWN0KTtcbiAgfVxuICBpZiAocmVxdWVzdC5vcmlnaW5hbCkge1xuICAgIHJlcXVlc3Qub3JpZ2luYWwgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ocmVxdWVzdC5vcmlnaW5hbCk7XG4gIH1cbiAgcmVxdWVzdC51c2VyID0gYXdhaXQgdXNlckZvclNlc3Npb25Ub2tlbihyZXF1ZXN0LnNlc3Npb25Ub2tlbik7XG4gIGF3YWl0IG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke2NsYXNzTmFtZX1gKTtcbiAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRyaWdnZXIocmVxdWVzdCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVzZXJGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuKSB7XG4gIGlmICghc2Vzc2lvblRva2VuKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHEgPSBuZXcgUGFyc2UuUXVlcnkoJ19TZXNzaW9uJyk7XG4gIHEuZXF1YWxUbygnc2Vzc2lvblRva2VuJywgc2Vzc2lvblRva2VuKTtcbiAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHEuZmlyc3QoeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCB1c2VyID0gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbiAgaWYgKCF1c2VyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGF3YWl0IHVzZXIuZmV0Y2goeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIHJldHVybiB1c2VyO1xufVxuIl19 \ No newline at end of file diff --git a/lib/vendor/README.md b/lib/vendor/README.md deleted file mode 100644 index 04e3256f72..0000000000 --- a/lib/vendor/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# mongoUrl - -A fork of node's `url` module, with the modification that commas and colons are -allowed in hostnames. While this results in a slightly incorrect parsed result, -as the hostname field for a mongodb should be an array of replica sets, it's -good enough to let us pull out and escape the auth portion of the URL. - -https://github.com/parse-community/parse-server/pull/986 diff --git a/lib/vendor/mongodbUrl.js b/lib/vendor/mongodbUrl.js deleted file mode 100644 index 6b95552f05..0000000000 --- a/lib/vendor/mongodbUrl.js +++ /dev/null @@ -1,1064 +0,0 @@ -// A slightly patched version of node's url module, with support for mongodb:// -// uris. -// -// See https://github.com/nodejs/node/blob/master/LICENSE for licensing -// information -'use strict'; - -const punycode = require('punycode'); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; -exports.Url = Url; - -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; -} // Reference: RFC 3986, RFC 1808, RFC 2396 -// define these here so at least they only have to be -// compiled once on the first module load. - - -const protocolPattern = /^([a-z0-9.+-]+:)/i; -const portPattern = /:[0-9]*$/; // Special case for a simple path URL - -const simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/; // protocols that can allow "unsafe" and "unwise" chars. - -const unsafeProtocol = { - javascript: true, - 'javascript:': true -}; // protocols that never have a hostname. - -const hostlessProtocol = { - javascript: true, - 'javascript:': true -}; // protocols that always contain a // bit. - -const slashedProtocol = { - http: true, - 'http:': true, - https: true, - 'https:': true, - ftp: true, - 'ftp:': true, - gopher: true, - 'gopher:': true, - file: true, - 'file:': true -}; - -const querystring = require('querystring'); -/* istanbul ignore next: improve coverage */ - - -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url instanceof Url) return url; - var u = new Url(); - u.parse(url, parseQueryString, slashesDenoteHost); - return u; -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) { - if (typeof url !== 'string') { - throw new TypeError('Parameter "url" must be a string, not ' + typeof url); - } // Copy chrome, IE, opera backslash-handling behavior. - // Back slashes before the query string get converted to forward slashes - // See: https://code.google.com/p/chromium/issues/detail?id=25916 - - - var hasHash = false; - var start = -1; - var end = -1; - var rest = ''; - var lastPos = 0; - var i = 0; - - for (var inWs = false, split = false; i < url.length; ++i) { - const code = url.charCodeAt(i); // Find first and last non-whitespace characters for trimming - - const isWs = code === 32 - /* */ - || code === 9 - /*\t*/ - || code === 13 - /*\r*/ - || code === 10 - /*\n*/ - || code === 12 - /*\f*/ - || code === 160 - /*\u00A0*/ - || code === 65279; - /*\uFEFF*/ - - if (start === -1) { - if (isWs) continue; - lastPos = start = i; - } else { - if (inWs) { - if (!isWs) { - end = -1; - inWs = false; - } - } else if (isWs) { - end = i; - inWs = true; - } - } // Only convert backslashes while we haven't seen a split character - - - if (!split) { - switch (code) { - case 35: - // '#' - hasHash = true; - // Fall through - - case 63: - // '?' - split = true; - break; - - case 92: - // '\\' - if (i - lastPos > 0) rest += url.slice(lastPos, i); - rest += '/'; - lastPos = i + 1; - break; - } - } else if (!hasHash && code === 35 - /*#*/ - ) { - hasHash = true; - } - } // Check if string was non-empty (including strings with only whitespace) - - - if (start !== -1) { - if (lastPos === start) { - // We didn't convert any backslashes - if (end === -1) { - if (start === 0) rest = url;else rest = url.slice(start); - } else { - rest = url.slice(start, end); - } - } else if (end === -1 && lastPos < url.length) { - // We converted some backslashes and have only part of the entire string - rest += url.slice(lastPos); - } else if (end !== -1 && lastPos < end) { - // We converted some backslashes and have only part of the entire string - rest += url.slice(lastPos, end); - } - } - - if (!slashesDenoteHost && !hasHash) { - // Try fast path regexp - const simplePath = simplePathPattern.exec(rest); - - if (simplePath) { - this.path = rest; - this.href = rest; - this.pathname = simplePath[1]; - - if (simplePath[2]) { - this.search = simplePath[2]; - - if (parseQueryString) { - this.query = querystring.parse(this.search.slice(1)); - } else { - this.query = this.search.slice(1); - } - } else if (parseQueryString) { - this.search = ''; - this.query = {}; - } - - return this; - } - } - - var proto = protocolPattern.exec(rest); - - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.slice(proto.length); - } // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - - - if (slashesDenoteHost || proto || /^\/\/[^@\/]+@[^@\/]+/.test(rest)) { - var slashes = rest.charCodeAt(0) === 47 - /*/*/ - && rest.charCodeAt(1) === 47; - /*/*/ - - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.slice(2); - this.slashes = true; - } - } - - if (!hostlessProtocol[proto] && (slashes || proto && !slashedProtocol[proto])) { - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:b path:/?@c - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. - var hostEnd = -1; - var atSign = -1; - var nonHost = -1; - - for (i = 0; i < rest.length; ++i) { - switch (rest.charCodeAt(i)) { - case 9: // '\t' - - case 10: // '\n' - - case 13: // '\r' - - case 32: // ' ' - - case 34: // '"' - - case 37: // '%' - - case 39: // '\'' - - case 59: // ';' - - case 60: // '<' - - case 62: // '>' - - case 92: // '\\' - - case 94: // '^' - - case 96: // '`' - - case 123: // '{' - - case 124: // '|' - - case 125: - // '}' - // Characters that are never ever allowed in a hostname from RFC 2396 - if (nonHost === -1) nonHost = i; - break; - - case 35: // '#' - - case 47: // '/' - - case 63: - // '?' - // Find the first instance of any host-ending characters - if (nonHost === -1) nonHost = i; - hostEnd = i; - break; - - case 64: - // '@' - // At this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - atSign = i; - nonHost = -1; - break; - } - - if (hostEnd !== -1) break; - } - - start = 0; - - if (atSign !== -1) { - this.auth = decodeURIComponent(rest.slice(0, atSign)); - start = atSign + 1; - } - - if (nonHost === -1) { - this.host = rest.slice(start); - rest = ''; - } else { - this.host = rest.slice(start, nonHost); - rest = rest.slice(nonHost); - } // pull out port. - - - this.parseHost(); // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - - if (typeof this.hostname !== 'string') this.hostname = ''; - var hostname = this.hostname; // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - - var ipv6Hostname = hostname.charCodeAt(0) === 91 - /*[*/ - && hostname.charCodeAt(hostname.length - 1) === 93; - /*]*/ - // validate a little. - - if (!ipv6Hostname) { - const result = validateHostname(this, rest, hostname); - if (result !== undefined) rest = result; - } // hostnames are always lower case. - - - this.hostname = this.hostname.toLowerCase(); - - if (!ipv6Hostname) { - // IDNA Support: Returns a punycoded representation of "domain". - // It only converts parts of the domain name that - // have non-ASCII characters, i.e. it doesn't matter if - // you call it with a domain that already is ASCII-only. - this.hostname = punycode.toASCII(this.hostname); - } - - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; // strip [ and ] from the hostname - // the host field still retains them, though - - if (ipv6Hostname) { - this.hostname = this.hostname.slice(1, -1); - - if (rest[0] !== '/') { - rest = '/' + rest; - } - } - } // now rest is set to the post-host stuff. - // chop off any delim chars. - - - if (!unsafeProtocol[lowerProto]) { - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - const result = autoEscapeStr(rest); - if (result !== undefined) rest = result; - } - - var questionIdx = -1; - var hashIdx = -1; - - for (i = 0; i < rest.length; ++i) { - const code = rest.charCodeAt(i); - - if (code === 35 - /*#*/ - ) { - this.hash = rest.slice(i); - hashIdx = i; - break; - } else if (code === 63 - /*?*/ - && questionIdx === -1) { - questionIdx = i; - } - } - - if (questionIdx !== -1) { - if (hashIdx === -1) { - this.search = rest.slice(questionIdx); - this.query = rest.slice(questionIdx + 1); - } else { - this.search = rest.slice(questionIdx, hashIdx); - this.query = rest.slice(questionIdx + 1, hashIdx); - } - - if (parseQueryString) { - this.query = querystring.parse(this.query); - } - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - - var firstIdx = questionIdx !== -1 && (hashIdx === -1 || questionIdx < hashIdx) ? questionIdx : hashIdx; - - if (firstIdx === -1) { - if (rest.length > 0) this.pathname = rest; - } else if (firstIdx > 0) { - this.pathname = rest.slice(0, firstIdx); - } - - if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { - this.pathname = '/'; - } // to support http.request - - - if (this.pathname || this.search) { - const p = this.pathname || ''; - const s = this.search || ''; - this.path = p + s; - } // finally, reconstruct the href based on what has been validated. - - - this.href = this.format(); - return this; -}; -/* istanbul ignore next: improve coverage */ - - -function validateHostname(self, rest, hostname) { - for (var i = 0, lastPos; i <= hostname.length; ++i) { - var code; - if (i < hostname.length) code = hostname.charCodeAt(i); - - if (code === 46 - /*.*/ - || i === hostname.length) { - if (i - lastPos > 0) { - if (i - lastPos > 63) { - self.hostname = hostname.slice(0, lastPos + 63); - return '/' + hostname.slice(lastPos + 63) + rest; - } - } - - lastPos = i + 1; - continue; - } else if (code >= 48 - /*0*/ - && code <= 57 || - /*9*/ - code >= 97 - /*a*/ - && code <= 122 - /*z*/ - || code === 45 - /*-*/ - || code >= 65 - /*A*/ - && code <= 90 - /*Z*/ - || code === 43 - /*+*/ - || code === 95 - /*_*/ - || - /* BEGIN MONGO URI PATCH */ - code === 44 - /*,*/ - || code === 58 - /*:*/ - || - /* END MONGO URI PATCH */ - code > 127) { - continue; - } // Invalid host character - - - self.hostname = hostname.slice(0, i); - if (i < hostname.length) return '/' + hostname.slice(i) + rest; - break; - } -} -/* istanbul ignore next: improve coverage */ - - -function autoEscapeStr(rest) { - var newRest = ''; - var lastPos = 0; - - for (var i = 0; i < rest.length; ++i) { - // Automatically escape all delimiters and unwise characters from RFC 2396 - // Also escape single quotes in case of an XSS attack - switch (rest.charCodeAt(i)) { - case 9: - // '\t' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%09'; - lastPos = i + 1; - break; - - case 10: - // '\n' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%0A'; - lastPos = i + 1; - break; - - case 13: - // '\r' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%0D'; - lastPos = i + 1; - break; - - case 32: - // ' ' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%20'; - lastPos = i + 1; - break; - - case 34: - // '"' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%22'; - lastPos = i + 1; - break; - - case 39: - // '\'' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%27'; - lastPos = i + 1; - break; - - case 60: - // '<' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%3C'; - lastPos = i + 1; - break; - - case 62: - // '>' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%3E'; - lastPos = i + 1; - break; - - case 92: - // '\\' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%5C'; - lastPos = i + 1; - break; - - case 94: - // '^' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%5E'; - lastPos = i + 1; - break; - - case 96: - // '`' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%60'; - lastPos = i + 1; - break; - - case 123: - // '{' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%7B'; - lastPos = i + 1; - break; - - case 124: - // '|' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%7C'; - lastPos = i + 1; - break; - - case 125: - // '}' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%7D'; - lastPos = i + 1; - break; - } - } - - if (lastPos === 0) return; - if (lastPos < rest.length) return newRest + rest.slice(lastPos);else return newRest; -} // format a parsed object into a url string - -/* istanbul ignore next: improve coverage */ - - -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (typeof obj === 'string') obj = urlParse(obj);else if (typeof obj !== 'object' || obj === null) throw new TypeError('Parameter "urlObj" must be an object, not ' + obj === null ? 'null' : typeof obj);else if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.format = function () { - var auth = this.auth || ''; - - if (auth) { - auth = encodeAuth(auth); - auth += '@'; - } - - var protocol = this.protocol || ''; - var pathname = this.pathname || ''; - var hash = this.hash || ''; - var host = false; - var query = ''; - - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); - - if (this.port) { - host += ':' + this.port; - } - } - - if (this.query !== null && typeof this.query === 'object') query = querystring.stringify(this.query); - var search = this.search || query && '?' + query || ''; - if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58 - /*:*/ - ) protocol += ':'; - var newPathname = ''; - var lastPos = 0; - - for (var i = 0; i < pathname.length; ++i) { - switch (pathname.charCodeAt(i)) { - case 35: - // '#' - if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); - newPathname += '%23'; - lastPos = i + 1; - break; - - case 63: - // '?' - if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); - newPathname += '%3F'; - lastPos = i + 1; - break; - } - } - - if (lastPos > 0) { - if (lastPos !== pathname.length) pathname = newPathname + pathname.slice(lastPos);else pathname = newPathname; - } // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - - - if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charCodeAt(0) !== 47 - /*/*/ - ) pathname = '/' + pathname; - } else if (!host) { - host = ''; - } - - search = search.replace('#', '%23'); - if (hash && hash.charCodeAt(0) !== 35 - /*#*/ - ) hash = '#' + hash; - if (search && search.charCodeAt(0) !== 63 - /*?*/ - ) search = '?' + search; - return protocol + host + pathname + search + hash; -}; -/* istanbul ignore next: improve coverage */ - - -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.resolve = function (relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; -/* istanbul ignore next: improve coverage */ - - -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.resolveObject = function (relative) { - if (typeof relative === 'string') { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } - - var result = new Url(); - var tkeys = Object.keys(this); - - for (var tk = 0; tk < tkeys.length; tk++) { - var tkey = tkeys[tk]; - result[tkey] = this[tkey]; - } // hash is always overridden, no matter what. - // even href="" will remove it. - - - result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. - - if (relative.href === '') { - result.href = result.format(); - return result; - } // hrefs like //foo/bar always cut to the protocol. - - - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - var rkeys = Object.keys(relative); - - for (var rk = 0; rk < rkeys.length; rk++) { - var rkey = rkeys[rk]; - if (rkey !== 'protocol') result[rkey] = relative[rkey]; - } //urlParse appends trailing / to urls like http://www.example.com - - - if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } - - result.href = result.format(); - return result; - } - - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - var keys = Object.keys(relative); - - for (var v = 0; v < keys.length; v++) { - var k = keys[v]; - result[k] = relative[k]; - } - - result.href = result.format(); - return result; - } - - result.protocol = relative.protocol; - - if (!relative.host && !/^file:?$/.test(relative.protocol) && !hostlessProtocol[relative.protocol]) { - const relPath = (relative.pathname || '').split('/'); - - while (relPath.length && !(relative.host = relPath.shift())); - - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; // to support http.request - - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; - } - - var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/'; - var isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/'; - var mustEndAbs = isRelAbs || isSourceAbs || result.host && relative.pathname; - var removeAllDots = mustEndAbs; - var srcPath = result.pathname && result.pathname.split('/') || []; - var relPath = relative.pathname && relative.pathname.split('/') || []; - var psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - - if (psychotic) { - result.hostname = ''; - result.port = null; - - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host;else srcPath.unshift(result.host); - } - - result.host = ''; - - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host;else relPath.unshift(relative.host); - } - - relative.host = null; - } - - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); - } - - if (isRelAbs) { - // it's absolute. - result.host = relative.host || relative.host === '' ? relative.host : result.host; - result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (relative.search !== null && relative.search !== undefined) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); //occasionally the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - - const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; - - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - result.search = relative.search; - result.query = relative.query; //to support http.request - - if (result.pathname !== null || result.search !== null) { - result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); - } - - result.href = result.format(); - return result; - } - - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; //to support http.request - - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - - result.href = result.format(); - return result; - } // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - - - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - - var up = 0; - - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - - if (last === '.') { - spliceOne(srcPath, i); - } else if (last === '..') { - spliceOne(srcPath, i); - up++; - } else if (up) { - spliceOne(srcPath, i); - up--; - } - } // if the path is allowed to go above the root, restore leading ..s - - - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } - } - - if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - - if (hasTrailingSlash && srcPath.join('/').substr(-1) !== '/') { - srcPath.push(''); - } - - var isAbsolute = srcPath[0] === '' || srcPath[0] && srcPath[0].charAt(0) === '/'; // put the host back - - if (psychotic) { - if (isAbsolute) { - result.hostname = result.host = ''; - } else { - result.hostname = result.host = srcPath.length ? srcPath.shift() : ''; - } //occasionally the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - - - const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; - - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - mustEndAbs = mustEndAbs || result.host && srcPath.length; - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); - } - - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); - } //to support request.http - - - if (result.pathname !== null || result.search !== null) { - result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); - } - - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; -}; -/* istanbul ignore next: improve coverage */ - - -Url.prototype.parseHost = function () { - var host = this.host; - var port = portPattern.exec(host); - - if (port) { - port = port[0]; - - if (port !== ':') { - this.port = port.slice(1); - } - - host = host.slice(0, host.length - port.length); - } - - if (host) this.hostname = host; -}; // About 1.5x faster than the two-arg version of Array#splice(). - -/* istanbul ignore next: improve coverage */ - - -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) list[i] = list[k]; - - list.pop(); -} - -var hexTable = new Array(256); - -for (var i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); -/* istanbul ignore next: improve coverage */ - - -function encodeAuth(str) { - // faster encodeURIComponent alternative for encoding auth uri components - var out = ''; - var lastPos = 0; - - for (var i = 0; i < str.length; ++i) { - var c = str.charCodeAt(i); // These characters do not need escaping: - // ! - . _ ~ - // ' ( ) * : - // digits - // alpha (uppercase) - // alpha (lowercase) - - if (c === 0x21 || c === 0x2d || c === 0x2e || c === 0x5f || c === 0x7e || c >= 0x27 && c <= 0x2a || c >= 0x30 && c <= 0x3a || c >= 0x41 && c <= 0x5a || c >= 0x61 && c <= 0x7a) { - continue; - } - - if (i - lastPos > 0) out += str.slice(lastPos, i); - lastPos = i + 1; // Other ASCII characters - - if (c < 0x80) { - out += hexTable[c]; - continue; - } // Multi-byte characters ... - - - if (c < 0x800) { - out += hexTable[0xc0 | c >> 6] + hexTable[0x80 | c & 0x3f]; - continue; - } - - if (c < 0xd800 || c >= 0xe000) { - out += hexTable[0xe0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; - continue; - } // Surrogate pair - - - ++i; - var c2; - if (i < str.length) c2 = str.charCodeAt(i) & 0x3ff;else c2 = 0; - c = 0x10000 + ((c & 0x3ff) << 10 | c2); - out += hexTable[0xf0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3f] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; - } - - if (lastPos === 0) return str; - if (lastPos < str.length) return out + str.slice(lastPos); - return out; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZW5kb3IvbW9uZ29kYlVybC5qcyJdLCJuYW1lcyI6WyJwdW55Y29kZSIsInJlcXVpcmUiLCJleHBvcnRzIiwicGFyc2UiLCJ1cmxQYXJzZSIsInJlc29sdmUiLCJ1cmxSZXNvbHZlIiwicmVzb2x2ZU9iamVjdCIsInVybFJlc29sdmVPYmplY3QiLCJmb3JtYXQiLCJ1cmxGb3JtYXQiLCJVcmwiLCJwcm90b2NvbCIsInNsYXNoZXMiLCJhdXRoIiwiaG9zdCIsInBvcnQiLCJob3N0bmFtZSIsImhhc2giLCJzZWFyY2giLCJxdWVyeSIsInBhdGhuYW1lIiwicGF0aCIsImhyZWYiLCJwcm90b2NvbFBhdHRlcm4iLCJwb3J0UGF0dGVybiIsInNpbXBsZVBhdGhQYXR0ZXJuIiwidW5zYWZlUHJvdG9jb2wiLCJqYXZhc2NyaXB0IiwiaG9zdGxlc3NQcm90b2NvbCIsInNsYXNoZWRQcm90b2NvbCIsImh0dHAiLCJodHRwcyIsImZ0cCIsImdvcGhlciIsImZpbGUiLCJxdWVyeXN0cmluZyIsInVybCIsInBhcnNlUXVlcnlTdHJpbmciLCJzbGFzaGVzRGVub3RlSG9zdCIsInUiLCJwcm90b3R5cGUiLCJUeXBlRXJyb3IiLCJoYXNIYXNoIiwic3RhcnQiLCJlbmQiLCJyZXN0IiwibGFzdFBvcyIsImkiLCJpbldzIiwic3BsaXQiLCJsZW5ndGgiLCJjb2RlIiwiY2hhckNvZGVBdCIsImlzV3MiLCJzbGljZSIsInNpbXBsZVBhdGgiLCJleGVjIiwicHJvdG8iLCJsb3dlclByb3RvIiwidG9Mb3dlckNhc2UiLCJ0ZXN0IiwiaG9zdEVuZCIsImF0U2lnbiIsIm5vbkhvc3QiLCJkZWNvZGVVUklDb21wb25lbnQiLCJwYXJzZUhvc3QiLCJpcHY2SG9zdG5hbWUiLCJyZXN1bHQiLCJ2YWxpZGF0ZUhvc3RuYW1lIiwidW5kZWZpbmVkIiwidG9BU0NJSSIsInAiLCJoIiwiYXV0b0VzY2FwZVN0ciIsInF1ZXN0aW9uSWR4IiwiaGFzaElkeCIsImZpcnN0SWR4IiwicyIsInNlbGYiLCJuZXdSZXN0Iiwib2JqIiwiY2FsbCIsImVuY29kZUF1dGgiLCJpbmRleE9mIiwic3RyaW5naWZ5IiwibmV3UGF0aG5hbWUiLCJyZXBsYWNlIiwic291cmNlIiwicmVsYXRpdmUiLCJyZWwiLCJ0a2V5cyIsIk9iamVjdCIsImtleXMiLCJ0ayIsInRrZXkiLCJya2V5cyIsInJrIiwicmtleSIsInYiLCJrIiwicmVsUGF0aCIsInNoaWZ0IiwidW5zaGlmdCIsImpvaW4iLCJpc1NvdXJjZUFicyIsImNoYXJBdCIsImlzUmVsQWJzIiwibXVzdEVuZEFicyIsInJlbW92ZUFsbERvdHMiLCJzcmNQYXRoIiwicHN5Y2hvdGljIiwicG9wIiwiY29uY2F0IiwiYXV0aEluSG9zdCIsImxhc3QiLCJoYXNUcmFpbGluZ1NsYXNoIiwidXAiLCJzcGxpY2VPbmUiLCJzdWJzdHIiLCJwdXNoIiwiaXNBYnNvbHV0ZSIsImxpc3QiLCJpbmRleCIsIm4iLCJoZXhUYWJsZSIsIkFycmF5IiwidG9TdHJpbmciLCJ0b1VwcGVyQ2FzZSIsInN0ciIsIm91dCIsImMiLCJjMiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBLE1BQU1BLFFBQVEsR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBeEI7O0FBRUFDLE9BQU8sQ0FBQ0MsS0FBUixHQUFnQkMsUUFBaEI7QUFDQUYsT0FBTyxDQUFDRyxPQUFSLEdBQWtCQyxVQUFsQjtBQUNBSixPQUFPLENBQUNLLGFBQVIsR0FBd0JDLGdCQUF4QjtBQUNBTixPQUFPLENBQUNPLE1BQVIsR0FBaUJDLFNBQWpCO0FBRUFSLE9BQU8sQ0FBQ1MsR0FBUixHQUFjQSxHQUFkOztBQUVBLFNBQVNBLEdBQVQsR0FBZTtBQUNiLE9BQUtDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQSxPQUFLQyxPQUFMLEdBQWUsSUFBZjtBQUNBLE9BQUtDLElBQUwsR0FBWSxJQUFaO0FBQ0EsT0FBS0MsSUFBTCxHQUFZLElBQVo7QUFDQSxPQUFLQyxJQUFMLEdBQVksSUFB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QUFZLENBQUNBLENBQUMsR0FBRyxLQUFMLEtBQWUsRUFBaEIsR0FBc0JDLEVBQWpDLENBQUo7QUFDQUYsSUFBQUEsR0FBRyxJQUNETCxRQUFRLENBQUMsT0FBUU0sQ0FBQyxJQUFJLEVBQWQsQ0FBUixHQUNBTixRQUFRLENBQUMsT0FBU00sQ0FBQyxJQUFJLEVBQU4sR0FBWSxJQUFyQixDQURSLEdBRUFOLFFBQVEsQ0FBQyxPQUFTTSxDQUFDLElBQUksQ0FBTixHQUFXLElBQXBCLENBRlIsR0FHQU4sUUFBUSxDQUFDLE9BQVFNLENBQUMsR0FBRyxJQUFiLENBSlY7QUFLRDs7QUFDRCxNQUFJcEYsT0FBTyxLQUFLLENBQWhCLEVBQW1CLE9BQU9rRixHQUFQO0FBQ25CLE1BQUlsRixPQUFPLEdBQUdrRixHQUFHLENBQUM5RSxNQUFsQixFQUEwQixPQUFPK0UsR0FBRyxHQUFHRCxHQUFHLENBQUMxRSxLQUFKLENBQVVSLE9BQVYsQ0FBYjtBQUMxQixTQUFPbUYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBzbGlnaHRseSBwYXRjaGVkIHZlcnNpb24gb2Ygbm9kZSdzIHVybCBtb2R1bGUsIHdpdGggc3VwcG9ydCBmb3IgbW9uZ29kYjovL1xuLy8gdXJpcy5cbi8vXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvbWFzdGVyL0xJQ0VOU0UgZm9yIGxpY2Vuc2luZ1xuLy8gaW5mb3JtYXRpb25cblxuJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG5cbmV4cG9ydHMucGFyc2UgPSB1cmxQYXJzZTtcbmV4cG9ydHMucmVzb2x2ZSA9IHVybFJlc29sdmU7XG5leHBvcnRzLnJlc29sdmVPYmplY3QgPSB1cmxSZXNvbHZlT2JqZWN0O1xuZXhwb3J0cy5mb3JtYXQgPSB1cmxGb3JtYXQ7XG5cbmV4cG9ydHMuVXJsID0gVXJsO1xuXG5mdW5jdGlvbiBVcmwoKSB7XG4gIHRoaXMucHJvdG9jb2wgPSBudWxsO1xuICB0aGlzLnNsYXNoZXMgPSBudWxsO1xuICB0aGlzLmF1dGggPSBudWxsO1xuICB0aGlzLmhvc3QgPSBudWxsO1xuICB0aGlzLnBvcnQgPSBudWxsO1xuICB0aGlzLmhvc3RuYW1lID0gbnVsbDtcbiAgdGhpcy5oYXNoID0gbnVsbDtcbiAgdGhpcy5zZWFyY2ggPSBudWxsO1xuICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgdGhpcy5wYXRobmFtZSA9IG51bGw7XG4gIHRoaXMucGF0aCA9IG51bGw7XG4gIHRoaXMuaHJlZiA9IG51bGw7XG59XG5cbi8vIFJlZmVyZW5jZTogUkZDIDM5ODYsIFJGQyAxODA4LCBSRkMgMjM5NlxuXG4vLyBkZWZpbmUgdGhlc2UgaGVyZSBzbyBhdCBsZWFzdCB0aGV5IG9ubHkgaGF2ZSB0byBiZVxuLy8gY29tcGlsZWQgb25jZSBvbiB0aGUgZmlyc3QgbW9kdWxlIGxvYWQuXG5jb25zdCBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pO1xuY29uc3QgcG9ydFBhdHRlcm4gPSAvOlswLTldKiQvO1xuXG4vLyBTcGVjaWFsIGNhc2UgZm9yIGEgc2ltcGxlIHBhdGggVVJMXG5jb25zdCBzaW1wbGVQYXRoUGF0dGVybiA9IC9eKFxcL1xcLz8oPyFcXC8pW15cXD9cXHNdKikoXFw/W15cXHNdKik/JC87XG5cbi8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuY29uc3QgdW5zYWZlUHJvdG9jb2wgPSB7XG4gIGphdmFzY3JpcHQ6IHRydWUsXG4gICdqYXZhc2NyaXB0Oic6IHRydWUsXG59O1xuLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuY29uc3QgaG9zdGxlc3NQcm90b2NvbCA9IHtcbiAgamF2YXNjcmlwdDogdHJ1ZSxcbiAgJ2phdmFzY3JpcHQ6JzogdHJ1ZSxcbn07XG4vLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbmNvbnN0IHNsYXNoZWRQcm90b2NvbCA9IHtcbiAgaHR0cDogdHJ1ZSxcbiAgJ2h0dHA6JzogdHJ1ZSxcbiAgaHR0cHM6IHRydWUsXG4gICdodHRwczonOiB0cnVlLFxuICBmdHA6IHRydWUsXG4gICdmdHA6JzogdHJ1ZSxcbiAgZ29waGVyOiB0cnVlLFxuICAnZ29waGVyOic6IHRydWUsXG4gIGZpbGU6IHRydWUsXG4gICdmaWxlOic6IHRydWUsXG59O1xuY29uc3QgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsIGluc3RhbmNlb2YgVXJsKSByZXR1cm4gdXJsO1xuXG4gIHZhciB1ID0gbmV3IFVybCgpO1xuICB1LnBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpO1xuICByZXR1cm4gdTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQYXJhbWV0ZXIgXCJ1cmxcIiBtdXN0IGJlIGEgc3RyaW5nLCBub3QgJyArIHR5cGVvZiB1cmwpO1xuICB9XG5cbiAgLy8gQ29weSBjaHJvbWUsIElFLCBvcGVyYSBiYWNrc2xhc2gtaGFuZGxpbmcgYmVoYXZpb3IuXG4gIC8vIEJhY2sgc2xhc2hlcyBiZWZvcmUgdGhlIHF1ZXJ5IHN0cmluZyBnZXQgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlc1xuICAvLyBTZWU6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0yNTkxNlxuICB2YXIgaGFzSGFzaCA9IGZhbHNlO1xuICB2YXIgc3RhcnQgPSAtMTtcbiAgdmFyIGVuZCA9IC0xO1xuICB2YXIgcmVzdCA9ICcnO1xuICB2YXIgbGFzdFBvcyA9IDA7XG4gIHZhciBpID0gMDtcbiAgZm9yICh2YXIgaW5XcyA9IGZhbHNlLCBzcGxpdCA9IGZhbHNlOyBpIDwgdXJsLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHVybC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gRmluZCBmaXJzdCBhbmQgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGZvciB0cmltbWluZ1xuICAgIGNvbnN0IGlzV3MgPVxuICAgICAgY29kZSA9PT0gMzIgLyogKi8gfHxcbiAgICAgIGNvZGUgPT09IDkgLypcXHQqLyB8fFxuICAgICAgY29kZSA9PT0gMTMgLypcXHIqLyB8fFxuICAgICAgY29kZSA9PT0gMTAgLypcXG4qLyB8fFxuICAgICAgY29kZSA9PT0gMTIgLypcXGYqLyB8fFxuICAgICAgY29kZSA9PT0gMTYwIC8qXFx1MDBBMCovIHx8XG4gICAgICBjb2RlID09PSA2NTI3OTsgLypcXHVGRUZGKi9cbiAgICBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICBpZiAoaXNXcykgY29udGludWU7XG4gICAgICBsYXN0UG9zID0gc3RhcnQgPSBpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5Xcykge1xuICAgICAgICBpZiAoIWlzV3MpIHtcbiAgICAgICAgICBlbmQgPSAtMTtcbiAgICAgICAgICBpbldzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNXcykge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBpbldzID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBPbmx5IGNvbnZlcnQgYmFja3NsYXNoZXMgd2hpbGUgd2UgaGF2ZW4ndCBzZWVuIGEgc3BsaXQgY2hhcmFjdGVyXG4gICAgaWYgKCFzcGxpdCkge1xuICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgIGNhc2UgMzU6IC8vICcjJ1xuICAgICAgICAgIGhhc0hhc2ggPSB0cnVlO1xuICAgICAgICAvLyBGYWxsIHRocm91Z2hcbiAgICAgICAgY2FzZSA2MzogLy8gJz8nXG4gICAgICAgICAgc3BsaXQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSByZXN0ICs9IHVybC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgICByZXN0ICs9ICcvJztcbiAgICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaGFzSGFzaCAmJiBjb2RlID09PSAzNSAvKiMqLykge1xuICAgICAgaGFzSGFzaCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgaWYgc3RyaW5nIHdhcyBub24tZW1wdHkgKGluY2x1ZGluZyBzdHJpbmdzIHdpdGggb25seSB3aGl0ZXNwYWNlKVxuICBpZiAoc3RhcnQgIT09IC0xKSB7XG4gICAgaWYgKGxhc3RQb3MgPT09IHN0YXJ0KSB7XG4gICAgICAvLyBXZSBkaWRuJ3QgY29udmVydCBhbnkgYmFja3NsYXNoZXNcblxuICAgICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgICAgaWYgKHN0YXJ0ID09PSAwKSByZXN0ID0gdXJsO1xuICAgICAgICBlbHNlIHJlc3QgPSB1cmwuc2xpY2Uoc3RhcnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdCA9IHVybC5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVuZCA9PT0gLTEgJiYgbGFzdFBvcyA8IHVybC5sZW5ndGgpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcyk7XG4gICAgfSBlbHNlIGlmIChlbmQgIT09IC0xICYmIGxhc3RQb3MgPCBlbmQpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcywgZW5kKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXNsYXNoZXNEZW5vdGVIb3N0ICYmICFoYXNIYXNoKSB7XG4gICAgLy8gVHJ5IGZhc3QgcGF0aCByZWdleHBcbiAgICBjb25zdCBzaW1wbGVQYXRoID0gc2ltcGxlUGF0aFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgICBpZiAoc2ltcGxlUGF0aCkge1xuICAgICAgdGhpcy5wYXRoID0gcmVzdDtcbiAgICAgIHRoaXMuaHJlZiA9IHJlc3Q7XG4gICAgICB0aGlzLnBhdGhuYW1lID0gc2ltcGxlUGF0aFsxXTtcbiAgICAgIGlmIChzaW1wbGVQYXRoWzJdKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gc2ltcGxlUGF0aFsyXTtcbiAgICAgICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5zZWFyY2guc2xpY2UoMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucXVlcnkgPSB0aGlzLnNlYXJjaC5zbGljZSgxKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gJyc7XG4gICAgICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHZhciBwcm90byA9IHByb3RvY29sUGF0dGVybi5leGVjKHJlc3QpO1xuICBpZiAocHJvdG8pIHtcbiAgICBwcm90byA9IHByb3RvWzBdO1xuICAgIHZhciBsb3dlclByb3RvID0gcHJvdG8udG9Mb3dlckNhc2UoKTtcbiAgICB0aGlzLnByb3RvY29sID0gbG93ZXJQcm90bztcbiAgICByZXN0ID0gcmVzdC5zbGljZShwcm90by5sZW5ndGgpO1xuICB9XG5cbiAgLy8gZmlndXJlIG91dCBpZiBpdCdzIGdvdCBhIGhvc3RcbiAgLy8gdXNlckBzZXJ2ZXIgaXMgKmFsd2F5cyogaW50ZXJwcmV0ZWQgYXMgYSBob3N0bmFtZSwgYW5kIHVybFxuICAvLyByZXNvbHV0aW9uIHdpbGwgdHJlYXQgLy9mb28vYmFyIGFzIGhvc3Q9Zm9vLHBhdGg9YmFyIGJlY2F1c2UgdGhhdCdzXG4gIC8vIGhvdyB0aGUgYnJvd3NlciByZXNvbHZlcyByZWxhdGl2ZSBVUkxzLlxuICBpZiAoc2xhc2hlc0Rlbm90ZUhvc3QgfHwgcHJvdG8gfHwgL15cXC9cXC9bXkBcXC9dK0BbXkBcXC9dKy8udGVzdChyZXN0KSkge1xuICAgIHZhciBzbGFzaGVzID0gcmVzdC5jaGFyQ29kZUF0KDApID09PSA0NyAvKi8qLyAmJiByZXN0LmNoYXJDb2RlQXQoMSkgPT09IDQ3OyAvKi8qL1xuICAgIGlmIChzbGFzaGVzICYmICEocHJvdG8gJiYgaG9zdGxlc3NQcm90b2NvbFtwcm90b10pKSB7XG4gICAgICByZXN0ID0gcmVzdC5zbGljZSgyKTtcbiAgICAgIHRoaXMuc2xhc2hlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFob3N0bGVzc1Byb3RvY29sW3Byb3RvXSAmJiAoc2xhc2hlcyB8fCAocHJvdG8gJiYgIXNsYXNoZWRQcm90b2NvbFtwcm90b10pKSkge1xuICAgIC8vIHRoZXJlJ3MgYSBob3N0bmFtZS5cbiAgICAvLyB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgLywgPywgOywgb3IgIyBlbmRzIHRoZSBob3N0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gQCBpbiB0aGUgaG9zdG5hbWUsIHRoZW4gbm9uLWhvc3QgY2hhcnMgKmFyZSogYWxsb3dlZFxuICAgIC8vIHRvIHRoZSBsZWZ0IG9mIHRoZSBsYXN0IEAgc2lnbiwgdW5sZXNzIHNvbWUgaG9zdC1lbmRpbmcgY2hhcmFjdGVyXG4gICAgLy8gY29tZXMgKmJlZm9yZSogdGhlIEAtc2lnbi5cbiAgICAvLyBVUkxzIGFyZSBvYm5veGlvdXMuXG4gICAgLy9cbiAgICAvLyBleDpcbiAgICAvLyBodHRwOi8vYUBiQGMvID0+IHVzZXI6YUBiIGhvc3Q6Y1xuICAgIC8vIGh0dHA6Ly9hQGI/QGMgPT4gdXNlcjphIGhvc3Q6YiBwYXRoOi8/QGNcblxuICAgIC8vIHYwLjEyIFRPRE8oaXNhYWNzKTogVGhpcyBpcyBub3QgcXVpdGUgaG93IENocm9tZSBkb2VzIHRoaW5ncy5cbiAgICAvLyBSZXZpZXcgb3VyIHRlc3QgY2FzZSBhZ2FpbnN0IGJyb3dzZXJzIG1vcmUgY29tcHJlaGVuc2l2ZWx5LlxuXG4gICAgdmFyIGhvc3RFbmQgPSAtMTtcbiAgICB2YXIgYXRTaWduID0gLTE7XG4gICAgdmFyIG5vbkhvc3QgPSAtMTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7ICsraSkge1xuICAgICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgICAgY2FzZSA5OiAvLyAnXFx0J1xuICAgICAgICBjYXNlIDEwOiAvLyAnXFxuJ1xuICAgICAgICBjYXNlIDEzOiAvLyAnXFxyJ1xuICAgICAgICBjYXNlIDMyOiAvLyAnICdcbiAgICAgICAgY2FzZSAzNDogLy8gJ1wiJ1xuICAgICAgICBjYXNlIDM3OiAvLyAnJSdcbiAgICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgY2FzZSA1OTogLy8gJzsnXG4gICAgICAgIGNhc2UgNjA6IC8vICc8J1xuICAgICAgICBjYXNlIDYyOiAvLyAnPidcbiAgICAgICAgY2FzZSA5MjogLy8gJ1xcXFwnXG4gICAgICAgIGNhc2UgOTQ6IC8vICdeJ1xuICAgICAgICBjYXNlIDk2OiAvLyAnYCdcbiAgICAgICAgY2FzZSAxMjM6IC8vICd7J1xuICAgICAgICBjYXNlIDEyNDogLy8gJ3wnXG4gICAgICAgIGNhc2UgMTI1OiAvLyAnfSdcbiAgICAgICAgICAvLyBDaGFyYWN0ZXJzIHRoYXQgYXJlIG5ldmVyIGV2ZXIgYWxsb3dlZCBpbiBhIGhvc3RuYW1lIGZyb20gUkZDIDIzOTZcbiAgICAgICAgICBpZiAobm9uSG9zdCA9PT0gLTEpIG5vbkhvc3QgPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM1OiAvLyAnIydcbiAgICAgICAgY2FzZSA0NzogLy8gJy8nXG4gICAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSBob3N0LWVuZGluZyBjaGFyYWN0ZXJzXG4gICAgICAgICAgaWYgKG5vbkhvc3QgPT09IC0xKSBub25Ib3N0ID0gaTtcbiAgICAgICAgICBob3N0RW5kID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA2NDogLy8gJ0AnXG4gICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgZWl0aGVyIHdlIGhhdmUgYW4gZXhwbGljaXQgcG9pbnQgd2hlcmUgdGhlXG4gICAgICAgICAgLy8gYXV0aCBwb3J0aW9uIGNhbm5vdCBnbyBwYXN0LCBvciB0aGUgbGFzdCBAIGNoYXIgaXMgdGhlIGRlY2lkZXIuXG4gICAgICAgICAgYXRTaWduID0gaTtcbiAgICAgICAgICBub25Ib3N0ID0gLTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoaG9zdEVuZCAhPT0gLTEpIGJyZWFrO1xuICAgIH1cbiAgICBzdGFydCA9IDA7XG4gICAgaWYgKGF0U2lnbiAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYXV0aCA9IGRlY29kZVVSSUNvbXBvbmVudChyZXN0LnNsaWNlKDAsIGF0U2lnbikpO1xuICAgICAgc3RhcnQgPSBhdFNpZ24gKyAxO1xuICAgIH1cbiAgICBpZiAobm9uSG9zdCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuaG9zdCA9IHJlc3Quc2xpY2Uoc3RhcnQpO1xuICAgICAgcmVzdCA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhvc3QgPSByZXN0LnNsaWNlKHN0YXJ0LCBub25Ib3N0KTtcbiAgICAgIHJlc3QgPSByZXN0LnNsaWNlKG5vbkhvc3QpO1xuICAgIH1cblxuICAgIC8vIHB1bGwgb3V0IHBvcnQuXG4gICAgdGhpcy5wYXJzZUhvc3QoKTtcblxuICAgIC8vIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgLy8gc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICBpZiAodHlwZW9mIHRoaXMuaG9zdG5hbWUgIT09ICdzdHJpbmcnKSB0aGlzLmhvc3RuYW1lID0gJyc7XG5cbiAgICB2YXIgaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lO1xuXG4gICAgLy8gaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAvLyBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID1cbiAgICAgIGhvc3RuYW1lLmNoYXJDb2RlQXQoMCkgPT09IDkxIC8qWyovICYmIGhvc3RuYW1lLmNoYXJDb2RlQXQoaG9zdG5hbWUubGVuZ3RoIC0gMSkgPT09IDkzOyAvKl0qL1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlSG9zdG5hbWUodGhpcywgcmVzdCwgaG9zdG5hbWUpO1xuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIGhvc3RuYW1lcyBhcmUgYWx3YXlzIGxvd2VyIGNhc2UuXG4gICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICAvLyBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55Y29kZWQgcmVwcmVzZW50YXRpb24gb2YgXCJkb21haW5cIi5cbiAgICAgIC8vIEl0IG9ubHkgY29udmVydHMgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHRoYXRcbiAgICAgIC8vIGhhdmUgbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIGkuZS4gaXQgZG9lc24ndCBtYXR0ZXIgaWZcbiAgICAgIC8vIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIEFTQ0lJLW9ubHkuXG4gICAgICB0aGlzLmhvc3RuYW1lID0gcHVueWNvZGUudG9BU0NJSSh0aGlzLmhvc3RuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMucG9ydCA/ICc6JyArIHRoaXMucG9ydCA6ICcnO1xuICAgIHZhciBoID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcbiAgICB0aGlzLmhvc3QgPSBoICsgcDtcblxuICAgIC8vIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAvLyB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnNsaWNlKDEsIC0xKTtcbiAgICAgIGlmIChyZXN0WzBdICE9PSAnLycpIHtcbiAgICAgICAgcmVzdCA9ICcvJyArIHJlc3Q7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gbm93IHJlc3QgaXMgc2V0IHRvIHRoZSBwb3N0LWhvc3Qgc3R1ZmYuXG4gIC8vIGNob3Agb2ZmIGFueSBkZWxpbSBjaGFycy5cbiAgaWYgKCF1bnNhZmVQcm90b2NvbFtsb3dlclByb3RvXSkge1xuICAgIC8vIEZpcnN0LCBtYWtlIDEwMCUgc3VyZSB0aGF0IGFueSBcImF1dG9Fc2NhcGVcIiBjaGFycyBnZXRcbiAgICAvLyBlc2NhcGVkLCBldmVuIGlmIGVuY29kZVVSSUNvbXBvbmVudCBkb2Vzbid0IHRoaW5rIHRoZXlcbiAgICAvLyBuZWVkIHRvIGJlLlxuICAgIGNvbnN0IHJlc3VsdCA9IGF1dG9Fc2NhcGVTdHIocmVzdCk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICB9XG5cbiAgdmFyIHF1ZXN0aW9uSWR4ID0gLTE7XG4gIHZhciBoYXNoSWR4ID0gLTE7XG4gIGZvciAoaSA9IDA7IGkgPCByZXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHJlc3QuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gMzUgLyojKi8pIHtcbiAgICAgIHRoaXMuaGFzaCA9IHJlc3Quc2xpY2UoaSk7XG4gICAgICBoYXNoSWR4ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoY29kZSA9PT0gNjMgLyo/Ki8gJiYgcXVlc3Rpb25JZHggPT09IC0xKSB7XG4gICAgICBxdWVzdGlvbklkeCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXN0aW9uSWR4ICE9PSAtMSkge1xuICAgIGlmIChoYXNoSWR4ID09PSAtMSkge1xuICAgICAgdGhpcy5zZWFyY2ggPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4KTtcbiAgICAgIHRoaXMucXVlcnkgPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCwgaGFzaElkeCk7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCArIDEsIGhhc2hJZHgpO1xuICAgIH1cbiAgICBpZiAocGFyc2VRdWVyeVN0cmluZykge1xuICAgICAgdGhpcy5xdWVyeSA9IHF1ZXJ5c3RyaW5nLnBhcnNlKHRoaXMucXVlcnkpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuXG4gIHZhciBmaXJzdElkeCA9XG4gICAgcXVlc3Rpb25JZHggIT09IC0xICYmIChoYXNoSWR4ID09PSAtMSB8fCBxdWVzdGlvbklkeCA8IGhhc2hJZHgpID8gcXVlc3Rpb25JZHggOiBoYXNoSWR4O1xuICBpZiAoZmlyc3RJZHggPT09IC0xKSB7XG4gICAgaWYgKHJlc3QubGVuZ3RoID4gMCkgdGhpcy5wYXRobmFtZSA9IHJlc3Q7XG4gIH0gZWxzZSBpZiAoZmlyc3RJZHggPiAwKSB7XG4gICAgdGhpcy5wYXRobmFtZSA9IHJlc3Quc2xpY2UoMCwgZmlyc3RJZHgpO1xuICB9XG4gIGlmIChzbGFzaGVkUHJvdG9jb2xbbG93ZXJQcm90b10gJiYgdGhpcy5ob3N0bmFtZSAmJiAhdGhpcy5wYXRobmFtZSkge1xuICAgIHRoaXMucGF0aG5hbWUgPSAnLyc7XG4gIH1cblxuICAvLyB0byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICBpZiAodGhpcy5wYXRobmFtZSB8fCB0aGlzLnNlYXJjaCkge1xuICAgIGNvbnN0IHAgPSB0aGlzLnBhdGhuYW1lIHx8ICcnO1xuICAgIGNvbnN0IHMgPSB0aGlzLnNlYXJjaCB8fCAnJztcbiAgICB0aGlzLnBhdGggPSBwICsgcztcbiAgfVxuXG4gIC8vIGZpbmFsbHksIHJlY29uc3RydWN0IHRoZSBocmVmIGJhc2VkIG9uIHdoYXQgaGFzIGJlZW4gdmFsaWRhdGVkLlxuICB0aGlzLmhyZWYgPSB0aGlzLmZvcm1hdCgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB2YWxpZGF0ZUhvc3RuYW1lKHNlbGYsIHJlc3QsIGhvc3RuYW1lKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsYXN0UG9zOyBpIDw9IGhvc3RuYW1lLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvZGU7XG4gICAgaWYgKGkgPCBob3N0bmFtZS5sZW5ndGgpIGNvZGUgPSBob3N0bmFtZS5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChjb2RlID09PSA0NiAvKi4qLyB8fCBpID09PSBob3N0bmFtZS5sZW5ndGgpIHtcbiAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIHtcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gNjMpIHtcbiAgICAgICAgICBzZWxmLmhvc3RuYW1lID0gaG9zdG5hbWUuc2xpY2UoMCwgbGFzdFBvcyArIDYzKTtcbiAgICAgICAgICByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UobGFzdFBvcyArIDYzKSArIHJlc3Q7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAoY29kZSA+PSA0OCAvKjAqLyAmJiBjb2RlIDw9IDU3KSAvKjkqLyB8fFxuICAgICAgKGNvZGUgPj0gOTcgLyphKi8gJiYgY29kZSA8PSAxMjIpIC8qeiovIHx8XG4gICAgICBjb2RlID09PSA0NSAvKi0qLyB8fFxuICAgICAgKGNvZGUgPj0gNjUgLypBKi8gJiYgY29kZSA8PSA5MCkgLypaKi8gfHxcbiAgICAgIGNvZGUgPT09IDQzIC8qKyovIHx8XG4gICAgICBjb2RlID09PSA5NSAvKl8qLyB8fFxuICAgICAgLyogQkVHSU4gTU9OR08gVVJJIFBBVENIICovXG4gICAgICBjb2RlID09PSA0NCAvKiwqLyB8fFxuICAgICAgY29kZSA9PT0gNTggLyo6Ki8gfHxcbiAgICAgIC8qIEVORCBNT05HTyBVUkkgUEFUQ0ggKi9cbiAgICAgIGNvZGUgPiAxMjdcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICAvLyBJbnZhbGlkIGhvc3QgY2hhcmFjdGVyXG4gICAgc2VsZi5ob3N0bmFtZSA9IGhvc3RuYW1lLnNsaWNlKDAsIGkpO1xuICAgIGlmIChpIDwgaG9zdG5hbWUubGVuZ3RoKSByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UoaSkgKyByZXN0O1xuICAgIGJyZWFrO1xuICB9XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBhdXRvRXNjYXBlU3RyKHJlc3QpIHtcbiAgdmFyIG5ld1Jlc3QgPSAnJztcbiAgdmFyIGxhc3RQb3MgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJlc3QubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBBdXRvbWF0aWNhbGx5IGVzY2FwZSBhbGwgZGVsaW1pdGVycyBhbmQgdW53aXNlIGNoYXJhY3RlcnMgZnJvbSBSRkMgMjM5NlxuICAgIC8vIEFsc28gZXNjYXBlIHNpbmdsZSBxdW90ZXMgaW4gY2FzZSBvZiBhbiBYU1MgYXR0YWNrXG4gICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgIGNhc2UgOTogLy8gJ1xcdCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMDknO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMDogLy8gJ1xcbidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEEnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMzogLy8gJ1xccidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEQnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMjogLy8gJyAnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTIwJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzQ6IC8vICdcIidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjInO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjcnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2MDogLy8gJzwnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTNDJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjI6IC8vICc+J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyUzRSc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclNUMnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5NDogLy8gJ14nXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTVFJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgOTY6IC8vICdgJ1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU2MCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyMzogLy8gJ3snXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTdCJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI0OiAvLyAnfCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclN0MnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjU6IC8vICd9J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU3RCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID09PSAwKSByZXR1cm47XG4gIGlmIChsYXN0UG9zIDwgcmVzdC5sZW5ndGgpIHJldHVybiBuZXdSZXN0ICsgcmVzdC5zbGljZShsYXN0UG9zKTtcbiAgZWxzZSByZXR1cm4gbmV3UmVzdDtcbn1cblxuLy8gZm9ybWF0IGEgcGFyc2VkIG9iamVjdCBpbnRvIGEgdXJsIHN0cmluZ1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybEZvcm1hdChvYmopIHtcbiAgLy8gZW5zdXJlIGl0J3MgYW4gb2JqZWN0LCBhbmQgbm90IGEgc3RyaW5nIHVybC5cbiAgLy8gSWYgaXQncyBhbiBvYmosIHRoaXMgaXMgYSBuby1vcC5cbiAgLy8gdGhpcyB3YXksIHlvdSBjYW4gY2FsbCB1cmxfZm9ybWF0KCkgb24gc3RyaW5nc1xuICAvLyB0byBjbGVhbiB1cCBwb3RlbnRpYWxseSB3b25reSB1cmxzLlxuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIG9iaiA9IHVybFBhcnNlKG9iaik7XG4gIGVsc2UgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1BhcmFtZXRlciBcInVybE9ialwiIG11c3QgYmUgYW4gb2JqZWN0LCBub3QgJyArIG9iaiA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiBvYmpcbiAgICApO1xuICBlbHNlIGlmICghKG9iaiBpbnN0YW5jZW9mIFVybCkpIHJldHVybiBVcmwucHJvdG90eXBlLmZvcm1hdC5jYWxsKG9iaik7XG5cbiAgcmV0dXJuIG9iai5mb3JtYXQoKTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXV0aCA9IHRoaXMuYXV0aCB8fCAnJztcbiAgaWYgKGF1dGgpIHtcbiAgICBhdXRoID0gZW5jb2RlQXV0aChhdXRoKTtcbiAgICBhdXRoICs9ICdAJztcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHRoaXMucHJvdG9jb2wgfHwgJyc7XG4gIHZhciBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJyc7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoIHx8ICcnO1xuICB2YXIgaG9zdCA9IGZhbHNlO1xuICB2YXIgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/IHRoaXMuaG9zdG5hbWUgOiAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5xdWVyeSA9PT0gJ29iamVjdCcpXG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSk7XG5cbiAgdmFyIHNlYXJjaCA9IHRoaXMuc2VhcmNoIHx8IChxdWVyeSAmJiAnPycgKyBxdWVyeSkgfHwgJyc7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLmNoYXJDb2RlQXQocHJvdG9jb2wubGVuZ3RoIC0gMSkgIT09IDU4IC8qOiovKSBwcm90b2NvbCArPSAnOic7XG5cbiAgdmFyIG5ld1BhdGhuYW1lID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRobmFtZS5sZW5ndGg7ICsraSkge1xuICAgIHN3aXRjaCAocGF0aG5hbWUuY2hhckNvZGVBdChpKSkge1xuICAgICAgY2FzZSAzNTogLy8gJyMnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1BhdGhuYW1lICs9IHBhdGhuYW1lLnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdQYXRobmFtZSArPSAnJTIzJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdQYXRobmFtZSArPSBwYXRobmFtZS5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UGF0aG5hbWUgKz0gJyUzRic7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID4gMCkge1xuICAgIGlmIChsYXN0UG9zICE9PSBwYXRobmFtZS5sZW5ndGgpIHBhdGhuYW1lID0gbmV3UGF0aG5hbWUgKyBwYXRobmFtZS5zbGljZShsYXN0UG9zKTtcbiAgICBlbHNlIHBhdGhuYW1lID0gbmV3UGF0aG5hbWU7XG4gIH1cblxuICAvLyBvbmx5IHRoZSBzbGFzaGVkUHJvdG9jb2xzIGdldCB0aGUgLy8uICBOb3QgbWFpbHRvOiwgeG1wcDosIGV0Yy5cbiAgLy8gdW5sZXNzIHRoZXkgaGFkIHRoZW0gdG8gYmVnaW4gd2l0aC5cbiAgaWYgKHRoaXMuc2xhc2hlcyB8fCAoKCFwcm90b2NvbCB8fCBzbGFzaGVkUHJvdG9jb2xbcHJvdG9jb2xdKSAmJiBob3N0ICE9PSBmYWxzZSkpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckNvZGVBdCgwKSAhPT0gNDcgLyovKi8pIHBhdGhuYW1lID0gJy8nICsgcGF0aG5hbWU7XG4gIH0gZWxzZSBpZiAoIWhvc3QpIHtcbiAgICBob3N0ID0gJyc7XG4gIH1cblxuICBzZWFyY2ggPSBzZWFyY2gucmVwbGFjZSgnIycsICclMjMnKTtcblxuICBpZiAoaGFzaCAmJiBoYXNoLmNoYXJDb2RlQXQoMCkgIT09IDM1IC8qIyovKSBoYXNoID0gJyMnICsgaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2guY2hhckNvZGVBdCgwKSAhPT0gNjMgLyo/Ki8pIHNlYXJjaCA9ICc/JyArIHNlYXJjaDtcblxuICByZXR1cm4gcHJvdG9jb2wgKyBob3N0ICsgcGF0aG5hbWUgKyBzZWFyY2ggKyBoYXNoO1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybFJlc29sdmUoc291cmNlLCByZWxhdGl2ZSkge1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZShyZWxhdGl2ZSk7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5VcmwucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAocmVsYXRpdmUpIHtcbiAgcmV0dXJuIHRoaXMucmVzb2x2ZU9iamVjdCh1cmxQYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpKS5mb3JtYXQoKTtcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiByZWxhdGl2ZTtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmVPYmplY3QocmVsYXRpdmUpO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24gKHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgcmVsYXRpdmUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIHZhciB0a2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICBmb3IgKHZhciB0ayA9IDA7IHRrIDwgdGtleXMubGVuZ3RoOyB0aysrKSB7XG4gICAgdmFyIHRrZXkgPSB0a2V5c1t0a107XG4gICAgcmVzdWx0W3RrZXldID0gdGhpc1t0a2V5XTtcbiAgfVxuXG4gIC8vIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAvLyBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgcmVzdWx0Lmhhc2ggPSByZWxhdGl2ZS5oYXNoO1xuXG4gIC8vIGlmIHRoZSByZWxhdGl2ZSB1cmwgaXMgZW1wdHksIHRoZW4gdGhlcmUncyBub3RoaW5nIGxlZnQgdG8gZG8gaGVyZS5cbiAgaWYgKHJlbGF0aXZlLmhyZWYgPT09ICcnKSB7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGhyZWZzIGxpa2UgLy9mb28vYmFyIGFsd2F5cyBjdXQgdG8gdGhlIHByb3RvY29sLlxuICBpZiAocmVsYXRpdmUuc2xhc2hlcyAmJiAhcmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAvLyB0YWtlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBwcm90b2NvbCBmcm9tIHJlbGF0aXZlXG4gICAgdmFyIHJrZXlzID0gT2JqZWN0LmtleXMocmVsYXRpdmUpO1xuICAgIGZvciAodmFyIHJrID0gMDsgcmsgPCBya2V5cy5sZW5ndGg7IHJrKyspIHtcbiAgICAgIHZhciBya2V5ID0gcmtleXNbcmtdO1xuICAgICAgaWYgKHJrZXkgIT09ICdwcm90b2NvbCcpIHJlc3VsdFtya2V5XSA9IHJlbGF0aXZlW3JrZXldO1xuICAgIH1cblxuICAgIC8vdXJsUGFyc2UgYXBwZW5kcyB0cmFpbGluZyAvIHRvIHVybHMgbGlrZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tXG4gICAgaWYgKHNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdICYmIHJlc3VsdC5ob3N0bmFtZSAmJiAhcmVzdWx0LnBhdGhuYW1lKSB7XG4gICAgICByZXN1bHQucGF0aCA9IHJlc3VsdC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKHJlbGF0aXZlLnByb3RvY29sICYmIHJlbGF0aXZlLnByb3RvY29sICE9PSByZXN1bHQucHJvdG9jb2wpIHtcbiAgICAvLyBpZiBpdCdzIGEga25vd24gdXJsIHByb3RvY29sLCB0aGVuIGNoYW5naW5nXG4gICAgLy8gdGhlIHByb3RvY29sIGRvZXMgd2VpcmQgdGhpbmdzXG4gICAgLy8gZmlyc3QsIGlmIGl0J3Mgbm90IGZpbGU6LCB0aGVuIHdlIE1VU1QgaGF2ZSBhIGhvc3QsXG4gICAgLy8gYW5kIGlmIHRoZXJlIHdhcyBhIHBhdGhcbiAgICAvLyB0byBiZWdpbiB3aXRoLCB0aGVuIHdlIE1VU1QgaGF2ZSBhIHBhdGguXG4gICAgLy8gaWYgaXQgaXMgZmlsZTosIHRoZW4gdGhlIGhvc3QgaXMgZHJvcHBlZCxcbiAgICAvLyBiZWNhdXNlIHRoYXQncyBrbm93biB0byBiZSBob3N0bGVzcy5cbiAgICAvLyBhbnl0aGluZyBlbHNlIGlzIGFzc3VtZWQgdG8gYmUgYWJzb2x1dGUuXG4gICAgaWYgKCFzbGFzaGVkUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHJlbGF0aXZlKTtcbiAgICAgIGZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICAgICAgICB2YXIgayA9IGtleXNbdl07XG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgICAgfVxuICAgICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJlc3VsdC5wcm90b2NvbCA9IHJlbGF0aXZlLnByb3RvY29sO1xuICAgIGlmIChcbiAgICAgICFyZWxhdGl2ZS5ob3N0ICYmXG4gICAgICAhL15maWxlOj8kLy50ZXN0KHJlbGF0aXZlLnByb3RvY29sKSAmJlxuICAgICAgIWhvc3RsZXNzUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdXG4gICAgKSB7XG4gICAgICBjb25zdCByZWxQYXRoID0gKHJlbGF0aXZlLnBhdGhuYW1lIHx8ICcnKS5zcGxpdCgnLycpO1xuICAgICAgd2hpbGUgKHJlbFBhdGgubGVuZ3RoICYmICEocmVsYXRpdmUuaG9zdCA9IHJlbFBhdGguc2hpZnQoKSkpO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0KSByZWxhdGl2ZS5ob3N0ID0gJyc7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSByZWxhdGl2ZS5ob3N0bmFtZSA9ICcnO1xuICAgICAgaWYgKHJlbFBhdGhbMF0gIT09ICcnKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgaWYgKHJlbFBhdGgubGVuZ3RoIDwgMikgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gcmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJztcbiAgdmFyIGlzUmVsQWJzID0gcmVsYXRpdmUuaG9zdCB8fCAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpO1xuICB2YXIgbXVzdEVuZEFicyA9IGlzUmVsQWJzIHx8IGlzU291cmNlQWJzIHx8IChyZXN1bHQuaG9zdCAmJiByZWxhdGl2ZS5wYXRobmFtZSk7XG4gIHZhciByZW1vdmVBbGxEb3RzID0gbXVzdEVuZEFicztcbiAgdmFyIHNyY1BhdGggPSAocmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5zcGxpdCgnLycpKSB8fCBbXTtcbiAgdmFyIHJlbFBhdGggPSAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSkgfHwgW107XG4gIHZhciBwc3ljaG90aWMgPSByZXN1bHQucHJvdG9jb2wgJiYgIXNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdO1xuXG4gIC8vIGlmIHRoZSB1cmwgaXMgYSBub24tc2xhc2hlZCB1cmwsIHRoZW4gcmVsYXRpdmVcbiAgLy8gbGlua3MgbGlrZSAuLi8uLiBzaG91bGQgYmUgYWJsZVxuICAvLyB0byBjcmF3bCB1cCB0byB0aGUgaG9zdG5hbWUsIGFzIHdlbGwuICBUaGlzIGlzIHN0cmFuZ2UuXG4gIC8vIHJlc3VsdC5wcm90b2NvbCBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSBub3cuXG4gIC8vIExhdGVyIG9uLCBwdXQgdGhlIGZpcnN0IHBhdGggcGFydCBpbnRvIHRoZSBob3N0IGZpZWxkLlxuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gJyc7XG4gICAgcmVzdWx0LnBvcnQgPSBudWxsO1xuICAgIGlmIChyZXN1bHQuaG9zdCkge1xuICAgICAgaWYgKHNyY1BhdGhbMF0gPT09ICcnKSBzcmNQYXRoWzBdID0gcmVzdWx0Lmhvc3Q7XG4gICAgICBlbHNlIHNyY1BhdGgudW5zaGlmdChyZXN1bHQuaG9zdCk7XG4gICAgfVxuICAgIHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgaWYgKHJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgICByZWxhdGl2ZS5ob3N0bmFtZSA9IG51bGw7XG4gICAgICByZWxhdGl2ZS5wb3J0ID0gbnVsbDtcbiAgICAgIGlmIChyZWxhdGl2ZS5ob3N0KSB7XG4gICAgICAgIGlmIChyZWxQYXRoWzBdID09PSAnJykgcmVsUGF0aFswXSA9IHJlbGF0aXZlLmhvc3Q7XG4gICAgICAgIGVsc2UgcmVsUGF0aC51bnNoaWZ0KHJlbGF0aXZlLmhvc3QpO1xuICAgICAgfVxuICAgICAgcmVsYXRpdmUuaG9zdCA9IG51bGw7XG4gICAgfVxuICAgIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzICYmIChyZWxQYXRoWzBdID09PSAnJyB8fCBzcmNQYXRoWzBdID09PSAnJyk7XG4gIH1cblxuICBpZiAoaXNSZWxBYnMpIHtcbiAgICAvLyBpdCdzIGFic29sdXRlLlxuICAgIHJlc3VsdC5ob3N0ID0gcmVsYXRpdmUuaG9zdCB8fCByZWxhdGl2ZS5ob3N0ID09PSAnJyA/IHJlbGF0aXZlLmhvc3QgOiByZXN1bHQuaG9zdDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPVxuICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdG5hbWUgPT09ICcnID8gcmVsYXRpdmUuaG9zdG5hbWUgOiByZXN1bHQuaG9zdG5hbWU7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICBzcmNQYXRoID0gcmVsUGF0aDtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gdGhlIGRvdC1oYW5kbGluZyBiZWxvdy5cbiAgfSBlbHNlIGlmIChyZWxQYXRoLmxlbmd0aCkge1xuICAgIC8vIGl0J3MgcmVsYXRpdmVcbiAgICAvLyB0aHJvdyBhd2F5IHRoZSBleGlzdGluZyBmaWxlLCBhbmQgdGFrZSB0aGUgbmV3IHBhdGggaW5zdGVhZC5cbiAgICBpZiAoIXNyY1BhdGgpIHNyY1BhdGggPSBbXTtcbiAgICBzcmNQYXRoLnBvcCgpO1xuICAgIHNyY1BhdGggPSBzcmNQYXRoLmNvbmNhdChyZWxQYXRoKTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKHJlbGF0aXZlLnNlYXJjaCAhPT0gbnVsbCAmJiByZWxhdGl2ZS5zZWFyY2ggIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGp1c3QgcHVsbCBvdXQgdGhlIHNlYXJjaC5cbiAgICAvLyBsaWtlIGhyZWY9Jz9mb28nLlxuICAgIC8vIFB1dCB0aGlzIGFmdGVyIHRoZSBvdGhlciB0d28gY2FzZXMgYmVjYXVzZSBpdCBzaW1wbGlmaWVzIHRoZSBib29sZWFuc1xuICAgIGlmIChwc3ljaG90aWMpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5zaGlmdCgpO1xuICAgICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAgIC8vdGhpcyBlc3BlY2lhbGx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgIGNvbnN0IGF1dGhJbkhvc3QgPVxuICAgICAgICByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBubyBwYXRoIGF0IGFsbC4gIGVhc3kuXG4gICAgLy8gd2UndmUgYWxyZWFkeSBoYW5kbGVkIHRoZSBvdGhlciBzdHVmZiBhYm92ZS5cbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgLy8gaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gIC8vIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIHZhciBsYXN0ID0gc3JjUGF0aC5zbGljZSgtMSlbMF07XG4gIHZhciBoYXNUcmFpbGluZ1NsYXNoID1cbiAgICAoKHJlc3VsdC5ob3N0IHx8IHJlbGF0aXZlLmhvc3QgfHwgc3JjUGF0aC5sZW5ndGggPiAxKSAmJiAobGFzdCA9PT0gJy4nIHx8IGxhc3QgPT09ICcuLicpKSB8fFxuICAgIGxhc3QgPT09ICcnO1xuXG4gIC8vIHN0cmlwIHNpbmdsZSBkb3RzLCByZXNvbHZlIGRvdWJsZSBkb3RzIHRvIHBhcmVudCBkaXJcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHNyY1BhdGgubGVuZ3RoOyBpID49IDA7IGktLSkge1xuICAgIGxhc3QgPSBzcmNQYXRoW2ldO1xuICAgIGlmIChsYXN0ID09PSAnLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09ICcuLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3BsaWNlT25lKHNyY1BhdGgsIGkpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGF0aCBpcyBhbGxvd2VkIHRvIGdvIGFib3ZlIHRoZSByb290LCByZXN0b3JlIGxlYWRpbmcgLi5zXG4gIGlmICghbXVzdEVuZEFicyAmJiAhcmVtb3ZlQWxsRG90cykge1xuICAgIGZvciAoOyB1cC0tOyB1cCkge1xuICAgICAgc3JjUGF0aC51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtdXN0RW5kQWJzICYmIHNyY1BhdGhbMF0gIT09ICcnICYmICghc3JjUGF0aFswXSB8fCBzcmNQYXRoWzBdLmNoYXJBdCgwKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoaGFzVHJhaWxpbmdTbGFzaCAmJiBzcmNQYXRoLmpvaW4oJy8nKS5zdWJzdHIoLTEpICE9PSAnLycpIHtcbiAgICBzcmNQYXRoLnB1c2goJycpO1xuICB9XG5cbiAgdmFyIGlzQWJzb2x1dGUgPSBzcmNQYXRoWzBdID09PSAnJyB8fCAoc3JjUGF0aFswXSAmJiBzcmNQYXRoWzBdLmNoYXJBdCgwKSA9PT0gJy8nKTtcblxuICAvLyBwdXQgdGhlIGhvc3QgYmFja1xuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5sZW5ndGggPyBzcmNQYXRoLnNoaWZ0KCkgOiAnJztcbiAgICB9XG4gICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAvL3RoaXMgZXNwZWNpYWxseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAvL3VybC5yZXNvbHZlT2JqZWN0KCdtYWlsdG86bG9jYWwxQGRvbWFpbjEnLCAnbG9jYWwyQGRvbWFpbjInKVxuICAgIGNvbnN0IGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgIH1cbiAgfVxuXG4gIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzIHx8IChyZXN1bHQuaG9zdCAmJiBzcmNQYXRoLmxlbmd0aCk7XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgIWlzQWJzb2x1dGUpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IHNyY1BhdGguam9pbignLycpO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgKyAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2VIb3N0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaG9zdCA9IHRoaXMuaG9zdDtcbiAgdmFyIHBvcnQgPSBwb3J0UGF0dGVybi5leGVjKGhvc3QpO1xuICBpZiAocG9ydCkge1xuICAgIHBvcnQgPSBwb3J0WzBdO1xuICAgIGlmIChwb3J0ICE9PSAnOicpIHtcbiAgICAgIHRoaXMucG9ydCA9IHBvcnQuc2xpY2UoMSk7XG4gICAgfVxuICAgIGhvc3QgPSBob3N0LnNsaWNlKDAsIGhvc3QubGVuZ3RoIC0gcG9ydC5sZW5ndGgpO1xuICB9XG4gIGlmIChob3N0KSB0aGlzLmhvc3RuYW1lID0gaG9zdDtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICh2YXIgaSA9IGluZGV4LCBrID0gaSArIDEsIG4gPSBsaXN0Lmxlbmd0aDsgayA8IG47IGkgKz0gMSwgayArPSAxKSBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxudmFyIGhleFRhYmxlID0gbmV3IEFycmF5KDI1Nik7XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKVxuICBoZXhUYWJsZVtpXSA9ICclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCk7XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gZW5jb2RlQXV0aChzdHIpIHtcbiAgLy8gZmFzdGVyIGVuY29kZVVSSUNvbXBvbmVudCBhbHRlcm5hdGl2ZSBmb3IgZW5jb2RpbmcgYXV0aCB1cmkgY29tcG9uZW50c1xuICB2YXIgb3V0ID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gVGhlc2UgY2hhcmFjdGVycyBkbyBub3QgbmVlZCBlc2NhcGluZzpcbiAgICAvLyAhIC0gLiBfIH5cbiAgICAvLyAnICggKSAqIDpcbiAgICAvLyBkaWdpdHNcbiAgICAvLyBhbHBoYSAodXBwZXJjYXNlKVxuICAgIC8vIGFscGhhIChsb3dlcmNhc2UpXG4gICAgaWYgKFxuICAgICAgYyA9PT0gMHgyMSB8fFxuICAgICAgYyA9PT0gMHgyZCB8fFxuICAgICAgYyA9PT0gMHgyZSB8fFxuICAgICAgYyA9PT0gMHg1ZiB8fFxuICAgICAgYyA9PT0gMHg3ZSB8fFxuICAgICAgKGMgPj0gMHgyNyAmJiBjIDw9IDB4MmEpIHx8XG4gICAgICAoYyA+PSAweDMwICYmIGMgPD0gMHgzYSkgfHxcbiAgICAgIChjID49IDB4NDEgJiYgYyA8PSAweDVhKSB8fFxuICAgICAgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N2EpXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBvdXQgKz0gc3RyLnNsaWNlKGxhc3RQb3MsIGkpO1xuXG4gICAgbGFzdFBvcyA9IGkgKyAxO1xuXG4gICAgLy8gT3RoZXIgQVNDSUkgY2hhcmFjdGVyc1xuICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgb3V0ICs9IGhleFRhYmxlW2NdO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gTXVsdGktYnl0ZSBjaGFyYWN0ZXJzIC4uLlxuICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgIG91dCArPSBoZXhUYWJsZVsweGMwIHwgKGMgPj4gNildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChjIDwgMHhkODAwIHx8IGMgPj0gMHhlMDAwKSB7XG4gICAgICBvdXQgKz1cbiAgICAgICAgaGV4VGFibGVbMHhlMCB8IChjID4+IDEyKV0gK1xuICAgICAgICBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzZildICtcbiAgICAgICAgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIC8vIFN1cnJvZ2F0ZSBwYWlyXG4gICAgKytpO1xuICAgIHZhciBjMjtcbiAgICBpZiAoaSA8IHN0ci5sZW5ndGgpIGMyID0gc3RyLmNoYXJDb2RlQXQoaSkgJiAweDNmZjtcbiAgICBlbHNlIGMyID0gMDtcbiAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNmZikgPDwgMTApIHwgYzIpO1xuICAgIG91dCArPVxuICAgICAgaGV4VGFibGVbMHhmMCB8IChjID4+IDE4KV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNmKV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M2YpXSArXG4gICAgICBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNmKV07XG4gIH1cbiAgaWYgKGxhc3RQb3MgPT09IDApIHJldHVybiBzdHI7XG4gIGlmIChsYXN0UG9zIDwgc3RyLmxlbmd0aCkgcmV0dXJuIG91dCArIHN0ci5zbGljZShsYXN0UG9zKTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ== \ No newline at end of file